From c464c27f6383e7de8dda606a198763bf71f6a91e Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 29 Feb 2024 18:54:54 +0100 Subject: [PATCH 01/41] adding comments to clarify that DMRS samples generated for channel estimation at reception already takes into account complex conjugate needed for said estimation --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 12 +++++++++-- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 20 +++++++++---------- .../nr_dl_channel_estimation.c | 19 ++++++++++++++---- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 36e737f0e6..9ca768f690 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -110,8 +110,16 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { - nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], (int32_t *)pilot, (1000+p), 0, nb_rb_pusch, - (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); + // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + nr_pusch_dmrs_rx(gNB, + Ns, + gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], + (int32_t *)pilot, + (1000 + p), + 0, + nb_rb_pusch, + (pusch_pdu->bwp_start + pusch_pdu->rb_start) * NR_NB_SC_PER_RB, + pusch_pdu->dmrs_config_type); } else { // if transform precoding or SC-FDMA is enabled in Uplink // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible const uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2)); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 5da33435ed..726d116457 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -195,9 +195,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, } -int nr_pbch_dmrs_rx(int symbol, - unsigned int *nr_gold_pbch, - int32_t *output) +int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) { int m,m0,m1; uint8_t idx=0; @@ -257,14 +255,14 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin } int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, - unsigned int Ns, - int16_t *dmrs_seq, - int32_t *output, - unsigned short p, - unsigned char lp, - unsigned short nb_pusch_rb, - uint32_t re_offset, - uint8_t dmrs_type) + unsigned int Ns, + int16_t *dmrs_seq, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pusch_rb, + uint32_t re_offset, + uint8_t dmrs_type) { int8_t w, nb_dmrs; int k; 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 a310e7d127..7cae5c135d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -658,7 +658,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif // generate pilot - nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); + // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -898,7 +899,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } // generate pilot - nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); + // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -1111,7 +1113,8 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, dmrs_ref = BWPStart; // generate pilot int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); - nr_pdcch_dmrs_rx(ue,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,(nb_rb_coreset+dmrs_ref)); + // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0], 2000, (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -1648,7 +1651,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } c16_t pilot[3280] __attribute__((aligned(16))); - nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], (int32_t *)pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type); + // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + nr_pdsch_dmrs_rx(ue, + Ns, + ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], + (int32_t *)pilot, + 1000 + p, + 0, + nb_rb_pdsch + rb_offset, + config_type); uint8_t nushift = 0; if (config_type == NFAPI_NR_DMRS_TYPE1) { From ed65b52c3c8b935d566665faba299832f4c966e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20da=20Silva?= Date: Wed, 28 Feb 2024 17:00:18 +0100 Subject: [PATCH 02/41] SCF222.10.02: PDUsize in DL_TTI.request is 4 bytes SCF 222.10.02, Table 3-35: the PDUSize parameter of a DL_TTI.request PDU includes the 4 bytes required for PDUType and PDUSize parameters (each 2 bytes), not 2. This is required for the Aerial interoperability. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 6f40b0ba52..9a554dc0bb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -412,7 +412,7 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + dl_tti_pdcch_pdu->PDUSize = (uint16_t)(4+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; nr_configure_pdcch(pdcch_pdu_rel15, @@ -422,7 +422,7 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + dl_tti_pdsch_pdu->PDUSize = (uint16_t)(4+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); dl_req->nPDUs += 1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; From 2129ee3c9c6d5970e27caa5c994fa777c172df31 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 1 Mar 2024 13:02:03 +0100 Subject: [PATCH 03/41] remove global visibility of log variables, remove circular .h dependancy --- common/utils/LOG/log.c | 52 ++++++++----------- common/utils/LOG/log.h | 5 +- common/utils/LOG/log_extern.h | 31 ----------- common/utils/LOG/log_if.h | 34 ------------ doc/Doxyfile | 1 - executables/nr-gnb.c | 2 +- executables/softmodem-common.c | 6 +-- openair1/PHY/defs_common.h | 2 +- openair1/SIMULATION/LTE_PHY/framegen.c | 2 +- openair1/SIMULATION/LTE_PHY/pucchsim.c | 2 +- openair2/E1AP/e1ap_setup.c | 1 - openair2/ENB_APP/NB_IoT_config.c | 1 - openair2/GNB_APP/gnb_config.c | 1 - .../PDCP_v10.1.0/pdcp_sequence_manager.c | 2 +- openair2/UTIL/CLI/cli_cmd.c | 1 - openair2/UTIL/OPT/opt.h | 2 +- radio/IRIS/iris_lib.cpp | 2 +- targets/TEST/AT_COMMANDS/oaisim.c | 3 +- targets/TEST/PDCP/test_pdcp.c | 2 +- targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c | 3 +- 20 files changed, 36 insertions(+), 119 deletions(-) delete mode 100644 common/utils/LOG/log_extern.h delete mode 100644 common/utils/LOG/log_if.h diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index d2ef196e55..0d0bc144f7 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -46,7 +46,7 @@ #include #include #include -#include "common/utils/LOG/log_extern.h" +#include "common/utils/LOG/log.h" // main log variables @@ -58,18 +58,16 @@ void read_cpu_hardware (void) __attribute__ ((constructor)); void read_cpu_hardware (void) {} #endif -log_mem_cnt_t log_mem_d[2]; -int log_mem_flag = 0; +static log_mem_cnt_t log_mem_d[2]; +static int log_mem_flag = 0; volatile int log_mem_side=0; -pthread_mutex_t log_mem_lock; -pthread_cond_t log_mem_notify; -pthread_t log_mem_thread; -int log_mem_file_cnt=0; +static pthread_mutex_t log_mem_lock; +static pthread_cond_t log_mem_notify; +static pthread_t log_mem_thread; +static int log_mem_file_cnt=0; volatile int log_mem_write_flag=0; volatile int log_mem_write_side=0; -char __log_mem_filename[1024]={0}; -char * log_mem_filename = &__log_mem_filename[0]; -char logmem_filename[1024] = {0}; +static char * log_mem_filename; const mapping log_level_names[] = {{"error", OAILOG_ERR}, {"warn", OAILOG_WARNING}, @@ -935,28 +933,22 @@ static void log_output_memory(log_component_t *c, const char *file, const char * } } -int logInit_log_mem (void) +int logInit_log_mem (char * filename) { - if (log_mem_flag == 1) { - log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE); - log_mem_d[0].buf_index = 0; - log_mem_d[0].enable_flag = 1; - log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE); - log_mem_d[1].buf_index = 0; - log_mem_d[1].enable_flag = 1; - log_mem_side = 0; - if ((pthread_mutex_init(&log_mem_lock, NULL) != 0) || (pthread_cond_init(&log_mem_notify, NULL) != 0)) { - log_mem_d[1].enable_flag=0; - return -1; - } - pthread_create(&log_mem_thread, NULL, (void *(*)(void *))flush_mem_to_file, (void *)NULL); - } else { - log_mem_d[0].buf_p = NULL; - log_mem_d[1].buf_p = NULL; - log_mem_d[0].enable_flag = 0; - log_mem_d[1].enable_flag = 0; + log_mem_flag = 1; + log_mem_filename = filename; // in present code, the parameter is safe permanent pointer + log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE); + log_mem_d[0].buf_index = 0; + log_mem_d[0].enable_flag = 1; + log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE); + log_mem_d[1].buf_index = 0; + log_mem_d[1].enable_flag = 1; + log_mem_side = 0; + if ((pthread_mutex_init(&log_mem_lock, NULL) != 0) || (pthread_cond_init(&log_mem_notify, NULL) != 0)) { + log_mem_d[1].enable_flag=0; + return -1; } - + pthread_create(&log_mem_thread, NULL, (void *(*)(void *))flush_mem_to_file, (void *)NULL); printf("log init done\n"); return 0; diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index eb557ed28f..af4c0fe82f 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -272,8 +272,7 @@ extern "C" { } #endif #endif -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log_if.h" + /*----------------------------------------------------------------------------*/ int logInit (void); void logTerm (void); @@ -299,7 +298,7 @@ int register_log_component(char *name, char *fext, int compidx); #define LOG_MEM_SIZE 100*1024*1024 #define LOG_MEM_FILE "./logmem.log" void flush_mem_to_file(void); -int logInit_log_mem(void); +int logInit_log_mem(char*); void close_log_mem(void); typedef struct { diff --git a/common/utils/LOG/log_extern.h b/common/utils/LOG/log_extern.h deleted file mode 100644 index 4a253530e7..0000000000 --- a/common/utils/LOG/log_extern.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "log.h" - -extern log_t *g_log; - -extern const mapping log_level_names[]; -extern const mapping log_options[]; -extern const mapping log_maskmap[]; -extern int log_mem_flag; -extern char * log_mem_filename; -extern char logmem_filename[1024]; diff --git a/common/utils/LOG/log_if.h b/common/utils/LOG/log_if.h deleted file mode 100644 index 531b9df62e..0000000000 --- a/common/utils/LOG/log_if.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file log_if.h -* \brief log interface -* \author Navid Nikaein -* \date 2009 - 2014 -* \version 0.3 -* \warning This component can be runned only in user-space -* @ingroup routing -*/ - -// LTS: kept this file for compatibility -// this file was probably a trial to separate internal functions and external ones -// but it has never been finished, most source code include directly log.h (not log_if.h) -#include "log.h" diff --git a/doc/Doxyfile b/doc/Doxyfile index c92e9fb336..53b59bb536 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -902,7 +902,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/vcd_signal_dumper.h \ @CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/log.c \ @CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/log.h \ -@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/log_extern.h \ @CMAKE_CURRENT_SOURCE_DIR@/../common/utils/time_stat.h \ @CMAKE_CURRENT_SOURCE_DIR@/../common/utils/ocp_itti/all_msg.h \ @CMAKE_CURRENT_SOURCE_DIR@/../common/utils/ocp_itti/intertask_interface.h \ diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 2a12126d7d..a67754e6f9 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -69,7 +69,7 @@ #include "common/ran_context.h" #include "RRC/LTE/rrc_extern.h" #include "PHY_INTERFACE/phy_interface.h" -#include "common/utils/LOG/log_extern.h" +#include "common/utils/LOG/log.h" #include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_externs.h" #include "UTIL/MATH/oml.h" diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index b750092a39..c4b25d7f20 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -138,10 +138,8 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask) } if (logmem_filename != NULL && strlen(logmem_filename) > 0) { - log_mem_filename = &logmem_filename[0]; - log_mem_flag = 1; - printf("Enabling OPT for log save at memory %s\n",log_mem_filename); - logInit_log_mem(); + printf("Enabling OPT for log save at memory %s\n",logmem_filename); + logInit_log_mem(logmem_filename); } if (noS1) { diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 7098bd8c6f..ff774d7789 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -953,7 +953,7 @@ typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_rela #define NB_BANDS_MAX 8 -#include "common/utils/LOG/log_extern.h" +#include "common/utils/LOG/log.h" extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c index 74f76e56b9..521df12ca1 100644 --- a/openair1/SIMULATION/LTE_PHY/framegen.c +++ b/openair1/SIMULATION/LTE_PHY/framegen.c @@ -39,7 +39,7 @@ #include "LAYER2/MAC/defs.h" #include "PHY_INTERFACE/defs.h" #include "LAYER2/MAC/vars.h" -#include "UTIL/LOG/log_extern.h" +#include "UTIL/LOG/log.h" uint16_t n_rnti = 0x1235; int n_users = 1; diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index f88934d380..2ca891f023 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -31,7 +31,7 @@ #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" -#include "UTIL/LOG/log_extern.h" +#include "UTIL/LOG/log.h" #include "unitary_defs.h" diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index 70f90b9a56..31dbf6e407 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -24,7 +24,6 @@ #include #include "common/utils/LOG/log.h" #include "common/utils/nr/nr_common.h" -#include "common/utils/LOG/log_extern.h" #include "assertions.h" #include "common/utils/ocp_itti/intertask_interface.h" #include "openair2/GNB_APP/gnb_paramdef.h" diff --git a/openair2/ENB_APP/NB_IoT_config.c b/openair2/ENB_APP/NB_IoT_config.c index 0bd30d86b3..35e3ade4a4 100644 --- a/openair2/ENB_APP/NB_IoT_config.c +++ b/openair2/ENB_APP/NB_IoT_config.c @@ -31,7 +31,6 @@ #include #include "log.h" -#include "log_extern.h" #include "assertions.h" #include "intertask_interface.h" #include "s1ap_eNB.h" diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 3b5d159d34..1046e24e11 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -32,7 +32,6 @@ #include "common/utils/LOG/log.h" #include "common/utils/nr/nr_common.h" -#include "common/utils/LOG/log_extern.h" #include "assertions.h" #include "oai_asn1.h" #include "executables/softmodem-common.h" diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c index 31beb3a9e0..69d355533a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c @@ -27,7 +27,7 @@ */ #include "pdcp_sequence_manager.h" -#include "common/utils//LOG/log_if.h" +#include "common/utils//LOG/log.h" #include "pdcp_util.h" /* diff --git a/openair2/UTIL/CLI/cli_cmd.c b/openair2/UTIL/CLI/cli_cmd.c index 021c7c0b97..59f6bebfd2 100644 --- a/openair2/UTIL/CLI/cli_cmd.c +++ b/openair2/UTIL/CLI/cli_cmd.c @@ -32,7 +32,6 @@ #include "cli.h" #include "log.h" -#include "log_extern.h" extern cli_config *cli_cfg; diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index ce890a7933..e3b8059f23 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -48,7 +48,7 @@ This header file must be included */ #endif #ifndef project_include #define project_include - #include "common/utils/LOG/log_if.h" + #include "common/utils/LOG/log.h" #include "PHY/defs_RU.h" #endif diff --git a/radio/IRIS/iris_lib.cpp b/radio/IRIS/iris_lib.cpp index 47f4d2b4ef..44cea81b4e 100644 --- a/radio/IRIS/iris_lib.cpp +++ b/radio/IRIS/iris_lib.cpp @@ -19,7 +19,7 @@ #include #include #include -#include "common/utils/LOG/log_extern.h" +#include "common/utils/LOG/log.h" #include "common_lib.h" #include diff --git a/targets/TEST/AT_COMMANDS/oaisim.c b/targets/TEST/AT_COMMANDS/oaisim.c index bbbbe3da5f..fa6a348c97 100644 --- a/targets/TEST/AT_COMMANDS/oaisim.c +++ b/targets/TEST/AT_COMMANDS/oaisim.c @@ -32,8 +32,7 @@ #include "LAYER2/RLC/AM_v9.3.0/rlc_am.h" #include "LAYER2/MAC/defs.h" #include "LAYER2/MAC/vars.h" -#include "UTIL/LOG/log_if.h" -#include "UTIL/LOG/log_extern.h" +#include "UTIL/LOG/log.h" #include "RRC/LTE/vars.h" #include "PHY_INTERFACE/vars.h" #include "UTIL/AT_COMMANDS/parser.h" diff --git a/targets/TEST/PDCP/test_pdcp.c b/targets/TEST/PDCP/test_pdcp.c index fb8259bbde..1e634fa74d 100644 --- a/targets/TEST/PDCP/test_pdcp.c +++ b/targets/TEST/PDCP/test_pdcp.c @@ -27,7 +27,7 @@ #include "MAC_INTERFACE/vars.h" #include "LAYER2/MAC/vars.h" -#include "UTIL/LOG/log_if.h" +#include "UTIL/LOG/log.h" #include "test_util.h" #include "test_pdcp.h" diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c index 7116f696dc..b60737dac8 100644 --- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c +++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c @@ -32,8 +32,7 @@ #include "LAYER2/MAC/defs.h" #include "LAYER2/MAC/vars.h" -#include "UTIL/LOG/log_if.h" -#include "UTIL/LOG/log_extern.h" +#include "UTIL/LOG/log.h" #include "RRC/LTE/vars.h" #include "PHY_INTERFACE/vars.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" From d1002cc72962c8a0b5fb608a92dcfb6ce70414de Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 1 Mar 2024 13:40:36 +0100 Subject: [PATCH 04/41] move declarations out from log.h to a better place --- common/utils/LOG/log.c | 9 +++++++++ common/utils/LOG/log.h | 11 ----------- common/utils/utils.h | 1 + openair2/PHY_INTERFACE/phy_stub_UE.c | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 0d0bc144f7..fa2d8b4c81 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -48,6 +48,8 @@ #include #include "common/utils/LOG/log.h" +#define LOG_MEM_SIZE 100*1024*1024 + // main log variables // Fixme: a better place to be shure it is called @@ -58,6 +60,13 @@ void read_cpu_hardware (void) __attribute__ ((constructor)); void read_cpu_hardware (void) {} #endif + +typedef struct { + char* buf_p; + int buf_index; + int enable_flag; +} log_mem_cnt_t; + static log_mem_cnt_t log_mem_d[2]; static int log_mem_flag = 0; volatile int log_mem_side=0; diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index af4c0fe82f..542ebaa73c 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -57,8 +57,6 @@ #ifdef NDEBUG #warning assert is disabled #endif -#define NUM_ELEMENTS(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0])) -#define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < NUM_ELEMENTS(ARRAY)) #ifdef __cplusplus extern "C" { @@ -295,17 +293,8 @@ int is_newline( char *str, int size); int register_log_component(char *name, char *fext, int compidx); -#define LOG_MEM_SIZE 100*1024*1024 -#define LOG_MEM_FILE "./logmem.log" -void flush_mem_to_file(void); int logInit_log_mem(char*); void close_log_mem(void); - -typedef struct { - char* buf_p; - int buf_index; - int enable_flag; -} log_mem_cnt_t; /** @}*/ diff --git a/common/utils/utils.h b/common/utils/utils.h index b1a7305cd4..3d0ae99417 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -18,6 +18,7 @@ extern "C" { #endif #define sizeofArray(a) (sizeof(a)/sizeof(*(a))) +#define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < sizeofArray(ARRAY)) #define cmax(a,b) ((a>b) ? (a) : (b)) #define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 58cd8eacf7..9b87f06ba8 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -1957,7 +1957,7 @@ static int get_mcs_from_sinr(float sinr) static int get_cqi_from_mcs(void) { static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; - assert(NUM_ELEMENTS(mcs_to_cqi) == NUM_MCS); + assert(sizeofArray(mcs_to_cqi) == NUM_MCS); int sf = 0; while(sf < NUM_NFAPI_SUBFRAME) { From bc6d1ad48d7caa7b2ae47c684a84629f9a2d79f8 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 1 Mar 2024 14:32:58 +0100 Subject: [PATCH 05/41] reduce the hot memory for LOG_x decision from 1.2MB to less than one mem page (4KB) --- common/utils/LOG/log.c | 24 +++++++++++++----------- common/utils/LOG/log.h | 15 ++++++++------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index fa2d8b4c81..e8b16ca480 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -416,8 +416,8 @@ int register_log_component(char *name, g_log->log_component[computed_compidx].name = strdup(name); g_log->log_component[computed_compidx].stream = stdout; g_log->log_component[computed_compidx].filelog = 0; - g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/.%s */ - sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext); + g_log->log_rarely_used[computed_compidx].filelog_name = malloc(strlen(name) + 16); /* /tmp/.%s */ + sprintf(g_log->log_rarely_used[computed_compidx].filelog_name, "/tmp/%s.%s", name, fext); } else { fprintf(stderr,"{LOG} %s %d Couldn't register component %s\n",__FILE__,__LINE__,name); } @@ -427,11 +427,13 @@ int register_log_component(char *name, static void unregister_all_log_components(void) { - log_component_t* lc = &g_log->log_component[0]; + log_component_t *lc = g_log->log_component; + log_component_back_t *lb = g_log->log_rarely_used; while (lc->name) { free((char *)lc->name); // defined as const, but assigned through strdup() - free(lc->filelog_name); + free(lb->filelog_name); lc++; + lb++; } } @@ -545,7 +547,7 @@ static inline int log_header(log_component_t *c, int line, int level) { - int flag= g_log->flag | c->flag; + int flag = g_log->flag; // | c->flag; char threadname[64]; if (flag & FLAG_THREAD ) { @@ -635,8 +637,8 @@ void log_dump(int component, va_list args; char *wbuf; log_component_t *c = &g_log->log_component[component]; - int flag= g_log->flag | c->flag; - + int flag = g_log->flag; // | c->flag; + switch(datatype) { case LOG_DUMP_DOUBLE: wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL); @@ -685,7 +687,7 @@ int set_log(int component, OAILOG_ERR); if ( g_log->log_component[component].level != OAILOG_DISABLE ) - g_log->log_component[component].savedlevel = g_log->log_component[component].level; + g_log->log_rarely_used[component].savedlevel = g_log->log_component[component].level; g_log->log_component[component].level = level; return 0; @@ -704,7 +706,7 @@ void set_glog_onlinelog(int enable) { for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { if ( enable ) { - g_log->log_component[c].level = g_log->log_component[c].savedlevel; + g_log->log_component[c].level = g_log->log_rarely_used[c].savedlevel; g_log->log_component[c].vprint = vfprintf; g_log->log_component[c].print = fprintf; g_log->log_component[c].stream = stdout; @@ -741,7 +743,7 @@ void set_glog_filelog(int enable) void set_component_filelog(int comp) { if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) { - g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w"); + g_log->log_component[comp].stream = fopen(g_log->log_rarely_used[comp].filelog_name, "w"); } g_log->log_component[comp].vprint = vfprintf; @@ -892,7 +894,7 @@ static void log_output_memory(log_component_t *c, const char *file, const char * len = MAX_LOG_TOTAL; } } - if ( !((g_log->flag | c->flag) & FLAG_NOCOLOR) ) { + if (!((g_log->flag /*| c->flag*/) & FLAG_NOCOLOR)) { int n = snprintf(log_buffer+len, MAX_LOG_TOTAL-len, "%s", log_level_highlight_end[level]); if (n > 0) { len += n; diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 542ebaa73c..a7aec50825 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -235,23 +235,24 @@ typedef struct { typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap ); typedef int(*log_print_func_t)(FILE *stream, const char *format, ... ); +typedef struct { + int savedlevel; + char *filelog_name; +} log_component_back_t; + typedef struct { const char *name; int level; - int savedlevel; - int flag; - int filelog; - char *filelog_name; + int filelog; FILE *stream; log_vprint_func_t vprint; - log_print_func_t print; - /* SR: make the log buffer component relative */ - // char log_buffer[MAX_LOG_TOTAL]; + log_print_func_t print; } log_component_t; typedef struct { log_component_t log_component[MAX_LOG_COMPONENTS]; + log_component_back_t log_rarely_used[MAX_LOG_COMPONENTS]; char level2string[NUM_LOG_LEVEL]; int flag; char *filelog_name; From dd5691f0ce0531c1ae0dec2a77f17afe0c78f17d Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Fri, 9 Feb 2024 10:25:52 +0000 Subject: [PATCH 06/41] Rename FR2 SA configuration file to be compliant with the 'Configuration files: naming style guide' Missing u3 --- doc/NR_SA_Tutorial_OAI_nrUE.md | 2 +- ...2prb.usrpx410.conf => gnb.sa.band257.u3.32prb.usrpx410.conf} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename targets/PROJECTS/GENERIC-NR-5GC/CONF/{gnb.sa.band257.32prb.usrpx410.conf => gnb.sa.band257.u3.32prb.usrpx410.conf} (100%) diff --git a/doc/NR_SA_Tutorial_OAI_nrUE.md b/doc/NR_SA_Tutorial_OAI_nrUE.md index 6ba09a7ca8..be21f71097 100644 --- a/doc/NR_SA_Tutorial_OAI_nrUE.md +++ b/doc/NR_SA_Tutorial_OAI_nrUE.md @@ -120,7 +120,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band ### RFsimulator in FR2 ```bash cd ~/openairinterface5g/cmake_targets/ran_build/build -sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.32prb.usrpx410.conf --rfsim +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf --rfsim ``` # 5. OAI UE diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.32prb.usrpx410.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf similarity index 100% rename from targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.32prb.usrpx410.conf rename to targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf From 10d7b537a4a56dbd3e64e00e81e70400683b4806 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Wed, 14 Feb 2024 12:05:31 +0000 Subject: [PATCH 07/41] Tutorials: upgrade Open Cells Project UICC/SIM programming tool to version 3.3 --- doc/NR_SA_Tutorial_COTS_UE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/NR_SA_Tutorial_COTS_UE.md b/doc/NR_SA_Tutorial_COTS_UE.md index 7feab970a4..7b7e235600 100644 --- a/doc/NR_SA_Tutorial_COTS_UE.md +++ b/doc/NR_SA_Tutorial_COTS_UE.md @@ -45,7 +45,7 @@ Please install and configure OAI CN5G as described here: ## 2.2 SIM Card -Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v3.2](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v3.2.tgz). +Program UICC/SIM Card with [Open Cells Project](https://open-cells.com/) programming tool [uicc-v3.3](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v3.3.tgz). ```bash sudo ./program_uicc --adm 12345678 --imsi 001010000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate From 24d30ae78a658be798c3047cbc0975d4ae688ea2 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 1 Mar 2024 16:17:09 +0100 Subject: [PATCH 08/41] log module improvement: remove redundant declarations y using C macro, remove unused variables, remove unused log components, move information to smaller visibility --- common/utils/LOG/log.c | 231 ++++++++---------- common/utils/LOG/log.h | 174 +++++-------- common/utils/telnetsrv/telnetsrv_proccmd.c | 142 ++++++----- .../PDCP_v10.1.0/pdcp_sequence_manager.c | 2 +- 4 files changed, 244 insertions(+), 305 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index e8b16ca480..a37ec44751 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -78,40 +78,87 @@ volatile int log_mem_write_flag=0; volatile int log_mem_write_side=0; static char * log_mem_filename; -const mapping log_level_names[] = {{"error", OAILOG_ERR}, +static mapping log_level_names[] = {{"error", OAILOG_ERR}, {"warn", OAILOG_WARNING}, {"analysis", OAILOG_ANALYSIS}, {"info", OAILOG_INFO}, {"debug", OAILOG_DEBUG}, {"trace", OAILOG_TRACE}, {NULL, -1}}; +mapping * log_level_names_ptr(void) +{ + return log_level_names; +} -const mapping log_options[] = {{"nocolor", FLAG_NOCOLOR}, - {"level", FLAG_LEVEL}, - {"thread", FLAG_THREAD}, - {"line_num", FLAG_FILE_LINE}, - {"function", FLAG_FUNCT}, - {"time", FLAG_TIME}, - {"thread_id", FLAG_THREAD_ID}, - {"wall_clock", FLAG_REAL_TIME}, + +/** @defgroup _log_format Defined log format + * @ingroup _macro + * @brief Macro of log formats defined by LOG + * @{*/ +static const unsigned int FLAG_NOCOLOR = 1; /*!< \brief use colors in log messages, depending on level */ +static const unsigned int FLAG_THREAD = 1 << 1; /*!< \brief display thread name in log messages */ +static const unsigned int FLAG_LEVEL = 1 << 2; /*!< \brief display log level in log messages */ +static const unsigned int FLAG_FUNCT = 1 << 3; +static const unsigned int FLAG_FILE_LINE = 1 << 4; +static const unsigned int FLAG_TIME = 1 << 5; +static const unsigned int FLAG_THREAD_ID = 1 << 6; +static const unsigned int FLAG_REAL_TIME = 1 << 7; +static const unsigned int FLAG_INITIALIZED = 1 << 8; + +/** @}*/ +static mapping log_options[] = {{"nocolor", FLAG_NOCOLOR}, + {"level", FLAG_LEVEL}, + {"thread", FLAG_THREAD}, + {"line_num", FLAG_FILE_LINE}, + {"function", FLAG_FUNCT}, + {"time", FLAG_TIME}, + {"thread_id", FLAG_THREAD_ID}, + {"wall_clock", FLAG_REAL_TIME}, + {NULL, -1}}; +mapping * log_option_names_ptr(void) +{ + return log_options; +} + +static mapping log_maskmap[] = {{"PRACH", DEBUG_PRACH}, + {"RU", DEBUG_RU}, + {"UE_PHYPROC", DEBUG_UE_PHYPROC}, + {"LTEESTIM", DEBUG_LTEESTIM}, + {"DLCELLSPEC", DEBUG_DLCELLSPEC}, + {"ULSCH", DEBUG_ULSCH}, + {"RRC", DEBUG_RRC}, + {"PDCP", DEBUG_PDCP}, + {"DFT", DEBUG_DFT}, + {"ASN1", DEBUG_ASN1}, + {"CTRLSOCKET", DEBUG_CTRLSOCKET}, + {"SECURITY", DEBUG_SECURITY}, + {"NAS", DEBUG_NAS}, + {"RLC", DEBUG_RLC}, + {"DLSCH_DECOD", DEBUG_DLSCH_DECOD}, + {"UE_TIMING", UE_TIMING}, {NULL, -1}}; +mapping * log_maskmap_ptr(void) +{ + return log_maskmap; +} -const mapping log_maskmap[] = LOG_MASKMAP_INIT; - +/* .log_format = 0x13 uncolored standard messages + * .log_format = 0x93 colored standard messages */ +/* keep white space in first position; switching it to 0 allows colors to be disabled*/ +static const char *const LOG_RED = "\033[1;31m"; /*!< \brief VT100 sequence for bold red foreground */ +static const char *const LOG_GREEN = "\033[32m"; /*!< \brief VT100 sequence for green foreground */ +static const char *const LOG_ORANGE = "\033[93m"; /*!< \brief VT100 sequence for orange foreground */ +static const char *const LOG_BLUE = "\033[34m"; /*!< \brief VT100 sequence for blue foreground */ +static const char *const LOG_CYBL = "\033[40;36m"; /*!< \brief VT100 sequence for cyan foreground on black background */ +static const char *const LOG_RESET = "\033[0m"; /*!< \brief VT100 sequence for reset (black) foreground */ static const char *const log_level_highlight_start[] = {LOG_RED, LOG_ORANGE, LOG_GREEN, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */ + static const char *const log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ static void log_output_memory(log_component_t *c, const char *file, const char *func, int line, int comp, int level, const char* format,va_list args); - -int write_file_matlab(const char *fname, - const char *vname, - void *data, - int length, - int dec, - unsigned int format, - int multiVec) +int write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec) { FILE *fp=NULL; int i; @@ -281,15 +328,15 @@ int write_file_matlab(const char *fname, } /* get log parameters from configuration file */ -void log_getconfig(log_t *g_log) +void log_getconfig(log_t *g_log) { char *gloglevel = NULL; int consolelog = 0; paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS]; - paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)]; - paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)]; + paramdef_t logparams_debug[sizeofArray(log_maskmap)]; + paramdef_t logparams_dump[sizeofArray(log_maskmap)]; int ret = config_get(config_get_if(), logparams_defaults, sizeofArray(logparams_defaults), CONFIG_STRING_LOG_PREFIX); if (ret <0) { @@ -311,10 +358,10 @@ void log_getconfig(log_t *g_log) } /* build the parameter array for setting per component log level and infile options */ - memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS); - memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS); + memset(logparams_level, 0, sizeof(logparams_level)); + memset(logparams_logfile, 0, sizeof(logparams_logfile)); - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) { + for (int i = 0; i < MAX_LOG_PREDEF_COMPONENTS; i++) { if(g_log->log_component[i].name == NULL) { g_log->log_component[i].name = malloc(17); sprintf((char *)g_log->log_component[i].name,"comp%i?",i); @@ -348,11 +395,11 @@ void log_getconfig(log_t *g_log) config_get(config_get_if(), logparams_logfile, MAX_LOG_PREDEF_COMPONENTS, CONFIG_STRING_LOG_PREFIX); /* now set the log levels and infile option, according to what we read */ - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) { - g_log->log_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr)); + for (int i = 0; i < MAX_LOG_PREDEF_COMPONENTS; i++) { + g_log->log_component[i].level = map_str_to_int(log_level_names, *logparams_level[i].strptr); set_log(i, g_log->log_component[i].level); - if (*(logparams_logfile[i].uptr) == 1) + if (*logparams_logfile[i].uptr == 1) set_component_filelog(i); } @@ -393,16 +440,10 @@ void log_getconfig(log_t *g_log) set_glog_onlinelog(consolelog); } -int register_log_component(char *name, - char *fext, - int compidx) +int register_log_component(const char *name, const char *fext, int compidx) { int computed_compidx=compidx; - if (strlen(fext) > 3) { - fext[3]=0; /* limit log file extension to 3 chars */ - } - if (compidx < 0) { /* this is not a pre-defined component */ for (int i = MAX_LOG_PREDEF_COMPONENTS; i< MAX_LOG_COMPONENTS; i++) { if (g_log->log_component[i].name == NULL) { @@ -416,8 +457,9 @@ int register_log_component(char *name, g_log->log_component[computed_compidx].name = strdup(name); g_log->log_component[computed_compidx].stream = stdout; g_log->log_component[computed_compidx].filelog = 0; - g_log->log_rarely_used[computed_compidx].filelog_name = malloc(strlen(name) + 16); /* /tmp/.%s */ - sprintf(g_log->log_rarely_used[computed_compidx].filelog_name, "/tmp/%s.%s", name, fext); + g_log->log_rarely_used[computed_compidx].filelog_name = calloc(1, strlen(name) + 16); /* /tmp/.%s */ + sprintf(g_log->log_rarely_used[computed_compidx].filelog_name, "/tmp/%s.", name); + strncat(g_log->log_rarely_used[computed_compidx].filelog_name, fext, 3); } else { fprintf(stderr,"{LOG} %s %d Couldn't register component %s\n",__FILE__,__LINE__,name); } @@ -450,7 +492,6 @@ int isLogInitDone (void) int logInit (void) { - int i; g_log = calloc(1, sizeof(log_t)); if (g_log == NULL) { @@ -458,69 +499,17 @@ int logInit (void) exit(EXIT_FAILURE); } - memset(g_log,0,sizeof(log_t)); - register_log_component("PHY","log",PHY); - register_log_component("MAC","log",MAC); - register_log_component("OPT","log",OPT); - register_log_component("RLC","log",RLC); - register_log_component("PDCP","log",PDCP); - register_log_component("RRC","log",RRC); - register_log_component("OMG","csv",OMG); - register_log_component("OTG","log",OTG); - register_log_component("OTG_LATENCY","dat",OTG_LATENCY); - register_log_component("OTG_LATENCY_BG","dat",OTG_LATENCY_BG); - register_log_component("OTG_GP","dat",OTG_GP); - register_log_component("OTG_GP_BG","dat",OTG_GP_BG); - register_log_component("OTG_JITTER","dat",OTG_JITTER); - register_log_component("PERF","",PERF); - register_log_component("OIP","",OIP); - register_log_component("OCM","log",OCM); - register_log_component("HW","",HW); - register_log_component("OSA","",OSA); - register_log_component("eRAL","",RAL_ENB); - register_log_component("mRAL","",RAL_UE); - register_log_component("ENB_APP","log",ENB_APP); - register_log_component("MCE_APP","log",MCE_APP); - register_log_component("MME_APP","log",MME_APP); - register_log_component("TMR","",TMR); - register_log_component("EMU","log",EMU); - register_log_component("USIM","txt",USIM); - register_log_component("SIM","txt",SIM); - /* following log component are used for the localization*/ - register_log_component("LOCALIZE","log",LOCALIZE); - register_log_component("NAS","log",NAS); - register_log_component("UDP","",UDP_); - register_log_component("GTPU","",GTPU); - register_log_component("SDAP","",SDAP); - register_log_component("S1AP","",S1AP); - register_log_component("F1AP","",F1AP); - register_log_component("E1AP","",E1AP); - register_log_component("M2AP","",M2AP); - register_log_component("M3AP","",M3AP); - register_log_component("SCTP","",SCTP); - register_log_component("X2AP","",X2AP); - register_log_component("LOADER","log",LOADER); - register_log_component("ASN1","log",ASN1); - register_log_component("NFAPI_VNF","log",NFAPI_VNF); - register_log_component("NFAPI_PNF","log",NFAPI_PNF); - register_log_component("GNB_APP","log",GNB_APP); - register_log_component("NR_RRC","log",NR_RRC); - register_log_component("NR_MAC","log",NR_MAC); - register_log_component("NR_MAC_DCI", "log", NR_MAC_DCI); - register_log_component("NR_PHY_DCI", "log", NR_PHY_DCI); - register_log_component("NR_PHY","log",NR_PHY); - register_log_component("NGAP","",NGAP); - register_log_component("ITTI","log",ITTI); - register_log_component("UTIL","log",UTIL); + for (int i = 0; i < MAX_LOG_PREDEF_COMPONENTS; i++) + register_log_component(comp_name[i], comp_extension[i], i); for (int i=0 ; log_level_names[i].name != NULL ; i++) - g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name - + g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name + g_log->filelog_name = "/tmp/openair.log"; log_getconfig(g_log); // set all unused component items to 0, they are for non predefined components - for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + for (int i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { memset(&(g_log->log_component[i]),0,sizeof(log_component_t)); } @@ -547,7 +536,7 @@ static inline int log_header(log_component_t *c, int line, int level) { - int flag = g_log->flag; // | c->flag; + int flag = g_log->flag; char threadname[64]; if (flag & FLAG_THREAD ) { @@ -637,7 +626,7 @@ void log_dump(int component, va_list args; char *wbuf; log_component_t *c = &g_log->log_component[component]; - int flag = g_log->flag; // | c->flag; + int flag = g_log->flag; switch(datatype) { case LOG_DUMP_DOUBLE: @@ -681,8 +670,7 @@ int set_log(int component, int level) { /* Checking parameters */ - DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), - component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); + DevCheck((component >= 0) && (component < MAX_LOG_COMPONENTS), component, 0, MAX_LOG_COMPONENTS); DevCheck((level < NUM_LOG_LEVEL) && (level >= OAILOG_DISABLE), level, NUM_LOG_LEVEL, OAILOG_ERR); @@ -693,8 +681,6 @@ int set_log(int component, return 0; } - - void set_glog(int level) { for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { @@ -715,6 +701,7 @@ void set_glog_onlinelog(int enable) } } } + void set_glog_filelog(int enable) { static FILE *fptr; @@ -750,6 +737,7 @@ void set_component_filelog(int comp) g_log->log_component[comp].print = fprintf; g_log->log_component[comp].filelog = 1; } + void close_component_filelog(int comp) { g_log->log_component[comp].filelog = 0; @@ -786,40 +774,19 @@ int map_str_to_int(const mapping *map, const char *str) /* map an int to a string. Takes a mapping array and a value */ char *map_int_to_str(const mapping *map, const int val) { - while (1) { - if (map->name == NULL) { - return NULL; - } - + while (map->name) { if (map->value == val) { return map->name; } - map++; } -} - -int is_newline(char *str, - int size) -{ - int i; - - for ( i = 0; i < size; i++ ) { - if ( str[i] == '\n' ) { - return 1; - } - } - - /* if we get all the way to here, there must not have been a newline! */ - return 0; + return NULL; } void logClean (void) { - int i; - if(isLogInitDone()) { - for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + for (int i = 0; i < MAX_LOG_COMPONENTS; i++) { close_component_filelog(i); } } @@ -894,7 +861,7 @@ static void log_output_memory(log_component_t *c, const char *file, const char * len = MAX_LOG_TOTAL; } } - if (!((g_log->flag /*| c->flag*/) & FLAG_NOCOLOR)) { + if (!((g_log->flag) & FLAG_NOCOLOR)) { int n = snprintf(log_buffer+len, MAX_LOG_TOTAL-len, "%s", log_level_highlight_end[level]); if (n > 0) { len += n; @@ -948,12 +915,12 @@ int logInit_log_mem (char * filename) { log_mem_flag = 1; log_mem_filename = filename; // in present code, the parameter is safe permanent pointer - log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE); - log_mem_d[0].buf_index = 0; - log_mem_d[0].enable_flag = 1; - log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE); - log_mem_d[1].buf_index = 0; - log_mem_d[1].enable_flag = 1; + for (log_mem_cnt_t *ptr = log_mem_d; ptr < log_mem_d + sizeofArray(log_mem_d); ptr++) + *ptr = (log_mem_cnt_t){ + .buf_p = malloc(LOG_MEM_SIZE), + .buf_index = 0, + .enable_flag = 1, + }; log_mem_side = 0; if ((pthread_mutex_init(&log_mem_lock, NULL) != 0) || (pthread_cond_init(&log_mem_notify, NULL) != 0)) { log_mem_d[1].enable_flag=0; diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index a7aec50825..249dab5580 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -85,31 +85,6 @@ extern "C" { #define NUM_LOG_LEVEL 6 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/ /** @}*/ -/** @defgroup _log_format Defined log format - * @ingroup _macro - * @brief Macro of log formats defined by LOG - * @{*/ - -/* .log_format = 0x13 uncolored standard messages - * .log_format = 0x93 colored standard messages */ -/* keep white space in first position; switching it to 0 allows colors to be disabled*/ -#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ -#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ -#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ -#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ -#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ -#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ -#define FLAG_NOCOLOR 0x0001 /*!< \brief use colors in log messages, depending on level */ -#define FLAG_THREAD 0x0008 /*!< \brief display thread name in log messages */ -#define FLAG_LEVEL 0x0010 /*!< \brief display log level in log messages */ -#define FLAG_FUNCT 0x0020 -#define FLAG_FILE_LINE 0x0040 -#define FLAG_TIME 0x0100 -#define FLAG_THREAD_ID 0x0200 -#define FLAG_REAL_TIME 0x0400 -#define FLAG_INITIALIZED 0x8000 -/** @}*/ - #define SET_LOG_OPTION(O) g_log->flag = (g_log->flag | O) #define CLEAR_LOG_OPTION(O) g_log->flag = (g_log->flag & (~O)) @@ -138,92 +113,73 @@ extern "C" { #define DEBUG_DLSCH_DECOD (1<<14) #define UE_TIMING (1<<20) - -#define LOG_MASKMAP_INIT {\ - {"PRACH", DEBUG_PRACH},\ - {"RU", DEBUG_RU},\ - {"UE_PHYPROC", DEBUG_UE_PHYPROC},\ - {"LTEESTIM", DEBUG_LTEESTIM},\ - {"DLCELLSPEC", DEBUG_DLCELLSPEC},\ - {"ULSCH", DEBUG_ULSCH},\ - {"RRC", DEBUG_RRC},\ - {"PDCP", DEBUG_PDCP},\ - {"DFT", DEBUG_DFT},\ - {"ASN1", DEBUG_ASN1},\ - {"CTRLSOCKET", DEBUG_CTRLSOCKET},\ - {"SECURITY", DEBUG_SECURITY},\ - {"NAS", DEBUG_NAS},\ - {"RLC", DEBUG_RLC},\ - {"DLSCH_DECOD", DEBUG_DLSCH_DECOD},\ - {"UE_TIMING", UE_TIMING},\ - {NULL,-1}\ - } - #define SET_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask | B) #define CLEAR_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask & (~B)) #define SET_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask | B) #define CLEAR_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask & (~B)) -typedef enum { - MIN_LOG_COMPONENTS = 0, - PHY = MIN_LOG_COMPONENTS, - MAC, - EMU, - SIM, - OMG, - OPT, - OTG, - OTG_LATENCY, - OTG_LATENCY_BG, - OTG_GP, - OTG_GP_BG, - OTG_JITTER, - RLC, - PDCP, - RRC, - NAS, - PERF, - OIP, - CLI, - OCM, - UDP_, - GTPU, - SDAP, - SPGW, - S1AP, - F1AP, - E1AP, - SCTP, - HW, - OSA, - RAL_ENB, - RAL_UE, - ENB_APP, - MCE_APP, - MME_APP, - TMR, - USIM, - LOCALIZE, - F1U, - X2AP, - M2AP, - M3AP, - NGAP, - GNB_APP, - NR_RRC, - NR_MAC, - NR_MAC_DCI, - NR_PHY_DCI, - NR_PHY, - LOADER, - ASN1, - NFAPI_VNF, - NFAPI_PNF, - ITTI, - UTIL, - MAX_LOG_PREDEF_COMPONENTS, -} comp_name_t; +#define FOREACH_COMP(COMP_DEF) \ + COMP_DEF(PHY, log) \ + COMP_DEF(MAC, log) \ + COMP_DEF(EMU, log) \ + COMP_DEF(SIM, txt) \ + COMP_DEF(OMG, csv) \ + COMP_DEF(OPT, log) \ + COMP_DEF(OTG, log) \ + COMP_DEF(OTG_LATENCY, dat) \ + COMP_DEF(OTG_LATENCY_BG, dat) \ + COMP_DEF(OTG_GP, dat) \ + COMP_DEF(OTG_GP_BG, dat) \ + COMP_DEF(OTG_JITTER, dat) \ + COMP_DEF(RLC, ) \ + COMP_DEF(PDCP, ) \ + COMP_DEF(RRC, ) \ + COMP_DEF(NAS, log) \ + COMP_DEF(OIP, ) \ + COMP_DEF(CLI, ) \ + COMP_DEF(OCM, ) \ + COMP_DEF(GTPU, ) \ + COMP_DEF(SDAP, ) \ + COMP_DEF(SPGW, ) \ + COMP_DEF(S1AP, ) \ + COMP_DEF(F1AP, ) \ + COMP_DEF(E1AP, ) \ + COMP_DEF(SCTP, ) \ + COMP_DEF(HW, ) \ + COMP_DEF(OSA, ) \ + COMP_DEF(ENB_APP, log) \ + COMP_DEF(MCE_APP, log) \ + COMP_DEF(MME_APP, log) \ + COMP_DEF(TMR, ) \ + COMP_DEF(USIM, log) \ + COMP_DEF(F1U, ) \ + COMP_DEF(X2AP, ) \ + COMP_DEF(M2AP, ) \ + COMP_DEF(M3AP, ) \ + COMP_DEF(NGAP, ) \ + COMP_DEF(GNB_APP, log) \ + COMP_DEF(NR_RRC, log) \ + COMP_DEF(NR_MAC, log) \ + COMP_DEF(NR_MAC_DCI, log) \ + COMP_DEF(NR_PHY_DCI, log) \ + COMP_DEF(NR_PHY, log) \ + COMP_DEF(LOADER, log) \ + COMP_DEF(ASN1, log) \ + COMP_DEF(NFAPI_VNF, log) \ + COMP_DEF(NFAPI_PNF, log) \ + COMP_DEF(ITTI, log) \ + COMP_DEF(UTIL, log) \ + COMP_DEF(MAX_LOG_PREDEF_COMPONENTS, ) + +#define COMP_ENUM(comp, file_extension) comp, +typedef enum { FOREACH_COMP(COMP_ENUM) } comp_name_t; + +#define COMP_TEXT(comp, file_extension) #comp, +static const char *const comp_name[] = {FOREACH_COMP(COMP_TEXT)}; + +#define COMP_EXTENSION(comp, file_extension) #file_extension, +static const char *const comp_extension[] = {FOREACH_COMP(COMP_EXTENSION)}; #define MAX_LOG_DYNALLOC_COMPONENTS 20 #define MAX_LOG_COMPONENTS (MAX_LOG_PREDEF_COMPONENTS + MAX_LOG_DYNALLOC_COMPONENTS) @@ -242,7 +198,7 @@ typedef struct { typedef struct { const char *name; - int level; + int level; int filelog; FILE *stream; log_vprint_func_t vprint; @@ -282,6 +238,9 @@ void log_dump(int component, void *buffer, int buffsize,int datatype, const char int set_log(int component, int level); void set_glog(int level); +mapping * log_level_names_ptr(void); +mapping * log_option_names_ptr(void); +mapping * log_maskmap_ptr(void); void set_glog_onlinelog(int enable); void set_glog_filelog(int enable); void set_component_filelog(int comp); @@ -290,9 +249,8 @@ void set_component_consolelog(int comp); int map_str_to_int(const mapping *map, const char *str); char *map_int_to_str(const mapping *map, const int val); void logClean (void); -int is_newline( char *str, int size); -int register_log_component(char *name, char *fext, int compidx); +int register_log_component(const char *name, const char *fext, int compidx); int logInit_log_mem(char*); void close_log_mem(void); diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index bf2a9a4e8c..4255b20956 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -256,6 +256,9 @@ void print_threads(char *buf, int debug, telnet_printfunc_t prnt) int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt) { webdatadef_t *logsdata = (webdatadef_t *)data; + const mapping *const log_level_names = log_level_names_ptr(); + const mapping *const log_options = log_option_names_ptr(); + const mapping *log_maskmap = log_maskmap_ptr(); if (strncmp(cmdbuff, "set", 3) == 0) { telnet_printfunc_t printfunc = (prnt != NULL) ? prnt : (telnet_printfunc_t)printf; if (strcasestr(cmdbuff, "loglvl") != NULL) { @@ -274,7 +277,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun logsdata->lines[0].val[0], logsdata->lines[0].val[1], enabled ? "enabled" : "disabled", - loginfile ? g_log->log_component[logsdata->numlines].filelog_name : "stdout"); + loginfile ? g_log->log_rarely_used[logsdata->numlines].filelog_name : "stdout"); } if (strcasestr(cmdbuff, "logopt") != NULL) { int optbit = map_str_to_int(log_options, logsdata->lines[0].val[0]); @@ -329,12 +332,14 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun snprintf(logsdata->columns[3].coltitle, TELNET_CMD_MAXSIZE, "in file"); logsdata->columns[3].coltype = TELNET_CHECKVAL_BOOL; - for (int i = MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + for (int i = 0; i < MAX_LOG_COMPONENTS; i++) { if (g_log->log_component[i].name != NULL) { logsdata->numlines++; logsdata->lines[i].val[0] = (char *)(g_log->log_component[i].name); - logsdata->lines[i].val[1] = map_int_to_str(log_level_names, (g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_component[i].savedlevel); + logsdata->lines[i].val[1] = map_int_to_str( + log_level_names, + (g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_rarely_used[i].savedlevel); logsdata->lines[i].val[2] = (g_log->log_component[i].level >= 0) ? "true" : "false"; logsdata->lines[i].val[3] = (g_log->log_component[i].filelog > 0) ? "true" : "false"; } @@ -353,7 +358,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun for (int i = 0; log_maskmap[i].name != NULL; i++) { logsdata->numlines++; - logsdata->lines[i].val[0] = log_maskmap[i].name; + logsdata->lines[i].val[0] = (char *)log_maskmap[i].name; logsdata->lines[i].val[1] = (g_log->debug_mask & log_maskmap[i].value) ? "true" : "false"; logsdata->lines[i].val[2] = (g_log->dump_mask & log_maskmap[i].value) ? "true" : "false"; } @@ -370,7 +375,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun for (int i = 0; log_options[i].name != NULL; i++) { logsdata->numlines++; - logsdata->lines[i].val[0] = log_options[i].name; + logsdata->lines[i].val[0] = (char *)log_options[i].name; logsdata->lines[i].val[1] = (g_log->flag & log_options[i].value) ? "true" : "false"; } } @@ -395,17 +400,23 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt) } if (strcasestr(buf,"loglvl") != NULL) { prnt("\n component level enabled output\n"); - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - if (g_log->log_component[i].name != NULL) { - prnt("%02i %17.17s:%10.10s %s %s\n",i ,g_log->log_component[i].name, - map_int_to_str(log_level_names,(g_log->log_component[i].level>=0)?g_log->log_component[i].level:g_log->log_component[i].savedlevel), - ((g_log->log_component[i].level>=0)?"Y":"N"), - ((g_log->log_component[i].filelog>0)?g_log->log_component[i].filelog_name:"stdout")); - } + const mapping *const log_level_names = log_level_names_ptr(); + for (int i = 0; i < MAX_LOG_COMPONENTS; i++) { + if (g_log->log_component[i].name != NULL) { + prnt("%02i %17.17s:%10.10s %s %s\n", + i, + g_log->log_component[i].name, + map_int_to_str( + log_level_names, + (g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_rarely_used[i].savedlevel), + ((g_log->log_component[i].level >= 0) ? "Y" : "N"), + ((g_log->log_component[i].filelog > 0) ? g_log->log_rarely_used[i].filelog_name : "stdout")); + } } } if (strcasestr(buf,"logopt") != NULL) { prnt("\n option enabled\n"); + const mapping *const log_options = log_option_names_ptr(); for (int i=0; log_options[i].name != NULL; i++) { prnt("%02i %17.17s %10.10s \n",i ,log_options[i].name, ((g_log->flag & log_options[i].value)?"Y":"N") ); @@ -413,6 +424,7 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt) } if (strcasestr(buf,"dbgopt") != NULL) { prnt("\n module debug dumpfile\n"); + const mapping *log_maskmap = log_maskmap_ptr(); for (int i=0; log_maskmap[i].name != NULL ; i++) { prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name, ((g_log->debug_mask & log_maskmap[i].value)?"Y":"N"), @@ -528,7 +540,9 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); if (debug > 0) prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd)); - + const mapping *const log_level_names = log_level_names_ptr(); + const mapping *const log_options = log_option_names_ptr(); + const mapping *log_maskmap = log_maskmap_ptr(); if (s == 1 && logsubcmd != NULL) { if (strcasestr(logsubcmd,"online") != NULL) { if (strcasestr(buf,"noonline") != NULL) { @@ -540,21 +554,21 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); } } else if (strcasestr(logsubcmd,"show") != NULL) { - prnt("Available log levels: \n "); - for (int i=0; log_level_names[i].name != NULL; i++) - prnt("%s ",log_level_names[i].name); - prnt("\n\n"); - prnt("Available display options: \n "); - for (int i=0; log_options[i].name != NULL; i++) - prnt("%s ",log_options[i].name); - prnt("\n\n"); - prnt("Available debug and dump options: \n "); - for (int i=0; log_maskmap[i].name != NULL; i++) - prnt("%s ",log_maskmap[i].name); - prnt("\n\n"); - proccmd_show("loglvl",debug,prnt); - proccmd_show("logopt",debug,prnt); - proccmd_show("dbgopt",debug,prnt); + prnt("Available log levels: \n "); + for (int i = 0; log_level_names[i].name != NULL; i++) + prnt("%s ", log_level_names[i].name); + prnt("\n\n"); + prnt("Available display options: \n "); + for (int i = 0; log_options[i].name != NULL; i++) + prnt("%s ", log_options[i].name); + prnt("\n\n"); + prnt("Available debug and dump options: \n "); + for (int i = 0; log_maskmap[i].name != NULL; i++) + prnt("%s ", log_maskmap[i].name); + prnt("\n\n"); + proccmd_show("loglvl", debug, prnt); + proccmd_show("logopt", debug, prnt); + proccmd_show("dbgopt", debug, prnt); } else if (strcasestr(logsubcmd,"help") != NULL) { prnt(PROCCMD_LOG_HELP_STRING); @@ -569,40 +583,40 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); l=sscanf(logsubcmd,"%m[^'_']_%ms",&logparam,&opt); if (l == 2 && strcmp(logparam,"print") == 0){ - optbit=map_str_to_int(log_options,opt); - if (optbit < 0) { - prnt("option %s unknown\n",opt); - } else { - if (idx1 > 0) - SET_LOG_OPTION(optbit); - else - CLEAR_LOG_OPTION(optbit); - proccmd_show("logopt",debug,prnt); - } + optbit = map_str_to_int(log_options, opt); + if (optbit < 0) { + prnt("option %s unknown\n", opt); + } else { + if (idx1 > 0) + SET_LOG_OPTION(optbit); + else + CLEAR_LOG_OPTION(optbit); + proccmd_show("logopt", debug, prnt); + } } else if (l == 2 && strcmp(logparam,"debug") == 0){ - optbit=map_str_to_int(log_maskmap,opt); - if (optbit < 0) { - prnt("module %s unknown\n",opt); - } else { - if (idx1 > 0) - SET_LOG_DEBUG(optbit); - else - CLEAR_LOG_DEBUG(optbit); - proccmd_show("dbgopt",debug,prnt); - } + optbit = map_str_to_int(log_maskmap, opt); + if (optbit < 0) { + prnt("module %s unknown\n", opt); + } else { + if (idx1 > 0) + SET_LOG_DEBUG(optbit); + else + CLEAR_LOG_DEBUG(optbit); + proccmd_show("dbgopt", debug, prnt); + } } else if (l == 2 && strcmp(logparam,"dump") == 0){ - optbit=map_str_to_int(log_maskmap,opt); - if (optbit < 0) { - prnt("module %s unknown\n",opt); - } else { - if (idx1 > 0) - SET_LOG_DUMP(optbit); - else - CLEAR_LOG_DUMP(optbit); - proccmd_show("dump", debug, prnt); - } + optbit = map_str_to_int(log_maskmap, opt); + if (optbit < 0) { + prnt("module %s unknown\n", opt); + } else { + if (idx1 > 0) + SET_LOG_DUMP(optbit); + else + CLEAR_LOG_DUMP(optbit); + proccmd_show("dump", debug, prnt); + } } if (logparam != NULL) free(logparam); if (opt != NULL) free(opt); @@ -620,11 +634,11 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr)); if (l ==2 ) { if (strcmp(logparam,"level") == 0) { - level=map_str_to_int(log_level_names,tmpstr); - if (level < 0) { - prnt("level %s unknown\n",tmpstr); - level=OAILOG_DISABLE - 1; - } + level = map_str_to_int(log_level_names, tmpstr); + if (level < 0) { + prnt("level %s unknown\n", tmpstr); + level = OAILOG_DISABLE - 1; + } } else { prnt("%s%s unknown log sub command \n",logparam, tmpstr); } @@ -650,7 +664,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); if (level >= OAILOG_DISABLE) set_log(i, level); else if ( enable == 1) - set_log(i,g_log->log_component[i].savedlevel); + set_log(i, g_log->log_rarely_used[i].savedlevel); else if ( filelog == 1 ) { set_component_filelog(i); } else if ( filelog == 0 ) { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c index 69d355533a..5aa5e33304 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c @@ -27,7 +27,7 @@ */ #include "pdcp_sequence_manager.h" -#include "common/utils//LOG/log.h" +#include "common/utils/LOG/log.h" #include "pdcp_util.h" /* From 284d07c5ae39faf0673752fdea3f7096e643feb3 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 15 Jan 2024 13:50:26 +0100 Subject: [PATCH 09/41] nfapi_nr_interface cleanup --- .../nfapi/public_inc/nfapi_nr_interface.h | 515 +----------------- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 8 - openair1/PHY/INIT/nr_init.c | 2 - openair1/PHY/NR_REFSIG/dmrs_nr.c | 14 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 1 + openair1/PHY/NR_TRANSPORT/nr_dci.h | 1 + openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h | 1 + .../nr_dl_channel_estimation.c | 3 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 3 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 1 + openair1/SCHED_NR/fapi_nr_l1.h | 1 - openair1/SCHED_NR/phy_procedures_nr_gNB.c | 1 - openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 1 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 1 + .../NR_MAC_UE/nr_ue_dci_configuration.c | 1 - .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 - openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 - openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + openair2/NR_PHY_INTERFACE/NR_IF_Module.h | 1 - 19 files changed, 26 insertions(+), 538 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index ad6a325848..a6ab614bde 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -9,19 +9,6 @@ #ifndef _NFAPI_NR_INTERFACE_H_ #define _NFAPI_NR_INTERFACE_H_ -#include "nfapi_interface.h" -#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" - -#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 -#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 -#define NFAPI_NR_MAX_NB_CORESETS 12 -#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 - - - -// nFAPI enums - - //These TLVs are used exclusively by nFAPI #define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100 #define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101 @@ -37,510 +24,26 @@ #define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F #define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120 -/* -#define NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG 0x510A -#define NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG 0x510B -#define NFAPI_NR_NFAPI_RF_BANDS_TAG 0x5114 -#define NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG 0x5128 -#define NFAPI_NR_NFAPI_NRARFCN_TAG 0x5129 -#define NFAPI_NR_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG 0x5130 -#define NFAPI_NR_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG 0x5131 -#define NFAPI_NR_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG 0x5132 -#define NFAPI_NR_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG 0x5133 -*/ -// P5 Message Structures - -typedef struct { - nfapi_uint16_tlv_t numerology_index_mu; - nfapi_uint16_tlv_t duplex_mode; - nfapi_uint16_tlv_t dl_cyclic_prefix_type; - nfapi_uint16_tlv_t ul_cyclic_prefix_type; -} nfapi_nr_subframe_config_t; - -#define NFAPI_NR_SUBFRAME_CONFIG_DUPLEX_MODE_TAG 0x5001 -#define NFAPI_NR_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG 0x5002 -#define NFAPI_NR_SUBFRAME_CONFIG_PB_TAG 0x5003 -#define NFAPI_NR_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG 0x5004 -#define NFAPI_NR_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG 0x5005 -#define NFAPI_NR_SUBFRAME_CONFIG_NUMEROLOGY_INDEX_MU_TAG 0x5006 - -typedef struct { - nfapi_uint16_tlv_t dl_carrier_bandwidth; - nfapi_uint16_tlv_t ul_carrier_bandwidth; - nfapi_uint16_tlv_t dl_absolutefrequencypointA; - nfapi_uint16_tlv_t ul_absolutefrequencypointA; - nfapi_uint16_tlv_t dl_offsettocarrier; - nfapi_uint16_tlv_t ul_offsettocarrier; - nfapi_uint16_tlv_t dl_subcarrierspacing; - nfapi_uint16_tlv_t ul_subcarrierspacing; - nfapi_uint16_tlv_t dl_specificcarrier_k0; - nfapi_uint16_tlv_t ul_specificcarrier_k0; - nfapi_uint16_tlv_t NIA_subcarrierspacing; -} nfapi_nr_rf_config_t; - -#define NFAPI_NR_RF_CONFIG_DL_CARRIER_BANDWIDTH_TAG 0x500A -#define NFAPI_NR_RF_CONFIG_UL_CARRIER_BANDWIDTH_TAG 0x500B -#define NFAPI_NR_RF_CONFIG_DL_SUBCARRIERSPACING_TAG 0x500C -#define NFAPI_NR_RF_CONFIG_UL_SUBCARRIERSPACING_TAG 0x500D -#define NFAPI_NR_RF_CONFIG_DL_OFFSETTOCARRIER_TAG 0x500E -#define NFAPI_NR_RF_CONFIG_UL_OFFSETTOCARRIER_TAG 0x500F - -typedef struct { - nfapi_uint16_tlv_t physical_cell_id; - nfapi_uint16_tlv_t half_frame_index; - nfapi_uint16_tlv_t ssb_subcarrier_offset; - nfapi_uint16_tlv_t ssb_sib1_position_in_burst; // in sib1 - nfapi_uint64_tlv_t ssb_scg_position_in_burst; // in servingcellconfigcommon - nfapi_uint16_tlv_t ssb_periodicity; - nfapi_uint16_tlv_t ss_pbch_block_power; - nfapi_uint16_tlv_t n_ssb_crb; -} nfapi_nr_sch_config_t; - -typedef struct { - nfapi_uint16_tlv_t dl_bandwidth; - nfapi_uint16_tlv_t ul_bandwidth; - nfapi_uint16_tlv_t dl_offset; - nfapi_uint16_tlv_t ul_offset; - nfapi_uint16_tlv_t dl_subcarrierSpacing; - nfapi_uint16_tlv_t ul_subcarrierSpacing; -} nfapi_nr_initialBWP_config_t; - -#define NFAPI_INITIALBWP_DL_BANDWIDTH_TAG 0x5010 -#define NFAPI_INITIALBWP_DL_OFFSET_TAG 0x5011 -#define NFAPI_INITIALBWP_DL_SUBCARRIERSPACING_TAG 0x5012 -#define NFAPI_INITIALBWP_UL_BANDWIDTH_TAG 0x5013 -#define NFAPI_INITIALBWP_UL_OFFSET_TAG 0x5014 -#define NFAPI_INITIALBWP_UL_SUBCARRIERSPACING_TAG 0x5015 - - -#define NFAPI_NR_SCH_CONFIG_PHYSICAL_CELL_ID_TAG 0x501E -#define NFAPI_NR_SCH_CONFIG_HALF_FRAME_INDEX_TAG 0x501F -#define NFAPI_NR_SCH_CONFIG_SSB_SUBCARRIER_OFFSET_TAG 0x5020 -#define NFAPI_NR_SCH_CONFIG_SSB_POSITION_IN_BURST 0x5021 -#define NFAPI_NR_SCH_CONFIG_SSB_PERIODICITY 0x5022 -#define NFAPI_NR_SCH_CONFIG_SS_PBCH_BLOCK_POWER 0x5023 -#define NFAPI_NR_SCH_CONFIG_N_SSB_CRB 0x5024 -#define NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS 16 -#define NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS 16 - -typedef struct { - nfapi_uint16_tlv_t dmrs_TypeA_Position; - nfapi_uint16_tlv_t num_PDSCHTimeDomainResourceAllocations; - nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_k0[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; - nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_mappingType[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; - nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_startSymbolAndLength[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; -} nfapi_nr_pdsch_config_t; -#define NFAPI_NR_PDSCH_CONFIG_TAG - - -typedef struct { - nfapi_uint16_tlv_t prach_RootSequenceIndex; ///// L1 parameter 'PRACHRootSequenceIndex' - nfapi_uint16_tlv_t prach_msg1_SubcarrierSpacing; ///// L1 parameter 'prach-Msg1SubcarrierSpacing' - nfapi_uint16_tlv_t restrictedSetConfig; - nfapi_uint16_tlv_t msg3_transformPrecoding; ///// L1 parameter 'msg3-tp' - nfapi_uint16_tlv_t ssb_perRACH_OccasionAndCB_PreamblesPerSSB; - nfapi_uint16_tlv_t ra_ContentionResolutionTimer; - nfapi_uint16_tlv_t rsrp_ThresholdSSB; - /////////////////--------------------NR RACH-ConfigGeneric--------------------///////////////// - nfapi_uint16_tlv_t prach_ConfigurationIndex; ///// L1 parameter 'PRACHConfigurationIndex' - nfapi_uint16_tlv_t prach_msg1_FDM; ///// L1 parameter 'prach-FDM' - nfapi_uint16_tlv_t prach_msg1_FrequencyStart; ///// L1 parameter 'prach-frequency-start' - nfapi_uint16_tlv_t zeroCorrelationZoneConfig; - nfapi_uint16_tlv_t preambleReceivedTargetPower; - nfapi_uint16_tlv_t preambleTransMax; - nfapi_uint16_tlv_t powerRampingStep; - nfapi_uint16_tlv_t ra_ResponseWindow; -} nfapi_nr_rach_config_t; - -typedef struct { - nfapi_uint16_tlv_t groupHoppingEnabledTransformPrecoding; ///// L1 parameter 'Group-hopping-enabled-Transform-precoding' - nfapi_uint16_tlv_t msg3_DeltaPreamble; ///// L1 parameter 'Delta-preamble-msg3' - nfapi_uint16_tlv_t p0_NominalWithGrant; ///// L1 parameter 'p0-nominal-pusch-withgrant' - nfapi_uint16_tlv_t dmrs_TypeA_Position; - nfapi_uint16_tlv_t num_PUSCHTimeDomainResourceAllocations; - nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_k2[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'K2' - nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_mappingType[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'Mapping-type' - nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_startSymbolAndLength[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; -} nfapi_nr_pusch_config_t; - -typedef struct { - uint8_t pucch_resource_common; - nfapi_uint16_tlv_t pucch_GroupHopping; ///// L1 parameter 'PUCCH-GroupHopping' - nfapi_uint16_tlv_t p0_nominal; ///// L1 parameter 'p0-nominal-pucch' -} nfapi_nr_pucch_config_t; - - - -typedef struct { - nfapi_tl_t tl; - - nfapi_uint16_tlv_t controlResourceSetZero; - nfapi_uint16_tlv_t searchSpaceZero; - - // nfapi_nr_SearchSpace_t sib1searchSpace; - // nfapi_nr_SearchSpace_t sibssearchSpace; - // nfapi_nr_SearchSpace_t ra_SearchSpace; -}nfapi_nr_pdcch_config_t; - -typedef struct { -//NR TDD-UL-DL-ConfigCommon ///// L1 parameter 'UL-DL-configuration-common' - nfapi_uint16_tlv_t referenceSubcarrierSpacing; ///// L1 parameter 'reference-SCS' - nfapi_uint16_tlv_t dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity' - nfapi_uint16_tlv_t nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots' - nfapi_uint16_tlv_t nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common' - nfapi_uint16_tlv_t nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots' - nfapi_uint16_tlv_t nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common' - nfapi_uint16_tlv_t Pattern2Present; - nfapi_uint16_tlv_t Pattern2_dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity' - nfapi_uint16_tlv_t Pattern2_nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots' - nfapi_uint16_tlv_t Pattern2_nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common' - nfapi_uint16_tlv_t Pattern2_nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots' - nfapi_uint16_tlv_t Pattern2_nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common' -} nfapi_nr_tdd_ul_dl_config_t; - -typedef struct { - //RateMatchPattern is used to configure one rate matching pattern for PDSCH ///// L1 parameter 'Resource-set-cekk' - nfapi_uint16_tlv_t Match_Id; - nfapi_uint16_tlv_t patternType; - nfapi_uint16_tlv_t symbolsInResourceBlock; ///// L1 parameter 'rate-match-PDSCH-bitmap2 - nfapi_uint16_tlv_t periodicityAndPattern; ///// L1 parameter 'rate-match-PDSCH-bitmap3' - nfapi_uint16_tlv_t controlResourceSet; - nfapi_uint16_tlv_t subcarrierSpacing; ///// L1 parameter 'resource-pattern-scs' - nfapi_uint16_tlv_t mode; -} nfapi_nr_ratematchpattern_t; - -typedef struct { - //NR RateMatchPatternLTE-CRS - nfapi_uint16_tlv_t carrierfreqDL; ///// L1 parameter 'center-subcarrier-location' - nfapi_uint16_tlv_t dl_bandwidth; ///// L1 parameter 'BW' - nfapi_uint16_tlv_t nrofcrs_Ports; ///// L1 parameter 'rate-match-resources-numb-LTE-CRS-antenna-port' - nfapi_uint16_tlv_t v_Shift; ///// L1 parameter 'rate-match-resources-LTE-CRS-v-shift' - nfapi_uint16_tlv_t frame_Period; - nfapi_uint16_tlv_t frame_Offset; -} nfapi_nr_ratematchpattern_lte_crs_t; - -typedef struct { - nfapi_p4_p5_message_header_t header; - uint8_t num_tlv; - nfapi_nr_subframe_config_t subframe_config; - nfapi_nr_rf_config_t rf_config; - nfapi_nr_sch_config_t sch_config; - nfapi_nr_initialBWP_config_t initialBWP_config; - nfapi_nr_pdsch_config_t pdsch_config; - nfapi_nr_rach_config_t rach_config; - nfapi_nr_pusch_config_t pusch_config; - nfapi_nr_pucch_config_t pucch_config; - nfapi_nr_pdcch_config_t pdcch_config; - nfapi_nr_tdd_ul_dl_config_t tdd_ul_dl_config; - nfapi_nr_ratematchpattern_t ratematchpattern; - nfapi_nr_ratematchpattern_lte_crs_t ratematchpattern_lte_crs; - nfapi_nr_nfapi_t nfapi_config; - - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_nr_config_request_t; - -typedef enum { - NFAPI_NR_USS_FORMAT_0_0_AND_1_0, - NFAPI_NR_USS_FORMAT_0_1_AND_1_1, -} nfapi_nr_uss_dci_formats_e; - -typedef enum { - NFAPI_NR_SEARCH_SPACE_TYPE_COMMON=0, - NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC -} nfapi_nr_search_space_type_e; - -typedef enum { - NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0=0, - NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0A, - NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, - NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_2 -} nfapi_nr_common_search_space_type_e; - -typedef enum { - NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1=0, - NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2, - NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3 -} nfapi_nr_ssb_and_cset_mux_pattern_type_e; - typedef enum { NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=1, NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=0 } nfapi_nr_cce_reg_mapping_type_e; typedef enum { - NFAPI_NR_CSET_CONFIG_MIB_SIB1=0, + NFAPI_NR_CSET_CONFIG_MIB_SIB1 = 0, NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0 } nfapi_nr_coreset_config_type_e; typedef enum { - NFAPI_NR_CSET_SAME_AS_REG_BUNDLE=0, - NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS -} nfapi_nr_coreset_precoder_granularity_type_e; + NFAPI_NR_DMRS_TYPE1, + NFAPI_NR_DMRS_TYPE2 +} nfapi_nr_dmrs_type_e; typedef enum { - NFAPI_NR_QCL_TYPE_A=0, - NFAPI_NR_QCL_TYPE_B, - NFAPI_NR_QCL_TYPE_C, - NFAPI_NR_QCL_TYPE_D -} nfapi_nr_qcl_type_e; - -typedef enum { - NFAPI_NR_SS_PERIODICITY_SL1=1, - NFAPI_NR_SS_PERIODICITY_SL2=2, - NFAPI_NR_SS_PERIODICITY_SL4=4, - NFAPI_NR_SS_PERIODICITY_SL5=5, - NFAPI_NR_SS_PERIODICITY_SL8=8, - NFAPI_NR_SS_PERIODICITY_SL10=10, - NFAPI_NR_SS_PERIODICITY_SL16=16, - NFAPI_NR_SS_PERIODICITY_SL20=20, - NFAPI_NR_SS_PERIODICITY_SL40=40, - NFAPI_NR_SS_PERIODICITY_SL80=80, - NFAPI_NR_SS_PERIODICITY_SL160=160, - NFAPI_NR_SS_PERIODICITY_SL320=320, - NFAPI_NR_SS_PERIODICITY_SL640=640, - NFAPI_NR_SS_PERIODICITY_SL1280=1280, - NFAPI_NR_SS_PERIODICITY_SL2560=2560 -} nfapi_nr_search_space_monitoring_periodicity_e; - -typedef enum { - NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A=0, - NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B, - NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C, - NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST -} nfapi_nr_pdsch_time_domain_alloc_type_e; - -typedef enum { - NFAPI_NR_PDSCH_MAPPING_TYPE_A=0, - NFAPI_NR_PDSCH_MAPPING_TYPE_B -} nfapi_nr_pdsch_mapping_type_e; - -typedef enum { - NFAPI_NR_PDSCH_RBG_CONFIG_TYPE1=0, - NFAPI_NR_PDSCH_RBG_CONFIG_TYPE2 -} nfapi_nr_pdsch_rbg_config_type_e; - -typedef enum { - NFAPI_NR_PRG_GRANULARITY_2=2, - NFAPI_NR_PRG_GRANULARITY_4=4, - NFAPI_NR_PRG_GRANULARITY_WIDEBAND -} nfapi_nr_prg_granularity_e; - -typedef enum { - NFAPI_NR_PRB_BUNDLING_TYPE_STATIC=0, - NFAPI_NR_PRB_BUNDLING_TYPE_DYNAMIC -} nfapi_nr_prb_bundling_type_e; - -typedef enum { - NFAPI_NR_MCS_TABLE_QAM64_LOW_SE=0, - NFAPI_NR_MCS_TABLE_QAM256 -} nfapi_nr_pdsch_mcs_table_e; - -// P7 Sub Structures - -/* -typedef struct { - -nfapi_tl_t tl; - -uint8_t format_indicator; //1 bit -uint16_t frequency_domain_assignment; //up to 16 bits -uint8_t time_domain_assignment; // 4 bits -uint8_t frequency_hopping_flag; //1 bit - -uint8_t ra_preamble_index; //6 bits -uint8_t ss_pbch_index; //6 bits -uint8_t prach_mask_index; //4 bits - -uint8_t vrb_to_prb_mapping; //0 or 1 bit -uint8_t mcs; //5 bits -uint8_t ndi; //1 bit -uint8_t rv; //2 bits -uint8_t harq_pid; //4 bits -uint8_t dai; //0, 2 or 4 bits -uint8_t dai1; //1 or 2 bits -uint8_t dai2; //0 or 2 bits -uint8_t tpc; //2 bits -uint8_t pucch_resource_indicator; //3 bits -uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits - -uint8_t short_messages_indicator; //2 bits -uint8_t short_messages; //8 bits -uint8_t tb_scaling; //2 bits - -uint8_t carrier_indicator; //0 or 3 bits -uint8_t bwp_indicator; //0, 1 or 2 bits -uint8_t prb_bundling_size_indicator; //0 or 1 bits -uint8_t rate_matching_indicator; //0, 1 or 2 bits -uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits -uint8_t transmission_configuration_indication; //0 or 3 bits -uint8_t srs_request; //2 bits -uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits -uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit -uint8_t dmrs_sequence_initialization; //0 or 1 bit - -uint8_t srs_resource_indicator; -uint8_t precoding_information; -uint8_t csi_request; -uint8_t ptrs_dmrs_association; -uint8_t beta_offset_indicator; //0 or 2 bits - -uint8_t slot_format_indicator_count; -uint8_t *slot_format_indicators; - -uint8_t pre_emption_indication_count; -uint16_t *pre_emption_indications; //14 bit - -uint8_t block_number_count; -uint8_t *block_numbers; - -uint8_t ul_sul_indicator; //0 or 1 bit -uint8_t antenna_ports; - -uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits -uint16_t padding; - -} nfapi_nr_dl_config_dci_dl_pdu_rel15_t; -*/ -//#define NFAPI_NR_DL_CONFIG_REQUEST_DCI_DL_PDU_REL15_TAG 0x???? - - - -/* -typedef struct{ - nfapi_tl_t tl; - uint8_t coreset_id; - uint64_t frequency_domain_resources; - uint8_t duration; - uint8_t cce_reg_mapping_type; - uint8_t reg_bundle_size; - uint8_t interleaver_size; - uint8_t shift_index; - uint8_t precoder_granularity; - uint8_t tci_state_id; - uint8_t tci_present_in_dci; - uint32_t dmrs_scrambling_id; -} nfapi_nr_coreset_t; - -typedef struct{ - nfapi_tl_t tl; - uint8_t search_space_id; - uint8_t coreset_id; - uint8_t search_space_type; - uint8_t duration; - uint8_t css_formats_0_0_and_1_0; - uint8_t css_format_2_0; - uint8_t css_format_2_1; - uint8_t css_format_2_2; - uint8_t css_format_2_3; - uint8_t uss_dci_formats; - uint16_t srs_monitoring_periodicity; - uint16_t slot_monitoring_periodicity; - uint16_t slot_monitoring_offset; - uint32_t monitoring_symbols_in_slot; - uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS]; -} nfapi_nr_search_space_t; - - -typedef struct { - nfapi_tl_t tl; - uint16_t rnti; - uint8_t rnti_type; - uint8_t dci_format; - uint16_t cce_index; - /// Number of CRB in BWP that this DCI configures - uint16_t n_RB_BWP; - uint8_t config_type; - uint8_t search_space_type; - uint8_t common_search_space_type; - uint8_t aggregation_level; - uint8_t n_rb; - uint8_t n_symb; - int8_t rb_offset; - uint8_t cr_mapping_type; - uint8_t reg_bundle_size; - uint8_t interleaver_size; - uint8_t shift_index; - uint8_t mux_pattern; - uint8_t precoder_granularity; - uint8_t first_slot; - uint8_t first_symbol; - uint8_t nb_ss_sets_per_slot; - uint8_t nb_slots; - uint8_t sfn_mod2; - uint16_t scrambling_id; - nfapi_bf_vector_t bf_vector; -} nfapi_nr_dl_config_pdcch_parameters_rel15_t; - -*/ - - -typedef enum {nr_pusch_freq_hopping_disabled = 0 , - nr_pusch_freq_hopping_enabled = 1 - } nr_pusch_freq_hopping_t; - -typedef struct{ - uint8_t aperiodicSRS_ResourceTrigger; -} nfapi_nr_ul_srs_config_t; - -typedef struct { - uint8_t bandwidth_part_ind; - uint16_t number_rbs; - uint16_t start_rb; - uint8_t frame_offset; - uint16_t number_symbols; - uint16_t start_symbol; - uint8_t length_dmrs; - nr_pusch_freq_hopping_t pusch_freq_hopping; - uint8_t mcs; - uint8_t Qm; - uint16_t R; - uint8_t ndi; - uint8_t rv; - int8_t accumulated_delta_PUSCH; - int8_t absolute_delta_PUSCH; - uint8_t n_layers; - uint8_t tpmi; - uint8_t n_dmrs_cdm_groups; - uint8_t dmrs_ports[4]; - uint8_t n_front_load_symb; - nfapi_nr_ul_srs_config_t srs_config; - uint8_t csi_reportTriggerSize; - uint8_t maxCodeBlockGroupsPerTransportBlock; - uint8_t ptrs_dmrs_association_port; - uint8_t beta_offset_ind; -} nfapi_nr_ul_config_ulsch_pdu_rel15_t; - - - - - -typedef struct { - uint16_t rnti; - nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15; -} nfapi_nr_ul_config_ulsch_pdu; - -typedef struct { - uint8_t pdu_type; - uint8_t pdu_size; - - union { - // nfapi_nr_ul_config_uci_pdu uci_pdu; - nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; - // nfapi_nr_ul_config_srs_pdu srs_pdu; - }; -} nfapi_nr_ul_config_request_pdu_t; - -typedef struct { - nfapi_tl_t tl; - uint8_t number_pdu; - nfapi_nr_ul_config_request_pdu_t *ul_config_pdu_list; -} nfapi_nr_ul_config_request_body_t; - -typedef struct { - nfapi_p7_message_header_t header; - uint16_t sfn_sf; - nfapi_nr_ul_config_request_body_t ul_config_request_body; - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_nr_ul_config_request_t; + NFAPI_NR_SRS_BEAMMANAGEMENT = 0, + NFAPI_NR_SRS_CODEBOOK = 1, + NFAPI_NR_SRS_NONCODEBOOK = 2, + NFAPI_NR_SRS_ANTENNASWITCH = 3 +} nfapi_nr_srs_usage_e; #endif diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index a70e18af11..ac5e915857 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -11,7 +11,6 @@ #include "stddef.h" #include "nfapi_interface.h" -#include "nfapi_nr_interface.h" #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 @@ -26,13 +25,6 @@ // Extension to the generic structures for single tlv values - -typedef enum { - NFAPI_NR_DMRS_TYPE1=0, - NFAPI_NR_DMRS_TYPE2 -} nfapi_nr_dmrs_type_e; - - typedef struct { /// Value: 0 -> 1, 0: Payload is carried directly in the value field, 1: Pointer to payload is in the value field uint16_t tag; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index c864a0366a..3214d3a5ac 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -39,8 +39,6 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "SCHED_NR/fapi_nr_l1.h" -#include "nfapi_nr_interface.h" - #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index 275df1a0d4..4576f322f3 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -32,29 +32,29 @@ #include "PHY/NR_REFSIG/ss_pbch_nr.h" #include "PHY/NR_REFSIG/dmrs_nr.h" - - +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, uint16_t start_sc, uint16_t ofdm_symbol_size, uint8_t numDmrsCdmGrpsNoData, - uint8_t dmrs_type) { + uint8_t dmrs_type) +{ uint8_t delta; uint16_t diff; - if (k>start_sc) + if (k > start_sc) diff = k-start_sc; else diff = (ofdm_symbol_size-start_sc)+k; for (int i = 0; i #include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" @@ -34,6 +33,8 @@ #include "filt16a_32.h" #include "T.h" #include +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" + extern openair0_config_t openair0_cfg[]; //#define DEBUG_PDSCH diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index b51a8b3b2d..d2a37ceb3c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -36,15 +36,14 @@ #include "PHY/phy_extern_nr_ue.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" -#include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "SCHED_NR_UE/defs.h" #include "SIMULATION/TOOLS/sim.h" #include "executables/nr-uesoftmodem.h" #include "PHY/CODING/nrLDPC_extern.h" #include "common/utils/nr/nr_common.h" #include "openair1/PHY/TOOLS/phy_scope_interface.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" //#define ENABLE_PHY_PAYLOAD_DEBUG 1 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 1bea7b0a6d..e2b726e21f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -41,6 +41,7 @@ #include "common/utils/nr/nr_common.h" #include #include "openair1/PHY/TOOLS/phy_scope_interface.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" /* dynamic shift for LLR computation for TM3/4 * set as command line argument, see lte-softmodem.c diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index b845bad1c0..28a6d84b9f 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -32,7 +32,6 @@ #include "PHY/defs_gNB.h" #include "SCHED_NR/sched_nr.h" -#include "nfapi_nr_interface.h" #include "nfapi_nr_interface_scf.h" // added diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index cfbd8d9c12..77514d0cfe 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -27,7 +27,6 @@ #include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" -#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" #include "fapi_nr_l1.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f1c9ce4066..82ccca43ee 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -53,6 +53,7 @@ #include "executables/nr-uesoftmodem.h" #include "SCHED_NR_UE/pucch_uci_ue_nr.h" #include +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" //#define DEBUG_PHY_PROC //#define NR_PDCCH_SCHED_DEBUG diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6dd91140b6..86ce0c348a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -36,6 +36,7 @@ #include "mac_defs.h" #include "oai_asn1.h" #include "RRC/NR_UE/rrc_defs.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" #define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */ #define NR_DL_MAX_NB_CW (2) /* number of downlink code word */ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 65e8dd3fc4..991328b18c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -38,7 +38,6 @@ #include "common/utils/nr/nr_common.h" #include "executables/softmodem-common.h" #include -#include "nfapi_nr_interface.h" void fill_dci_search_candidates(const NR_SearchSpace_t *ss, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 97c42c57f0..38f4c41a07 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -37,8 +37,6 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "LAYER2/RLC/rlc.h" -/*NFAPI*/ -#include "nfapi_nr_interface.h" /*TAG*/ #include "NR_TAG-Id.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 61ce2c49f9..e76e3cd091 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -317,12 +317,6 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti); int nr_get_default_pucch_res(int pucch_ResourceCommon); -int get_dlscs(nfapi_nr_config_request_t *cfg); - -int get_ulscs(nfapi_nr_config_request_t *cfg); - -int get_symbolsperslot(nfapi_nr_config_request_t *cfg); - int nr_write_ce_dlsch_pdu(module_id_t module_idP, const NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *mac_pdu, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index f2c66bd99f..4724eac162 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -78,6 +78,7 @@ /* Interface */ #include "nfapi_nr_interface_scf.h" +#include "nfapi_nr_interface.h" #include "NR_PHY_INTERFACE/NR_IF_Module.h" #include "mac_rrc_ul.h" diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 108e0afe7a..e7cbb331bc 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -35,7 +35,6 @@ #include #include -#include "nfapi_nr_interface.h" #include "nfapi_nr_interface_scf.h" #include "common/platform_constants.h" #include "common/platform_types.h" From 4f32110c72e3887c17a6df573cdde60ad5d9b22a Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 15 Jan 2024 13:58:35 +0100 Subject: [PATCH 10/41] avoid usage of ASN1 structure at PHY for SRS --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 27 ++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 77514d0cfe..0062875fb3 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -37,10 +37,7 @@ #include "executables/nr-softmodem.h" #include "executables/softmodem-common.h" #include "nfapi/oai_integration/vendor_ext.h" -#include "NR_SRS-ResourceSet.h" - #include "assertions.h" - #include //#define DEBUG_RXDATA @@ -1039,17 +1036,17 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) case 0: LOG_W(NR_PHY, "SRS report was not requested by MAC\n"); return 0; - case 1 << NR_SRS_ResourceSet__usage_beamManagement: - srs_indication->srs_usage = NR_SRS_ResourceSet__usage_beamManagement; + case 1 << NFAPI_NR_SRS_BEAMMANAGEMENT: + srs_indication->srs_usage = NFAPI_NR_SRS_BEAMMANAGEMENT; break; - case 1 << NR_SRS_ResourceSet__usage_codebook: - srs_indication->srs_usage = NR_SRS_ResourceSet__usage_codebook; + case 1 << NFAPI_NR_SRS_CODEBOOK: + srs_indication->srs_usage = NFAPI_NR_SRS_CODEBOOK; break; - case 1 << NR_SRS_ResourceSet__usage_nonCodebook: - srs_indication->srs_usage = NR_SRS_ResourceSet__usage_nonCodebook; + case 1 << NFAPI_NR_SRS_NONCODEBOOK: + srs_indication->srs_usage = NFAPI_NR_SRS_NONCODEBOOK; break; - case 1 << NR_SRS_ResourceSet__usage_antennaSwitching: - srs_indication->srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching; + case 1 << NFAPI_NR_SRS_ANTENNASWITCH: + srs_indication->srs_usage = NFAPI_NR_SRS_ANTENNASWITCH; break; default: LOG_E(NR_PHY, "Invalid srs_pdu->srs_parameters_v4.usage %i\n", srs_pdu->srs_parameters_v4.usage); @@ -1072,7 +1069,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) start_meas(&gNB->srs_report_tlv_stats); switch (srs_indication->srs_usage) { - case NR_SRS_ResourceSet__usage_beamManagement: { + case NFAPI_NR_SRS_BEAMMANAGEMENT: { start_meas(&gNB->srs_beam_report_stats); nfapi_nr_srs_beamforming_report_t nr_srs_bf_report; nr_srs_bf_report.prg_size = srs_pdu->beamforming.prg_size; @@ -1101,7 +1098,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) break; } - case NR_SRS_ResourceSet__usage_codebook: { + case NFAPI_NR_SRS_CODEBOOK: { start_meas(&gNB->srs_iq_matrix_stats); nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_channel_iq_matrix; nr_srs_channel_iq_matrix.normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation; @@ -1150,8 +1147,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) break; } - case NR_SRS_ResourceSet__usage_nonCodebook: - case NR_SRS_ResourceSet__usage_antennaSwitching: + case NFAPI_NR_SRS_NONCODEBOOK: + case NFAPI_NR_SRS_ANTENNASWITCH: LOG_W(NR_PHY, "PHY procedures for this SRS usage are not implemented yet!\n"); break; From c917825dab73238656f77a9193d0099862d58d05 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 15 Jan 2024 15:26:14 +0100 Subject: [PATCH 11/41] remove calls to LTE mac.h in NR --- nfapi/oai_integration/nfapi_vnf.c | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 2 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 8 +++++-- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 8 +++---- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 14 ++++++------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 4 ++-- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 13 ++++++------ .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 21 ++++++++++++------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 10 --------- openair2/RRC/NR/nr_rrc_defs.h | 1 - openair2/RRC/NR_UE/L2_interface_ue.c | 9 ++------ 11 files changed, 42 insertions(+), 49 deletions(-) diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 71bda06800..c01637c558 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -46,6 +46,7 @@ #include "common/ran_context.h" #include "openair2/PHY_INTERFACE/queue_t.h" #include "gnb_ind_vars.h" +#include "LAYER2/MAC/mac.h" #define TEST diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index a39376ae25..dbdc437af8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -59,7 +59,7 @@ // Definitions for MAC control and data #define NR_BCCH_DL_SCH 3 // SI #define NR_BCCH_BCH 5 // MIB -#define CCCH_PAYLOAD_SIZE_MAX 512 +#define NR_CCCH_PAYLOAD_SIZE_MAX 512 #define RAR_PAYLOAD_SIZE_MAX 128 #define MAX_CSI_REPORTCONFIG 48 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 1b786af544..e98cd687be 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -45,7 +45,6 @@ /* MAC */ #include "LAYER2/NR_MAC_COMMON/nr_mac.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" -#include "LAYER2/MAC/mac.h" #include "NR_MAC_COMMON/nr_mac_extern.h" #include "mac_defs_sl.h" @@ -181,7 +180,7 @@ typedef struct { // after multiplexing buffer remain for each lcid int32_t LCID_buffer_remain; // buffer status for each lcid - uint8_t LCID_status; + bool LCID_buffer_with_data; // logical channel group id of this LCID long LCGID; // Bj bucket usage per lcid @@ -445,6 +444,11 @@ typedef struct nr_lcordered_info_s { uint32_t bucket_size; } nr_lcordered_info_t; + +typedef struct { + uint8_t payload[NR_CCCH_PAYLOAD_SIZE_MAX]; +} __attribute__ ((__packed__)) NR_CCCH_PDU; + typedef struct { NR_SearchSpace_t *otherSI_SS; NR_SearchSpace_t *ra_SS; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index f2f625b79c..c7e43e50f8 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -95,13 +95,13 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value // configured by the NW. - mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->BSR_reporting_active = BSR_TRIGGER_NONE; + mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; for (int i = 0; i < NR_MAX_NUM_LCID; i++) { LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i); - mac->scheduling_info.lc_sched_info[i].LCID_status = LCID_EMPTY; + mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false; mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0; mac->scheduling_info.lc_sched_info[i].Bj = 0; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index dc5da31ca9..02b4d38453 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1147,12 +1147,12 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) // First check ReTxBSR Timer because it is always configured // Decrement ReTxBSR Timer if it is running and not null - if ((mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.retxBSR_SF != 0)) { + if ((mac->scheduling_info.retxBSR_SF != NR_MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.retxBSR_SF != 0)) { mac->scheduling_info.retxBSR_SF--; } // Decrement Periodic Timer if it is running and not null - if ((mac->scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.periodicBSR_SF != 0)) { + if ((mac->scheduling_info.periodicBSR_SF != NR_MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.periodicBSR_SF != 0)) { mac->scheduling_info.periodicBSR_SF--; } @@ -1194,7 +1194,7 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { // Reset transmission status lcid_bytes_in_buffer[lcid - 1] = 0; - mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_EMPTY; + mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_with_data = false; } for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) { @@ -1235,7 +1235,7 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t rlc_status.bytes_in_buffer, frameP, slotP); - mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_NOT_EMPTY; + mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_with_data = true; //Update BSR_bytes and position in lcid_reordered_array only if Group is defined if (lcgid < NR_MAX_NUM_LCGID) { @@ -2693,7 +2693,7 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, } //Restart ReTxBSR Timer at new grant indication (38.321) - if (mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) { + if (mac->scheduling_info.retxBSR_SF != NR_MAC_UE_BSR_TIMER_NOT_RUNNING) { mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer); } @@ -2918,7 +2918,7 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, } // Reset BSR Trigger flags - mac->BSR_reporting_active = BSR_TRIGGER_NONE; + mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; } } @@ -3242,7 +3242,7 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, // skip the logical channel if no data in the buffer initially or the data in the buffer was zero because it was written in to // MAC PDU - if (!sched_info->lc_sched_info[lcid - 1].LCID_status || !lcids_data_status[lcid - 1]) { + if (!sched_info->lc_sched_info[lcid - 1].LCID_buffer_with_data || !lcids_data_status[lcid - 1]) { lcids_data_status[lcid - 1] = false; continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 161598ec2d..326ba5fce4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -617,7 +617,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, } } LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); - ra->state = Msg2; ra->timing_offset = timing_offset; ra->preamble_slot = slotP; @@ -653,11 +652,12 @@ void nr_initiate_ra_proc(module_id_t module_idP, && !((find_nr_UE(&nr_mac->UE_info, ra->rnti) == NULL) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 0x1 && ra->rnti <= 0xffef)); if (loop == 100) { - LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + LOG_E(NR_MAC, "[RAPROC] initialisation random access aborted\n"); abort(); } } + ra->state = Msg2; ra->RA_rnti = ra_rnti; ra->preamble_index = preamble_index; ra->beam_id = cc->ssb_index[beam_index]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9199327501..d5116385e3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1966,18 +1966,17 @@ NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP) return NULL; } -int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) { -//------------------------------------------------------------------------------ - int RA_id; - RA_t *ra = (RA_t *) &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0]; +int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) +{ + NR_RA_t *ra = &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0]; - for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { + for (int RA_id = 0; RA_id < NR_NB_RA_PROC_MAX; RA_id++) { LOG_D(NR_MAC, "Checking RA_id %d for %x : state %d\n", RA_id, rntiP, ra[RA_id].state); - if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP) + if (ra[RA_id].state != RA_IDLE && ra[RA_id].rnti == rntiP) return RA_id; } @@ -3047,7 +3046,7 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1); const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0]; DevAssert(bearer->servedRadioBearer->choice.srb_Identity == 1); - nr_rlc_add_srb(UE->rnti, DCCH, bearer); + nr_rlc_add_srb(UE->rnti, bearer->servedRadioBearer->choice.srb_Identity, bearer); } void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 13aa2a3546..04f2c2fdc9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -332,8 +332,10 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) new_CellGroup); } - if (req->rrc_container != NULL) - nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); + if (req->rrc_container != NULL) { + logical_chan_id_t id = 1; + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container, req->rrc_container_length); + } UE->capability = ue_cap; if (ue_cap != NULL) { @@ -424,8 +426,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) handle_ue_context_drbs_release(req->gNB_DU_ue_id, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup); } - if (req->rrc_container != NULL) - nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); + if (req->rrc_container != NULL) { + logical_chan_id_t id = 1; + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container, req->rrc_container_length); + } if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { LOG_E(NR_MAC, @@ -498,9 +502,10 @@ void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *conf } NR_SCHED_UNLOCK(&mac->sched_lock); - if (confirm->rrc_container_length > 0) - nr_rlc_srb_recv_sdu(confirm->gNB_DU_ue_id, DCCH, confirm->rrc_container, confirm->rrc_container_length); - + if (confirm->rrc_container_length > 0) { + logical_chan_id_t id = 1; + nr_rlc_srb_recv_sdu(confirm->gNB_DU_ue_id, id, confirm->rrc_container, confirm->rrc_container_length); + } /* nothing else to be done? */ } @@ -589,7 +594,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) du_add_f1_ue_data(dl_rrc->gNB_DU_ue_id, &new_ue_data); } - if (UE->expect_reconfiguration && dl_rrc->srb_id == DCCH) { + if (UE->expect_reconfiguration && dl_rrc->srb_id == 1) { /* we expected a reconfiguration, and this is on DCCH. We assume this is * the reconfiguration: nr_mac_prepare_cellgroup_update() already stored * the CellGroupConfig. Below, we trigger a timer, and the CellGroupConfig diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 4724eac162..9028dbc797 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -85,8 +85,6 @@ /* MAC */ #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" -#include "LAYER2/MAC/mac.h" -#include "NR_TAG.h" #include @@ -251,14 +249,6 @@ typedef struct { /// Outgoing BCCH pdu for PHY uint8_t sib1_bcch_pdu[NR_MAX_SIB_LENGTH / 8]; int sib1_bcch_length; - /// Outgoing BCCH DCI allocation - uint32_t BCCH_alloc_pdu; - /// Outgoing CCCH pdu for PHY - CCCH_PDU CCCH_pdu; - /// Outgoing PCCH DCI allocation - uint32_t PCCH_alloc_pdu; - /// Outgoing PCCH pdu for PHY - PCCH_PDU PCCH_pdu; /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 4dc17fd493..b92150e65b 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -40,7 +40,6 @@ #include "nr_rrc_common.h" #include "ds/byte_array.h" -#include "common/ngran_types.h" #include "common/platform_constants.h" #include "common/platform_types.h" #include "mac_rrc_dl.h" diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 0b61f3fc82..b3eac63e4c 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -33,7 +33,6 @@ #include "rrc_defs.h" #include "rrc_proto.h" #include "assertions.h" -#include "MAC/mac.h" #include "LAYER2/NR_MAC_COMMON/nr_mac.h" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" @@ -89,13 +88,9 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); } break; - - case CCCH: - AssertFatal(false, "use RLC instead\n"); - break; - + case NR_SBCCH_SL_BCH: - if (pdu_len>0) { + if (pdu_len > 0) { LOG_T(NR_RRC, "[UE %d] Received SL-MIB for NR_SBCCH_SL_BCH.\n", module_id); MessageDef *message_p; From 1baf2aa3a44d19ef675edafd47ed84f7a0300f95 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 24 Jan 2024 14:15:18 +0100 Subject: [PATCH 12/41] rework handling DAI at MAC UE, to improve the scenario where there are more than 4 harq per pucch --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 3 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 111 ++++++++++--------- 2 files changed, 59 insertions(+), 55 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 1b786af544..785169d339 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -340,10 +340,9 @@ typedef struct { frame_t ul_frame; int ul_slot; uint8_t ack; - uint8_t dai; int n_CCE; int N_CCE; - int j_dai; + int dai_cumul; int8_t delta_pucch; uint32_t R; uint32_t TBS; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index bbbed17648..f81a142cd4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1306,10 +1306,9 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, current_harq->active = true; current_harq->ack_received = false; current_harq->pucch_resource_indicator = pucch_id; - current_harq->dai = dai; - current_harq->j_dai = 0; current_harq->n_CCE = n_CCE; current_harq->N_CCE = N_CCE; + current_harq->dai_cumul = 0; current_harq->delta_pucch = delta_pucch; // FIXME k0 != 0 currently not taken into consideration int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : get_softmodem_params()->numerology; @@ -1322,27 +1321,39 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, } // counter DAI in DCI ranges from 0 to 3 // we might have more than 4 HARQ processes to report per PUCCH - // we need to keep track of how many same DAI were received - int count = 0; + // we need to keep track of how many DAI we received in a slot (dai_cumul) despite the modulo operation + int highest_dai = -1; + int temp_dai = dai; for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) { + // looking for other active HARQ processes with feedback in the same frame/slot if (i == harq_id) continue; NR_UE_HARQ_STATUS_t *harq = &mac->dl_harq_info[i]; if (harq->active && harq->ul_frame == current_harq->ul_frame && harq->ul_slot == current_harq->ul_slot) { - if (harq->dai == dai) { - // need to take into account possible - // missed DCI detections - int missed_detections = count / (4 * (current_harq->j_dai + 1)); - current_harq->j_dai += (missed_detections + 1); - count += missed_detections; - } - count++; + // highest_dai is the largest cumulative dai in the set of HARQ allocations for a given slot + if (harq->dai_cumul > highest_dai) + highest_dai = harq->dai_cumul - 1; } } - LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d fb time %d\n", - harq_id, frame, slot, current_harq->ul_frame, current_harq->ul_slot, data_toul_fb); + + current_harq->dai_cumul = temp_dai + 1; // DAI = 0 (temp_dai) corresponds to 1st assignment and so on + // if temp_dai is less or equal than cumulative highest dai for given slot + // it's an indication dai was reset due to modulo 4 operation + if (temp_dai <= highest_dai) { + int mod4_count = (highest_dai / 4) + 1; // to take into account how many times dai wrapped up (modulo 4) + current_harq->dai_cumul += (mod4_count * 4); + } + LOG_D(NR_MAC, + "Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d fb time %d total dai %d\n", + harq_id, + frame, + slot, + current_harq->ul_frame, + current_harq->ul_slot, + data_toul_fb, + current_harq->dai_cumul); } int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, @@ -2284,46 +2295,40 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_sfn = frame; mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_slot = slot; } - if (current_harq->dai >= NR_DL_MAX_DAI) { - LOG_E(MAC,"PUCCH Downlink DAI has an invalid value of %d\n", current_harq->dai); - } - else { - if (res_ind != -1 && res_ind != current_harq->pucch_resource_indicator) - LOG_E(MAC, - "Value of pucch_resource_indicator %d not matching with what set before %d (Possibly due to a false DCI) \n", - current_harq->pucch_resource_indicator, - res_ind); - else{ - int dai_current = current_harq->dai + (current_harq->j_dai * 4) + 1; // DCI DAI to counter DAI conversion - - if (dai_current == 0) { - LOG_E(MAC,"PUCCH Downlink dai is invalid\n"); - return false; - } else if (dai_current > dai_max) { - dai_max = dai_current; - } - - number_harq_feedback++; - if (current_harq->ack_received) { - ack_data[code_word][dai_current - 1] = current_harq->ack; - current_harq->active = false; - current_harq->ack_received = false; - } else { - LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); - ack_data[code_word][dai_current - 1] = 0; - } - dai[code_word][dai_current - 1] = current_harq->dai + 1; - int temp_ind = current_harq->pucch_resource_indicator; - AssertFatal(res_ind == -1 || res_ind == temp_ind, - "Current resource index %d does not match with previous resource index %d\n", - temp_ind, - res_ind); - res_ind = temp_ind; - pucch->n_CCE = current_harq->n_CCE; - pucch->N_CCE = current_harq->N_CCE; - pucch->delta_pucch = current_harq->delta_pucch; - LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid); + if (res_ind != -1 && res_ind != current_harq->pucch_resource_indicator) + LOG_E(NR_MAC, + "Value of pucch_resource_indicator %d not matching with what set before %d (Possibly due to a false DCI) \n", + current_harq->pucch_resource_indicator, + res_ind); + else{ + if (current_harq->dai_cumul == 0) { + LOG_E(NR_MAC,"PUCCH Downlink DAI is invalid\n"); + return false; + } else if (current_harq->dai_cumul > dai_max) { + dai_max = current_harq->dai_cumul; } + + number_harq_feedback++; + int dai_index = current_harq->dai_cumul - 1; + if (current_harq->ack_received) { + ack_data[code_word][dai_index] = current_harq->ack; + current_harq->active = false; + current_harq->ack_received = false; + } else { + LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); + ack_data[code_word][dai_index] = 0; + } + dai[code_word][dai_index] = (dai_index % 4) + 1; // value between 1 and 4 + int temp_ind = current_harq->pucch_resource_indicator; + AssertFatal(res_ind == -1 || res_ind == temp_ind, + "Current resource index %d does not match with previous resource index %d\n", + temp_ind, + res_ind); + res_ind = temp_ind; + pucch->n_CCE = current_harq->n_CCE; + pucch->N_CCE = current_harq->N_CCE; + pucch->delta_pucch = current_harq->delta_pucch; + LOG_D(NR_MAC,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid); } } } From c5c883f71dc2a63f55d1a7e9f59dcc70e9b3b3cb Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 22 Feb 2024 13:15:54 +0100 Subject: [PATCH 13/41] small-bug-from-cdb18d38bfa6aee288a68d9e8881615a48addd83-and-one-gcc-warning --- cmake_targets/build_oai | 2 +- cmake_targets/nas_sim_tools/CMakeLists.txt | 3 ++- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 4fd7defd0c..ab0dd0cda9 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -521,7 +521,7 @@ function main() { mkdir -p $DIR/nas_sim_tools/build cd $DIR/nas_sim_tools/build - eval $CMAKE_CMD .. + ${CMAKE_CMD% *} .. compilations nas_sim_tools usim.txt usim compilations nas_sim_tools nvram.txt nvram compilations nas_sim_tools conf2uedata.txt conf2uedata diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 55c981701b..4f0be81064 100755 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5) project(NAS_SIM_TOOLS) @@ -6,6 +6,7 @@ include(FindPkgConfig) pkg_search_module(CONFIG libconfig REQUIRED) include_directories(${CONFIG_INCLUDE_DIRS}) add_definitions(-std=gnu99) +include("../macros.cmake") ENABLE_LANGUAGE(C) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 9abb5ab748..d2cda44280 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -104,9 +104,9 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort nfapi_nr_pm_pdu_t *pmi_pdu = malloc16(mat.num_pm_idx * sizeof(*pmi_pdu)); AssertFatal(pmi_pdu != NULL, "out of memory\n"); mat.pmi_pdu = pmi_pdu; - AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); // Generation of codebook Type1 with codebookMode 1 (num_antenna_ports < 16) + AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); // Generate DFT vertical beams // ll: index of a vertical beams vector (represented by i1_1 in TS 38.214) const int max_l = N1 * O1 + (K1 - 1) * O1; From 885611cd006e356681b8d2a96d546c0185fd16ae Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 28 Feb 2024 08:41:26 +0100 Subject: [PATCH 14/41] SRS config: make explicit that > 30 UEs don't work, handle gracefully at runtime We can only support up to 30 UEs for SRS. In this commit, we change: - if the total number of UEs is > 32, throw error during compilation to raise awareness (32 so that a multiple of two still works, everything else is confusing, see also next point) - during runtime, handle gracefully if UID is 30 or 31 to not abort (we can simply not allocate SRS resources) Also, refactor config_srs() to always give back new memory; the code is shorter and clearer. Rename to get_contig_srs() to make it explicit. --- openair2/RRC/NR/nr_rrc_config.c | 72 +++++++++++++-------------------- 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index d85bedf79e..06e5f75442 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -608,25 +608,27 @@ static struct NR_SRS_Resource__resourceType__periodic *configure_periodic_srs(co return periodic_srs; } -static void config_srs(const NR_ServingCellConfigCommon_t *scc, - NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, - const NR_UE_NR_Capability_t *uecap, - const int curr_bwp, - const int uid, - const int res_id, - const long maxMIMO_Layers, - const int do_srs) +static NR_SetupRelease_SRS_Config_t *get_config_srs(const NR_ServingCellConfigCommon_t *scc, + const NR_UE_NR_Capability_t *uecap, + const int curr_bwp, + const int uid, + const int res_id, + const long maxMIMO_Layers, + int do_srs) { - setup_release_srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; - - NR_SRS_Config_t *srs_Config; - if (setup_release_srs_Config->choice.setup) { - srs_Config = setup_release_srs_Config->choice.setup; - ASN_STRUCT_FREE(asn_DEF_NR_SRS_Config, srs_Config); + // if in the future NUMBER_OF_gNB_MAX is increased, it will be necessary to improve the allocation of SRS resources, + // where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations. + static_assert(NUMBER_OF_gNB_MAX <= 32, + "SRS can only handle up to 30 UEs (additional ones are handled gracefully, but don't have SRS enabled\n"); + if (do_srs && (uid < 0 || uid > 29)) { + LOG_E(NR_RRC, "gNB cannot allocate SRS resources for UID %d: available resources exceeded\n", uid); + do_srs = 0; } + NR_SetupRelease_SRS_Config_t *setup_release_srs_Config = calloc(1,sizeof(*setup_release_srs_Config)); + setup_release_srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; setup_release_srs_Config->choice.setup = calloc(1,sizeof(*setup_release_srs_Config->choice.setup)); - srs_Config = setup_release_srs_Config->choice.setup; + NR_SRS_Config_t *srs_Config = setup_release_srs_Config->choice.setup; srs_Config->srs_ResourceSetToReleaseList = NULL; @@ -733,6 +735,8 @@ static void config_srs(const NR_ServingCellConfigCommon_t *scc, srs_res0->spatialRelationInfo->referenceSignal.present = NR_SRS_SpatialRelationInfo__referenceSignal_PR_ssb_Index; srs_res0->spatialRelationInfo->referenceSignal.choice.ssb_Index = 0; asn1cSeqAdd(&srs_Config->srs_ResourceToAddModList->list,srs_res0); + + return setup_release_srs_Config; } void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, @@ -1443,15 +1447,7 @@ static void config_uplinkBWP(NR_BWP_Uplink_t *ubwp, && servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers ? *servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1; - ubwp->bwp_Dedicated->srs_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->srs_Config)); - config_srs(scc, - ubwp->bwp_Dedicated->srs_Config, - NULL, - curr_bwp, - uid, - bwp_loop+1, - maxMIMO_Layers, - configuration->do_SRS); + ubwp->bwp_Dedicated->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, bwp_loop + 1, maxMIMO_Layers, configuration->do_SRS); ubwp->bwp_Dedicated->configuredGrantConfig = NULL; ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL; @@ -2227,8 +2223,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, : 1; // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 - initialUplinkBWP->srs_Config = calloc(1, sizeof(*initialUplinkBWP->srs_Config)); - config_srs(scc, initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, maxMIMO_Layers, 0); + initialUplinkBWP->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, 0, maxMIMO_Layers, 0); scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing); @@ -2525,17 +2520,8 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, // UL and SRS configuration if (configuration->do_SRS && uplinkConfig && uplinkConfig->initialUplinkBWP) { - if (!uplinkConfig->initialUplinkBWP->srs_Config) { - uplinkConfig->initialUplinkBWP->srs_Config = calloc(1, sizeof(*uplinkConfig->initialUplinkBWP->srs_Config)); - } - config_srs(scc, - SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config, - uecap, - curr_bwp, - uid, - 0, - maxMIMO_Layers, - configuration->do_SRS); + ASN_STRUCT_FREE(asn_DEF_NR_SetupRelease_SRS_Config, uplinkConfig->initialUplinkBWP->srs_Config); + uplinkConfig->initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, uid, 0, maxMIMO_Layers, configuration->do_SRS); } // Set DL MCS table @@ -2570,7 +2556,9 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, } *pusch_Config->maxRank = ul_max_layers; } - config_srs(scc, ul_bwp->bwp_Dedicated->srs_Config, uecap, bwp_size, uid, i + 1, maxMIMO_Layers, configuration->do_SRS); + + ASN_STRUCT_FREE(asn_DEF_NR_SetupRelease_SRS_Config, ul_bwp->bwp_Dedicated->srs_Config); + ul_bwp->bwp_Dedicated->srs_Config = get_config_srs(scc, uecap, bwp_size, uid, i + 1, maxMIMO_Layers, configuration->do_SRS); } } update_cqitables(bwp_Dedicated->pdsch_Config, SpCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup); @@ -2648,11 +2636,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC if (uecap == NULL) LOG_E(RRC, "No UE Capabilities available when programming default CellGroup in NSA\n"); - // This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4. - // However, if in the future NUMBER_OF_UE_MAX is increased, it will be necessary to improve the allocation of SRS resources, - // where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations. - AssertFatal(uid >= 0 && uid < 30, "gNB cannot allocate the SRS resources\n"); - uint64_t bitmap = get_ssb_bitmap(servingcellconfigcommon); // See comment at the end of this function regarding ServingCellConfig fix_servingcellconfigdedicated(servingcellconfigdedicated); @@ -2772,8 +2755,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - initialUplinkBWP->srs_Config = calloc(1, sizeof(*initialUplinkBWP->srs_Config)); - config_srs(servingcellconfigcommon, initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, maxMIMO_Layers, configuration->do_SRS); + initialUplinkBWP->srs_Config = get_config_srs(servingcellconfigcommon, NULL, curr_bwp, uid, 0, maxMIMO_Layers, configuration->do_SRS); // Downlink BWPs int n_dl_bwp = 1; From 70be05381f38d650ee5ffd474f4bc594a1124195 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 28 Feb 2024 08:08:37 +0100 Subject: [PATCH 15/41] remove unused UE_PF_PO and ue_pf_po_mutex They use 4G NUMBER_OF_UE_MAX, which is not supposed to be present in 5G. Further, the mutex and variable are global state; for Paging, we should use F1. --- executables/nr-softmodem.c | 4 --- executables/nr-uesoftmodem.c | 3 --- openair2/RRC/NR/nr_rrc_extern.h | 4 --- openair2/RRC/NR/rrc_gNB.c | 43 +++------------------------------ 4 files changed, 3 insertions(+), 51 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 3d9c02f5e4..04b66237dc 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -679,9 +679,6 @@ int main( int argc, char **argv ) { AssertFatal(ret == 0, "cannot create ITTI tasks\n"); } - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); mlockall(MCL_CURRENT | MCL_FUTURE); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); @@ -823,7 +820,6 @@ int main( int argc, char **argv ) { pthread_mutex_destroy(&sync_mutex); pthread_cond_destroy(&nfapi_sync_cond); pthread_mutex_destroy(&nfapi_sync_mutex); - pthread_mutex_destroy(&ue_pf_po_mutex); // *** Handle per CC_id openair0 diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index de1c97a07b..a0ea170aa5 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -567,9 +567,6 @@ int main(int argc, char **argv) } init_openair0(); - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); set_latency_target(); if(IS_SOFTMODEM_DOSCOPE_QT) { diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h index 64e6095dcd..0752941dbc 100644 --- a/openair2/RRC/NR/nr_rrc_extern.h +++ b/openair2/RRC/NR/nr_rrc_extern.h @@ -51,8 +51,4 @@ extern uint16_t RACH_FREQ_ALLOC; extern MAC_MEAS_T BCCH_MEAS_TRIGGER,CCCH_MEAS_TRIGGER,DCCH_MEAS_TRIGGER,DTCH_MEAS_TRIGGER; extern MAC_AVG_T BCCH_MEAS_AVG,CCCH_MEAS_AVG,DCCH_MEAS_AVG, DTCH_MEAS_AVG; -extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - -extern pthread_mutex_t ue_pf_po_mutex; - #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 513e874073..0dc77fcf09 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2698,14 +2698,12 @@ rrc_gNB_generate_RRCRelease( int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx) { instance_t instance = 0; - uint8_t CC_id = 0; const unsigned int Ttab[4] = {32,64,128,256}; uint8_t Tc; uint8_t Tue; uint32_t pfoffset; uint32_t N; /* N: min(T,nB). total count of PF in one DRX cycle */ uint32_t Ns = 0; /* Ns: max(1,nB/T) */ - uint8_t i_s; /* i_s = floor(UE_ID/N) mod Ns */ uint32_t T; /* DRX cycle */ uint32_t length; uint8_t buffer[RRC_BUF_SIZE]; @@ -2767,44 +2765,9 @@ int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint return (-1); } - /* insert data to UE_PF_PO or update data in UE_PF_PO */ - pthread_mutex_lock(&ue_pf_po_mutex); - uint8_t i = 0; - - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(tmsi%1024)) - || (UE_PF_PO[CC_id][i].enable_flag != true)) { - /* set T = min(Tc,Tue) */ - UE_PF_PO[CC_id][i].T = T; - /* set UE_ID */ - UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)(tmsi%1024); - /* calculate PF and PO */ - /* set PF_min and PF_offset: (SFN + PF_offset) mod T = (T div N)*(UE_ID mod N) */ - UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); - UE_PF_PO[CC_id][i].PF_offset = pfoffset; - /* set i_s */ - /* i_s = floor(UE_ID/N) mod Ns */ - i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); - UE_PF_PO[CC_id][i].i_s = i_s; - - // TODO,set PO - - if (UE_PF_PO[CC_id][i].enable_flag == true) { - //paging exist UE log - LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Update exist UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, - T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset); - } else { - /* set enable_flag */ - UE_PF_PO[CC_id][i].enable_flag = true; - //paging new UE log - LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Insert a new UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, - T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset); - } - break; - } - } - - pthread_mutex_unlock(&ue_pf_po_mutex); + (void) N; /* not used, suppress warning */ + (void) Ns; /* not used, suppress warning */ + (void) pfoffset; /* not used, suppress warning */ /* Create message for PDCP (DLInformationTransfer_t) */ length = do_NR_Paging (instance, From 7ea883352901aae571248f68fc119cefe4122e4c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 28 Feb 2024 10:38:56 +0100 Subject: [PATCH 16/41] Use MAX_MOBILES_PER_GNB in 5G NR code NUMBER_OF_UE_MAX is a 4G constant, use 5G one instead --- openair1/PHY/TOOLS/nr_phy_scope.c | 14 +++++++------- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- openair2/RRC/NR/rrc_gNB.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 79ac95ef73..f9abcf211b 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -614,8 +614,8 @@ static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) { // PUSCH Throughput /* - float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; - float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; + float tput_time_enb[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}}; + float tput_enb[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}}; memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); @@ -725,7 +725,7 @@ static void *scope_thread_gNB(void *arg) { int fl_argc=1; char *name="5G-gNB-scope"; fl_initialize (&fl_argc, &name, NULL, 0, 0); - int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue); + int nb_ue=min(MAX_MOBILES_PER_GNB, scope_enb_num_ue); OAI_phy_scope_t *form_gnb = create_phy_scope_gnb(); while (!oai_exit) { @@ -985,9 +985,9 @@ static void uePdschIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_ } static void uePdschThroughput (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { /* - float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; - float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; - float tput_ue_max[NUMBER_OF_UE_MAX] = {0}; + float tput_time_ue[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}}; + float tput_ue[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}}; + float tput_ue_max[MAX_MOBILES_PER_GNB] = {0}; // PDSCH Throughput @@ -1178,7 +1178,7 @@ static void reset_stats_gNB(FL_OBJECT *button, int i,k; //PHY_VARS_gNB *phy_vars_gNB = RC.gNB[0][0]; - for (i=0; idlsch[i][0]->Mlimit; j++) { phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index f4f6e891b2..b252f1cdd4 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -136,7 +136,7 @@ nrUE_params_t *get_nrUE_params(void) { uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; -channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX]; +channel_desc_t *UE2gNB[MAX_MOBILES_PER_GNB][NUMBER_OF_gNB_MAX]; int NB_UE_INST = 1; configmodule_interface_t *uniqCfg = NULL; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 0dc77fcf09..f0df5996a3 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -317,7 +317,7 @@ static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc) void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) { AssertFatal(rrc != NULL, "RC.nrrrc not initialized!"); - AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); + AssertFatal(MAX_MOBILES_PER_GNB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); AssertFatal(configuration!=NULL,"configuration input is null\n"); rrc->module_id = 0; rrc_gNB_CU_DU_init(rrc); From 711518ba00c21d9d44263d62e5db7a8d3616ec83 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 28 Feb 2024 08:03:08 +0100 Subject: [PATCH 17/41] Move NUMBER_FRAMES_PHY_UE_INACTIVE to smaller scope --- common/openairinterface5g_limits.h | 2 -- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/openairinterface5g_limits.h b/common/openairinterface5g_limits.h index d9e49e26a7..d2f44a6195 100644 --- a/common/openairinterface5g_limits.h +++ b/common/openairinterface5g_limits.h @@ -12,8 +12,6 @@ # define NUMBER_OF_SRS_MAX 16 # define NUMBER_OF_SCH_STATS_MAX 16 -#define NUMBER_FRAMES_PHY_UE_INACTIVE 10 - #define MAX_MANAGED_ENB_PER_MOBILE 2 #define MAX_MANAGED_GNB_PER_MOBILE 2 diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index ec7f6cae69..76fbb5da7f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -33,6 +33,8 @@ #include "PHY/defs_gNB.h" #include "common/utils/threadPool/thread-pool.h" +#define NUMBER_FRAMES_PHY_UE_INACTIVE 10 + void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL); NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL); From 98c309ffe3a510d8c98d3b6c8bce9a4470efd2a7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 27 Feb 2024 18:52:07 +0100 Subject: [PATCH 18/41] Refactor nr_decode_pucch0() to not rely on uci_stats the uci_stats variable (pointing to per-UE statistics for UCI) is used in function nr_decode_pucch0() to store information which is important beyond statistics, e.g., uci_stats->pucch0_thres as a threshold (which comes from somewhere else) This commit refactors to use original or intermediate variables to not mix uci_stats usage with actual processing. Also, group uci_stats a bit more. --- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 35b5b1be3d..4ef42119bf 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -348,9 +348,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, #endif index=maxpos; - uci_stats->pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]]; - uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]; - LOG_D(PHY,"n00[%d] = %d, n01[%d] = %d\n",prb_offset[0],uci_stats->pucch0_n00,prb_offset[1],uci_stats->pucch0_n01); + int pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]]; + int pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]; + LOG_D(PHY, "n00[%d] = %d, n01[%d] = %d\n", prb_offset[0], pucch0_n00, prb_offset[1], pucch0_n01); + + uci_stats->pucch0_n00 = pucch0_n00; + uci_stats->pucch0_n01 = pucch0_n01; + uci_stats->pucch0_thres = gNB->pucch0_thres; + // estimate CQI for MAC (from antenna port 0 only) int max_n0 = max(gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]], gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]); @@ -363,7 +368,6 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, else cqi = (640 + SNRtimes10) / 5; - uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/ bool no_conf=false; if (nr_sequences>1) { if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) { @@ -372,7 +376,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, "%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n", frame, slot, - uci_stats->pucch0_thres, + gNB->pucch0_thres, SNRtimes10, xrtmag_dBtimes10, xrtmag_next_dBtimes10); @@ -388,7 +392,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->rssi = 1280 - (10 * dB_fixed(32767 * 32767)) - dB_fixed_times10(signal_energy_ant0); if (pucch_pdu->bit_len_harq==0) { - uci_pdu->sr.sr_confidence_level = SNRtimes10 < uci_stats->pucch0_thres; + uci_pdu->sr.sr_confidence_level = SNRtimes10 < gNB->pucch0_thres; uci_stats->pucch0_sr_trials++; if (xrtmag_dBtimes10>(10*max_n0+100)) { uci_pdu->sr.sr_indication = 1; @@ -415,9 +419,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, xrtmag_next_dBtimes10, pucch_power_dBtimes10, max_n0, - uci_stats->pucch0_n00, - uci_stats->pucch0_n01, - uci_stats->pucch0_thres, + pucch0_n00, + pucch0_n01, + gNB->pucch0_thres, cqi, SNRtimes10, 10 * log10((double)signal_energy_ant0)); @@ -450,9 +454,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, xrtmag_next_dBtimes10, pucch_power_dBtimes10, max_n0, - uci_stats->pucch0_n00, - uci_stats->pucch0_n01, - uci_stats->pucch0_thres, + pucch0_n00, + pucch0_n01, + gNB->pucch0_thres, cqi, SNRtimes10); if (pucch_pdu->sr_flag == 1) { From 8d87f0c4e2edb38c0bc0f5e447becf124c71ea20 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 27 Feb 2024 18:54:36 +0100 Subject: [PATCH 19/41] get_phy_stats(): full list is non-fatal Do not assert if the list of phy statistics is full; instead return NULL. In most places, this is handled appropriately (we do not store anything if we can't). In nr_decode_pucch0(), the return value of get_phy_stats() is used a little bit all over the function, and a constant if (uci_stats) uci_stats->variable++; would look ugly, so make uci_stats point to the stack if we cannot store in the phy_stats. --- openair1/PHY/INIT/nr_init.c | 5 ++++- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index c864a0366a..1f918086b2 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -79,8 +79,11 @@ NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti) else if (!stats->active && first_free == -1) first_free = i; } + + if (first_free < 0) + return NULL; + // new stats - AssertFatal(first_free >= 0, "PHY statistics list is full\n"); stats = &gNB->phy_stats[first_free]; stats->active = true; stats->rnti = rnti; diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 4ef42119bf..8a44e410f9 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -162,10 +162,15 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, pucch_pdu->bit_len_harq, pucch_pdu->sr_flag); + /* it might be that the stats list is full: In this case, we will simply + * write to some memory on the stack instead of the UE's UCI stats */ + NR_gNB_UCI_STATS_t stack_uci_stats = {0}; + NR_gNB_UCI_STATS_t *uci_stats = &stack_uci_stats; NR_gNB_PHY_STATS_t *phy_stats = get_phy_stats(gNB, pucch_pdu->rnti); - AssertFatal(phy_stats != NULL, "phy_stats shouldn't be NULL\n"); - phy_stats->frame = frame; - NR_gNB_UCI_STATS_t *uci_stats = &phy_stats->uci_stats; + if (phy_stats != NULL) { + phy_stats->frame = frame; + uci_stats = &phy_stats->uci_stats; + } int nr_sequences; const uint8_t *mcs; From 09a75009cecfc30b476f7968d2e6c8c133a49e07 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 27 Feb 2024 19:25:51 +0100 Subject: [PATCH 20/41] nr_fill_ulsch(): gracefully handle case of no ulsch found --- openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 7 +++++-- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 2 -- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 7e7562ff22..bc3046c578 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -34,7 +34,7 @@ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" -NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid) +static NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid) { int16_t first_free_index = -1; AssertFatal(gNB != NULL, "gNB is null\n"); @@ -62,7 +62,10 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t { int harq_pid = ulsch_pdu->pusch_data.harq_process_id; NR_gNB_ULSCH_t *ulsch = find_nr_ulsch(gNB, ulsch_pdu->rnti, harq_pid); - AssertFatal(ulsch, "No ulsch_id found for rnti %04x\n", ulsch_pdu->rnti); + if (ulsch == NULL) { + LOG_E(NR_PHY, "No ulsch_id found for rnti %04x\n", ulsch_pdu->rnti); + return; + } ulsch->rnti = ulsch_pdu->rnti; ulsch->harq_pid = harq_pid; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 76fbb5da7f..817fe90931 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -73,8 +73,6 @@ void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, uint32_t length, int16_t **llr_layers); -NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid); - void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB); void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); From c1895918270696b42de00611883b986cdd2cd01f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 29 Feb 2024 10:20:38 +0100 Subject: [PATCH 21/41] Add header guards inr nr_ulsch.h to avoid circular dependencies --- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 817fe90931..fa7d085ed0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -30,6 +30,9 @@ * \warning */ +#ifndef NR_ULSCH_H_ +#define NR_ULSCH_H_ + #include "PHY/defs_gNB.h" #include "common/utils/threadPool/thread-pool.h" @@ -78,3 +81,5 @@ void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB); void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch); + +#endif /* NR_ULSCH_H_ */ From e80d8a01f3b358cc1dd4e7bc7cdb9c4fb11e43ca Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 29 Feb 2024 15:36:31 +0100 Subject: [PATCH 22/41] delete dead code --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 70 ----------------------- 1 file changed, 70 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index cfbd8d9c12..4005c7d581 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -471,76 +471,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, else if (SNRtimes10 > 635) cqi=255; else cqi=(640+SNRtimes10)/5; - - if (0/*pusch_pdu->mcs_index == 9*/) { - __attribute__((unused)) - int off = ((pusch_pdu->rb_size&1) == 1)? 4:0; - - LOG_M("rxsigF0.m", - "rxsF0", - &gNB->common_vars - .rxdataF[0][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot], - gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot, - 1, - 1); - LOG_M("chestF0.m", - "chF0", - &gNB->pusch_vars[0].ul_ch_estimates[0][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size], - gNB->frame_parms.ofdm_symbol_size, - 1, - 1); - LOG_M("chestF0_ext.m", - "chF0_ext", - &gNB->pusch_vars[0] - .ul_ch_estimates_ext[0][(pusch_pdu->start_symbol_index + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (pusch_pdu->nr_of_symbols - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)), - 1, - 1); - LOG_M("rxsigF0_comp.m", - "rxsF0_comp", - &gNB->pusch_vars[0].rxdataF_comp[0][pusch_pdu->start_symbol_index * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - pusch_pdu->nr_of_symbols * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)), - 1, - 1); - LOG_M("rxsigF0_llr.m", - "rxsF0_llr", - &gNB->pusch_vars[0].llr[0], - (pusch_pdu->nr_of_symbols - 1) * NR_NB_SC_PER_RB * pusch_pdu->rb_size * pusch_pdu->qam_mod_order, - 1, - 0); - if (gNB->frame_parms.nb_antennas_rx > 1) { - LOG_M( - "rxsigF1.m", - "rxsF1", - &gNB->common_vars - .rxdataF[1][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot], - gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot, - 1, - 1); - LOG_M("chestF1.m", - "chF1", - &gNB->pusch_vars[0].ul_ch_estimates[1][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size], - gNB->frame_parms.ofdm_symbol_size, - 1, - 1); - LOG_M("chestF1_ext.m", - "chF1_ext", - &gNB->pusch_vars[0] - .ul_ch_estimates_ext[1][(pusch_pdu->start_symbol_index + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (pusch_pdu->nr_of_symbols - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)), - 1, - 1); - LOG_M("rxsigF1_comp.m", - "rxsF1_comp", - &gNB->pusch_vars[0].rxdataF_comp[1][pusch_pdu->start_symbol_index * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - pusch_pdu->nr_of_symbols * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)), - 1, - 1); - } - exit(-1); - - } - // crc indication uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs; gNB->UL_INFO.crc_ind.crc_list = &gNB->crc_pdu_list[0]; From 012894592202f43c25b41fec3de2f006eed7139b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 29 Feb 2024 16:51:31 +0100 Subject: [PATCH 23/41] nr_fill_indication(): protect with mutex nr_fill_indication() fills CRC and RX requests, to be sent from L1 to L2. Before this commit, nr_fill_indication() is called when - we finally decoded LDPC (or not) - low signal on PUSCH This might happen at the same time, i.e., nr_fill_indication() might try to fill both CRC and RX, in the same list, from different threads. This can lead to this assertion: Assertion (crc->rnti == rx->rnti) failed! In handle_nr_ulsch() ../../../openair2/NR_PHY_INTERFACE/NR_IF_Module.c:190 mis-match between CRC RNTI e071 and RX RNTI 5e3b e.g., e071 is low energy, and while 5e3b related message are filled in one thread, e071 is being put into the message structure as well. At least that is my understanding. I could not actually reproduce this assertion; to be seen if it still happens. --- openair1/PHY/INIT/nr_init.c | 4 ++++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 12 +++++++++++- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 9 +++++++-- openair2/NR_PHY_INTERFACE/NR_IF_Module.h | 8 +++++--- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 1f918086b2..864420f56e 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -135,6 +135,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) load_LDPClib(NULL, &ldpc_interface); + pthread_mutex_init(&gNB->UL_INFO.crc_rx_mutex, NULL); + if (gNB->ldpc_offload_flag) load_LDPClib("_t2", &ldpc_interface_offload); gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; @@ -331,6 +333,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB() const int n_buf = Prx * max_ul_mimo_layers; + pthread_mutex_destroy(&gNB->UL_INFO.crc_rx_mutex); + PHY_MEASUREMENTS_gNB *meas = &gNB->measurements; free_and_zero(meas->n0_subband_power); free_and_zero(meas->n0_subband_power_dB); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 4005c7d581..4289c98a57 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -471,6 +471,14 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, else if (SNRtimes10 > 635) cqi=255; else cqi=(640+SNRtimes10)/5; + // multiple threads might call this function at the same time, or while the + // L2 reads the messages. Hence, if not protected, crc and rx indications + // might not appear pairwise (in the same order) in the same slot, or even in + // separate slots. The L2 does not support this; hence, use the crc_rx_mutex + // to ensure that messages are pairwise. + int rc = pthread_mutex_lock(&gNB->UL_INFO.crc_rx_mutex); + DevAssert(rc == 0); + // crc indication uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs; gNB->UL_INFO.crc_ind.crc_list = &gNB->crc_pdu_list[0]; @@ -507,8 +515,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, gNB->rx_pdu_list[num_rx].pdu_length = harq_process->TBS; gNB->rx_pdu_list[num_rx].pdu = harq_process->b; } - gNB->UL_INFO.rx_ind.number_of_pdus++; + + rc = pthread_mutex_unlock(&gNB->UL_INFO.crc_rx_mutex); + DevAssert(rc == 0); } // Function to fill UL RB mask to be used for N0 measurements diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 37bedddf46..8494a56492 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -177,6 +177,9 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) } if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) { + // see nr_fill_indication about why this mutex is necessary + int rc = pthread_mutex_lock(&UL_info->crc_rx_mutex); + DevAssert(rc == 0); AssertFatal(UL_info->rx_ind.number_of_pdus == UL_info->crc_ind.number_crcs, "number_of_pdus %d, number_crcs %d\n", UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs); @@ -210,9 +213,11 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) rx->rssi); handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc); } + UL_info->rx_ind.number_of_pdus = 0; + UL_info->crc_ind.number_crcs = 0; + rc = pthread_mutex_unlock(&UL_info->crc_rx_mutex); + DevAssert(rc == 0); } - UL_info->rx_ind.number_of_pdus = 0; - UL_info->crc_ind.number_crcs = 0; } void handle_nr_srs(NR_UL_IND_t *UL_info) { diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 108e0afe7a..ba230e4f63 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -64,6 +64,11 @@ typedef struct { /// crc indication list nfapi_nr_crc_indication_t crc_ind; + /// RX indication + nfapi_nr_rx_data_indication_t rx_ind; + /// mutex to protect concurrent access to crc_ind and rx_ind, which the L2 + /// needs to be pairwise + pthread_mutex_t crc_rx_mutex; /// RACH indication list nfapi_nr_rach_indication_t rach_ind; @@ -71,9 +76,6 @@ typedef struct { /// SRS indication list nfapi_nr_srs_indication_t srs_ind; - /// RX indication - nfapi_nr_rx_data_indication_t rx_ind; - /// UCI indication nfapi_nr_uci_indication_t uci_ind; From 4245dd9be9ffe0d5f058385dfcc9c20f9b4c92ea Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 7 Mar 2024 09:43:22 +0100 Subject: [PATCH 24/41] Remove useless declarations --- openair1/PHY/phy_vars.h | 2 -- openair2/RRC/NR/nr_rrc_extern.h | 16 ---------------- 2 files changed, 18 deletions(-) diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h index 89063c5be2..85d2d2a59f 100644 --- a/openair1/PHY/phy_vars.h +++ b/openair1/PHY/phy_vars.h @@ -30,8 +30,6 @@ PHY_VARS_UE ***PHY_vars_UE_g; UL_RCC_IND_t UL_RCC_INFO; -NR_UL_IND_t UL_INFO; - unsigned char NB_RU=0; int number_of_cards; uint8_t max_turbo_iterations=4; diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h index 0752941dbc..66483214a7 100644 --- a/openair2/RRC/NR/nr_rrc_extern.h +++ b/openair2/RRC/NR/nr_rrc_extern.h @@ -34,21 +34,5 @@ #include "COMMON/mac_rrc_primitives.h" #include "LAYER2/RLC/rlc.h" #include "openair2/RRC/common.h" - void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration); - -extern UE_RRC_INST *UE_rrc_inst; - -extern uint8_t DRB2LCHAN[8]; - -extern int NB_UE_INST; -extern void* bigphys_malloc(int); - - -//uint8_t RACH_TIME_ALLOC; -extern uint16_t RACH_FREQ_ALLOC; -// uint8_t NB_RACH; -extern MAC_MEAS_T BCCH_MEAS_TRIGGER,CCCH_MEAS_TRIGGER,DCCH_MEAS_TRIGGER,DTCH_MEAS_TRIGGER; -extern MAC_AVG_T BCCH_MEAS_AVG,CCCH_MEAS_AVG,DCCH_MEAS_AVG, DTCH_MEAS_AVG; - #endif From 6259b62a18ad96b5a720948218b186056984129f Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Thu, 18 Jan 2024 16:42:51 +0100 Subject: [PATCH 25/41] CI AW2S Multi-UE: attach/detach 15 UEs, ping from 15 UEs --- ci-scripts/ci_ueinfra.yaml | 36 ++++++++++++++++ .../xml_files/container_sa_aw2s_asue.xml | 43 +++++++++++++++++-- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index deef3718ec..0618aeadea 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -119,6 +119,42 @@ amarisoft_ue_10: NetworkScript: ip netns exec ue10 ip a show dev pdn0 CmdPrefix: ip netns exec ue10 MTU: 1500 +amarisoft_ue_11: + Host: amariue + AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":11}' + DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":11}' + NetworkScript: ip netns exec ue11 ip a show dev pdn0 + CmdPrefix: ip netns exec ue11 + MTU: 1500 +amarisoft_ue_12: + Host: amariue + AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":12}' + DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":12}' + NetworkScript: ip netns exec ue12 ip a show dev pdn0 + CmdPrefix: ip netns exec ue12 + MTU: 1500 +amarisoft_ue_13: + Host: amariue + AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":13}' + DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":13}' + NetworkScript: ip netns exec ue13 ip a show dev pdn0 + CmdPrefix: ip netns exec ue13 + MTU: 1500 +amarisoft_ue_14: + Host: amariue + AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":14}' + DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":14}' + NetworkScript: ip netns exec ue14 ip a show dev pdn0 + CmdPrefix: ip netns exec ue14 + MTU: 1500 +amarisoft_ue_15: + Host: amariue + AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":15}' + DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":15}' + NetworkScript: ip netns exec ue15 ip a show dev pdn0 + CmdPrefix: ip netns exec ue15 + MTU: 1500 + oai_ue_caracal: Host: caracal diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index 4d81b123e6..0dd7ddd15f 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -40,6 +40,11 @@ 002008 002009 002010 + 002011 + 002012 + 002013 + 002014 + 002015 000100 000010 000020 @@ -132,12 +137,42 @@ amarisoft_ue_10 + + Attach_UE + Attach UE + amarisoft_ue_11 + + + + Attach_UE + Attach UE + amarisoft_ue_12 + + + + Attach_UE + Attach UE + amarisoft_ue_13 + + + + Attach_UE + Attach UE + amarisoft_ue_14 + + + + Attach_UE + Attach UE + amarisoft_ue_15 + + Iperf iperf (DL/7Mbps/UDP)(30 sec)(multi-ue profile) -u -b 70M -t 30 -i 1 -R IPERF3 - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 25 80 balanced @@ -148,7 +183,7 @@ iperf (UL/3.6Mbps/UDP)(30 sec)(multi-ue profile) -u -b 36M -t 30 -i 1 IPERF3 - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 25 80 balanced @@ -157,7 +192,7 @@ Ping Ping: 20pings in 20sec, multi-ue - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 -c 20 %cn_ip% 1 25 @@ -175,7 +210,7 @@ Detach_UE Detach UE - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 From 066aa3379981bf29cffedfe1ff0781f92bd899e1 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Fri, 1 Mar 2024 14:38:37 +0100 Subject: [PATCH 26/41] Add 16th UE to AW2S pipeline - connection and ping test --- ci-scripts/ci_ueinfra.yaml | 8 +++++++- ci-scripts/xml_files/container_sa_aw2s_asue.xml | 15 +++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index 0618aeadea..2636c7413a 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -154,7 +154,13 @@ amarisoft_ue_15: NetworkScript: ip netns exec ue15 ip a show dev pdn0 CmdPrefix: ip netns exec ue15 MTU: 1500 - +amarisoft_ue_16: + Host: amariue + AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":16}' + DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":16}' + NetworkScript: ip netns exec ue16 ip a show dev pdn0 + CmdPrefix: ip netns exec ue16 + MTU: 1500 oai_ue_caracal: Host: caracal diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index 0dd7ddd15f..10170885f0 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -48,6 +48,7 @@ 000100 000010 000020 + 002016 000200 003000 004000 @@ -198,11 +199,17 @@ 25 + + Attach_UE + Attach UE + amarisoft_ue_16 + + Ping - Ping: 100pings in 20sec, multi-ue - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 - -c 100 -i 0.2 %cn_ip% + Ping: 50pings in 10sec, multi-ue + amarisoft_ue_16 + -c 50 -i 0.2 %cn_ip% 1 30 @@ -210,7 +217,7 @@ Detach_UE Detach UE - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 amarisoft_ue_16 From fc8d0c59c658afb5190e1cdd636aee22a748beb6 Mon Sep 17 00:00:00 2001 From: mir Date: Mon, 6 Nov 2023 18:01:34 +0100 Subject: [PATCH 27/41] Scan build: Result of operation is garbage or undefined --- common/utils/nr/nr_common.h | 4 --- common/utils/utils.h | 18 ++++++++++--- .../PHY/CODING/nrLDPC_encoder/ldpc_encoder.c | 1 + .../CODING/nrPolar_tools/nr_polar_decoder.c | 1 + .../nrPolar_tools/nr_polar_procedures.c | 6 +++-- openair1/PHY/CODING/viterbi.c | 1 + openair1/PHY/LTE_TRANSPORT/prach.c | 2 ++ openair1/PHY/LTE_TRANSPORT/pucch.c | 6 ++--- openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c | 2 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 25 +++++++++++++------ .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 3 ++- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 2 ++ .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 5 ++-- .../nr_dl_channel_estimation.c | 2 ++ openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c | 2 ++ openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 1 + .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 3 +-- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 7 ++++++ openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 3 +++ openair1/PHY/defs_nr_UE.h | 6 ++--- openair1/SIMULATION/RF/dac.c | 7 +++--- openair2/ENB_APP/enb_app.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 2 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 3 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c | 1 + openair2/MCE_APP/mce_app.c | 2 +- openair3/NAS/UE/EMM/IdleMode.c | 2 +- 27 files changed, 81 insertions(+), 38 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 3082691f1b..79e587221b 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -214,10 +214,6 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) -#define cmax(a,b) ((a>b) ? (a) : (b)) -#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) -#define cmin(a,b) ((ab) ? (a) : (b)) -#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) -#define cmin(a,b) ((a _b ? _a : _b; }) + + +#define cmax3(a,b,c) ( cmax(cmax(a,b), cmax(b,c)) ) + +// Prevent double evaluation in min macro +#define cmin(a,b) ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) + + + #ifdef __cplusplus #ifdef min diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c index f6d065a75b..ebcb6bf4f5 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c @@ -171,6 +171,7 @@ int LDPCencoder(unsigned char **inputArray, unsigned char **outputArray, encoder { fprintf(fd,"\n//row: %d\n",i1); fprintf(fd2,"\n//row: %d\n",i1); + AssertFatal(shift > 0 , "The result of the right shift is undefined because the right operand is negative\n"); fprintf(fd," d2[%d]=",(Zc*i1)>>shift); fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1)); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 06c852a7dd..4eac4279a4 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -116,6 +116,7 @@ int8_t polar_decoder(double *input, } //The index of the last 1-valued bit that appears in each column. + AssertFatal(polarParams->crcParityBits > 0, "UB for VLA"); uint16_t last1ind[polarParams->crcParityBits]; for (int j=0; jcrcParityBits; j++) { diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index 31eff03185..bf0a0ffee5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -239,7 +239,7 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, { int Q_Ftmp_N[N + 1]; // Last element shows the final int Q_Itmp_N[N + 1]; // array index assigned a value. - + for (int i = 0; i <= N; i++) { Q_Ftmp_N[i] = -1; // Empty array. Q_Itmp_N[i] = -1; @@ -282,11 +282,13 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, // Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N for (int n = 0; n <= N - 1; n++) { bool flag = true; - for (int m = 0; m <= Q_Ftmp_N[N]; m++) + for (int m = 0; m <= Q_Ftmp_N[N]; m++){ + AssertFatal(m < N+1, "Buffer boundary overflow"); if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) { flag = false; break; } + } if (flag) { Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n]; Q_Itmp_N[N]++; diff --git a/openair1/PHY/CODING/viterbi.c b/openair1/PHY/CODING/viterbi.c index cf04de3f32..20242c8914 100644 --- a/openair1/PHY/CODING/viterbi.c +++ b/openair1/PHY/CODING/viterbi.c @@ -292,6 +292,7 @@ void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short // Traceback if (traceback == 1) { prev_state0 = 0; + AssertFatal((offset+n-1) > 0, "Left shift is undefined if the left operand is negative\n"); TB_ptr2 = (unsigned char *)&TB[(offset+n-1)<<2]; for (position = offset+n-1 ; position>-1; position--) { diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index ed4ca98049..2d3f964ef5 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -171,6 +171,8 @@ void rx_prach0(PHY_VARS_eNB *eNB, AssertFatal(ru!=NULL,"ru is null\n"); int8_t dBEn0=0; int16_t *prach[nb_rx]; + memset(prach, 0, nb_rx * sizeof(int16_t)); + for (int aa=0; aaif_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node // DJP - indexing below in subframe zero takes us off the beginning of the array??? diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 2173fffa7d..c8adb38f7c 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -756,9 +756,9 @@ uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB, LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; uint32_t u,v,n,aa; - uint32_t z[12*14]; - int16_t *zptr; - int16_t rxcomp[NB_ANTENNAS_RX][2*12*14]; + uint32_t z[12*14] = {0}; + int16_t *zptr = NULL; + int16_t rxcomp[NB_ANTENNAS_RX][2*12*14] = {0}; uint8_t ns,N_UL_symb,nsymb,n_cs_base; uint16_t i,j,re_offset; uint8_t m,l; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index de1af613ef..d8d3008be7 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -5188,7 +5188,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe) sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg, 3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]); - sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64); + sinr_eff = cmax3(sinr_eff_qpsk, sinr_eff_qam16,sinr_eff_qam64); //printf("SINR_Eff = %e\n",sinr_eff); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 36e737f0e6..06ee3ed2ba 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -634,10 +634,21 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size*(1<num_symbols)]; uint32_t noise_power_per_rb[srs_pdu->bwp_size]; - int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; - int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; - int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; - int16_t noise_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; + + const uint32_t arr_len = frame_parms->nb_antennas_rx * N_ap * M_sc_b_SRS; + + int16_t ch_real[arr_len]; + memset(ch_real, 0, arr_len * sizeof(int16_t)); + + int16_t ch_imag[arr_len]; + memset(ch_imag, 0, arr_len * sizeof(int16_t)); + + int16_t noise_real[arr_len]; + memset(noise_real, 0, arr_len * sizeof(int16_t)); + + int16_t noise_imag[arr_len]; + memset(noise_imag, 0, arr_len * sizeof(int16_t)); + int16_t ls_estimated[2]; uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) >> 2; // >> 2 <=> /sizeof(int32_t) @@ -836,8 +847,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) // Compute signal power - uint32_t signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) - + calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); + uint32_t signal_power = calc_power(ch_real, arr_len) + calc_power(ch_imag, arr_len); #ifdef SRS_DEBUG LOG_I(NR_PHY,"signal_power = %u\n", signal_power); @@ -890,8 +900,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, } // for (int rb = 0; rb < m_SRS_b; rb++) - uint32_t noise_power = max(calc_power(noise_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) - + calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS), 1); + const uint32_t noise_power = max(calc_power(noise_real, arr_len) + calc_power(noise_imag, arr_len), 1); *snr = dB_fixed((int32_t)((signal_power<> 2); + AssertFatal(((int *)&determ_fin_128[0])[k] > 0 ,"Right shifting negative values is UB" ); + sum_det += ((((uint32_t *)&determ_fin_128[0])[k]) >> 2); } int b = log2_approx(sum_det) - 8; diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 35b5b1be3d..62b564808a 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -225,6 +225,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, x_im[1] = table_5_2_2_2_2_Im[u[1]]; c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32))); + memset(xr, 0, frame_parms->nb_antennas_rx * pucch_pdu->nr_of_symbols * 12); + int64_t xrtmag=0,xrtmag_next=0; uint8_t maxpos=0; uint8_t index=0; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index e9d159ff4b..7c145e92b4 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -74,9 +74,10 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, } // filter position to reduce jitter - if (clear == 1) + if (clear == 1){ + AssertFatal(max_pos > -1, "The result of the left shift is undefined if the left operand is negative"); ue->max_pos_fil = max_pos << 15; - else + } else ue->max_pos_fil = ((ue->max_pos_fil * coef) >> 15) + (max_pos * ncoef); // do not filter to have proactive timing adjustment 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 88dd247780..e09f89e54d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -129,6 +129,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, printf("[gNB %d][rsc %d] PRS config l %d k_prime %d:\nprs_cfg->SymbolStart %d\nprs_cfg->NumPRSSymbols %d\nprs_cfg->NumRB %d\nprs_cfg->CombSize %d\n", gNB_id, rsc_id, l, k_prime, prs_cfg->SymbolStart, prs_cfg->NumPRSSymbols, prs_cfg->NumRB, prs_cfg->CombSize); #endif // Pilots generation and modulation + + AssertFatal(num_pilots > 0, "num_pilots needs to be gt 0 or mod_prs[0] UB"); for (int m = 0; m < num_pilots; m++) { idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3); diff --git a/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c b/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c index 3317c036d8..69ec76b5eb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c @@ -510,6 +510,8 @@ void cic_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, in void fir_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, int rate_change, int scaling_factor) { + AssertFatal(length > 0, "Precondition not met"); + int32_t *buffer_one; int32_t *buffer_two; int32_t *input; diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 7e80721524..f68b594246 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -409,6 +409,7 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue, } /// Power noise estimation + AssertFatal(csirs_config_pdu->nr_of_rbs > 0, " nr_of_rbs needs to be greater than 0\n"); uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs]; uint16_t noise_imag[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs]; for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 1bea7b0a6d..8fb8f61ec9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -275,7 +275,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, const int frame = proc->frame_rx; const int nr_slot_rx = proc->nr_slot_rx; const int gNB_id = proc->gNB_id; - uint8_t slot = 0; int32_t codeword_TB0 = -1; @@ -699,7 +698,7 @@ void nr_dlsch_deinterleaving(uint8_t symbol, N_bundle = nb_rb_pdsch/L; C=N_bundle/R; - uint32_t *bundle_deint = malloc(N_bundle*sizeof(uint32_t)); + uint32_t *bundle_deint = calloc(N_bundle, sizeof(uint32_t)); printf("N_bundle %u L %d nb_rb_pdsch %d\n",N_bundle, L,nb_rb_pdsch); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 19f7e89a7f..768099ebe5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -895,6 +895,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, * n_id = N_ID_cell if higher layer parameter not configured */ uint8_t btilde[M_bit]; + memset(btilde, 0, sizeof(btilde)); + // rnti is given by the C-RNTI uint16_t rnti=pucch_pdu->rnti, n_id=0; #ifdef DEBUG_NR_PUCCH_TX @@ -912,6 +914,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, */ // complex-valued symbol d(0) c16_t d[M_bit]; + memset(d, 0, sizeof(d)); + uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; const int16_t baseVal = (amp * ONE_OVER_SQRT2) >> 15; @@ -962,6 +966,7 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, // uint8_t nrofSymbols; // complex-valued symbol d(0) c16_t y_n[4 * M_bit]; // 4 is the maximum number n_SF_PUCCH_s, so is the maximunm size of y_n + memset(y_n, 0, sizeof(y_n)); // Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1) // k={0,..11} n={0,1,2,3} // parameter PUCCH-F4-preDFT-OCC-index set of {0,1,2,3} -> n @@ -1051,6 +1056,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, * Implementing Transform pre-coding subclause 6.3.2.6.4 */ c16_t z[4 * M_bit]; // 4 is the maximum number n_SF_PUCCH_s + memset(z, 0 , sizeof(z)); + #define M_PI 3.14159265358979323846 // pi const int64_t base = round(32767 / sqrt(12 * nrofPRB)); for (int l=0; lframe_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n"); for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { int pss_symbol = 0; @@ -370,7 +371,9 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, { uint8_t i; c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR]; + memset(pss_ext, 0, NB_ANTENNAS_RX * LENGTH_SSS_NR * sizeof(c16_t)); c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]; + memset(sss_ext, 0, NB_ANTENNAS_RX * LENGTH_SSS_NR * sizeof(c16_t)); uint8_t Nid2 = GET_NID2(ue->common_vars.nid2); uint16_t Nid1; uint8_t phase; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index bb77dac067..aae2338540 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -86,9 +86,9 @@ #define openair_sched_exit() exit(-1) #define bzero(s,n) (memset((s),0,(n))) -#define cmax(a,b) ((a>b) ? (a) : (b)) -#define cmin(a,b) ((ac) ? (cmax(a,b)) : (c)) +//#define cmax(a,b) ((a>b) ? (a) : (b)) +//#define cmin(a,b) ((ac) ? (cmax(a,b)) : (c)) /// suppress compiler warning for unused arguments #define UNUSED(x) (void)x; diff --git a/openair1/SIMULATION/RF/dac.c b/openair1/SIMULATION/RF/dac.c index 5721e5ec48..d5cb985c4f 100644 --- a/openair1/SIMULATION/RF/dac.c +++ b/openair1/SIMULATION/RF/dac.c @@ -94,12 +94,10 @@ double dac_fixed_gain(double *s_re[2], int i; int aa; - double amp1_local,*amp1p; + double amp1_local = 0.0; + double *amp1p = (amp1 == NULL) ? &1_local : amp1; double amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); //this is amp per tx antenna - if (amp1==NULL) amp1p = &1_local; - else amp1p = amp1; - if (do_amp_compute==1) { *amp1p = 0; for (aa=0; aaeNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; UE_info->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; - num_sdus++; #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", @@ -1660,6 +1659,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, LOG_T(MAC, "\n"); #endif + num_sdus++; } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index ce96d5ab87..c21aac0b63 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -4539,7 +4539,8 @@ extract_pucch_csi(module_id_t mod_idP, AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, "cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_NOTHING!\n"); AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); - uint16_t Npd, N_OFFSET_CQI; + uint16_t Npd = 0; + uint16_t N_OFFSET_CQI = 0; int H, K, bandwidth_part, L, Lmask; int ri = sched_ctl->periodic_ri_received[CC_idP]; get_csi_params(cc, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 521616f82d..2e5fb0c7a1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -186,6 +186,7 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr if ((row == 2 && col == 2) || (row == 4 && col == 2)) { int array_lim = num_prgs >> 2; + AssertFatal(array_lim > 0 , "Needed to avoid UB\n"); int antenna_rank[array_lim]; int count = 0; diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c index c832df5585..53194d4899 100644 --- a/openair2/MCE_APP/mce_app.c +++ b/openair2/MCE_APP/mce_app.c @@ -315,7 +315,7 @@ void *MCE_app_task(void *args_p) { uint32_t register_mce_pending=0; uint32_t registered_mce=0; //long mce_register_retry_timer_id; - long mce_scheduling_info_timer_id; + long mce_scheduling_info_timer_id = 0; //uint32_t m3_register_mce_pending = 0; // uint32_t x2_registered_mce = 0; // long x2_mce_register_retry_timer_id; diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index 33e291931f..66a82c8011 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -679,7 +679,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, { LOG_FUNC_IN; - emm_sap_t emm_sap; + emm_sap_t emm_sap = {0}; int rc = RETURNerror; emm_data_t *emm_data = user->emm_data; emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; From 275c3c6aa812411b962cbd1eddabedc31d5de428 Mon Sep 17 00:00:00 2001 From: mir Date: Tue, 14 Nov 2023 13:45:22 +0100 Subject: [PATCH 28/41] Bugfix cmax and memory init --- common/utils/utils.h | 2 +- openair1/PHY/LTE_TRANSPORT/prach.c | 2 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/utils.h b/common/utils/utils.h index a5976fd904..6687249077 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -25,7 +25,7 @@ extern "C" { _a > _b ? _a : _b; }) -#define cmax3(a,b,c) ( cmax(cmax(a,b), cmax(b,c)) ) +#define cmax3(a,b,c) ( cmax(cmax(a,b), c) ) // Prevent double evaluation in min macro #define cmin(a,b) ({ __typeof__ (a) _a = (a); \ diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 2d3f964ef5..ec5fa88d94 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -171,7 +171,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, AssertFatal(ru!=NULL,"ru is null\n"); int8_t dBEn0=0; int16_t *prach[nb_rx]; - memset(prach, 0, nb_rx * sizeof(int16_t)); + memset(prach, 0, nb_rx * sizeof(int16_t*)); for (int aa=0; aaif_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 62b564808a..e930a46a08 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -225,7 +225,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, x_im[1] = table_5_2_2_2_2_Im[u[1]]; c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32))); - memset(xr, 0, frame_parms->nb_antennas_rx * pucch_pdu->nr_of_symbols * 12); + memset(xr, 0, frame_parms->nb_antennas_rx * pucch_pdu->nr_of_symbols * 12 * sizeof(c64_t)); int64_t xrtmag=0,xrtmag_next=0; uint8_t maxpos=0; From 573e7d3a4ae9207543b0fcb1e2422c1410219e7e Mon Sep 17 00:00:00 2001 From: mir Date: Tue, 27 Feb 2024 16:08:31 +0100 Subject: [PATCH 29/41] Comments from MR --- openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 4 ++-- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 6 ++---- openair1/PHY/defs_nr_UE.h | 3 --- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 4eac4279a4..61525c6905 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -116,7 +116,7 @@ int8_t polar_decoder(double *input, } //The index of the last 1-valued bit that appears in each column. - AssertFatal(polarParams->crcParityBits > 0, "UB for VLA"); + AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n"); uint16_t last1ind[polarParams->crcParityBits]; for (int j=0; jcrcParityBits; j++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 8fb8f61ec9..f730bdebe3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -698,7 +698,8 @@ void nr_dlsch_deinterleaving(uint8_t symbol, N_bundle = nb_rb_pdsch/L; C=N_bundle/R; - uint32_t *bundle_deint = calloc(N_bundle, sizeof(uint32_t)); + uint32_t bundle_deint[N_bundle]; + memset(bundle_deint, 0 , sizeof(bundle_deint)); printf("N_bundle %u L %d nb_rb_pdsch %d\n",N_bundle, L,nb_rb_pdsch); @@ -726,7 +727,6 @@ void nr_dlsch_deinterleaving(uint8_t symbol, //printf("k %d m %d bundle_deint %d llr_deint %d\n", k, m, bundle_deint[k], llr_deint[bundle_deint[k]*nb_re*L+m]); } } - free(bundle_deint); } //============================================================================================== diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index c190eef15b..ac2ae3ac5e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -370,10 +370,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { uint8_t i; - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR]; - memset(pss_ext, 0, NB_ANTENNAS_RX * LENGTH_SSS_NR * sizeof(c16_t)); - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]; - memset(sss_ext, 0, NB_ANTENNAS_RX * LENGTH_SSS_NR * sizeof(c16_t)); + c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0}; + c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0}; uint8_t Nid2 = GET_NID2(ue->common_vars.nid2); uint16_t Nid1; uint8_t phase; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index aae2338540..969cac85f5 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -86,9 +86,6 @@ #define openair_sched_exit() exit(-1) #define bzero(s,n) (memset((s),0,(n))) -//#define cmax(a,b) ((a>b) ? (a) : (b)) -//#define cmin(a,b) ((ac) ? (cmax(a,b)) : (c)) /// suppress compiler warning for unused arguments #define UNUSED(x) (void)x; From fabf7e595f7f29a5a537f7d5dd960108d9f57332 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 7 Mar 2024 12:46:34 +0100 Subject: [PATCH 30/41] preventing crash caused by negative absolute slot RX value --- executables/nr-gnb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 2a12126d7d..86d0b42996 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -117,7 +117,10 @@ static void tx_func(void *param) int slot_rx = info->slot_rx; int absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms); int absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead; - + if (absslot_rx < 0) { + LOG_W(NR_PHY, "Slot ahead %d is larger than absslot_tx %d. Cannot start TX yet.\n", info->gNB->RU_list[0]->sl_ahead, absslot_tx); + return; + } LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx); PHY_VARS_gNB *gNB = info->gNB; module_id_t module_id = gNB->Mod_id; From c5e4bea6b957225da96cdb9f762d3418febffb3c Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 7 Mar 2024 15:28:22 +0100 Subject: [PATCH 31/41] make explicit return of the clock drift to shift the corresponding number of samples remove corresponding global variables --- executables/nr-ue.c | 172 ++++---- .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 72 +--- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 19 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 390 +++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 12 +- openair1/PHY/defs_nr_UE.h | 9 +- openair1/SCHED_NR_UE/defs.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 16 +- openair1/SIMULATION/NR_PHY/dlsim.c | 1 - openair1/SIMULATION/NR_PHY/pbchsim.c | 23 +- 10 files changed, 331 insertions(+), 385 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 98c0443422..12d487637b 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -439,11 +439,13 @@ static void UE_synch(void *arg) { uint64_t dl_carrier, ul_carrier; nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier); - - if (nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa) == 0) { + nr_initial_sync_t ret = nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa); + if (!ret.cell_notdetected) { + syncD->rx_offset = ret.rx_offset; freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync - hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + - round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); + hw_slot_offset = + ((ret.rx_offset << 1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + + round((float)((ret.rx_offset << 1) % UE->frame_parms.samples_per_subframe) / UE->frame_parms.samples_per_slot0); // rerun with new cell parameters and frequency-offset // todo: the freq_offset computed on DL shall be scaled before being applied to UL @@ -462,7 +464,6 @@ static void UE_synch(void *arg) { else UE->is_synchronized = 1; } else { - if (UE->UE_scan_carrier == 1) { if (freq_offset >= 0) @@ -607,8 +608,9 @@ void processSlotTX(void *arg) RU_write(rxtxD); } -static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data) +static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data) { + int sampleShift = 0; if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) { // Start synchronization with a target gNB @@ -636,20 +638,16 @@ static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *pro UE->if_inst->dl_indication(&dl_indication); } - uint64_t a=rdtsc_oai(); - pbch_pdcch_processing(UE, proc, phy_data); + sampleShift = pbch_pdcch_processing(UE, proc, phy_data); if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) { // indicate to tx thread to wait for DLSCH decoding const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame; - LOG_D(NR_PHY, "Adding one event to wait after decoding slot %d, for futre tx slot %d\n", proc->nr_slot_rx, ack_nack_slot); tx_wait_for_dlsch[ack_nack_slot]++; } - - LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500); } ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx); - return; + return sampleShift; } void UE_dl_processing(void *arg) { @@ -710,37 +708,39 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) } -void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { - - LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); - - if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { - // Resynchonize by slot (will work with numerology 1 only) - for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) { - int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ; - AssertFatal(unitTransfer == - UE->rfdevice.trx_read_func(&UE->rfdevice, - timestamp, - (void **)UE->common_vars.rxdata, - unitTransfer, - UE->frame_parms.nb_antennas_rx),""); - } - } else { - *timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms); - for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) { - int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ; - // we write before read because gNB waits for UE to write and both executions halt - // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot - if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer); - AssertFatal(unitTransfer == - UE->rfdevice.trx_read_func(&UE->rfdevice, - timestamp, - (void **)UE->common_vars.rxdata, - unitTransfer, - UE->frame_parms.nb_antennas_rx),""); - *timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write - } +static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int rx_offset) +{ + LOG_I(PHY, "Resynchronizing RX by %d samples\n", rx_offset); + if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { + // Resynchonize by slot (will work with numerology 1 only) + for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe / 2) { + int unitTransfer = size > UE->frame_parms.samples_per_subframe / 2 ? UE->frame_parms.samples_per_subframe / 2 : size; + AssertFatal(unitTransfer + == UE->rfdevice.trx_read_func(&UE->rfdevice, + timestamp, + (void **)UE->common_vars.rxdata, + unitTransfer, + UE->frame_parms.nb_antennas_rx), + ""); } + } else { + *timestamp += UE->frame_parms.get_samples_per_slot(1, &UE->frame_parms); + for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe) { + int unitTransfer = size > UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size; + // we write before read because gNB waits for UE to write and both executions halt + // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot + if (IS_SOFTMODEM_RFSIM) + dummyWrite(UE, *timestamp, unitTransfer); + AssertFatal(unitTransfer + == UE->rfdevice.trx_read_func(&UE->rfdevice, + timestamp, + (void **)UE->common_vars.rxdata, + unitTransfer, + UE->frame_parms.nb_antennas_rx), + ""); + *timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write + } + } } static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) { @@ -764,8 +764,6 @@ void *UE_thread(void *arg) //this thread should be over the processing thread to keep in real time PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0; - openair0_timestamp timestamp = 0; - openair0_timestamp writeTimestamp = 0; void *rxp[NB_ANTENNAS_RX]; int start_rx_stream = 0; fapi_nr_config_request_t *cfg = &UE->nrUE_config; @@ -796,9 +794,10 @@ void *UE_thread(void *arg) for(int i=0; i < num_ind_fifo; i++) { initNotifiedFIFO(UE->tx_resume_ind_fifo + i); } - + int shiftForNextFrame = 0; + int intialSyncOffset = 0; + openair0_timestamp sync_timestamp; while (!oai_exit) { - if (syncRunning) { notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool)); @@ -806,25 +805,28 @@ void *UE_thread(void *arg) syncRunning=false; if (UE->is_synchronized) { decoded_frame_rx = mac->mib_frame; - LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n", + LOG_A(PHY, + "UE synchronized! decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n", decoded_frame_rx, UE->init_sync_frame, trashed_frames); // shift the frame index with all the frames we trashed meanwhile we perform the synch search decoded_frame_rx = (decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER; + syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(res); + intialSyncOffset = syncMsg->rx_offset; } delNotifiedFIFO_elt(res); start_rx_stream=0; } else { if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { - // For IQ recorder/player we force synchronization to happen in 280 ms + // For IQ recorder-player we force synchronization to happen in 280 ms while (trashed_frames != 28) { - readFrame(UE, ×tamp, true); - trashed_frames+=2; + readFrame(UE, &sync_timestamp, true); + trashed_frames += 2; } } else { - readFrame(UE, ×tamp, true); - trashed_frames+=2; + readFrame(UE, &sync_timestamp, true); + trashed_frames += 2; } continue; } @@ -833,7 +835,7 @@ void *UE_thread(void *arg) AssertFatal(!syncRunning, "At this point synchronization can't be running\n"); if (!UE->is_synchronized) { - readFrame(UE, ×tamp, false); + readFrame(UE, &sync_timestamp, false); notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch); syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg); syncMsg->UE = UE; @@ -846,16 +848,16 @@ void *UE_thread(void *arg) if (start_rx_stream == 0) { start_rx_stream=1; - syncInFrame(UE, ×tamp); - UE->rx_offset=0; - UE->time_sync_cell=0; + syncInFrame(UE, &sync_timestamp, intialSyncOffset); + shiftForNextFrame = 0; // will be used to track clock drift // read in first symbol - AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void **)UE->common_vars.rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx),""); + AssertFatal(UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 + == UE->rfdevice.trx_read_func(&UE->rfdevice, + &sync_timestamp, + (void **)UE->common_vars.rxdata, + UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx), + ""); // we have the decoded frame index in the return of the synch process // and we shifted above to the first slot of next frame decoded_frame_rx++; @@ -871,7 +873,7 @@ void *UE_thread(void *arg) continue; } - + // start of normal case, the UE is in sync absolute_slot++; int slot_nr = absolute_slot % nb_slot_frame; @@ -893,26 +895,21 @@ void *UE_thread(void *arg) int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms); for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+ - UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)]; + rxp[i] = (void *)&UE->common_vars + .rxdata[i][firstSymSamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0)]; - int readBlockSize, writeBlockSize; - - readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms); - writeBlockSize = UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms); - if (UE->apply_timing_offset && (slot_nr == nb_slot_frame - 1)) { - const int sampShift = -(UE->rx_offset>>1); - readBlockSize -= sampShift; - writeBlockSize -= sampShift; - UE->apply_timing_offset = false; + int iq_shift_to_apply = 0; + if (slot_nr == nb_slot_frame - 1) { + // we shift of half of measured drift, at each beginning of frame for both rx and tx + iq_shift_to_apply = shiftForNextFrame; + shiftForNextFrame = 0; // We will get a new measured offset if we decode PBCH } - AssertFatal(readBlockSize == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - readBlockSize, - UE->frame_parms.nb_antennas_rx),""); + const int readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms) - iq_shift_to_apply; + openair0_timestamp rx_timestamp; + AssertFatal(readBlockSize + == UE->rfdevice.trx_read_func(&UE->rfdevice, &rx_timestamp, rxp, readBlockSize, UE->frame_parms.nb_antennas_rx), + ""); if(slot_nr == (nb_slot_frame - 1)) { // read in first symbol of next frame and adjust for timing drift @@ -931,11 +928,13 @@ void *UE_thread(void *arg) } // use previous timing_advance value to compute writeTimestamp - writeTimestamp = timestamp + - UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) - - firstSymSamp - UE->N_TA_offset - timing_advance; + const openair0_timestamp writeTimestamp = + rx_timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, DURATION_RX_TO_TX) - firstSymSamp + - UE->N_TA_offset - timing_advance; // but use current UE->timing_advance value to compute writeBlockSize + int writeBlockSize = + UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms) - iq_shift_to_apply; if (UE->timing_advance != timing_advance) { writeBlockSize -= UE->timing_advance - timing_advance; timing_advance = UE->timing_advance; @@ -948,7 +947,12 @@ void *UE_thread(void *arg) notifiedFIFO_elt_t *newRx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing); nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newRx); *curMsgRx = (nr_rxtx_thread_data_t){.proc = curMsg.proc, .UE = UE}; - UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data); + int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data); + if (ret) + // if ret is 0, no rx_offset has been computed, + // or the computed value is 0 = no offset to do + // we store it to apply the drift compensation at beginning of next frame + shiftForNextFrame = ret; pushTpool(&(get_nrUE_params()->Tpool), newRx); // Start TX slot processing here. It runs in parallel with RX slot processing diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index e9d159ff4b..bcac18a60b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -33,29 +33,22 @@ // The adjustment is performed once per frame based on the // last channel estimate of the receiver -void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, - PHY_VARS_NR_UE *ue, - module_id_t gNB_id, - const int estimateSz, - struct complex16 dl_ch_estimates_time[][estimateSz], - uint8_t frame, - uint8_t subframe, - unsigned char clear, - short coef) +int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, + PHY_VARS_NR_UE *ue, + module_id_t gNB_id, + const int estimateSz, + struct complex16 dl_ch_estimates_time[][estimateSz], + uint8_t frame, + uint8_t slot, + short coef) { - - static int count_max_pos_ok = 0; - static int first_time = 1; int max_val = 0, max_pos = 0; - const int sync_pos = 0; uint8_t sync_offset = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); short ncoef = 32767 - coef; - LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset); - // search for maximum position within the cyclic prefix for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) { int temp = 0; @@ -74,53 +67,32 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, } // filter position to reduce jitter - if (clear == 1) - ue->max_pos_fil = max_pos << 15; - else - ue->max_pos_fil = ((ue->max_pos_fil * coef) >> 15) + (max_pos * ncoef); + ue->max_pos_avg = ((ue->max_pos_avg * coef) >> 15) + (max_pos * ncoef); - // do not filter to have proactive timing adjustment - //ue->max_pos_fil = max_pos << 15; - - int diff = (ue->max_pos_fil >> 15) - sync_pos; + int diff = ue->max_pos_avg >> 15; if (frame_parms->freq_range==nr_FR2) sync_offset = 2; else sync_offset = 0; - if ( abs(diff) < (SYNCH_HYST+sync_offset) ) - ue->rx_offset = 0; - else - ue->rx_offset = diff; + int sampleShift = 0; + if (abs(diff) > (NR_SYNCH_HYST + sync_offset)) + sampleShift = diff; - const int sample_shift = -(ue->rx_offset>>1); + const int sample_shift = -(sampleShift / 2); // reset IIR filter for next offset calculation - ue->max_pos_fil += sample_shift * 32768; + ue->max_pos_avg += sample_shift * 32768; - if(abs(diff)<5) - count_max_pos_ok ++; - else - count_max_pos_ok = 0; - - //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok); - - if(count_max_pos_ok > 10 && first_time == 1) { - first_time = 0; - ue->time_sync_cell = 1; - } - -#ifdef DEBUG_PHY - LOG_I(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n", - subframe, + LOG_D(PHY, + "Slot %d: diff = %i, rx_offset (final) = %i : max_pos = %d, max_pos filtered = %ld, max_power = %d\n", + slot, diff, - ue->rx_offset, - clear, + sampleShift, max_pos, - ue->max_pos_fil, - max_val, - sync_pos); -#endif //DEBUG_PHY + ue->max_pos_avg, + max_val); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); + return sample_shift; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 14aa39c0a0..f47d49f877 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -30,7 +30,7 @@ */ /*!\brief Timing drift hysterisis in samples*/ -#define SYNCH_HYST 2 +#define NR_SYNCH_HYST 1 /* A function to perform the channel estimation of DL PRS signal */ int nr_prs_channel_estimation(uint8_t gNB_id, @@ -91,15 +91,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int rxdataFsize, c16_t rxdataF[][rxdataFsize]); -void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, - PHY_VARS_NR_UE *ue, - module_id_t gNB_id, - int estimateSz, - struct complex16 dl_ch_estimates_time [][estimateSz], - uint8_t frame, - uint8_t subframe, - unsigned char clear, - short coef); +int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, + PHY_VARS_NR_UE *ue, + module_id_t gNB_id, + int estimateSz, + struct complex16 dl_ch_estimates_time[][estimateSz], + uint8_t frame, + uint8_t subframe, + short coef); void nr_ue_measurements(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 56631c75ea..9e6a8bf7e5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -50,7 +50,7 @@ extern openair0_config_t openair0_cfg[]; //static nfapi_nr_config_request_t* config =&config_t; int cnt=0; -#define DEBUG_INITIAL_SYNCH +// #define DEBUG_INITIAL_SYNCH #define DUMP_PBCH_CH_ESTIMATES 0 // create a new node of SSB structure @@ -111,11 +111,6 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, NR_UE_SSB *best_ssb = NULL; NR_UE_SSB *current_ssb; -#ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id, - ue->rx_offset); -#endif - uint8_t N_L = (frame_parms->Lmax == 4)? 4:8; uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1; @@ -129,7 +124,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, start_meas(&ue->dlsch_channel_estimation_stats); // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im; @@ -147,7 +142,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, while (ret!=0 && temp_ptr != NULL) { start_meas(&ue->dlsch_channel_estimation_stats); - // computing channel estimation for selected best ssb + // computing channel estimation for selected best ssb const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz]; __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; @@ -178,242 +173,230 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, free_list(best_ssb); - - if (ret==0) { - - frame_parms->nb_antenna_ports_gNB = 1; //pbch_tx_ant; - - // set initial transmission mode to 1 or 2 depending on number of detected TX antennas - //frame_parms->mode1_flag = (pbch_tx_ant==1); - // openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1; + if (ret == 0) + frame_parms->nb_antenna_ports_gNB = 1; // pbch_tx_ant; + // set initial transmission mode to 1 or 2 depending on number of detected TX antennas + // frame_parms->mode1_flag = (pbch_tx_ant==1); + // openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1; -#ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); -#endif - return(0); - } else { - return(-1); - } - + LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); + return ret; } -int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa) +nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa) { - int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2, - int32_t metric_tdd_ncp=0; + int32_t metric_tdd_ncp = 0; uint8_t phase_tdd_ncp; int frame_id; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - int ret=-1; - int rx_power=0; //aarx, - + nr_initial_sync_t ret = {true, 0}; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN); - - LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL); + LOG_D(PHY, "nr_initial sync ue RB_DL %d\n", fp->N_RB_DL); /* Initial synchronisation * - * 1 radio frame = 10 ms - * <---------------------------------------------------------------------------> - * ----------------------------------------------------------------------------- - * | Received UE data buffer | - * ---------------------------------------------------------------------------- - * -------------------------- - * <-------------->| pss | pbch | sss | pbch | - * -------------------------- - * sync_pos SS/PBCH block - */ + * 1 radio frame = 10 ms + * <---------------------------------------------------------------------------> + * ----------------------------------------------------------------------------- + * | Received UE data buffer | + * ---------------------------------------------------------------------------- + * -------------------------- + * <-------------->| pss | pbch | sss | pbch | + * -------------------------- + * sync_pos SS/PBCH block + */ const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; - __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; + __attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; cnt++; - if (1){ // (cnt>100) - cnt =0; + if (1) { // (cnt>100) + cnt = 0; - // initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame - // only one frame is used for symulation tools - for (frame_id = 0; frame_id < n_frames; frame_id++) { - /* process pss search on received buffer */ - sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE); - if (sync_pos < fp->nb_prefix_samples) - continue; + // initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame + // only one frame is used for symulation tools + for (frame_id = 0; frame_id < n_frames; frame_id++) { + /* process pss search on received buffer */ + sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE); + if (sync_pos < fp->nb_prefix_samples) + continue; - ue->ssb_offset = sync_pos - fp->nb_prefix_samples; + ue->ssb_offset = sync_pos - fp->nb_prefix_samples; #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2); - LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset); + LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2); + LOG_I(PHY, "sync_pos %d ssb_offset %d \n", sync_pos, ue->ssb_offset); #endif - /* check that SSS/PBCH block is continuous inside the received buffer */ - if (ue->ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) < fp->samples_per_frame) { + /* check that SSS/PBCH block is continuous inside the received buffer */ + if (ue->ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) < fp->samples_per_frame) { + // digital compensation of FFO for SSB symbols + if (ue->UE_fo_compensation) { + double s_time = 1 / (1.0e3 * fp->samples_per_subframe); // sampling time + double off_angle = -2 * M_PI * s_time * (ue->common_vars.freq_offset); // offset rotation angle compensation per sample - // digital compensation of FFO for SSB symbols - if (ue->UE_fo_compensation){ - double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time - double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample + // In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1 + // and we do not know yet in which slot it goes. - // In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1 - // and we do not know yet in which slot it goes. - - for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) { - for (int ar=0; arnb_antennas_rx; ar++) { - const double re = ue->common_vars.rxdata[ar][n].r; - const double im = ue->common_vars.rxdata[ar][n].i; - ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle))); - ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle))); - } - } - } - - /* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */ - /* for NR this is not the case but slot_fep is still used for computing FFT of samples */ - /* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */ - /* symbol number are from beginning of SS/PBCH blocks as below: */ - /* Signal PSS PBCH SSS PBCH */ - /* symbol number 0 1 2 3 */ - /* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ - /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ - - for (int i = 0; i < NR_N_SYMBOLS_SSB; i++) - nr_slot_fep_init_sync(ue, proc, i, frame_id * fp->samples_per_frame + ue->ssb_offset, false, rxdataF, link_type_dl); - -#ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"Calling sss detection (normal CP)\n"); -#endif - - int freq_offset_sss = 0; - bool ret_sss = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF); - ret = !ret_sss; - // digital compensation of FFO for SSB symbols - if (ue->UE_fo_compensation){ - double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time - double off_angle = -2*M_PI*s_time*freq_offset_sss; // offset rotation angle compensation per sample - - // In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1 - // and we do not know yet in which slot it goes. - for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) { - for (int ar=0; arnb_antennas_rx; ar++) { - const double re = ue->common_vars.rxdata[ar][n].r; - const double im = ue->common_vars.rxdata[ar][n].i; - ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle))); - ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle))); + for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) { + for (int ar = 0; ar < fp->nb_antennas_rx; ar++) { + const double re = ue->common_vars.rxdata[ar][n].r; + const double im = ue->common_vars.rxdata[ar][n].i; + ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle))); + ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle))); + } } } - ue->common_vars.freq_offset += freq_offset_sss; - } - - if (ret==0) { //we got sss channel - nr_gold_pbch(ue); - ret = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss - } - - if (ret == 0) { - - // sync at symbol ue->symbol_offset - // computing the offset wrt the beginning of the frame - int mu = fp->numerology_index; - // number of symbols with different prefix length - // every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); - // for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync - ue->init_sync_frame = n_frames - 1 - frame_id; - - // compute the scramblingID_pdcch and the gold pdcch - ue->scramblingID_pdcch = fp->Nid_cell; - nr_gold_pdcch(ue,fp->Nid_cell); - - // compute the scrambling IDs for PDSCH DMRS - for (int i=0; iscramblingID_dlsch[i]=fp->Nid_cell; - nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]); - } - - nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); - - // initialize the pusch dmrs - for (int i=0; iscramblingID_ulsch[i]=fp->Nid_cell; - nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i); - } - - - // we also need to take into account the shift by samples_per_frame in case the if is true - if (ue->ssb_offset < sync_pos_frame){ - ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; - ue->init_sync_frame += 1; - } - else - ue->rx_offset = ue->ssb_offset - sync_pos_frame; - } - - /* - int nb_prefix_samples0 = fp->nb_prefix_samples0; - fp->nb_prefix_samples0 = fp->nb_prefix_samples; - - nr_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST); - nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST); - fp->nb_prefix_samples0 = nb_prefix_samples0; - - LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n", - ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, - ue->rx_offset, - ue->common_vars.freq_offset ); - */ + /* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */ + /* for NR this is not the case but slot_fep is still used for computing FFT of samples */ + /* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */ + /* symbol number are from beginning of SS/PBCH blocks as below: */ + /* Signal PSS PBCH SSS PBCH */ + /* symbol number 0 1 2 3 */ + /* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ + /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ + for (int i = 0; i < NR_N_SYMBOLS_SSB; i++) + nr_slot_fep_init_sync(ue, proc, i, frame_id * fp->samples_per_frame + ue->ssb_offset, false, rxdataF, link_type_dl); #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n", - fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret); + LOG_I(PHY, "Calling sss detection (normal CP)\n"); #endif - } - else { + int freq_offset_sss = 0; + bool ret_sss = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF); + ret.cell_notdetected = !ret_sss; // rx_sss_nr returns true if success + // digital compensation of FFO for SSB symbols + if (ue->UE_fo_compensation) { + double s_time = 1 / (1.0e3 * fp->samples_per_subframe); // sampling time + double off_angle = -2 * M_PI * s_time * freq_offset_sss; // offset rotation angle compensation per sample + + // In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1 + // and we do not know yet in which slot it goes. + for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) { + for (int ar = 0; ar < fp->nb_antennas_rx; ar++) { + const double re = ue->common_vars.rxdata[ar][n].r; + const double im = ue->common_vars.rxdata[ar][n].i; + ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle))); + ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle))); + } + } + + ue->common_vars.freq_offset += freq_offset_sss; + } + + if (ret.cell_notdetected == 0) { // we got sss channel + nr_gold_pbch(ue); + ret.cell_notdetected = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss + } + + if (ret.cell_notdetected == 0) { + // sync at symbol ue->symbol_offset + // computing the offset wrt the beginning of the frame + int mu = fp->numerology_index; + // number of symbols with different prefix length + // every 7*(1<symbol_offset / (7 * (1 << mu))) + 1; + sync_pos_frame = n_symb_prefix0 * (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + + (ue->symbol_offset - n_symb_prefix0) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + // for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of + // the n_frames we got sync + ue->init_sync_frame = n_frames - 1 - frame_id; + + // compute the scramblingID_pdcch and the gold pdcch + ue->scramblingID_pdcch = fp->Nid_cell; + nr_gold_pdcch(ue, fp->Nid_cell); + + // compute the scrambling IDs for PDSCH DMRS + for (int i = 0; i < NR_NB_NSCID; i++) { + ue->scramblingID_dlsch[i] = fp->Nid_cell; + nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]); + } + + nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); + + // initialize the pusch dmrs + for (int i = 0; i < NR_NB_NSCID; i++) { + ue->scramblingID_ulsch[i] = fp->Nid_cell; + nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i); + } + + // we also need to take into account the shift by samples_per_frame in case the if is true + if (ue->ssb_offset < sync_pos_frame) { + ret.rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; + ue->init_sync_frame += 1; + } else + ret.rx_offset = ue->ssb_offset - sync_pos_frame; + } + + /* + int nb_prefix_samples0 = fp->nb_prefix_samples0; + fp->nb_prefix_samples0 = fp->nb_prefix_samples; + + nr_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST); + nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST); + fp->nb_prefix_samples0 = nb_prefix_samples0; + + LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n", + ue->Mod_id, + ue->proc.proc_rxtx[0].frame_rx, + ue->rx_offset, + ue->common_vars.freq_offset ); + */ + #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos); + LOG_I(PHY, + "TDD Normal prefix: CellId %d metric %d, phase %d, pbch detected %d, measured offset %d\n", + fp->Nid_cell, + metric_tdd_ncp, + phase_tdd_ncp, + !ret.cell_notdetected, + ret.rx_offset); +#endif + + } else { +#ifdef DEBUG_INITIAL_SYNCH + LOG_I(PHY, "TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos); #endif } - if (ret == 0) break; - } - } - else { - ret = -1; + if (ret.cell_notdetected == 0) + break; + } + } else { + ret.cell_notdetected = true; } - /* Consider this is a false detection if the offset is > 1000 Hz + /* Consider this is a false detection if the offset is > 1000 Hz Not to be used now that offest estimation is in place - if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) ) - { - ret=-1; - LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset); - }*/ + if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) ) + { + ret=-1; + LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset); + }*/ - if (ret==0) { // PBCH found so indicate sync to higher layers and configure frame parameters + if (ret.cell_notdetected == 0) { // PBCH found so indicate sync to higher layers and configure frame parameters //#ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset); + LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n", ue->Mod_id, ret.rx_offset); //#endif if (ue->UE_scan_carrier == 0) { +#if UE_AUTOTEST_TRACE + LOG_I(PHY, + "[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n", + ue->Mod_id, + ue->rx_offset, + ue->common_vars.freq_offset); +#endif - #if UE_AUTOTEST_TRACE - LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n", - ue->Mod_id, - ue->rx_offset, - ue->common_vars.freq_offset ); - #endif - -// send sync status to higher layers later when timing offset converge to target timing - + // send sync status to higher layers later when timing offset converge to target timing } LOG_I(PHY, @@ -428,23 +411,22 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id, frame_parms->Nid_cell,frame_parms->frame_type); #endif - } // gain control - if (ret!=0) { //we are not synched, so we cannot use rssi measurement (which is based on channel estimates) - rx_power = 0; + if (ret.cell_notdetected != 0) { // we are not synched, so we cannot use rssi measurement (which is based on channel estimates) + int rx_power = 0; // do a measurement on the best guess of the PSS - //for (aarx=0; aarxnb_antennas_rx; aarx++) + // for (aarx=0; aarxnb_antennas_rx; aarx++) // rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2], - // frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); + // frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); /* // do a measurement on the full frame for (aarx=0; aarxnb_antennas_rx; aarx++) - rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0], - frame_parms->samples_per_subframe*10); + rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0], + frame_parms->samples_per_subframe*10); */ // we might add a low-pass filter here later @@ -453,12 +435,10 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]); #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"[UE%d] Initial sync : Estimated power: %d dB\n",ue->Mod_id,ue->measurements.rx_power_avg_dB[0] ); + LOG_I(PHY, "[UE%d] Initial sync : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]); #endif - } // exit_fun("debug exit"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT); return ret; } - 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 69169c1744..6888f36434 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -287,6 +287,7 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin /*! \brief receiver for the PBCH \returns number of tx antennas or -1 if error */ + int nr_rx_pbch(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, const int estimateSz, @@ -297,11 +298,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, fapiPbch_t *result, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, - PHY_VARS_NR_UE *ue, - int pbch_initial_symbol, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); - #ifndef modOrder #define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS #endif @@ -323,7 +319,11 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, @param n_frames @param sa current running mode */ -int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa); +typedef struct { + bool cell_notdetected; + int rx_offset; +} nr_initial_sync_t; +nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa); /*! \brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index bb77dac067..37a6c59854 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -485,12 +485,8 @@ typedef struct PHY_VARS_NR_UE_s { uint8_t init_sync_frame; /// temporary offset during cell search prior to MIB decoding int ssb_offset; - uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync - int rx_offset; /// Timing offset - int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP - int64_t max_pos_fil; /// Timing offset IIR filter - bool apply_timing_offset; /// Do time sync for current frame - int time_sync_cell; + uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync + int64_t max_pos_avg; /// Timing offset IIR filter /// Timing Advance updates variables /// Timing advance update computed from the TA command signalled from gNB @@ -644,6 +640,7 @@ typedef struct nr_rxtx_thread_data_s { int writeBlockSize; nr_phy_data_t phy_data; int tx_wait_for_dlsch; + int rx_offset; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index b3ce6944bb..f6b33359c8 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -98,7 +98,7 @@ typedef struct { */ 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 pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); +int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f1c9ce4066..35212ef12d 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -826,7 +826,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t * return dec; } -void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) +int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; @@ -834,6 +834,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr fapi_nr_config_request_t *cfg = &ue->nrUE_config; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; + int sampleShift = 0; nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); @@ -896,17 +897,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr if (ue->no_timing_correction==0 && pbchSuccess == 0) { LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); - nr_adjust_synch_ue(fp, - ue, - gNB_id, - fp->ofdm_symbol_size, - dl_ch_estimates_time, - frame_rx, - nr_slot_rx, - 0, - 16384); + sampleShift = + nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); } - ue->apply_timing_offset = true; } LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); nr_ue_rrc_measurements(ue, proc, rxdataF); @@ -996,6 +989,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); phy_pdcch_config->nb_search_space = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); + return sampleShift; } void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index bb0b8cbe6f..e2f1916a5b 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -959,7 +959,6 @@ int main(int argc, char **argv) //multipath channel //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0); - UE->rx_offset=0; UE_proc.frame_rx = frame; UE_proc.nr_slot_rx = slot; UE_proc.gNB_id = 0; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 9f084f190c..bfd23b7ffc 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -766,21 +766,22 @@ int main(int argc, char **argv) } if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, 1, 0); - printf("nr_initial_sync1 returns %d\n",ret); - if (ret<0) n_errors++; + nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0); + printf("nr_initial_sync1 returns %d\n", ret.cell_notdetected); + if (ret.cell_notdetected) + n_errors++; } else { UE_nr_rxtx_proc_t proc={0}; - UE->rx_offset=0; - uint8_t ssb_index = 0; - const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; - __attribute__((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz]; - __attribute__((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; - while (!((SSB_positions >> ssb_index) & 0x01)) - ssb_index++; // to select the first transmitted ssb - UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index); + uint8_t ssb_index = 0; + const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; + __attribute__((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz]; + __attribute__(( + aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + while (!((SSB_positions >> ssb_index) & 0x01)) + ssb_index++; // to select the first transmitted ssb + UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index); int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1)); proc.nr_slot_rx = ssb_slot; From 06820d372feb7592ff63915f6b01b327243308a2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Mar 2024 11:46:17 +0100 Subject: [PATCH 32/41] Add debugging script for image+coredump --- docker/debug_core_image.sh | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100755 docker/debug_core_image.sh diff --git a/docker/debug_core_image.sh b/docker/debug_core_image.sh new file mode 100755 index 0000000000..08d1719964 --- /dev/null +++ b/docker/debug_core_image.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +if [ $# -ne 3 ]; then + echo "usage: $0 " + exit 1 +fi + +die() { + echo $1 + exit 1 +} + +IMAGE=$1 +COREDUMP=$2 +SOURCES=$3 + +set -x + +# the image/build_oai builds in cmake_targets/ran_build/build, so source +# information is relative to this path. In case the user did not compile on +# their computer, this directory will not exist. still allow to find it by +# creating it +BUILD_DIR=$SOURCES/cmake_targets/ran_build/build +mkdir -p $BUILD_DIR || die "cannot create $BUILD_DIR: is $SOURCES valid?" + +# check if coredump is valid file +[ -f $COREDUMP ] || die "no such file: $COREDUMP" + +# check if image exists, and determine type (gnb, nr-ue) for correct invocation +# of gdb +docker image inspect $IMAGE > /dev/null || exit 1 +if [ $(grep "oai-gnb:" <<< $IMAGE) ] || [ $(grep "oai-gnb-aerial:" <<< $IMAGE) ]; then + EXEC=bin/nr-softmodem + TYPEPATH=oai-gnb +elif [ $(grep "oai-nr-ue:" <<< $IMAGE) ]; then + EXEC=bin/nr-uesoftmodem + TYPEPATH=oai-nr-ue +elif [ $(grep "oai-enb:" <<< $IMAGE) ]; then + EXEC=bin/lte-softmodem + TYPEPATH=oai-enb +elif [ $(grep "oai-lte-ue:" <<< $IMAGE) ]; then + EXEC=bin/lte-uesoftmodem + TYPEPATH=oai-lte-ue +else + die "cannot determine if image is gnb or nr-ue: must match \"oai-gnb:\" or \"oai-nr-ue:\"" +fi + +# run gdb inside a container. We mount the coredump and the sources inside the +# container, and run gdb with the core dump, the correct executable, and using +# the source directory to show correct line numbers +docker run --rm -it \ + -v $COREDUMP:/tmp/coredump \ + -v $SOURCES:/opt/$TYPEPATH/src \ + --entrypoint bash \ + $IMAGE \ + -c "gdb --dir=src/cmake_targets/ran_build/build $EXEC /tmp/coredump" From e615321eb2dd1176d83572150152cd8a029e352e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Mar 2024 11:42:41 +0100 Subject: [PATCH 33/41] Rewrite debugging instructions for CI fail --- doc/TESTBenches.md | 91 +++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index fa488a42f7..0b5b72679c 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -250,7 +250,44 @@ Some tests are run from source (e.g. `ci-scripts/xml_files/gnb_phytest_usrp_run.xml`), which directly give the options they are run with. -## How to retrieve core dumps (for CI team members) +## How to debug CI failures + +It is possible to debug CI failures using the generated core dump and the image +used for the run. A script is provided (see developer instructions below) that, +provided the core dump file, container image, and the source tree, executes +`gdb` inside the container; using the core dump information, a developer can +investigate the cause of failure. + +### Developer instructions + +The CI team will send you a docker image and a core dump file, and the commit +as of which the pipeline failed. Let's assume the coredump is stored at +`/tmp/coredump.tar.xz`, and the image is in `/tmp/oai-nr-ue.tar.gz`. First, you +should check out the corresponding branch (or directly the commit), let's say +in `~/oai-branch-fail`. Now, unpack the core dump, load the image into docker, +and use the script [`docker/debug_core_image.sh`](../docker/debug_core_image.sh) +to open gdb, as follows: + +``` +cd /tmp +tar -xJf /tmp/coredump.tar.xz +docker load < /tmp/oai-nr-ue.tar.gz +~/oai-branch-fail/docker/debug_core_image.sh /tmp/coredump ~/oai-branch-fail +``` + +where you replace `` with the image loaded in `docker load`. The script +will start the container and open gdb; you should see information about where +the failure (e.g., segmentation fault) happened. If you just see `??`, the core +dump and container image don't match. Be also on the lookout for the +corresponding message from gdb: +``` +warning: core file may not match specified executable file. +``` + +Once you quit `gdb`, the container image will be removed automatically. + + +### CI team instructions The entrypoint scripts of all containers print the core pattern that is used on the running machine. Search for `core_pattern` at the start of the container @@ -262,19 +299,14 @@ logs to retrieve the possible location. Possible locations might be: - abrt: see [documentation](https://abrt.readthedocs.io/en/latest/usage.html) - apport: see [documentation](https://wiki.ubuntu.com/Apport) -You furthermore have to extract the executable that caused the core dump. -Download the container image, and extract, e.g.: +See below for instructions on how to retrieve the core dump. Further, download +the image and store it to a file using `docker save`. Make sure to pick the +right image (Ubuntu or RHEL)! -``` -docker create --name c1 porcepix.sboai.cs.eurecom.fr/oai-gnb:develop-c99db698 -docker cp c1:/opt/oai-gnb/bin/nr-softmodem /tmp -docker rm c1 -``` - -### Core dump in a file +#### Core dump in a file **This is not recommended, as files could pile up and fill the system disk -completely!** Prefer systemd or abrt instead. +completely!** Prefer another method further down. If the core pattern is a path: it should at least include the time in the pattern name (suggested pattern: `/tmp/core.%e.%p.%t`) to correlate the time @@ -282,38 +314,31 @@ the segfault occurred with the CI logs. If you identified the core dump, copy the core dump from that machine; if identification is difficult, consider rerunning the pipeline. -### Core dump via systemd +#### Core dump via systemd -Run this command to list all core dumps: +Use the first command to list all core dumps. Scroll down to the core dump of +interest (it lists the executables in the last column; use the time to +correlate the segfault and the CI run). Take the PID of the executable (first +column after the time). Dump the core dump to a location of your choice. ``` sudo coredumpctl list -``` - -Scroll to the end and find the core dump of interest (it lists the executables -in the last column; use the time to correlate the segfault and the CI run). -Take the PID of the executable (first column after the time). Dump the core -dump to a location of your choice: - -``` sudo coredumpctl dump > /tmp/coredump ``` -### Core dump via abrt (automatic bug reporting tool) +#### Core dump via abrt (automatic bug reporting tool) TBD: use the documentation page for the moment. -### Core dump via apport - -On Ubuntu machines, apport first needs to be enabled to collect core dumps: +#### Core dump via apport +I did not find an easy way to use apport. Anyway, the systemd approach works +fine. So remove apport, install systemd-coredump, and verify it is the new +coredump handler: ``` -sudo systemctl enable apport.service -``` - -and [needs to be enabled](https://wiki.ubuntu.com/Apport#How_to_enable_apport). -Then, show a list of core dumps using - -``` -sudo apport-cli +sudo systemctl stop apport +sudo systemctl mask --now apport +sudo apt install systemd-coredump +# Verify this changed the core pattern to a pipe to systemd-coredump +sysctl kernel.core_pattern ``` From 8150a47ba501bcc6676c6b8de67574f63c901703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20da=20Silva?= Date: Wed, 22 Nov 2023 10:18:33 +0000 Subject: [PATCH 34/41] NVIDIA Aerial Integration - Aerial config file - Changes for ARC1.1. Change config file to max MCS 25. Fixed pdu size errors. - Remove taskset from Dockerfile.gNB.aerial.ubuntu20 after changing isolated CPUs - removed the USRP from Docker file Co-authored-by: Florian Kaltenberger Co-authored-by: Fredrik Molander Co-authored-by: Reem Bahsoun --- CMakeLists.txt | 3 +- cmake_targets/build_oai | 6 +- .../tools/install_libraries_to_system.patch | 76 + docker/Dockerfile.gNB.aerial.ubuntu20 | 103 ++ ...rfile.gNB.aerial.ubuntu20.sanitize-address | 109 ++ executables/nr-gnb.c | 2 +- executables/nr-ru.c | 2 +- executables/nr-softmodem.c | 22 +- executables/softmodem-common.h | 8 +- maketags | 2 +- nfapi/CMakeLists.txt | 1 + nfapi/oai_integration/aerial/CMakeLists.txt | 33 + nfapi/oai_integration/aerial/fapi_nvIPC.c | 683 +++++++++ nfapi/oai_integration/aerial/fapi_nvIPC.h | 61 + nfapi/oai_integration/aerial/fapi_vnf_p5.c | 765 ++++++++++ nfapi/oai_integration/aerial/fapi_vnf_p5.h | 75 + nfapi/oai_integration/aerial/fapi_vnf_p7.c | 1315 +++++++++++++++++ nfapi/oai_integration/aerial/fapi_vnf_p7.h | 243 +++ nfapi/oai_integration/nfapi.c | 3 +- nfapi/oai_integration/vendor_ext.h | 1 + .../nfapi/public_inc/nfapi_nr_interface_scf.h | 11 +- nfapi/open-nFAPI/nfapi/src/nfapi.c | 41 +- nfapi/open-nFAPI/nfapi/src/nfapi_p5.c | 213 ++- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 40 +- nfapi/open-nFAPI/pnf/src/pnf.c | 8 +- nfapi/open-nFAPI/vnf/src/vnf.c | 57 +- nfapi/open-nFAPI/vnf/src/vnf_p7.c | 4 +- openair1/SCHED_NR/fapi_nr_l1.c | 40 +- openair2/GNB_APP/gnb_config.c | 8 + openair2/LAYER2/NR_MAC_gNB/config.c | 13 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 47 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 32 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 6 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 14 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 46 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 18 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 19 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 12 +- openair2/PHY_INTERFACE/IF_Module.c | 10 +- .../CONF/gnb-vnf.sa.band78.273prb.aerial.conf | 262 ++++ 41 files changed, 4237 insertions(+), 179 deletions(-) create mode 100644 cmake_targets/tools/install_libraries_to_system.patch create mode 100644 docker/Dockerfile.gNB.aerial.ubuntu20 create mode 100644 docker/Dockerfile.gNB.aerial.ubuntu20.sanitize-address create mode 100644 nfapi/CMakeLists.txt create mode 100644 nfapi/oai_integration/aerial/CMakeLists.txt create mode 100644 nfapi/oai_integration/aerial/fapi_nvIPC.c create mode 100644 nfapi/oai_integration/aerial/fapi_nvIPC.h create mode 100644 nfapi/oai_integration/aerial/fapi_vnf_p5.c create mode 100644 nfapi/oai_integration/aerial/fapi_vnf_p5.h create mode 100644 nfapi/oai_integration/aerial/fapi_vnf_p7.c create mode 100644 nfapi/oai_integration/aerial/fapi_vnf_p7.h create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index b2605c529c..936938ed23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -726,7 +726,6 @@ set(SCHED_SRC_NR_UE add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE}) target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) - # nFAPI ################################# set(NFAPI_COMMON_SRC @@ -2066,6 +2065,8 @@ add_executable(nr-softmodem ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c ) +include(${OPENAIR_DIR}/nfapi/CMakeLists.txt) + target_link_libraries(nr-softmodem PRIVATE -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 4fd7defd0c..8870597164 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -93,7 +93,7 @@ Options: --UE-gen-nvram [output path] Specify gen_nvram_path (default \"$gen_nvram_path\") -w | --hardware - USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, None (Default) + USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default) Adds this RF board support (in external packages installation and in compilation) -t | --transport Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g @@ -289,6 +289,10 @@ function main() { TARGET_LIST="$TARGET_LIST aw2sori_transpro" CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON" ;; + "AERIAL"|"Aerial"|"aerial") + HW="OAI_AERIAL" + CMAKE_CMD="$CMAKE_CMD -DOAI_AERIAL=ON" + ;; "None") ;; *) diff --git a/cmake_targets/tools/install_libraries_to_system.patch b/cmake_targets/tools/install_libraries_to_system.patch new file mode 100644 index 0000000000..1e28c28418 --- /dev/null +++ b/cmake_targets/tools/install_libraries_to_system.patch @@ -0,0 +1,76 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 04cfa53..6eef6d6 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -42,6 +42,8 @@ OPTION(DOCA_GPU_DPDK "Enable DOCA GPUNetIO" ON) + OPTION(NVIPC_DOCA_ENABLE "Build libnvipc.so with DOCA" ON) + OPTION(NVIPC_DOCA_GPUNETIO "Use DOCA gpunetio in DOCA GPU DMA" OFF) + ++project(gt_common_libs) ++ + find_package(PkgConfig REQUIRED) + + # Disable NVIPC_DOCA_ENABLE if DOCA version < 2 +diff --git a/nvIPC/CMakeLists.txt b/nvIPC/CMakeLists.txt +index 633bbb7..dad7a7a 100644 +--- a/nvIPC/CMakeLists.txt ++++ b/nvIPC/CMakeLists.txt +@@ -19,7 +19,7 @@ + # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- ++include(GNUInstallDirs) + # lib: nvipc + set(SOURCES configs/nv_ipc_config.c + configs/nv_ipc_yaml_parser.cpp +@@ -68,6 +68,8 @@ target_include_directories(nvipc PUBLIC $) + target_include_directories(nvipc PUBLIC $) + ++set_target_properties(nvipc PROPERTIES PUBLIC_HEADER $) ++ + target_compile_options(nvipc PRIVATE ${AERIAL_ARCH_TUNE_FLAGS}) + + if(NVIPC_DPDK_ENABLE OR NVIPC_DOCA_GPUNETIO) +@@ -120,4 +122,8 @@ else() + target_link_libraries(nvipc PUBLIC rt -pthread nvlog) + endif() + ++install(TARGETS nvipc ++ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/..) ++ + add_subdirectory(tests) +diff --git a/nvlog/CMakeLists.txt b/nvlog/CMakeLists.txt +index 7b65242..c0c5080 100644 +--- a/nvlog/CMakeLists.txt ++++ b/nvlog/CMakeLists.txt +@@ -20,6 +20,8 @@ + # STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ++include(GNUInstallDirs) ++ + if(NOT CMAKE_BUILD_TYPE STREQUAL "Release") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g") +@@ -42,6 +44,8 @@ target_include_directories(nvlog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../extern + target_include_directories(nvlog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../external/fmtlog_flat) + target_link_libraries(nvlog rt -pthread yaml fmtlog-shared fmt::fmt) + ++set_target_properties(nvlog PROPERTIES PUBLIC_HEADER $) ++ + ######## libnvlog_static.a ############# + add_library(nvlog_static STATIC ${SOURCES}) + set_property(TARGET nvlog_static PROPERTY POSITION_INDEPENDENT_CODE ON) +@@ -68,5 +72,9 @@ target_compile_options(nvlog_static PRIVATE ${AERIAL_ARCH_TUNE_FLAGS}) + #add_executable(nvlog_observer ${SOURCES}) + #target_link_libraries(nvlog_observer nvlog_static -pthread) + ++install(TARGETS nvlog ++ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/../) ++ + ######## test directory ################ + add_subdirectory(test) diff --git a/docker/Dockerfile.gNB.aerial.ubuntu20 b/docker/Dockerfile.gNB.aerial.ubuntu20 new file mode 100644 index 0000000000..1fa9909b90 --- /dev/null +++ b/docker/Dockerfile.gNB.aerial.ubuntu20 @@ -0,0 +1,103 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu 22.04 +# +#--------------------------------------------------------------------- + +FROM ran-base:latest as ran-build + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + wget \ + ninja-build \ + #unzip is needed for protobuf + unzip \ + moreutils \ + vim-tiny \ + nano \ + # To build libnvipc + cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config + +RUN rm -Rf /oai-ran +WORKDIR /oai-ran +COPY . . + +RUN /bin/sh oaienv && \ + tar -xvzf nvipc_src.*.tar.gz && \ + cd nvipc_src.* && \ + git init && \ + git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \ + rm -rf build && mkdir build && cd build && \ + cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \ + make -j && make install + +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -w AERIAL --gNB --ninja + + +#start from scratch for target executable +FROM ubuntu:focal as oai-gnb-aerial +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + software-properties-common \ + procps \ + libsctp1 \ + tzdata \ + libatlas3-base \ + libconfig9 \ + openssl \ + net-tools \ + iperf \ + iproute2 \ + iputils-ping \ + gdb \ + libusb-1.0-0 && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-gnb/bin +COPY --from=ran-build \ + /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./ +COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh + +COPY --from=ran-build /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so /usr/local/lib/ + +#copy files from nvIPC +COPY --from=ran-build \ + /usr/local/lib/libfmtlog-shared.so \ + /usr/local/lib/libnvlog.so \ + /usr/local/lib/libnvipc.so \ + /usr/local/lib/ + + +WORKDIR /opt/oai-gnb +COPY --from=ran-build /tini /tini +ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.gNB.aerial.ubuntu20.sanitize-address b/docker/Dockerfile.gNB.aerial.ubuntu20.sanitize-address new file mode 100644 index 0000000000..60565a5429 --- /dev/null +++ b/docker/Dockerfile.gNB.aerial.ubuntu20.sanitize-address @@ -0,0 +1,109 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu 22.04 +# +#--------------------------------------------------------------------- + +FROM ran-base:latest as ran-build + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + wget \ + ninja-build \ + #unzip is needed for protobuf + unzip \ + moreutils \ + vim-tiny \ + nano \ + # To build libnvipc + cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config + +RUN rm -Rf /oai-ran +WORKDIR /oai-ran +COPY . . + +RUN /bin/sh oaienv && \ + tar -xvzf nvipc_src.*.tar.gz && \ + cd nvipc_src.* && \ + git init && \ + git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \ + rm -rf build && mkdir build && cd build && \ + cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \ + make -j && make install + +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -w AERIAL --gNB --ninja --sanitize-address + + +#start from scratch for target executable +FROM ubuntu:focal as oai-gnb-aerial +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + software-properties-common \ + procps \ + libsctp1 \ + tzdata \ + libatlas3-base \ + libconfig9 \ + openssl \ + net-tools \ + iperf \ + iproute2 \ + iputils-ping \ + gdb \ + libusb-1.0-0 && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-gnb/bin +COPY --from=ran-build \ + /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./ +COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh + +COPY --from=ran-build \ + /oai-ran/cmake_targets/ran_build/build/libcoding.so \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libdfts.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ + /usr/local/lib/ + +#copy files from nvIPC +COPY --from=ran-build \ + /usr/local/lib/libfmtlog-shared.so \ + /usr/local/lib/libnvlog.so \ + /usr/local/lib/libnvipc.so \ + /usr/local/lib/ + + +WORKDIR /opt/oai-gnb +COPY --from=ran-build /tini /tini +ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 2a12126d7d..87b9d30391 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -394,7 +394,7 @@ void init_gNB_Tpool(int inst) { // this will be removed when the msgDataTx is not necessary anymore gNB->msgDataTx = msgDataTx; - if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF)) + if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF) && (NFAPI_MODE != NFAPI_MODE_AERIAL)) threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 92fdc57e00..4287e6687b 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1285,7 +1285,7 @@ void *ru_thread( void *param ) { while (!oai_exit) { - if (NFAPI_MODE==NFAPI_MODE_VNF) { + if (NFAPI_MODE==NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL ) { // We should make a VNF main loop with proper tasks calls in case of VNF slot_start = timespec_add(slot_start,slot_duration); struct timespec curr_time; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 3d9c02f5e4..85bb9056fb 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -80,7 +80,9 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "nfapi/oai_integration/vendor_ext.h" #include "gnb_config.h" #include "openair2/E1AP/e1ap_common.h" - +#ifdef ENABLE_AERIAL +#include "nfapi/oai_integration/aerial/fapi_nvIPC.h" +#endif #ifdef E2_AGENT #include "openair2/E2AP/flexric/src/agent/e2_agent_api.h" #include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h" @@ -286,9 +288,15 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf itti_wait_ready(1); LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); +#ifdef ENABLE_AERIAL + AssertFatal(NFAPI_MODE == NFAPI_MODE_AERIAL,"Can only be run with '--nfapi AERIAL' when compiled with AERIAL support, if you want to run other (n)FAPI modes, please run ./build_oai without -w AERIAL"); +#endif + RCconfig_verify(cfg, node_type); - RCconfig_nr_prs(); + if(NFAPI_MODE != NFAPI_MODE_AERIAL){ + RCconfig_nr_prs(); + } if (RC.nb_nr_macrlc_inst > 0) RCconfig_nr_macrlc(cfg); @@ -687,7 +695,7 @@ int main( int argc, char **argv ) { pthread_mutex_init(&sync_mutex, NULL); usleep(1000); - if (NFAPI_MODE) { + if (NFAPI_MODE && NFAPI_MODE != NFAPI_MODE_AERIAL) { printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); @@ -706,7 +714,7 @@ int main( int argc, char **argv ) { printf("wait_gNBs()\n"); wait_gNBs(); printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - int sl_ahead=6; + int sl_ahead = NFAPI_MODE == NFAPI_MODE_AERIAL ? 0 : 6; if (RC.nb_RU >0) { printf("Initializing RU threads\n"); init_NR_RU(uniqCfg, get_softmodem_params()->rf_config_file); @@ -749,7 +757,9 @@ int main( int argc, char **argv ) { if (RC.nb_RU > 0) start_NR_RU(); - +#ifdef ENABLE_AERIAL + nvIPC_Init(); +#endif if (RC.nb_nr_L1_inst > 0) { printf("wait RUs\n"); wait_RUs(); @@ -778,7 +788,7 @@ int main( int argc, char **argv ) { load_softscope("nrqt", &p); } - if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) { + if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF && NFAPI_MODE != NFAPI_MODE_AERIAL) { printf("Not NFAPI mode - call init_eNB_afterRU()\n"); init_eNB_afterRU(); } else { diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 50aa335efb..43c8b4625e 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -103,7 +103,7 @@ extern "C" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n" -#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n" +#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF', 'AERIAL','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n" #define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n" #define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n" #define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence" @@ -232,9 +232,9 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s3a = { config_checkstr_assign_integer, \ - {"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ - {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ - 6 } }, \ + {"MONOLITHIC", "PNF", "VNF", "AERIAL","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ + {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF, NFAPI_MODE_AERIAL,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ + 7 } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ diff --git a/maketags b/maketags index 4c25bf6292..207d7ab376 100755 --- a/maketags +++ b/maketags @@ -1,4 +1,4 @@ #!/bin/sh echo "building ctags for openair1 and openair2 ..." -ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables radio +ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common fapi nfapi executables radio diff --git a/nfapi/CMakeLists.txt b/nfapi/CMakeLists.txt new file mode 100644 index 0000000000..7c75480aa6 --- /dev/null +++ b/nfapi/CMakeLists.txt @@ -0,0 +1 @@ +include(${OPENAIR_DIR}/nfapi/oai_integration/aerial/CMakeLists.txt) \ No newline at end of file diff --git a/nfapi/oai_integration/aerial/CMakeLists.txt b/nfapi/oai_integration/aerial/CMakeLists.txt new file mode 100644 index 0000000000..2514edf602 --- /dev/null +++ b/nfapi/oai_integration/aerial/CMakeLists.txt @@ -0,0 +1,33 @@ +add_boolean_option(OAI_AERIAL OFF "Activate OAI's AERIAL driver" OFF) +if (OAI_AERIAL) + message(STATUS "Building with support for Aerial") + + target_sources( + nr-softmodem + PRIVATE + ${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_nvIPC.c + ${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p7.c + ${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p5.c ) + + find_library(NVIPC_LIB nvipc REQUIRED) + if (NOT NVIPC_LIB) + message(FATAL_ERROR "-- nvipc library not found") + else () + message(STATUS " nvipc library found in ${NVIPC_LIB}") + #add_library(nvipc STATIC SHARED IMPORTED GLOBAL) + endif () + + find_library(NVLOG_LIB nvlog REQUIRED) + if (NOT NVLOG_LIB) + message(FATAL_ERROR "-- nvlog library not found") + else () + message(STATUS " nvlog library found in ${NVLOG_LIB}") + endif () + + add_compile_definitions(ENABLE_L2_SLT_RSP) + add_compile_definitions(FAPI_BYTE_ORDERING_BIG_ENDIAN) + add_compile_definitions(ENABLE_AERIAL) + target_link_libraries(nr-softmodem PRIVATE "${NVLOG_LIB}" "${NVIPC_LIB}") +else() + message(STATUS "No Support for Aerial") +endif() \ No newline at end of file diff --git a/nfapi/oai_integration/aerial/fapi_nvIPC.c b/nfapi/oai_integration/aerial/fapi_nvIPC.c new file mode 100644 index 0000000000..e080e51031 --- /dev/null +++ b/nfapi/oai_integration/aerial/fapi_nvIPC.c @@ -0,0 +1,683 @@ +/* +* 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 +*/ + +/*! \file fapi/oai-integration/fapi_nvIPC.c +* \brief OAI MAC/Aerial L1 interface file using FAPI over shared memory +* \author Ruben S. Silva +* \date 2023 +* \version 0.1 +* \company OpenAirInterface Software Alliance +* \email: contact@openairinterface.org, rsilva@allbesmart.pt +* \note +* \warning +*/ +#ifdef ENABLE_AERIAL +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fapi_nvIPC.h" +#include "nfapi_interface.h" +#include "nfapi.h" +#include "nfapi_nr_interface_scf.h" +#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h" + +#include "fapi_vnf_p5.h" +#include "fapi_vnf_p7.h" + +#define MAX_EVENTS 10 +#define RECV_BUF_LEN 8192 +char cpu_buf_recv[RECV_BUF_LEN]; + +uint16_t sfn = 0, slot = 0; +nv_ipc_t *ipc; +nfapi_vnf_config_t *vnf_config = 0; + +void set_config(nfapi_vnf_config_t *conf) +{ + vnf_config = conf; +} +static uint16_t old_sfn = 0; +static uint16_t old_slot = 0; +//////////////////////////////////////////////////////////////////////// +// Handle an RX message +static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg) +{ + if (msg == NULL) { + LOG_E(NFAPI_VNF, "%s: ERROR: buffer is empty\n", __func__); + return -1; + } + + char *p_cpu_data = NULL; + if (msg->data_buf != NULL) { + int gpu; + if (msg->data_pool == NV_IPC_MEMPOOL_CUDA_DATA) { + gpu = 1; + } else { + gpu = 0; + } + +#ifdef NVIPC_CUDA_ENABLE + // Test CUDA: call CUDA functions to change all string to lower case + test_cuda_to_lower_case(test_cuda_device_id, msg->data_buf, TEST_DATA_BUF_LEN, gpu); +#endif + + if (gpu) { + p_cpu_data = cpu_buf_recv; + memset(cpu_buf_recv, 0, RECV_BUF_LEN); + ipc->cuda_memcpy_to_host(ipc, p_cpu_data, msg->data_buf, RECV_BUF_LEN); + } else { + p_cpu_data = msg->data_buf; + } + } + + int messageBufLen = msg->msg_len; + int dataBufLen = msg->data_len; + uint8_t msgbuf[messageBufLen]; + uint8_t databuf[dataBufLen]; + memcpy(msgbuf, msg->msg_buf, messageBufLen); + memcpy(databuf, msg->data_buf, dataBufLen); + uint8_t *pReadPackedMessage = msgbuf; + uint8_t *pReadData = databuf; + uint8_t *end = msgbuf + messageBufLen; + uint8_t *data_end = databuf + dataBufLen; + + // unpack FAPI messages and handle them + if (vnf_config != 0) { + // first, unpack the header + fapi_phy_api_msg *fapi_msg = calloc(1, sizeof(fapi_phy_api_msg)); + if (!(pull8(&pReadPackedMessage, &fapi_msg->num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg->opaque_handle, end) + && pull16(&pReadPackedMessage, &fapi_msg->message_id, end) + && pull32(&pReadPackedMessage, &fapi_msg->message_length, end))) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FAPI message header unpack failed\n"); + return -1; + } + + switch (fapi_msg->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: + + if (vnf_config->nr_param_resp) { + nfapi_nr_param_response_scf_t msg_param_resp; + aerial_unpack_nr_param_response(&pReadPackedMessage, end, &msg_param_resp, &vnf_config->codec_config); + (vnf_config->nr_param_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_param_resp); + } + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: { + // unpack message + nfapi_nr_config_response_scf_t msg_config_response; + aerial_unpack_nr_config_response(&pReadPackedMessage, end, &msg_config_response, &vnf_config->codec_config); + // Check the error code + if (msg_config_response.error_code == NFAPI_NR_CONFIG_MSG_OK) { + // Invoke the call back + if (vnf_config->nr_config_resp) { + (vnf_config->nr_config_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_config_response); + } + } else { + // Error code not OK (MSG_INVALID_CONFIG) + /* MSG_INVALID_CONFIG.response structure + * Error code uint8_t + * Number of invalid or unsupported TLVs uint8_t + * Number of invalid TLVs that can only be configured in IDLE state uint8_t + * Number of invalid TLVs that can only be configured in RUNNING state uint8_t + * Number of missing TLVs uint8_t + * List of invalid or unsupported TLVs + * List of invalid TLVs that can only be configured in IDLE state + * List of invalid TLVs that can only be configured in RUNNING state + * List of missing TLVs + * */ + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: { + // TODO : ADD Support for NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION (0x06) + LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION\n"); + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: { + // TODO: Add Support for NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION (0x07) + LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION\n"); + //for (int i = 0; i < msg->msg_len; i++) { + // printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) msg->msg_buf)[i]); + //} + LOG_D(NFAPI_VNF,"old sfn %u\n", old_sfn); + LOG_D(NFAPI_VNF,"old slot %u\n", old_slot); + + break; + } + // P7 Messages + // P7 Message Handlers -> ((vnf_info *)vnf_config->user_data)->p7_vnfs->config-> + case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: { + nfapi_nr_slot_indication_scf_t ind; + aerial_unpack_nr_slot_indication(&pReadPackedMessage, + end, + &ind, + &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config); + // check if the sfn/slot unpacked come wrong at any time, should be old + 1 (slot 0 -- 19, sfn 0 -- 1023) + // add 1 to current sfn number + uint16_t old_slot_plus = ((old_slot + 1) % 20); + uint16_t old_sfn_plus = old_slot_plus == 0 ? ((old_sfn + 1) % 1024) : old_sfn; + if (old_slot_plus != ind.slot || old_sfn_plus != ind.sfn) { + LOG_E(NFAPI_VNF, + "\n============================================================================\n" + "sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n" + "============================================================================\n", + old_sfn, + old_slot, + ind.sfn, + ind.slot); + } + old_sfn = ind.sfn; + old_slot = ind.slot; + if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication) { + (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication)(&ind); + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: { + nfapi_nr_rx_data_indication_t ind; + ind.header.message_id = fapi_msg->message_id; + ind.header.message_length = fapi_msg->message_length; + aerial_unpack_nr_rx_data_indication( + &pReadPackedMessage, + end, + &pReadData, + data_end, + &ind, + &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__); + if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication) { + (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication)(&ind); + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: { + nfapi_nr_crc_indication_t crc_ind; + crc_ind.header.message_id = fapi_msg->message_id; + crc_ind.header.message_length = fapi_msg->message_length; + aerial_unpack_nr_crc_indication(&pReadPackedMessage, + end, + &crc_ind, + &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config); + if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication) { + (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication)(&crc_ind); + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: { + nfapi_nr_uci_indication_t ind; + aerial_unpack_nr_uci_indication(&pReadPackedMessage, + end, + &ind, + &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config); + + if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication) { + (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication)(&ind); + } + + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: { + nfapi_nr_srs_indication_t ind; + aerial_unpack_nr_srs_indication(&pReadPackedMessage, + end, + &ind, + &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config); + if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication) { + (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication)(&ind); + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: { + nfapi_nr_rach_indication_t ind; + aerial_unpack_nr_rach_indication(&pReadPackedMessage, + end, + &ind, + &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config); + if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication) { + (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication)(&ind); + } + break; + } + + default: { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, fapi_msg->message_id); + + break; + } + } + } + return 0; +} + +int8_t buf[1024]; + +nv_ipc_config_t nv_ipc_config; + +int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header) +{ + if (ipc == NULL) { + return -1; + } + nv_ipc_msg_t send_msg = {0}; + // look for the specific message + switch (header->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: + case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: + case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE: + break; + default: { + if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) { + // if(config && config->pack_p4_p5_vendor_extension) { + // result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config); + // } else { + // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id); + // } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id); + } + } break; + } + send_msg.msg_id = header->message_id; + send_msg.cell_id = 0; + send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header + send_msg.data_len = 0; + send_msg.data_buf = NULL; + send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG; + + // procedure is allocate->fill->send + int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0); + if (alloc_retval != 0) { + LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval); + ipc->tx_release(ipc, &send_msg); + return alloc_retval; + } + + memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len); + LOG_D(NFAPI_VNF, + "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n", + send_msg.cell_id, + send_msg.msg_id, + send_msg.msg_len, + send_msg.data_len, + send_msg.data_pool); + // Send the message + int send_retval = ipc->tx_send_msg(ipc, &send_msg); + if (send_retval < 0) { + LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval); + ipc->tx_release(ipc, &send_msg); + return send_retval; + } + + ipc->notify(ipc, 1); // notify that there's 1 message in queue + return 0; +} + +int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header) +{ + if (ipc == NULL) { + return -1; + } + nv_ipc_msg_t send_msg; + uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8]; + uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8; + + uint16_t present_sfn = 0; + uint16_t present_slot = 0; + pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd); + pull16(&pPacketBodyField, &present_slot, pPackMessageEnd); + + if (present_sfn != old_sfn || present_slot != old_slot) { + LOG_E(NFAPI_VNF, + "\n============================================================================\n" + "sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n" + "============================================================================\n", + present_sfn, + present_slot, + old_sfn, + old_slot); + } + // look for the specific message + switch (header->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + case NFAPI_UE_RELEASE_REQUEST: + case NFAPI_UE_RELEASE_RESPONSE: + case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + case NFAPI_TIMING_INFO: + case 0x8f: + break; + default: { + if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) { + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id); + } + } break; + } + + send_msg.msg_id = header->message_id; + send_msg.cell_id = 0; + send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header + send_msg.data_len = 0; + send_msg.data_buf = NULL; + send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG; + // procedure is allocate->fill->send + + // Allocate buffer for TX message + int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0); + if (alloc_retval != 0) { + LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval); + ipc->tx_release(ipc, &send_msg); + return alloc_retval; + } + + memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len); + LOG_D(NFAPI_VNF, + "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n", + send_msg.cell_id, + send_msg.msg_id, + send_msg.msg_len, + send_msg.data_len, + send_msg.data_pool); + // Send the message + int send_retval = ipc->tx_send_msg(ipc, &send_msg); + if (send_retval < 0) { + LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval); + ipc->tx_release(ipc, &send_msg); + return send_retval; + } + + ipc->notify(ipc, 1); // notify that there's 1 message in queue + return 0; +} + +int aerial_send_P7_msg_with_data(void *packedBuf, + uint32_t packedMsgLength, + void *dataBuf, + uint32_t dataLength, + nfapi_p7_message_header_t *header) +{ + if (ipc == NULL) { + return -1; + } + nv_ipc_msg_t send_msg; + uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8]; + uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8; + uint16_t present_sfn = 0; + uint16_t present_slot = 0; + pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd); + pull16(&pPacketBodyField, &present_slot, pPackMessageEnd); + + if (present_sfn != old_sfn || present_slot != old_slot) { + LOG_E(NFAPI_VNF, + "\n============================================================================\n" + "sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n" + "============================================================================\n", + present_sfn, + present_slot, + old_sfn, + old_slot); + } + // look for the specific message + switch (header->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + case NFAPI_UE_RELEASE_REQUEST: + case NFAPI_UE_RELEASE_RESPONSE: + case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + case NFAPI_TIMING_INFO: + break; + default: { + if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) { + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id); + } + } break; + } + + send_msg.msg_id = header->message_id; + send_msg.cell_id = 0; + send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header + send_msg.data_len = dataLength; + send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA; + + // procedure is allocate->fill->send + + // Allocate buffer for TX message + int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0); + if (alloc_retval != 0) { + LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval); + ipc->tx_release(ipc, &send_msg); + return alloc_retval; + } + + memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len); + memcpy(send_msg.data_buf, dataBuf, send_msg.data_len); + LOG_D(NFAPI_VNF, + "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n", + send_msg.cell_id, + send_msg.msg_id, + send_msg.msg_len, + send_msg.data_len, + send_msg.data_pool); + // Send the message + int send_retval = ipc->tx_send_msg(ipc, &send_msg); + if (send_retval != 0) { + LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval); + ipc->tx_release(ipc, &send_msg); + return send_retval; + } + + ipc->notify(ipc, 1); // notify that there's 1 message in queue + return 0; +} + +// Always allocate message buffer, but allocate data buffer only when data_len > 0 +static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg) +{ + if (ipc == NULL) { + return -1; + } + recv_msg->msg_buf = NULL; + recv_msg->data_buf = NULL; + + // Allocate buffer for TX message + if (ipc->rx_recv_msg(ipc, recv_msg) < 0) { + LOG_D(NFAPI_VNF, "%s: no more message available\n", __func__); + return -1; + } + LOG_D(NFAPI_VNF, + "recv: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n", + recv_msg->cell_id, + recv_msg->msg_id, + recv_msg->msg_len, + recv_msg->data_len, + recv_msg->data_pool); + ipc_handle_rx_msg(ipc, recv_msg); + + // Release buffer of RX message + int release_retval = ipc->rx_release(ipc, recv_msg); + if (release_retval != 0) { + LOG_E(NFAPI_VNF, "%s error: release RX buffer failed Error: %d\n", __FUNCTION__, release_retval); + return release_retval; + } + return 0; +} + +bool recv_task_running = false; +int stick_this_thread_to_core(int core_id) +{ + int num_cores = sysconf(_SC_NPROCESSORS_ONLN); + if (core_id < 0 || core_id >= num_cores) + return EINVAL; + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(core_id, &cpuset); + + pthread_t current_thread = pthread_self(); + return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset); +} +void *epoll_recv_task(void *arg) +{ + struct epoll_event ev, events[MAX_EVENTS]; + stick_this_thread_to_core(10); + LOG_D(NFAPI_VNF,"Aerial recv task start \n"); + int epoll_fd = epoll_create1(0); + if (epoll_fd == -1) { + LOG_E(NFAPI_VNF, "%s epoll_create failed\n", __func__); + } + + int ipc_rx_event_fd = ipc->get_fd(ipc); + ev.events = EPOLLIN; + ev.data.fd = ipc_rx_event_fd; + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) { + LOG_E(NFAPI_VNF, "%s epoll_ctl failed\n", __func__); + } + + while (1) { + if (!recv_task_running) { + recv_task_running = true; + } + LOG_D(NFAPI_VNF, "%s: epoll_wait fd_rx=%d ...\n", __func__, ipc_rx_event_fd); + + int nfds; + do { + // epoll_wait() may return EINTR when get unexpected signal SIGSTOP from system + nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); + } while (nfds == -1 && errno == EINTR); + + if (nfds < 0) { + LOG_E(NFAPI_VNF, "epoll_wait failed: epoll_fd=%d nfds=%d err=%d - %s\n", epoll_fd, nfds, errno, strerror(errno)); + } + + int n = 0; + for (n = 0; n < nfds; ++n) { + if (events[n].data.fd == ipc_rx_event_fd) { + ipc->get_value(ipc); + nv_ipc_msg_t recv_msg; + while (aerial_recv_msg(ipc, &recv_msg) == 0); + } + } + } + close(epoll_fd); + return NULL; +} + +int create_recv_thread(void) +{ + pthread_t thread_id; + + void *(*recv_task)(void *); + + recv_task = epoll_recv_task; + + int ret = pthread_create(&thread_id, NULL, recv_task, NULL); + if (ret != 0) { + LOG_E(NFAPI_VNF, "%s failed, ret = %d\n", __func__, ret); + } + return ret; +} + +int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport) +{ + // Create configuration + config->ipc_transport = _transport; + if (set_nv_ipc_default_config(config, module_type) < 0) { + LOG_E(NFAPI_VNF, "%s: set configuration failed\n", __func__); + return -1; + } + +#ifdef NVIPC_CUDA_ENABLE + int test_cuda_device_id = get_cuda_device_id(); +#else + int test_cuda_device_id = -1; +#endif + LOG_D(NFAPI_VNF,"CUDA device ID configured : %d \n", test_cuda_device_id); + config->transport_config.shm.cuda_device_id = test_cuda_device_id; + if (test_cuda_device_id >= 0) { + config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CUDA_DATA].pool_len = 128; + config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_DATA].pool_len = 1024; + config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_MSG].pool_len = 4096; + } + + return 0; +} + +int nvIPC_Init() { +// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller) + load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM); + // Create nv_ipc_t instance + if ((ipc = create_nv_ipc_interface(&nv_ipc_config)) == NULL) { + LOG_E(NFAPI_VNF, "%s: create IPC interface failed\n", __func__); + return -1; + } + LOG_I(NFAPI_VNF, "%s: create IPC interface successful\n", __func__); + sleep(1); + create_recv_thread(); + while(!recv_task_running){usleep(100000);} + aerial_pnf_nr_connection_indication_cb(vnf_config, 1); + return 0; +} +#endif diff --git a/nfapi/oai_integration/aerial/fapi_nvIPC.h b/nfapi/oai_integration/aerial/fapi_nvIPC.h new file mode 100644 index 0000000000..0fe559658c --- /dev/null +++ b/nfapi/oai_integration/aerial/fapi_nvIPC.h @@ -0,0 +1,61 @@ +/* +* 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 + */ + +/*! \file fapi/oai-integration/fapi_nvIPC.h +* \brief Header file for fapi_nvIPC.c +* \author Ruben S. Silva +* \date 2023 +* \version 0.1 +* \company OpenAirInterface Software Alliance +* \email: contact@openairinterface.org, rsilva@allbesmart.pt +* \note +* \warning + */ +#ifdef ENABLE_AERIAL +#ifndef OPENAIRINTERFACE_FAPI_NVIPC_H +#define OPENAIRINTERFACE_FAPI_NVIPC_H + +#include "nv_ipc.h" +#include "nv_ipc_utils.h" +#include "nvlog.h" +#include "nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h" +#include "openair1/PHY/defs_gNB.h" +#include "debug.h" + +typedef struct { + uint8_t num_msg; + uint8_t opaque_handle; + uint16_t message_id; + uint32_t message_length; +} fapi_phy_api_msg; + +int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header); +int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header); +int aerial_send_P7_msg_with_data(void *packedBuf, + uint32_t packedMsgLength, + void *dataBuf, + uint32_t dataLength, + nfapi_p7_message_header_t *header); +void set_config(nfapi_vnf_config_t *conf); +int nvIPC_Init(); + +#endif // OPENAIRINTERFACE_FAPI_NVIPC_H +#endif diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p5.c b/nfapi/oai_integration/aerial/fapi_vnf_p5.c new file mode 100644 index 0000000000..57ef1ddc11 --- /dev/null +++ b/nfapi/oai_integration/aerial/fapi_vnf_p5.c @@ -0,0 +1,765 @@ +/* +* 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 + */ + +/*! \file fapi/oai-integration/fapi_vnf_p5.c +* \brief OAI FAPI VNF P5 message handler procedures +* \author Ruben S. Silva +* \date 2023 +* \version 0.1 +* \company OpenAirInterface Software Alliance +* \email: contact@openairinterface.org, rsilva@allbesmart.pt +* \note +* \warning + */ +#ifdef ENABLE_AERIAL +#include "fapi_vnf_p5.h" +#include "fapi_vnf_p7.h" +#include "nfapi/open-nFAPI/nfapi/src/nfapi_p5.c" +#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h" + +extern RAN_CONTEXT_t RC; +extern UL_RCC_IND_t UL_RCC_INFO; +extern int single_thread_flag; +extern uint16_t sf_ahead; +extern uint16_t slot_ahead; + + +static pthread_t vnf_aerial_p7_start_pthread; +void *aerial_vnf_nr_aerial_p7_start_thread(void *ptr) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + pthread_setname_np(pthread_self(), "VNF_P7_AERIAL"); + nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; + aerial_nfapi_nr_vnf_p7_start(config); + return config; +} + +void *aerial_vnf_nr_p7_thread_start(void *ptr) +{ + // set_thread_priority(79); + int s; + cpu_set_t cpuset; + + CPU_SET(8, &cpuset); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) + printf("failed to set afinity\n"); + + set_priority(79); + + pthread_attr_t ptAttr; + if (pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { + printf("Failed to set pthread sched policy SCHED_RR\n"); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + struct sched_param thread_params; + thread_params.sched_priority = 20; + + if (pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) { + printf("failed to set sched param\n"); + } + + init_queue(&gnb_rach_ind_queue); + init_queue(&gnb_rx_ind_queue); + init_queue(&gnb_crc_ind_queue); + init_queue(&gnb_uci_ind_queue); + init_queue(&gnb_slot_ind_queue); + + vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; + p7_vnf->config->port = p7_vnf->local_port; + p7_vnf->config->sync_indication = &aerial_phy_sync_indication; + p7_vnf->config->slot_indication = &aerial_phy_slot_indication; + p7_vnf->config->harq_indication = &aerial_phy_harq_indication; + p7_vnf->config->nr_crc_indication = &aerial_phy_nr_crc_indication; + p7_vnf->config->nr_rx_data_indication = &aerial_phy_nr_rx_data_indication; + p7_vnf->config->nr_rach_indication = &aerial_phy_nr_rach_indication; + p7_vnf->config->nr_uci_indication = &aerial_phy_nr_uci_indication; + p7_vnf->config->srs_indication = &aerial_phy_srs_indication; + p7_vnf->config->sr_indication = &aerial_phy_sr_indication; + p7_vnf->config->cqi_indication = &aerial_phy_cqi_indication; + p7_vnf->config->lbt_dl_indication = &aerial_phy_lbt_dl_indication; + p7_vnf->config->nb_harq_indication = &aerial_phy_nb_harq_indication; + p7_vnf->config->nrach_indication = &aerial_phy_nrach_indication; + p7_vnf->config->nr_slot_indication = &aerial_phy_nr_slot_indication; + p7_vnf->config->nr_srs_indication = &aerial_phy_nr_srs_indication; + p7_vnf->config->malloc = &aerial_vnf_allocate; + p7_vnf->config->free = &aerial_vnf_deallocate; + p7_vnf->config->vendor_ext = &aerial_phy_vendor_ext; + p7_vnf->config->user_data = p7_vnf; + p7_vnf->mac->user_data = p7_vnf; + p7_vnf->config->codec_config.unpack_p7_vendor_extension = &aerial_phy_unpack_p7_vendor_extension; + p7_vnf->config->codec_config.pack_p7_vendor_extension = &aerial_phy_pack_p7_vendor_extension; + p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &aerial_phy_unpack_vendor_extension_tlv; + p7_vnf->config->codec_config.pack_vendor_extension_tlv = &aerial_phy_pack_vendor_extension_tlv; + p7_vnf->config->codec_config.allocate = &aerial_vnf_allocate; + p7_vnf->config->codec_config.deallocate = &aerial_vnf_deallocate; + p7_vnf->config->allocate_p7_vendor_ext = &aerial_phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &aerial_phy_deallocate_p7_vendor_ext; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__); + pthread_create(&vnf_aerial_p7_start_pthread, NULL, &aerial_vnf_nr_aerial_p7_start_thread, p7_vnf->config); + return 0; +} + + +int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) +{ + printf("[VNF] pnf connection indication idx:%d\n", p5_idx); + // in aerial, send first CONFIG.request, not PARAM.request + nfapi_nr_config_request_scf_t conf_req; + memset(&conf_req, 0, sizeof(conf_req)); + conf_req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST; + printf("Try to send first CONFIG.request\n"); + aerial_nr_send_config_request(config, p5_idx); + return 0; +} + +int aerial_pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf disconnection indication idx:%d\n", p5_idx); + vnf_info *vnf = (vnf_info *)(config->user_data); + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id); + return 0; +} + +int aerial_pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + vnf_info *vnf = (vnf_info *)(config->user_data); + pnf_info *pnf = vnf->pnfs; + + for (int i = 0; i < resp->pnf_phy.number_of_phys; ++i) { + phy_info phy; + memset(&phy, 0, sizeof(phy)); + phy.index = resp->pnf_phy.phy[i].phy_config_index; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); + + for (int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; + } + + pnf->phys[0] = phy; + } + nfapi_nr_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); + NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n"); + + for (unsigned i = 0; i < 2; ++i) { + req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id; + req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index; + req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0]; + } + + nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req); + return 0; +} + +int aerial_pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", + p5_idx, + resp->header.phy_id, + resp->header.message_id, + resp->header.message_length); + + if (1) { + nfapi_nr_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.phy_id = resp->header.phy_id; + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req); + } else { + // Rather than send the pnf_start_request we will demonstrate + // sending a vendor extention message. The start request will be + // send when the vendor extension response is received + // vnf_info* vnf = (vnf_info*)(config->user_data); + vendor_ext_p5_req req; + memset(&req, 0, sizeof(req)); + req.header.message_id = P5_VENDOR_EXT_REQ; + req.dummy1 = 45; + req.dummy2 = 1977; + nfapi_vnf_vendor_extension(config, p5_idx, &req.header); + } + + return 0; +} + +int aerial_pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp) +{ + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + pnf_info *pnf = vnf->pnfs; + nfapi_nr_param_request_scf_t req; + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", + p5_idx, + config, + config->user_data, + vnf->p7_vnfs[0].config, + vnf->p7_vnfs[0].thread_started); + + if (p7_vnf->thread_started == 0) { + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf); + p7_vnf->thread_started = 1; + } else { + // P7 thread already running. + } + + // start all the phys in the pnf. + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST; + req.header.phy_id = pnf->phys[0].id; + nfapi_nr_vnf_param_req(config, p5_idx, &req); + return 0; +} + +int aerial_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + struct sockaddr_in pnf_p7_sockaddr; + nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check + phy->remote_port = resp->nfapi_config.p7_pnf_port.value; + // phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value; + memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); + phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); + // for now just 1 + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", + p5_idx, + phy->id, + phy->remote_addr, + phy->remote_port, + p7_vnf->timing_window, + p7_vnf->periodic_timing_period, + p7_vnf->aperiodic_timing_enabled, + p7_vnf->periodic_timing_period); + req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST; + req->header.phy_id = phy->id; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n"); + // NFAPI_TRACE(NFAPI_TRACE_INFO, "\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]); + + req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG; + req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; + req->num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", ntohs(p7_vnf->local_port)); + req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + struct sockaddr_in vnf_p7_sockaddr; + vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); + memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); + req->num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); + req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG; + req->nfapi_config.timing_window.value = p7_vnf->timing_window; + NFAPI_TRACE(NFAPI_TRACE_INFO, + "\n[VNF]Timing window tag : %d Timing window:%u\n", + NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, + p7_vnf->timing_window); + req->num_tlv++; + + if (p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) { + req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG; + req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled); + req->num_tlv++; + + if (p7_vnf->periodic_timing_enabled) { + req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG; + req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period; + req->num_tlv++; + } + } + // TODO: Assign tag and value for P7 message offsets + req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET; + req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET; + req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET; + req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET; + + vendor_ext_tlv_2 ve2; + memset(&ve2, 0, sizeof(ve2)); + ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; + ve2.dummy = 2016; + req->vendor_extension = &ve2.tl; + nfapi_nr_vnf_config_req(config, p5_idx, req); + printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n", req->num_tlv); + return 0; +} + +int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx) +{ + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + + nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; //&RC.gNB[0]->gNB_config; // check + + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", + p5_idx, + phy->id, + phy->remote_addr, + phy->remote_port, + p7_vnf->timing_window, + p7_vnf->periodic_timing_period, + p7_vnf->aperiodic_timing_enabled, + p7_vnf->periodic_timing_period); + req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST; + req->header.phy_id = phy->id; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n"); + + + vnf_t *_this = (vnf_t *)(config); + + nfapi_vnf_phy_info_t *vnf_phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id); + + if (vnf_phy == NULL) { + printf("%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id); + return -1; + } + + nfapi_p4_p5_message_header_t *msg = &req->header; + uint16_t msg_len = sizeof(nfapi_nr_config_request_scf_t); + nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len); + memcpy(msgFAPI, &req->header, msg_len); + uint8_t tx_messagebufferFAPI[sizeof(_this->tx_message_buffer)]; + int packedMessageLengthFAPI = -1; + packedMessageLengthFAPI = + fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &_this->_public.codec_config); + + aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg); + + return 0; +} + +int aerial_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp) +{ + nfapi_nr_start_request_scf_t req; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + LOG_I(NFAPI_VNF, "Received CONFIG.response, gNB is ready! \n"); + + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST; + req.header.phy_id = resp->header.phy_id; + nfapi_nr_vnf_start_req(config, p5_idx, &req); + return 0; +} + +int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + vnf_info *vnf = (vnf_info *)(config->user_data); + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + + nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); + return 0; +} + +int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__); + + switch (msg->message_id) { + case P5_VENDOR_EXT_RSP: { + vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + // send the start request + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } break; + } + + return 0; +} + +int aerial_vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, + uint8_t **ppReadPackedMessage, + uint8_t *end, + void **ve, + nfapi_p4_p5_codec_config_t *codec) +{ + return -1; +} + +int aerial_vnf_pack_vendor_extension_tlv(void *vext, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) +{ + nfapi_tl_t *tlv = (nfapi_tl_t *)vext; + + switch (tlv->tag) { + case VENDOR_EXT_TLV_2_TAG: { + vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv; + + if (!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + + return 1; + } break; + } + + return -1; +} + +int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, + uint8_t **ppReadPackedMessage, + uint8_t *end, + nfapi_p4_p5_codec_config_t *codec) +{ + if (header->message_id == P5_VENDOR_EXT_RSP) { + vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header); + return (!pull16(ppReadPackedMessage, &req->error_code, end)); + } + + return 0; +} + +int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, + uint8_t **ppWritePackedMsg, + uint8_t *end, + nfapi_p4_p5_codec_config_t *codec) +{ + if (header->message_id == P5_VENDOR_EXT_REQ) { + vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header); + return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end))); + } + + return 0; +} + +nfapi_p4_p5_message_header_t *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size) +{ + if (message_id == P5_VENDOR_EXT_RSP) { + *msg_size = sizeof(vendor_ext_p5_rsp); + return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp)); + } + + return 0; +} + +void aerial_vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) +{ + free(header); +} + +void *aerial_vnf_p5_allocate(size_t size) +{ + // return (void*)memory_pool::allocate(size); + return (void *)malloc(size); +} + +void aerial_vnf_p5_deallocate(void *ptr) +{ + // memory_pool::deallocate((uint8_t*)ptr); + free(ptr); +} + +static vnf_info aerial_vnf; +void aerial_configure_nr_fapi_vnf() +{ + // TODO: Implement for FAPI + // nfapi_setmode(NFAPI_MODE_VNF); + memset(&aerial_vnf, 0, sizeof(aerial_vnf)); + memset(aerial_vnf.p7_vnfs, 0, sizeof(aerial_vnf.p7_vnfs)); + aerial_vnf.p7_vnfs[0].timing_window = 30; + aerial_vnf.p7_vnfs[0].periodic_timing_enabled = 0; + aerial_vnf.p7_vnfs[0].aperiodic_timing_enabled = 0; + aerial_vnf.p7_vnfs[0].periodic_timing_period = 10; + aerial_vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create(); + aerial_vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t)); + nfapi_vnf_config_t *config = nfapi_vnf_config_create(); + config->malloc = malloc; + config->free = free; + config->vnf_ipv4 = 1; + config->vnf_ipv6 = 0; + config->pnf_list = 0; + config->phy_list = 0; + + config->pnf_nr_connection_indication = &aerial_pnf_nr_connection_indication_cb; + config->pnf_disconnect_indication = &aerial_pnf_disconnection_indication_cb; + + config->pnf_nr_param_resp = &aerial_pnf_nr_param_resp_cb; + config->pnf_nr_config_resp = &aerial_pnf_nr_config_resp_cb; + config->pnf_nr_start_resp = &aerial_pnf_nr_start_resp_cb; + config->nr_param_resp = &aerial_nr_param_resp_cb; + config->nr_config_resp = &aerial_nr_config_resp_cb; + config->nr_start_resp = &aerial_nr_start_resp_cb; + config->vendor_ext = &aerial_vendor_ext_cb; + config->user_data = &aerial_vnf; + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &aerial_vnf_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &aerial_vnf_pack_vendor_extension_tlv; + config->codec_config.unpack_p4_p5_vendor_extension = &aerial_vnf_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &aerial_vnf_pack_p4_p5_vendor_extension; + config->allocate_p4_p5_vendor_ext = &aerial_vnf_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &aerial_vnf_deallocate_p4_p5_vendor_ext; + config->codec_config.allocate = &aerial_vnf_allocate; + config->codec_config.deallocate = &aerial_vnf_deallocate; + memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + set_config(config); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__); + nfapi_vnf_pnf_info_t *pnf = (nfapi_vnf_pnf_info_t *)malloc(sizeof(nfapi_vnf_pnf_info_t)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf); + memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t)); + pnf->p5_idx = 1; + pnf->connected = 1; + // Add needed parameters + + vnf_info *vnf = (vnf_info *)(config->user_data); + pnf_info *pnf_info = vnf->pnfs; + + for (int i = 0; i < 1; ++i) { + phy_info phy; + memset(&phy, 0, sizeof(phy)); + phy.index = 0; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, 0); + nfapi_vnf_allocate_phy(config, 1, &(phy.id)); + + for (int j = 0; j < 1; ++j) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, 0); + phy.rfs[0] = 0; + } + + pnf_info->phys[0] = phy; + } + + + nfapi_vnf_pnf_list_add(config, pnf); + + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", + 1, + config, + config->user_data, + vnf->p7_vnfs[0].config, + vnf->p7_vnfs[0].thread_started); + + if (p7_vnf->thread_started == 0) { + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf); + p7_vnf->thread_started = 1; + } else { + // P7 thread already running. + } +} +uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) +{ + return unpack_nr_param_response(ppReadPackedMsg, end, msg, config); +} +uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) +{ + return unpack_nr_config_response(ppReadPackedMsg, end, msg, config); +} + +// monitor the p7 endpoints and the timing loop and +// send indications to mac +int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config) +{ + if (config == 0) + return -1; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + + vnf_p7_t *vnf_p7 = (vnf_p7_t *)config; + + // Create p7 receive udp port + // todo : this needs updating for Ipv6 + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port); + + + struct timespec ref_time; + clock_gettime(CLOCK_MONOTONIC, &ref_time); + uint8_t setup_done = 0; + while (vnf_p7->terminate == 0) { + if (setup_done == 0) { + struct timespec curr_time; + clock_gettime(CLOCK_MONOTONIC, &curr_time); + uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec; + if (setup_time > 3) { + setup_done = 1; + } + } + + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n"); + close(vnf_p7->socket); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__); + + return 0; +} + +int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config){ + + nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *pWritePackedMessage = pPackedBuf; + + uint32_t packedMsgLen; + //uint16_t packedMsgLen16; + + if (pMessageBuf == NULL || pPackedBuf == NULL) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n"); + return -1; + } + uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint8_t *pPacketBodyField = &pWritePackedMessage[8]; + uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8]; + + pack_nr_p5_message_body(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config); + + // PHY API message header + push8(1, &pWritePackedMessage, pPackMessageEnd); // Number of messages + push8(0, &pWritePackedMessage, pPackMessageEnd); // Opaque handle + + // PHY API Message structure + push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd); // Message type ID + + if(1==1) { + // check for a valid message length + packedMsgLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField); + packedMsgLen-=1; + if(pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_START_REQUEST){ + //START.request doesn't have a body, length is 0 + packedMsgLen = 0; + }else if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message 0x%02x length error %d, buffer supplied %d\n",pMessageHeader->message_id, packedMsgLen, packedBufLen); + return -1; + } else { + + } + + // Update the message length in the header + if(!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd)) + return -1; + + // return the packed length + return (packedMsgLen); + } else { + // Failed to pack the meassage + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n"); + return -1; + } + +} + + +int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) +{ + nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config; + + ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST; + + // int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req); + int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_tti_req->header); + + if (retval != 0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + // Reset number of PDUs so that it is not resent + ul_tti_req->n_pdus = 0; + ul_tti_req->n_group = 0; + ul_tti_req->n_ulcch = 0; + ul_tti_req->n_ulsch = 0; + } + return retval; +} + +int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) +{ + nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config; + ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST; + // int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req); + int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_dci_req->header); + if (retval != 0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + ul_dci_req->numPdus = 0; + } + return retval; +} + +int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req) +{ + nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config; + tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST; + // LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_data_req->SFN), + // tx_data_req->Number_of_PDUs); int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req); + int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &tx_data_req->header); + if (retval != 0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + tx_data_req->Number_of_PDUs = 0; + } + + return retval; +} + +int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) +{ + nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config; + dl_config_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST; + dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &dl_config_req->header); + dl_config_req->dl_tti_request_body.nPDUs = 0; + dl_config_req->dl_tti_request_body.nGroup = 0; + + if (retval != 0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } + return retval; +} + +int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){ + nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config; + nfapi_nr_slot_indication_scf_t *nr_slot_resp = CALLOC(1, sizeof(*nr_slot_resp)); + nr_slot_resp->header.message_id = 0x8F; + nr_slot_resp->sfn = frame; + nr_slot_resp->slot = slot; + int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &nr_slot_resp->header); + if (retval != 0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } + return retval; +} +#endif diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p5.h b/nfapi/oai_integration/aerial/fapi_vnf_p5.h new file mode 100644 index 0000000000..9d3fb6d170 --- /dev/null +++ b/nfapi/oai_integration/aerial/fapi_vnf_p5.h @@ -0,0 +1,75 @@ +/* +* 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 + */ + +/*! \file fapi/oai-integration/fapi_vnf_p5.h +* \brief Header file for fapi_vnf_p5.c +* \author Ruben S. Silva +* \date 2023 +* \version 0.1 +* \company OpenAirInterface Software Alliance +* \email: contact@openairinterface.org, rsilva@allbesmart.pt +* \note +* \warning + */ +#ifdef ENABLE_AERIAL +#ifndef OPENAIRINTERFACE_FAPI_VNF_P5_H +#define OPENAIRINTERFACE_FAPI_VNF_P5_H +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nfapi_nr_interface_scf.h" +#include "nfapi_vnf_interface.h" +#include "nfapi_vnf.h" +#include "nfapi.h" +#include "nfapi/oai_integration/vendor_ext.h" +#include "fapi_nvIPC.h" + +#include "PHY/defs_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" + +#include "common/ran_context.h" +#include "openair2/PHY_INTERFACE/queue_t.h" +#include "gnb_ind_vars.h" +#include "nfapi/open-nFAPI/vnf/inc/vnf.h" + +void aerial_configure_nr_fapi_vnf(); +int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx); +int oai_fapi_send_end_request(int cell_id, uint32_t frame, uint32_t slot); +uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config); +uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config); +int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx); +int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config); +int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config); + +int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req); +int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req); +int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); +int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); +#endif //OPENAIRINTERFACE_FAPI_VNF_P5_H +#endif diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.c b/nfapi/oai_integration/aerial/fapi_vnf_p7.c new file mode 100644 index 0000000000..3e54b75375 --- /dev/null +++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.c @@ -0,0 +1,1315 @@ +/* +* 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 + */ + +/*! \file fapi/oai-integration/fapi_vnf_p7.c +* \brief OAI FAPI VNF P7 message handler procedures +* \author Ruben S. Silva +* \date 2023 +* \version 0.1 +* \company OpenAirInterface Software Alliance +* \email: contact@openairinterface.org, rsilva@allbesmart.pt +* \note +* \warning + */ +#ifdef ENABLE_AERIAL +#include "fapi_vnf_p7.h" +#include "nfapi/open-nFAPI/nfapi/src/nfapi_p7.c" + +extern RAN_CONTEXT_t RC; +extern UL_RCC_IND_t UL_RCC_INFO; +extern int single_thread_flag; +extern uint16_t sf_ahead; + +int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) +{ + struct timespec curr_t; + clock_gettime(CLOCK_MONOTONIC, &curr_t); + // NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME + // %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec); + gNB_L1_proc_t *proc = &gNB->proc; + gNB_L1_rxtx_proc_t *L1_proc = (slot & 1) ? &proc->L1_proc : &proc->L1_proc_tx; + + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); + // int i; + struct timespec wait; + clock_gettime(CLOCK_REALTIME, &wait); + wait.tv_sec = 0; + wait.tv_nsec += 5000L; + // wait.tv_nsec = 0; + // wake up TX for subframe n+sf_ahead + // lock the TX mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&L1_proc->mutex, &wait) != 0) { + LOG_E(PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx & 1, L1_proc->instance_cnt); + exit_fun("error locking mutex_rxtx"); + return (-1); + } + + { + static uint16_t old_slot = 0; + static uint16_t old_sfn = 0; + proc->slot_rx = old_slot; + proc->frame_rx = old_sfn; + // Try to be 1 frame back + old_slot = slot; + old_sfn = sfn; + // NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx); + if (old_slot == 0 && old_sfn % 100 == 0) + LOG_W(PHY, + "[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", + sfn, + slot, + old_sfn, + old_slot, + proc->frame_rx, + proc->slot_rx); + } + + ++L1_proc->instance_cnt; + // LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, + // proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx); + // We have just received and processed the common part of a subframe, say n. + // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired + // transmitted timestamp of the next TX slot (first). + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti, + // and proc->subframe_tx = proc->subframe_rx+sf_ahead + L1_proc->timestamp_tx = proc->timestamp_rx + (gNB->if_inst->sl_ahead * fp->samples_per_subframe); + L1_proc->frame_rx = proc->frame_rx; + L1_proc->slot_rx = proc->slot_rx; + L1_proc->frame_tx = (L1_proc->slot_rx > (19 - gNB->if_inst->sl_ahead)) ? (L1_proc->frame_rx + 1) & 1023 : L1_proc->frame_rx; + L1_proc->slot_tx = (L1_proc->slot_rx + gNB->if_inst->sl_ahead) % 20; + + // LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, + // L1_proc->frame_rx, L1_proc->slot_rx); NFAPI_TRACE(NFAPI_TRACE_INFO, "\nEntering wake_gNB_rxtx sfn %d slot + // %d\n",L1_proc->frame_rx,L1_proc->slot_rx); + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc->cond) != 0) { + LOG_E(PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); + exit_fun("ERROR pthread_clond_signal"); + return (-1); + } + + // LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__); + pthread_mutex_unlock(&L1_proc->mutex); + // LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__); + return (0); +} + +int aerialwake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) +{ + L1_proc_t *proc = &eNB->proc; + L1_rxtx_proc_t *L1_proc = (sf & 1) ? &proc->L1_proc : &proc->L1_proc_tx; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); + // int i; + struct timespec wait; + wait.tv_sec = 0; + wait.tv_nsec = 5000000L; + + // wake up TX for subframe n+sf_ahead + // lock the TX mutex and make sure the thread is ready + // if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { + // LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt ); + // exit_fun( "error locking mutex_rxtx" ); + // return(-1); + //} + + { + static uint16_t old_sf = 0; + static uint16_t old_sfn = 0; + proc->subframe_rx = old_sf; + proc->frame_rx = old_sfn; + // Try to be 1 frame back + old_sf = sf; + old_sfn = sfn; + + if (old_sf == 0 && old_sfn % 100 == 0) + LOG_D(PHY, "[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx); + } + // wake up TX for subframe n+sf_ahead + // lock the TX mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&L1_proc->mutex, &wait) != 0) { + LOG_E(PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx & 1, L1_proc->instance_cnt); + // exit_fun( "error locking mutex_rxtx" ); + return (-1); + } + static int busy_log_cnt = 0; + if (L1_proc->instance_cnt < 0) { + ++L1_proc->instance_cnt; + if (busy_log_cnt != 0) { + LOG_E(MAC, + "RCC singal to rxtx frame %d subframe %d busy end %d (frame %d subframe %d)\n", + L1_proc->frame_rx, + L1_proc->subframe_rx, + busy_log_cnt, + proc->frame_rx, + proc->subframe_rx); + } + busy_log_cnt = 0; + } else { + if (busy_log_cnt == 0) { + LOG_E(MAC, + "RCC singal to rxtx frame %d subframe %d busy %d (frame %d subframe %d)\n", + L1_proc->frame_rx, + L1_proc->subframe_rx, + L1_proc->instance_cnt, + proc->frame_rx, + proc->subframe_rx); + } + pthread_mutex_unlock(&L1_proc->mutex); + busy_log_cnt++; + return (0); + } + + pthread_mutex_unlock(&L1_proc->mutex); + + // LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, + // proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx); + // We have just received and processed the common part of a subframe, say n. + // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired + // transmitted timestamp of the next TX slot (first). + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti, + // and proc->subframe_tx = proc->subframe_rx+sf_ahead + L1_proc->timestamp_tx = proc->timestamp_rx + (sf_ahead * fp->samples_per_tti); + L1_proc->frame_rx = proc->frame_rx; + L1_proc->subframe_rx = proc->subframe_rx; + L1_proc->frame_tx = (L1_proc->subframe_rx > (9 - sf_ahead)) ? (L1_proc->frame_rx + 1) & 1023 : L1_proc->frame_rx; + L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead) % 10; + + // LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] L1_proc[instance_cnt_rxtx:%d rx:%d%d] About to wake rxtx thread\n\n", sfn, sf, + // proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx, L1_proc->frame_rx, L1_proc->subframe_rx); + + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc->cond) != 0) { + LOG_E(PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); + exit_fun("ERROR pthread_cond_signal"); + return (-1); + } + + return (0); +} + +extern pthread_cond_t nfapi_sync_cond; +extern pthread_mutex_t nfapi_sync_mutex; +extern int nfapi_sync_var; + +int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) +{ + // NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); + + if (sync == 1 && nfapi_sync_var != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Signal to OAI main code that it can go\n"); + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var = 0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } + + return (0); +} + +int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) +{ + static uint8_t first_time = 1; + + if (first_time) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot)); + first_time = 0; + } + + if (RC.gNB && RC.gNB[0]->configured) { + // uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); + // uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); + LOG_D(PHY, "[VNF] slot indication sfn:%d slot:%d\n", sfn, slot); + aerial_wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent + } else { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB); + + if (RC.gNB) + NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured); + } + + return 0; +} + +int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind) +{ + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + LOG_D(MAC, + "%s() NFAPI SFN/SF:%d number_of_harqs:%u\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), + ind->harq_indication_body.number_of_harqs); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex) == 0, "Mutex lock failed"); + if (NFAPI_MODE == NFAPI_MODE_VNF) { + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + + UL_RCC_INFO.harq_ind[index] = *ind; + + assert(ind->harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); + if (ind->harq_indication_body.number_of_harqs > 0) { + UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list = + malloc(sizeof(nfapi_harq_indication_pdu_t) * NFAPI_HARQ_IND_MAX_PDU); + } + for (int i = 0; i < ind->harq_indication_body.number_of_harqs; i++) { + memcpy(&UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list[i], + &ind->harq_indication_body.harq_pdu_list[i], + sizeof(nfapi_harq_indication_pdu_t)); + } + } else { + eNB->UL_INFO.harq_ind = *ind; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + + assert(ind->harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); + for (int i = 0; i < ind->harq_indication_body.number_of_harqs; i++) { + memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], + &ind->harq_indication_body.harq_pdu_list[i], + sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i])); + } + } + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex) == 0, "Mutex unlock failed"); + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_harq_ind(p7_vnf->mac, ind); + return 1; +} + +int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) +{ + if (NFAPI_MODE == NFAPI_MODE_AERIAL) { + nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind)); + crc_ind->header.message_id = ind->header.message_id; + crc_ind->number_crcs = ind->number_crcs; + crc_ind->sfn = ind->sfn; + crc_ind->slot = ind->slot; + if (ind->number_crcs > 0) { + crc_ind->crc_list = CALLOC(NFAPI_NR_CRC_IND_MAX_PDU, sizeof(nfapi_nr_crc_t)); + AssertFatal(crc_ind->crc_list != NULL, "Memory not allocated for crc_ind->crc_list in phy_nr_crc_indication."); + } + for (int j = 0; j < ind->number_crcs; j++) { + crc_ind->crc_list[j].handle = ind->crc_list[j].handle; + crc_ind->crc_list[j].rnti = ind->crc_list[j].rnti; + crc_ind->crc_list[j].harq_id = ind->crc_list[j].harq_id; + crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status; + crc_ind->crc_list[j].num_cb = ind->crc_list[j].num_cb; + crc_ind->crc_list[j].cb_crc_status = ind->crc_list[j].cb_crc_status; + crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi; + crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance; + crc_ind->crc_list[j].rssi = ind->crc_list[j].rssi; + if (crc_ind->crc_list[j].tb_crc_status != 0) { + LOG_D(NR_MAC, + "Received crc_ind.harq_id %d status %d for index %d SFN SLot %u %u with rnti %04x\n", + crc_ind->crc_list[j].harq_id, + crc_ind->crc_list[j].tb_crc_status, + j, + crc_ind->sfn, + crc_ind->slot, + crc_ind->crc_list[j].rnti); + } + } + if (!put_queue(&gnb_crc_ind_queue, crc_ind)) { + LOG_E(NR_MAC, "Put_queue failed for crc_ind\n"); + free(crc_ind->crc_list); + free(crc_ind); + } + } else { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode()); + } + return 1; +} + +int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) +{ + if (NFAPI_MODE == NFAPI_MODE_AERIAL) { + nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind)); + rx_ind->header.message_id = ind->header.message_id; + rx_ind->sfn = ind->sfn; + rx_ind->slot = ind->slot; + rx_ind->number_of_pdus = ind->number_of_pdus; + + if (ind->number_of_pdus > 0) { + rx_ind->pdu_list = CALLOC(NFAPI_NR_RX_DATA_IND_MAX_PDU, sizeof(nfapi_nr_rx_data_pdu_t)); + AssertFatal(rx_ind->pdu_list != NULL, "Memory not allocated for rx_ind->pdu_list in phy_nr_rx_data_indication."); + } + for (int j = 0; j < ind->number_of_pdus; j++) { + rx_ind->pdu_list[j].handle = ind->pdu_list[j].handle; + rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti; + rx_ind->pdu_list[j].harq_id = ind->pdu_list[j].harq_id; + rx_ind->pdu_list[j].pdu_length = ind->pdu_list[j].pdu_length; + rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi; + rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance; + rx_ind->pdu_list[j].rssi = ind->pdu_list[j].rssi; + rx_ind->pdu_list[j].pdu = ind->pdu_list[j].pdu; + LOG_D(NR_MAC, + "(%d.%d) Handle %d for index %d, RNTI, %04x, HARQID %d\n", + ind->sfn, + ind->slot, + ind->pdu_list[j].handle, + j, + ind->pdu_list[j].rnti, + ind->pdu_list[j].harq_id); + } + if (!put_queue(&gnb_rx_ind_queue, rx_ind)) { + LOG_E(NR_MAC, "Put_queue failed for rx_ind\n"); + free(rx_ind->pdu_list); + free(rx_ind); + } + } else { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode()); + } + return 1; +} + +int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) +{ + if (NFAPI_MODE == NFAPI_MODE_AERIAL) { + nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); + rach_ind->header.message_id = ind->header.message_id; + rach_ind->sfn = ind->sfn; + rach_ind->slot = ind->slot; + rach_ind->number_of_pdus = ind->number_of_pdus; + rach_ind->pdu_list = CALLOC(rach_ind->number_of_pdus, sizeof(*rach_ind->pdu_list)); + AssertFatal(rach_ind->pdu_list != NULL, "Memory not allocated for rach_ind->pdu_list in phy_nr_rach_indication."); + for (int i = 0; i < ind->number_of_pdus; i++) { + rach_ind->pdu_list[i].phy_cell_id = ind->pdu_list[i].phy_cell_id; + rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index; + rach_ind->pdu_list[i].slot_index = ind->pdu_list[i].slot_index; + rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index; + rach_ind->pdu_list[i].avg_rssi = ind->pdu_list[i].avg_rssi; + rach_ind->pdu_list[i].avg_snr = ind->pdu_list[i].avg_snr; + rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble; + rach_ind->pdu_list[i].preamble_list = CALLOC(ind->pdu_list[i].num_preamble, sizeof(nfapi_nr_prach_indication_preamble_t)); + AssertFatal(rach_ind->pdu_list[i].preamble_list != NULL, + "Memory not allocated for rach_ind->pdu_list[i].preamble_list in phy_nr_rach_indication."); + for (int j = 0; j < ind->pdu_list[i].num_preamble; j++) { + rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index; + rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance; + rach_ind->pdu_list[i].preamble_list[j].preamble_pwr = ind->pdu_list[i].preamble_list[j].preamble_pwr; + } + } + if (!put_queue(&gnb_rach_ind_queue, rach_ind)) { + LOG_E(NR_MAC, "Put_queue failed for rach_ind\n"); + for (int i = 0; i < ind->number_of_pdus; i++) { + free(rach_ind->pdu_list[i].preamble_list); + } + free(rach_ind->pdu_list); + free(rach_ind); + } else { + LOG_I(NR_MAC, "RACH.indication put_queue successfull\n"); + } + } else { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode()); + } + return 1; +} + +int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) +{ + if (NFAPI_MODE == NFAPI_MODE_AERIAL) { + nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind)); + AssertFatal(uci_ind != NULL, "Memory not allocated for uci_ind in phy_nr_uci_indication."); + *uci_ind = *ind; + + uci_ind->uci_list = CALLOC(NFAPI_NR_UCI_IND_MAX_PDU, sizeof(nfapi_nr_uci_t)); + AssertFatal(uci_ind->uci_list != NULL, "Memory not allocated for uci_ind->uci_list in phy_nr_uci_indication."); + for (int i = 0; i < ind->num_ucis; i++) { + uci_ind->uci_list[i] = ind->uci_list[i]; + + switch (uci_ind->uci_list[i].pdu_type) { + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__); + break; + + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { +// nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1; +// nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1; +// if (ind_pdu->sr) { +// uci_ind_pdu->sr = CALLOC(1, sizeof(*uci_ind_pdu->sr)); +// AssertFatal(uci_ind_pdu->sr != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); +// *uci_ind_pdu->sr = *ind_pdu->sr; +// } +// if (ind_pdu->harq) { +// uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq)); +// AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); +// +// *uci_ind_pdu->harq = *ind_pdu->harq; +// uci_ind_pdu->harq->harq_list = CALLOC(uci_ind_pdu->harq->num_harq, sizeof(*uci_ind_pdu->harq->harq_list)); +// AssertFatal(uci_ind_pdu->harq->harq_list != NULL, +// "Memory not allocated for uci_ind_pdu->harq->harq_list in phy_nr_uci_indication."); +// for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++) +// uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value; +// } + break; + } + + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4; + *uci_ind_pdu = *ind_pdu; + if (ind_pdu->harq.harq_payload) { + uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload)); + AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, + "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication."); + *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload; + } + if (ind_pdu->sr.sr_payload) { + uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload)); + AssertFatal(uci_ind_pdu->sr.sr_payload != NULL, + "Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication."); + *uci_ind_pdu->sr.sr_payload = *ind_pdu->sr.sr_payload; + } + if (ind_pdu->csi_part1.csi_part1_payload) { + uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload)); + AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, + "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication."); + *uci_ind_pdu->csi_part1.csi_part1_payload = *ind_pdu->csi_part1.csi_part1_payload; + } + if (ind_pdu->csi_part2.csi_part2_payload) { + uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload)); + AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, + "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication."); + *uci_ind_pdu->csi_part2.csi_part2_payload = *ind_pdu->csi_part2.csi_part2_payload; + } + break; + } + } + } + + if (!put_queue(&gnb_uci_ind_queue, uci_ind)) { + LOG_E(NR_MAC, "Put_queue failed for uci_ind\n"); + for (int i = 0; i < ind->num_ucis; i++) { + if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) { +// if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) { +// free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list); +// uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; +// free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq); +// uci_ind->uci_list[i].pucch_pdu_format_0_1.harq = NULL; +// } +// if (uci_ind->uci_list[i].pucch_pdu_format_0_1.sr) { +// free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr); +// uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL; +// } + } + if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) { + free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload); + free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload); + free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload); + } + } + free(uci_ind->uci_list); + uci_ind->uci_list = NULL; + free(uci_ind); + uci_ind = NULL; + } + } else { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode()); + } + return 1; +} + +int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_srs_ind(p7_vnf->mac, ind); + return 1; +} + +int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind) +{ + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex) == 0, "Mutex lock failed"); + if (NFAPI_MODE == NFAPI_MODE_VNF) { + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + + UL_RCC_INFO.sr_ind[index] = *ind; + LOG_D(MAC, + "%s() UL_INFO[%d].sr_ind.sr_indication_body.number_of_srs:%d\n", + __FUNCTION__, + index, + eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); + if (ind->sr_indication_body.number_of_srs > 0) { + assert(ind->sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); + UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t) * NFAPI_SR_IND_MAX_PDU); + } + + assert(ind->sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); + for (int i = 0; i < ind->sr_indication_body.number_of_srs; i++) { + nfapi_sr_indication_pdu_t *dest_pdu = &UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list[i]; + nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; + + LOG_D(MAC, + "SR_IND[PDU:%d %d][rnti:%x cqi:%d channel:%d]\n", + index, + i, + src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, + src_pdu->ul_cqi_information.channel); + + memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); + } + } else { + nfapi_sr_indication_t *dest_ind = &eNB->UL_INFO.sr_ind; + nfapi_sr_indication_pdu_t *dest_pdu_list = eNB->sr_pdu_list; + *dest_ind = *ind; + dest_ind->sr_indication_body.sr_pdu_list = dest_pdu_list; + LOG_D(MAC, + "%s() eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs:%d\n", + __FUNCTION__, + eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); + + assert(eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); + for (int i = 0; i < eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs; i++) { + nfapi_sr_indication_pdu_t *dest_pdu = &dest_ind->sr_indication_body.sr_pdu_list[i]; + nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; + LOG_D(MAC, + "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", + i, + src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, + src_pdu->ul_cqi_information.channel); + memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); + } + } + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex) == 0, "Mutex unlock failed"); + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_sr_ind(p7_vnf->mac, ind); + return 1; +} + +static bool aerial_is_ue_same(uint16_t ue_id_1, uint16_t ue_id_2) +{ + return (ue_id_1 == ue_id_2); +} + +static void aerial_analyze_cqi_pdus_for_duplicates(nfapi_cqi_indication_t *ind) +{ + uint16_t num_cqis = ind->cqi_indication_body.number_of_cqis; + assert(num_cqis <= NFAPI_CQI_IND_MAX_PDU); + for (int i = 0; i < num_cqis; i++) { + nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; + + LOG_I(MAC, + "CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", + i, + src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, + src_pdu->ul_cqi_information.channel); + + for (int j = i + 1; j < num_cqis; j++) { + uint16_t rnti_i = ind->cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti; + uint16_t rnti_j = ind->cqi_indication_body.cqi_pdu_list[j].rx_ue_information.rnti; + if (aerial_is_ue_same(rnti_i, rnti_j)) { + LOG_E(MAC, "Problem, two cqis received from a single UE for rnti %x\n", rnti_i); + // abort(); This will be fixed in merge request which handles multiple CQIs. + } + } + } +} + +int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_cqi_ind(p7_vnf->mac, ind); + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + LOG_D(MAC, + "%s() NFAPI SFN/SF:%d number_of_cqis:%u\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), + ind->cqi_indication_body.number_of_cqis); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex) == 0, "Mutex lock failed"); + if (NFAPI_MODE == NFAPI_MODE_VNF) { + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + + UL_RCC_INFO.cqi_ind[index] = *ind; + assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); + if (ind->cqi_indication_body.number_of_cqis > 0) { + UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list = + malloc(sizeof(nfapi_cqi_indication_pdu_t) * NFAPI_CQI_IND_MAX_PDU); + UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list = + malloc(sizeof(nfapi_cqi_indication_raw_pdu_t) * NFAPI_CQI_IND_MAX_PDU); + } + + aerial_analyze_cqi_pdus_for_duplicates(ind); + + assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); + for (int i = 0; i < ind->cqi_indication_body.number_of_cqis; i++) { + nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; + LOG_D(MAC, + "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", + i, + src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, + src_pdu->ul_cqi_information.channel); + memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list[i], src_pdu, sizeof(nfapi_cqi_indication_pdu_t)); + + memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list[i], + &ind->cqi_indication_body.cqi_raw_pdu_list[i], + sizeof(nfapi_cqi_indication_raw_pdu_t)); + } + } else { + nfapi_cqi_indication_t *dest_ind = &eNB->UL_INFO.cqi_ind; + *dest_ind = *ind; + dest_ind->cqi_indication_body.cqi_pdu_list = ind->cqi_indication_body.cqi_pdu_list; + dest_ind->cqi_indication_body.cqi_raw_pdu_list = ind->cqi_indication_body.cqi_raw_pdu_list; + assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); + for (int i = 0; i < ind->cqi_indication_body.number_of_cqis; i++) { + nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; + LOG_D(MAC, + "CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", + i, + src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, + src_pdu->ul_cqi_information.channel); + memcpy(&dest_ind->cqi_indication_body.cqi_pdu_list[i], src_pdu, sizeof(nfapi_cqi_indication_pdu_t)); + memcpy(&dest_ind->cqi_indication_body.cqi_raw_pdu_list[i], + &ind->cqi_indication_body.cqi_raw_pdu_list[i], + sizeof(nfapi_cqi_indication_raw_pdu_t)); + } + } + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex) == 0, "Mutex unlock failed"); + return 1; +} + +int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_lbt_dl_ind(p7_vnf->mac, ind); + return 1; +} + +int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_nb_harq_ind(p7_vnf->mac, ind); + return 1; +} + +int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + // mac_nrach_ind(p7_vnf->mac, ind); + return 1; +} + + +NR_Sched_Rsp_t g_sched_resp; +void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t* sched_info); +int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); +int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req); +int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t* tx_data_req); +int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t* ul_dci_req); +int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot); + +int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind) +{ + + NR_UL_IND_t ind = {.frame = slot_ind->sfn, .slot = slot_ind->slot, }; + NR_UL_indication(&ind); + // Call into the scheduler (this is hardcoded and should be init properly!) + // memset(sched_resp, 0, sizeof(*sched_resp)); + gNB_dlsch_ulsch_scheduler(0, slot_ind->sfn, slot_ind->slot, &g_sched_resp); + if (NFAPI_MODE == NFAPI_MODE_AERIAL) { +#ifdef ENABLE_AERIAL + bool send_slt_resp = false; + if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) { + oai_fapi_dl_tti_req(&g_sched_resp.DL_req); + send_slt_resp = true; + } + if (g_sched_resp.UL_tti_req.n_pdus > 0) { + oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req); + send_slt_resp = true; + } + if (g_sched_resp.TX_req.Number_of_PDUs > 0) { + oai_fapi_tx_data_req(&g_sched_resp.TX_req); + send_slt_resp = true; + } + if (g_sched_resp.UL_dci_req.numPdus > 0) { + oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req); + send_slt_resp = true; + } + if (send_slt_resp) { + oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot); + } +#endif + } + + return 1; +} + + +int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) +{ + uint8_t vnf_slot_ahead = 0; + uint32_t vnf_sfn_slot = sfnslot_add_slot(ind->sfn, ind->slot, vnf_slot_ahead); + uint16_t vnf_sfn = NFAPI_SFNSLOT2SFN(vnf_sfn_slot); + uint8_t vnf_slot = NFAPI_SFNSLOT2SLOT(vnf_sfn_slot); + LOG_D(MAC, "VNF SFN/Slot %d.%d \n", vnf_sfn, vnf_slot); + // printf( "VNF SFN/Slot %d.%d \n", vnf_sfn, vnf_slot); + trigger_scheduler(ind); + + return 1; +} + +int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) +{ + struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; + + gNB->UL_INFO.srs_ind = *ind; + + if (ind->number_of_pdus > 0) + gNB->UL_INFO.srs_ind.pdu_list = malloc(sizeof(nfapi_nr_srs_indication_pdu_t) * ind->number_of_pdus); + + for (int i = 0; i < ind->number_of_pdus; i++) { + memcpy(&gNB->UL_INFO.srs_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0])); + + LOG_D(MAC, + "%s() NFAPI SFN/Slot:%d.%d SRS_IND:number_of_pdus:%d UL_INFO:pdus:%d\n", + __FUNCTION__, + ind->sfn, + ind->slot, + ind->number_of_pdus, + gNB->UL_INFO.srs_ind.number_of_pdus); + } + + + return 1; +} + +void *aerial_vnf_allocate(size_t size) +{ + // return (void*)memory_pool::allocate(size); + return (void *)malloc(size); +} + +void aerial_vnf_deallocate(void *ptr) +{ + // memory_pool::deallocate((uint8_t*)ptr); + free(ptr); +} + +int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg) +{ + if (msg->message_id == P7_VENDOR_EXT_IND) { + // vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; + // NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] vendor_ext (error_code:%d)\n", ind->error_code); + } else { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", msg->message_id); + } + + return 0; +} + +int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, + uint8_t **ppReadPackedMessage, + uint8_t *end, + nfapi_p7_codec_config_t *config) +{ + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if (header->message_id == P7_VENDOR_EXT_IND) { + vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header); + + if (!pull16(ppReadPackedMessage, &req->error_code, end)) + return 0; + } + + return 1; +} + +int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, + uint8_t **ppWritePackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config) +{ + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if (header->message_id == P7_VENDOR_EXT_REQ) { + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header); + + if (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} + +int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, + uint8_t **ppReadPackedMessage, + uint8_t *end, + void **ve, + nfapi_p7_codec_config_t *codec) +{ + (void)tl; + (void)ppReadPackedMessage; + (void)ve; + return -1; +} + +int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec) +{ + // NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); + nfapi_tl_t *tlv = (nfapi_tl_t *)ve; + + switch (tlv->tag) { + case VENDOR_EXT_TLV_1_TAG: { + // NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); + vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)tlv; + + if (!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + + return 1; + } break; + + default: + return -1; + break; + } +} + +nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) +{ + if (message_id == P7_VENDOR_EXT_IND) { + *msg_size = sizeof(vendor_ext_p7_ind); + return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind)); + } + + return 0; +} + +void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) +{ + free(header); +} + +uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_nr_slot_indication_scf_t *msg, + nfapi_p7_codec_config_t *config) +{ + return unpack_nr_slot_indication(ppReadPackedMsg, end, msg, config); +} + +static uint8_t aerial_unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config) +{ + if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end) + && pull8(ppReadPackedMsg, &value->harq_id, end) && + // For Aerial, RX_DATA.indication PDULength is changed to 32 bit field + pull32(ppReadPackedMsg, &value->pdu_length, end) && pull8(ppReadPackedMsg, &value->ul_cqi, end) + && pull16(ppReadPackedMsg, &value->timing_advance, end) && pull16(ppReadPackedMsg, &value->rssi, end))) { + return 0; + } + + // Allocate space for the pdu to be unpacked later + uint32_t length = value->pdu_length; + value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * length, config); + + return 1; +} +uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + uint8_t **pDataMsg, + uint8_t *data_end, + nfapi_nr_rx_data_indication_t *msg, + nfapi_p7_codec_config_t *config) +{ + // For Aerial unpacking, the PDU data is packed in pDataMsg, and we read it after unpacking the PDU headers + + nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg; + // Unpack SFN, slot, nPDU + if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end) + && pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) { + return 0; + } + // Allocate the PDU list for number of PDUs + if (pNfapiMsg->number_of_pdus > 0) { + pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config); + } + // For each PDU, unpack its header + for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) { + if (!aerial_unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config)) + return 0; + } + // After unpacking the PDU headers, unpack the PDU data from the separate buffer + for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) { + if(!pullarray8(pDataMsg, + pNfapiMsg->pdu_list[i].pdu, + pNfapiMsg->pdu_list[i].pdu_length, + pNfapiMsg->pdu_list[i].pdu_length, + data_end)){ + return 0; + } + } + + return 1; +} + +uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_nr_crc_indication_t *msg, + nfapi_p7_codec_config_t *config) +{ + return unpack_nr_crc_indication(ppReadPackedMsg, end, msg, config); +} + +uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) +{ + return unpack_nr_uci_indication(ppReadPackedMsg, end, msg, config); +} + +uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) +{ + return unpack_nr_srs_indication(ppReadPackedMsg, end, msg, config); +} + +uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_nr_rach_indication_t *msg, + nfapi_p7_codec_config_t *config) +{ + return unpack_nr_rach_indication(ppReadPackedMsg, end, msg, config); +} + +static int32_t aerial_pack_tx_data_request(void *pMessageBuf, + void *pPackedBuf, + void *pDataBuf, + uint32_t packedBufLen, + uint32_t dataBufLen, + nfapi_p7_codec_config_t *config, + uint32_t *data_len) +{ + nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *end = pPackedBuf + packedBufLen; + uint8_t *data_end = pDataBuf + dataBufLen; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pDataPackedMessage = pDataBuf; + uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint8_t *pPacketBodyField = &pWritePackedMessage[8]; + uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8]; + uint8_t *pPackedDataField = &pDataPackedMessage[0]; + uint8_t *pPackedDataFieldStart = &pDataPackedMessage[0]; + + if (pMessageBuf == NULL || pPackedBuf == NULL) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); + return -1; + } + + // PHY API message header + // Number of messages [0] + // Opaque handle [1] + // PHY API Message structure + // Message type ID [2,3] + // Message Length [4,5,6,7] + // Message Body [8,...] + if (!(push8(1, &pWritePackedMessage, pPackMessageEnd) && push8(0, &pWritePackedMessage, pPackMessageEnd) + && push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd))) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n"); + return -1; + } + + uint8_t **ppWriteBody = &pPacketBodyField; + uint8_t **ppWriteData = &pPackedDataField; + nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)pMessageHeader; + + if (!(push16(pNfapiMsg->SFN, ppWriteBody, end) && push16(pNfapiMsg->Slot, ppWriteBody, end) + && push16(pNfapiMsg->Number_of_PDUs, ppWriteBody, end))) { + return 0; + } + + for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) { + nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)&pNfapiMsg->pdu_list[i]; + // recalculate PDU_Length for Aerial (leave only the size occupied in the payload buffer afterward) + // assuming there is only 1 TLV present + value->PDU_length = value->TLVs[0].length; + if (!(push32(value->PDU_length, ppWriteBody, end) + && // cuBB expects TX_DATA.request PDUSize to be 32 bit + push16(value->PDU_index, ppWriteBody, end) && push32(value->num_TLV, ppWriteBody, end))) { + return 0; + } + uint16_t k = 0; + uint16_t total_number_of_tlvs = value->num_TLV; + + for (; k < total_number_of_tlvs; ++k) { + // For Aerial, the TLV tag is always 2 + if (!(push16(/*value->TLVs[k].tag*/ 2, ppWriteBody, end) && push16(/*value->TLVs[k].length*/ 4, ppWriteBody, end))) { + return 0; + } + // value + if (!push32(0, ppWriteBody, end)) { + return 0; + } + } + } + + //Actual payloads are packed in a separate buffer + for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) { + nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)&pNfapiMsg->pdu_list[i]; + + uint16_t k = 0; + uint16_t total_number_of_tlvs = value->num_TLV; + + for (; k < total_number_of_tlvs; ++k) { + if (value->TLVs[k].length > 0) { + if (value->TLVs[k].length % 4 != 0) { + if (!pusharray32(value->TLVs[k].value.direct, 16384, ((value->TLVs[k].length + 3) / 4) - 1, ppWriteData, data_end)) { + return 0; + } + int bytesToAdd = 4 - (4 - (value->TLVs[k].length % 4)) % 4; + if (bytesToAdd != 4) { + for (int j = 0; j < bytesToAdd; j++) { + uint8_t toPush = (uint8_t)(value->TLVs[k].value.direct[((value->TLVs[k].length + 3) / 4) - 1] >> (j * 8)); + if (!push8(toPush, ppWriteData, data_end)) { + return 0; + } + } + } + } else { + // no padding needed + if (!pusharray32(value->TLVs[k].value.direct, 16384, ((value->TLVs[k].length + 3) / 4), ppWriteData, data_end)) { + return 0; + } + } + } else { + LOG_E(NR_MAC,"value->TLVs[i].length was 0! (%d.%d) \n", pNfapiMsg->SFN, pNfapiMsg->Slot); + } + } + } + + + // calculate data_len + uintptr_t dataHead = (uintptr_t)pPackedDataFieldStart; + uintptr_t dataEnd = (uintptr_t)pPackedDataField; + data_len[0] = dataEnd - dataHead; + + // check for a valid message length + uintptr_t msgHead = (uintptr_t)pPacketBodyFieldStart; + uintptr_t msgEnd = (uintptr_t)pPacketBodyField; + uint32_t packedMsgLen = msgEnd - msgHead; + uint16_t packedMsgLen16; + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return 0; + } else { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + pMessageHeader->message_length = packedMsgLen16; + + // Update the message length in the header + if (!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd)) + return 0; + + if (1) { + // quick test + if (pMessageHeader->message_length != packedMsgLen) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, + "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", + packedMsgLen, + pMessageHeader->message_length, + pMessageHeader->message_id); + } + } + + return (packedMsgLen16); +} + +int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config) +{ + nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *end = pPackedBuf + packedBufLen; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint8_t *pPacketBodyField = &pWritePackedMessage[8]; + uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8]; + + if (pMessageBuf == NULL || pPackedBuf == NULL) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); + return -1; + } + + // PHY API message header + // Number of messages [0] + // Opaque handle [1] + // PHY API Message structure + // Message type ID [2,3] + // Message Length [4,5,6,7] + // Message Body [8,...] + if (!(push8(1, &pWritePackedMessage, pPackMessageEnd) && push8(0, &pWritePackedMessage, pPackMessageEnd) + && push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd))) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n"); + return -1; + } + + // look for the specific message + uint8_t result = 0; + switch (pMessageHeader->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + result = pack_dl_tti_request(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + result = pack_ul_tti_request(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + // TX_DATA.request already handled by aerial_pack_tx_data_request + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + result = pack_ul_dci_request(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_UE_RELEASE_REQUEST: + result = pack_ue_release_request(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + result = pack_ue_release_response(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: + result = pack_nr_slot_indication(pMessageHeader, &pPacketBodyField, end, config); + + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: + result = pack_nr_rx_data_indication(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + result = pack_nr_crc_indication(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: + result = pack_nr_uci_indication(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: + result = pack_nr_srs_indication(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: + result = pack_nr_rach_indication(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + result = pack_nr_dl_node_sync(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + result = pack_nr_ul_node_sync(pMessageHeader, &pPacketBodyField, end, config); + break; + + case NFAPI_TIMING_INFO: + result = pack_nr_timing_info(pMessageHeader, &pPacketBodyField, end, config); + break; + + case 0x8f: + result = pack_nr_slot_indication(pMessageHeader, &pPacketBodyField, end, config); + break; + + default: { + if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) { + if (config && config->pack_p7_vendor_extension) { + result = (config->pack_p7_vendor_extension)(pMessageHeader, &pPacketBodyField, end, config); + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, + "%s VE NFAPI message ID %d. No ve ecoder provided\n", + __FUNCTION__, + pMessageHeader->message_id); + } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + } break; + } + + if (result == 0) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n"); + return -1; + } + + // check for a valid message length + uintptr_t msgHead = (uintptr_t)pPacketBodyFieldStart; + uintptr_t msgEnd = (uintptr_t)pPacketBodyField; + uint32_t packedMsgLen = msgEnd - msgHead; + uint16_t packedMsgLen16; + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } else { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + pMessageHeader->message_length = packedMsgLen16; + + // Update the message length in the header + if (!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd)) + return -1; + + if (1) { + // quick test + if (pMessageHeader->message_length != packedMsgLen) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, + "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", + packedMsgLen, + pMessageHeader->message_length, + pMessageHeader->message_id); + } + } + + return (packedMsgLen16); +} + +int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header) +{ + uint8_t FAPI_buffer[1024 * 64]; + // Check if TX_DATA request, if true, need to pack to data_buf + if (header->message_id + == NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST) { + uint8_t FAPI_data_buffer[1024 * 64]; + uint32_t data_len = 0; + int32_t len_FAPI = aerial_pack_tx_data_request(header, + FAPI_buffer, + FAPI_data_buffer, + sizeof(FAPI_buffer), + sizeof(FAPI_data_buffer), + &vnf_p7->_public.codec_config, + &data_len); + if (len_FAPI <=0) { + LOG_E(NFAPI_VNF,"Problem packing TX_DATA_request\n"); + return len_FAPI; + } + else + return aerial_send_P7_msg_with_data(FAPI_buffer, len_FAPI, FAPI_data_buffer, data_len, header); + } else { + // Create and send FAPI P7 message + int len_FAPI = fapi_nr_p7_message_pack(header, FAPI_buffer, sizeof(FAPI_buffer), &vnf_p7->_public.codec_config); + return aerial_send_P7_msg(FAPI_buffer, len_FAPI, header); + } +} +#endif diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.h b/nfapi/oai_integration/aerial/fapi_vnf_p7.h new file mode 100644 index 0000000000..a09ca94aa9 --- /dev/null +++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.h @@ -0,0 +1,243 @@ +/* +* 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 + */ + +/*! \file fapi/oai-integration/fapi_vnf_p7.h +* \brief Header file for fapi_vnf_p7.c +* \author Ruben S. Silva +* \date 2023 +* \version 0.1 +* \company OpenAirInterface Software Alliance +* \email: contact@openairinterface.org, rsilva@allbesmart.pt +* \note +* \warning + */ + +#ifdef ENABLE_AERIAL +#ifndef OPENAIRINTERFACE_FAPI_VNF_P7_H +#define OPENAIRINTERFACE_FAPI_VNF_P7_H + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nfapi_nr_interface_scf.h" +#include "nfapi_vnf_interface.h" +#include "nfapi_vnf.h" +#include "nfapi.h" +#include "nfapi/oai_integration/vendor_ext.h" +#include "fapi_nvIPC.h" + +#include "PHY/defs_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include "lte-softmodem.h" + +#include "common/ran_context.h" +#include "openair2/PHY_INTERFACE/queue_t.h" +#include "gnb_ind_vars.h" +#include "nfapi/open-nFAPI/vnf/inc/vnf.h" +#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h" +typedef struct { + uint8_t enabled; + uint32_t rx_port; + uint32_t tx_port; + char tx_addr[80]; +} udp_data; + +typedef struct { + uint16_t index; + uint16_t id; + uint8_t rfs[2]; + uint8_t excluded_rfs[2]; + + udp_data udp; + + char local_addr[80]; + int local_port; + + char *remote_addr; + int remote_port; + + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; + + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; + + uint8_t first_subframe_ind; + + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; + +} phy_info; + +typedef struct { + uint16_t index; + uint16_t band; + int16_t max_transmit_power; + int16_t min_transmit_power; + uint8_t num_antennas_supported; + uint32_t min_downlink_frequency; + uint32_t max_downlink_frequency; + uint32_t max_uplink_frequency; + uint32_t min_uplink_frequency; +} rf_info; + +typedef struct { + int release; + phy_info phys[2]; + rf_info rfs[2]; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; + +} pnf_info; + +typedef struct mac mac_t; +typedef struct mac { + void *user_data; + + void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req); + void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req); + void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req); + void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req); +} mac_t; + +typedef struct { + int local_port; + char local_addr[80]; + + unsigned timing_window; + unsigned periodic_timing_enabled; + unsigned aperiodic_timing_enabled; + unsigned periodic_timing_period; + + // This is not really the right place if we have multiple PHY, + // should be part of the phy struct + udp_data udp; + + uint8_t thread_started; + + nfapi_vnf_p7_config_t *config; + + mac_t *mac; + +} vnf_p7_info; + +typedef struct { + uint8_t wireshark_test_mode; + pnf_info pnfs[2]; + vnf_p7_info p7_vnfs[2]; + +} vnf_info; + +int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot); +int aerial_wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf); +int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync); +int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot); +int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind); +int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind); +int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind); +int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind); +int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind); +int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind); +int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind); +int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind); +int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind); +int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind); +int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind); +int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind); +int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind); +void *aerial_vnf_allocate(size_t size); +void aerial_vnf_deallocate(void *ptr); +int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg); +int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, + uint8_t **ppReadPackedMessage, + uint8_t *end, + nfapi_p7_codec_config_t *config); +int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, + uint8_t **ppWritePackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config); +int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, + uint8_t **ppReadPackedMessage, + uint8_t *end, + void **ve, + nfapi_p7_codec_config_t *codec); +int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec); +nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size); +void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header); + +uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_nr_slot_indication_scf_t *msg, + nfapi_p7_codec_config_t *config); +uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + uint8_t **pDataMsg, + uint8_t *data_end, + nfapi_nr_rx_data_indication_t *msg, + nfapi_p7_codec_config_t *config); +uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_nr_crc_indication_t *msg, + nfapi_p7_codec_config_t *config); +uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); +uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); +uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_nr_rach_indication_t *msg, + nfapi_p7_codec_config_t *config); + +// int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config); +int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header); +#endif // OPENAIRINTERFACE_FAPI_VNF_P7_H +#endif diff --git a/nfapi/oai_integration/nfapi.c b/nfapi/oai_integration/nfapi.c index 5e71c5e2a4..f60e36fb06 100644 --- a/nfapi/oai_integration/nfapi.c +++ b/nfapi/oai_integration/nfapi.c @@ -27,6 +27,7 @@ static const char *const nfapi_str_mode[] = { "MONOLITHIC", "PNF", "VNF", + "AERIAL", "UE_STUB_PNF", "UE_STUB_OFFNET", "STANDALONE_PNF", @@ -64,7 +65,7 @@ const char *nfapi_get_strmode(void) { } void nfapi_logmode() { - LOG_I(ENB_APP,"nfapi running mode: %s\n",nfapi_get_strmode()); + LOG_I(ENB_APP,"nfapi (%d) running mode: %s\n",nfapi_params.nfapi_mode,nfapi_get_strmode()); } nfapi_mode_t nfapi_getmode(void) { diff --git a/nfapi/oai_integration/vendor_ext.h b/nfapi/oai_integration/vendor_ext.h index 9a377dc27d..fe9117cad0 100644 --- a/nfapi/oai_integration/vendor_ext.h +++ b/nfapi/oai_integration/vendor_ext.h @@ -68,6 +68,7 @@ typedef enum { NFAPI_MONOLITHIC=0, NFAPI_MODE_PNF, NFAPI_MODE_VNF, + NFAPI_MODE_AERIAL, NFAPI_UE_STUB_PNF, NFAPI_UE_STUB_OFFNET, NFAPI_MODE_STANDALONE_PNF, diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index a70e18af11..39674a1edf 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -328,6 +328,7 @@ typedef struct #define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027 #define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028 +#define NFAPI_NR_CONFIG_TDD_TABLE 0x1035 //table 3-21 typedef struct @@ -1467,11 +1468,9 @@ typedef enum { //table 3-58 #define NFAPI_NR_MAX_TX_REQUEST_TLV 2 -typedef struct { - uint16_t PDU_length; // SCF 222.10.02 The total length (in bytes) of the PDU description and PDU data, without the padding bytes. - // (2 bytes PDU_Length + 2 bytes PDU_Index + 4 bytes num_TLV + TLV size ( 2 bytes tag + 2 bytes length + - // value size without padding)) - // TBS + 12 +typedef struct +{ + uint32_t PDU_length; uint16_t PDU_index; uint32_t num_TLV; nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV]; @@ -1505,7 +1504,7 @@ typedef struct uint32_t handle; uint16_t rnti; uint8_t harq_id; - uint16_t pdu_length; + uint32_t pdu_length;// For Aerial, RX_DATA.indication PDULength is changed to 32 bit field uint8_t ul_cqi; uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid uint16_t rssi; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c index 62d79bb511..b4b078cbed 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c @@ -102,8 +102,13 @@ uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) { uint8_t *pOut = *out; if((end - pOut) >= 2) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + pOut[1] = (in & 0xFF00) >> 8; + pOut[0] = (in & 0xFF); +#else pOut[0] = (in & 0xFF00) >> 8; pOut[1] = (in & 0xFF); +#endif (*out)+=2; return 2; } else { @@ -117,8 +122,13 @@ uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) { uint8_t *pOut = *out; if((end - pOut) >= 2) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + pOut[1] = (in & 0xFF00) >> 8; + pOut[0] = (in & 0xFF); +#else pOut[0] = (in & 0xFF00) >> 8; pOut[1] = (in & 0xFF); +#endif (*out)+=2; return 2; } else { @@ -132,10 +142,17 @@ uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) { uint8_t *pOut = *out; if((end - pOut) >= 4) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + pOut[3] = (in & 0xFF000000) >> 24; + pOut[2] = (in & 0xFF0000) >> 16; + pOut[1] = (in & 0xFF00) >> 8; + pOut[0] = (in & 0xFF); +#else pOut[0] = (in & 0xFF000000) >> 24; pOut[1] = (in & 0xFF0000) >> 16; pOut[2] = (in & 0xFF00) >> 8; pOut[3] = (in & 0xFF); +#endif (*out)+=4; return 4; } else { @@ -149,10 +166,17 @@ uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) { uint8_t *pOut = *out; if((end - pOut) >= 4) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + pOut[3] = (in & 0xFF000000) >> 24; + pOut[2] = (in & 0xFF0000) >> 16; + pOut[1] = (in & 0xFF00) >> 8; + pOut[0] = (in & 0xFF); +#else pOut[0] = (in & 0xFF000000) >> 24; pOut[1] = (in & 0xFF0000) >> 16; pOut[2] = (in & 0xFF00) >> 8; pOut[3] = (in & 0xFF); +#endif (*out)+=4; return 4; } else { @@ -194,7 +218,11 @@ uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) { uint8_t *pIn = *in; if((end - pIn) >=2 ) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + *out = ((pIn[1]) << 8) | pIn[0]; +#else *out = ((pIn[0]) << 8) | pIn[1]; +#endif (*in)+=2; return 2; } else { @@ -208,7 +236,11 @@ uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) { uint8_t *pIn = *in; if((end - pIn) >=2 ) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + *out = ((pIn[1]) << 8) | pIn[0]; +#else *out = ((pIn[0]) << 8) | pIn[1]; +#endif (*in)+=2; return 2; } else { @@ -222,7 +254,11 @@ uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) { uint8_t *pIn = *in; if((end - pIn) >= 4) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + *out = ((uint32_t)pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0]; +#else *out = ((uint32_t)pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; +#endif (*in) += 4; return 4; } else { @@ -236,7 +272,11 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) { uint8_t *pIn = *in; if((end - pIn) >=4 ) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + *out = (pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0]; +#else *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; +#endif (*in)+=4; return 4; } else { @@ -839,7 +879,6 @@ int unpack_nr_tlv_list(unpack_tlv_t unpack_fns[], } } } - return 1; } diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c index 661120d961..d1ac9fcdcb 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -35,6 +35,7 @@ #include #include "nfapi_nr_interface.h" #include "nfapi_nr_interface_scf.h" +#include "nfapi/oai_integration/vendor_ext.h" #include @@ -1670,6 +1671,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin end, &pack_uint16_tlv_value); numTLVs++; + + if (NFAPI_MODE != NFAPI_MODE_AERIAL) { + // TLV not supported by Aerial L1 + pack_nr_tlv(NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG, + &(pNfapiMsg->carrier_config.frequency_shift_7p5khz), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + } // END Carrier Configuration // START Cell Configuration @@ -1695,13 +1706,15 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin end, &pack_uint32_tlv_value); numTLVs++; - - retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG, - &(pNfapiMsg->ssb_config.bch_payload), - ppWritePackedMsg, - end, - &pack_uint8_tlv_value); - numTLVs++; + if (NFAPI_MODE != NFAPI_MODE_AERIAL) { + // TLV not supported by Aerial L1 + retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG, + &(pNfapiMsg->ssb_config.bch_payload), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + } retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), @@ -1780,6 +1793,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin end, &pack_uint16_tlv_value); numTLVs++; + for (int k = 0; k < prach_fd_occasion.num_unused_root_sequences.value; k++) { + prach_fd_occasion.unused_root_sequences_list[k].tl.tag = NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG; + prach_fd_occasion.unused_root_sequences_list[k].value = 0; + pack_nr_tlv(NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG, + &(prach_fd_occasion.unused_root_sequences_list[k]), + ppWritePackedMsg, + end, + &pack_uint16_tlv_value); + numTLVs++; + } } retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, @@ -1788,15 +1811,25 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin end, &pack_uint8_tlv_value); numTLVs++; + pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.tl.tag = NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG; + pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.value = 0; + pack_nr_tlv(NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG, + &(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; // END PRACH Configuration // START SSB Table - retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, - &(pNfapiMsg->ssb_table.ssb_offset_point_a), - ppWritePackedMsg, - end, - &pack_uint16_tlv_value); - numTLVs++; - + if (NFAPI_MODE != NFAPI_MODE_AERIAL) { + // TLV not supported by Aerial L1 + retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, + &(pNfapiMsg->ssb_table.ssb_offset_point_a), + ppWritePackedMsg, + end, + &pack_uint16_tlv_value); + numTLVs++; + } retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value); numTLVs++; @@ -1807,7 +1840,10 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin end, &pack_uint8_tlv_value); numTLVs++; - + /* was unused */ + pNfapiMsg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG; + pack_nr_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value); + numTLVs++; // SCF222.10.02 Table 3-25 : If included there must be two instances of this TLV retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), @@ -1822,26 +1858,48 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin end, &pack_uint32_tlv_value); numTLVs++; + if (NFAPI_MODE != NFAPI_MODE_AERIAL) { + // TLV not supported by Aerial L1 + for (int i = 0; i < 64; i++) { + // SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV + retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG, + &(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + } - for (int i = 0; i < 64; i++) { - // SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV - retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG, - &(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id), + // END SSB Table + // START TDD Table + retval &= pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, + &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value); numTLVs++; + // END TDD Table + for (int i = 0; i < 40; i++) { + for (int k = 0; k < 14; k++) { + pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, + &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + } + } } - - // END SSB Table - // START TDD Table - retval &= - pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value); - numTLVs++; - // END TDD Table - // START Measurement Config // SCF222.10.02 Table 3-27 : Contains only one TLV and is currently unused + pNfapiMsg->measurement_config.rssi_measurement.tl.tag = NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG; + pNfapiMsg->measurement_config.rssi_measurement.value = 1; + pack_nr_tlv(NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, + &(pNfapiMsg->measurement_config.rssi_measurement), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; // END Measurement Config // START Digital Beam Table (DBT) PDU @@ -1851,57 +1909,57 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin // START Precoding Matrix (PM) PDU // Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL // is 0xA011 END Precoding Matrix (PM) PDU - - // START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states - retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, - &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), - ppWritePackedMsg, - end, - &pack_ipv4_address_value); - numTLVs++; - - retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, - &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), - ppWritePackedMsg, - end, - &pack_ipv6_address_value); - numTLVs++; - - retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, - &(pNfapiMsg->nfapi_config.p7_vnf_port), - ppWritePackedMsg, - end, - &pack_uint16_tlv_value); - numTLVs++; - - retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, - &(pNfapiMsg->nfapi_config.timing_window), - ppWritePackedMsg, - end, - &pack_uint8_tlv_value); - numTLVs++; - - retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, - &(pNfapiMsg->nfapi_config.timing_info_mode), - ppWritePackedMsg, - end, - &pack_uint8_tlv_value); - numTLVs++; - - retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, - &(pNfapiMsg->nfapi_config.timing_info_period), - ppWritePackedMsg, - end, - &pack_uint8_tlv_value); - numTLVs++; - // END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states - - if (pNfapiMsg->vendor_extension != 0 && config != 0) { - retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); - NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag); + if(NFAPI_MODE != NFAPI_MODE_AERIAL){ + // START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states + retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, + &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), + ppWritePackedMsg, + end, + &pack_ipv4_address_value); numTLVs++; - } + retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, + &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), + ppWritePackedMsg, + end, + &pack_ipv6_address_value); + numTLVs++; + + retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, + &(pNfapiMsg->nfapi_config.p7_vnf_port), + ppWritePackedMsg, + end, + &pack_uint16_tlv_value); + numTLVs++; + + retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, + &(pNfapiMsg->nfapi_config.timing_window), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + + retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, + &(pNfapiMsg->nfapi_config.timing_info_mode), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + + retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, + &(pNfapiMsg->nfapi_config.timing_info_period), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + numTLVs++; + // END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states + + if (pNfapiMsg->vendor_extension != 0 && config != 0) { + retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag); + numTLVs++; + } + } pNfapiMsg->num_tlv = numTLVs; retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end); return retval; @@ -2170,7 +2228,7 @@ static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) { if (msgEnd < msgHead) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %lu, %lu\n", msgHead, msgEnd); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %p, %p\n", &msgHead, &msgEnd); return 0; } @@ -2178,6 +2236,7 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) { } // Main pack function - public + int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index e0868f8573..e11e2a1d16 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -328,8 +328,8 @@ static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePac } // TODO Add TX power info // Hardcoded values that represent 0db - if (!(push8(8, ppWritePackedMsg, end) && // powerControlOffset - push8(1, ppWritePackedMsg, end))) { // powerControlOffsetSS + if (!(push8(0, ppWritePackedMsg, end) && // powerControlOffset + push8(0, ppWritePackedMsg, end))) { // powerControlOffsetSS return 0; } // TODO Add CBG Fields @@ -346,9 +346,8 @@ static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePacke && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end) && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end) && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end) - && push8(0, ppWritePackedMsg, end) && + && push8(0, ppWritePackedMsg, end) // TODO add Tx Power Info - push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end) && push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end) && push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end) && push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) { @@ -1092,7 +1091,7 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui } static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) { - return( + if(!( push16(srs_pdu->rnti, ppWritePackedMsg, end) && push32(srs_pdu->handle, ppWritePackedMsg, end) && push16(srs_pdu->bwp_size, ppWritePackedMsg, end) && @@ -1117,7 +1116,23 @@ static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t push16(srs_pdu->t_srs, ppWritePackedMsg, end) && push16(srs_pdu->t_offset, ppWritePackedMsg, end) // TODO: ignoring beamforming tlv for now - ); + )){ + return 0; + } + // Rx Beamforming PDU + if(!(push16(srs_pdu->beamforming.num_prgs,ppWritePackedMsg,end) && + push16(srs_pdu->beamforming.prg_size,ppWritePackedMsg,end) && + push8(srs_pdu->beamforming.dig_bf_interface,ppWritePackedMsg,end))){ + return 0; + } + for(int prg = 0; prg < srs_pdu->beamforming.num_prgs; prg ++){ + for(int digInt = 0; digInt < srs_pdu->beamforming.dig_bf_interface; digInt++){ + if(!push16(srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,ppWritePackedMsg,end)){ + return 0; + } + } + } + return 1; } static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) { @@ -2002,6 +2017,7 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8 static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv; + AssertFatal(value->PDU_length <= 0xFFFF,"TX_DATA.request PDU_Length should be within 16 bit, according to SCF222.10.02"); if (!(push16(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end) && push32(value->num_TLV, ppWritePackedMsg, end))) return 0; @@ -3153,6 +3169,7 @@ return 1; static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) { + AssertFatal(value->pdu_length <= 0xFFFF,"RX_DATA.indication PDU_Length should be within 16 bit, according to SCF222.10.02"); if(!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end) && push8(value->harq_id, ppWritePackedMsg, end) && @@ -5886,7 +5903,7 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) { nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg; - if(!(pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) && + if(!(pull16(ppReadPackedMsg, (uint16_t *)&pNfapiMsg->PDU_length, end) && pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) && pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) )) @@ -5939,13 +5956,6 @@ static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, v for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) { if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) { - printf("%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n", - __FUNCTION__, - __LINE__, - i, - pNfapiMsg->pdu_list[i].PDU_length, - pNfapiMsg->pdu_list[i].PDU_index); - return 0; } } @@ -6065,7 +6075,7 @@ static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, nfapi_p7_codec_config_t *config) { if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end) - && pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, &value->pdu_length, end) + && pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->pdu_length, end) && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end) && pull16(ppReadPackedMsg, &value->rssi, end))) return 0; diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c index a4ff93b5e8..f16fd776d2 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -2040,8 +2040,10 @@ int pnf_read_dispatch_message(pnf_t* pnf) { NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n"); return 0; - } - message_size = header.message_length; + }else{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Unpack p5 message header success\n"); + } + message_size = header.message_length+header_buffer_size; // now have the size of the mesage } @@ -2206,7 +2208,7 @@ int pnf_nr_read_dispatch_message(pnf_t* pnf) // print the received message printf("\n MESSAGE RECEIVED: \n"); for(int i=0; itx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config); + int packedMessageLength = 0; + if (NFAPI_MODE == NFAPI_MODE_AERIAL) { +#ifdef ENABLE_AERIAL + // In case it is a FAPI message, create 2 messages, one with nFAPI header for OAI PNF and one with no nFAPI header for Aerial + // L1 + nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len); + memcpy(msgFAPI, msg, msg_len); + // create FAPI tx_buffer + uint8_t tx_messagebufferFAPI[sizeof(vnf->tx_message_buffer)]; + int packedMessageLengthFAPI = -1; + packedMessageLengthFAPI = + fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &vnf->_public.codec_config); + return aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg); +#else + return 0; +#endif + } else { + packedMessageLength = nfapi_nr_p5_message_pack(msg, + msg_len, + vnf->tx_message_buffer, + sizeof(vnf->tx_message_buffer), + &vnf->_public.codec_config); + + if (packedMessageLength < 0) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength); + return -1; + } + // printf("msg id = 0x%02x, entire message length: %d\n", msg->message_id, packedMessageLength); + // for (int i = 0; i < packedMessageLength; i++) { + // printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) vnf->tx_message_buffer)[i]); + // } + + return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0); + } + } else { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx); + return -1; + } - if (packedMessageLength < 0) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength); - return -1; - } - return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0); - } - else - { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx); - return -1; - } } diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index e4b4bef848..28c7b71656 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -25,7 +25,9 @@ #include #include #include - +#ifdef ENABLE_AERIAL +#include "nfapi/oai_integration/aerial/fapi_nvIPC.h" +#endif #include "vnf_p7.h" #ifdef NDEBUG diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 23f22a9f2a..504c5fabe0 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -29,6 +29,9 @@ * \note * \warning */ +#ifdef ENABLE_AERIAL +#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h" +#endif #include "fapi_nr_l1.h" #include "common/ran_context.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" @@ -37,7 +40,6 @@ #include "nfapi/oai_integration/vendor_ext.h" #include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" - extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req); @@ -237,19 +239,43 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) } } - if (NFAPI_MODE == NFAPI_MODE_VNF) { //If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs is greater than 0 + if (NFAPI_MODE == NFAPI_MODE_VNF) { // If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs > 0 - if(number_ul_tti_pdu>0) + if (number_ul_tti_pdu > 0) oai_nfapi_ul_tti_req(UL_tti_req); - if (number_ul_dci_pdu>0) + if (number_ul_dci_pdu > 0) oai_nfapi_ul_dci_req(UL_dci_req); - if (number_tx_data_pdu>0) + if (number_dl_pdu > 0) + oai_nfapi_dl_tti_req(DL_req); + + if (number_tx_data_pdu > 0) oai_nfapi_tx_data_req(TX_req); - if (number_dl_pdu>0) - oai_nfapi_dl_tti_req(DL_req); + } else if (NFAPI_MODE == NFAPI_MODE_AERIAL) { +#ifdef ENABLE_AERIAL + bool send_slt_resp = false; + if (number_dl_pdu > 0) { + oai_fapi_dl_tti_req(DL_req); + send_slt_resp = true; + } + if (number_ul_tti_pdu > 0) { + oai_fapi_ul_tti_req(UL_tti_req); + send_slt_resp = true; + } + if (number_tx_data_pdu > 0) { + oai_fapi_tx_data_req(TX_req); + send_slt_resp = true; + } + if (number_ul_dci_pdu > 0) { + oai_fapi_ul_dci_req(UL_dci_req); + send_slt_resp = true; + } + if (send_slt_resp) { + oai_fapi_send_end_request(0,frame,slot); + } +#endif } /* this thread is done with the sched_info, decrease the reference counter */ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 3b5d159d34..cc872eb73c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -91,6 +91,9 @@ #include "RRC/NR/nr_rrc_extern.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" #include "nfapi/oai_integration/vendor_ext.h" +#ifdef ENABLE_AERIAL +#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h" +#endif extern uint16_t sf_ahead; @@ -1303,6 +1306,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) configure_nr_nfapi_vnf( RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc, RC.nrmac[j]->eth_params_s.remote_addr, RC.nrmac[j]->eth_params_s.remote_portd, RC.nrmac[j]->eth_params_s.my_portd); printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc); + } else if(strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "aerial") == 0){ +#ifdef ENABLE_AERIAL + printf("Configuring VNF for Aerial connection\n"); + aerial_configure_nr_fapi_vnf(); +#endif } else { // other midhaul AssertFatal(1 == 0, "MACRLC %d: %s unknown southbound midhaul\n", j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 9abb5ab748..34763011f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -708,6 +708,12 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; cfg->num_tlv++; + uint8_t *mib_payload = nrmac->common_channels[0].MIB_pdu; + uint32_t mib = (mib_payload[2] << 16) | (mib_payload[1] << 8) | mib_payload[0]; + cfg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG; + cfg->ssb_table.MIB.value = mib; + cfg->num_tlv++; + nrmac->ssb_SubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; nrmac->ssb_OffsetPointA = cfg->ssb_table.ssb_offset_point_a.value; LOG_I(NR_MAC, @@ -837,11 +843,8 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c config_common(nrmac, config->pdsch_AntennaPorts, config->pusch_AntennaPorts, scc); - if (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) { - // fake that the gNB is configured in nFAPI mode, which would normally be - // done in a NR_PHY_config_req, but in this mode, there is no PHY - RC.gNB[0]->configured = 1; - } else { + if (NFAPI_MODE == NFAPI_MONOLITHIC) { + // nothing to be sent in the other cases NR_PHY_Config_t phycfg = {.Mod_id = 0, .CC_id = 0, .cfg = &nrmac->config[0]}; DevAssert(nrmac->if_inst->NR_PHY_config_req); nrmac->if_inst->NR_PHY_config_req(&phycfg); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 98e642279c..af8b077dea 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -91,6 +91,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, future_ul_tti_req->SFN = (prev_slot / num_slots) % 1024; LOG_D(NR_MAC, "%d.%d UL_tti_req_ahead SFN.slot = %d.%d for index %d \n", frameP, slotP, future_ul_tti_req->SFN, future_ul_tti_req->Slot, prev_slot % size); /* future_ul_tti_req->Slot is fixed! */ + for (int i = 0; i < future_ul_tti_req->n_pdus; i++) { + switch(future_ul_tti_req->pdus_list[i].pdu_type){ + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list){ + for (int j = 0; j < future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.num_prgs; ++j) { + if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ + free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list); + } + } + free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list); + } + break; + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list){ + for (int j = 0; j < future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.num_prgs; ++j) { + if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ + free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list); + } + } + free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list); + } + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list){ + for (int j = 0; j < future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.num_prgs; ++j) { + if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ + free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list); + } + } + free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list); + } + break; + case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: + if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list){ + for (int j = 0; j < future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.num_prgs; ++j) { + if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list){ + free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list); + } + } + free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list); + } + default: + break; + } + future_ul_tti_req->pdus_list[i].pdu_type = 0; + future_ul_tti_req->pdus_list[i].pdu_size = 0; + } future_ul_tti_req->n_pdus = 0; future_ul_tti_req->n_ulsch = 0; future_ul_tti_req->n_ulcch = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 161598ec2d..e110f531ac 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -317,6 +317,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP UL_tti_req->SFN = frameP; UL_tti_req->Slot = slotP; + UL_tti_req->rach_present = 1; for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion for (int td_index=0; td_index 0) { // Aerial needs slot_ahead = 0, requiring addition of another TDD period + eff_slot += tdd_period_slot; + } +#endif int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1; if (FR==nr_FR2) { int num_tdd_period = (eff_slot%nr_slots_per_frame[mu])/tdd_period_slot; @@ -1052,10 +1057,12 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, LOG_D(NR_MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d, ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos); pusch_pdu->dmrs_config_type = 0; pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. + pusch_pdu->pusch_identity = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 pusch_pdu->resource_alloc = 1; //type 1 + memset(pusch_pdu->rb_bitmap, 0, sizeof(pusch_pdu->rb_bitmap)); pusch_pdu->rb_start = msg3_first_rb; if (msg3_nb_rb > pusch_pdu->bwp_size) AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); @@ -1077,6 +1084,23 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->pusch_data.harq_process_id = 0; pusch_pdu->pusch_data.new_data_indicator = (round == 0) ? 1 : 0;; pusch_pdu->pusch_data.num_cb = 0; + + // Beamforming + pusch_pdu->beamforming.num_prgs = 0; + pusch_pdu->beamforming.prg_size = 0; // bwp_size; + pusch_pdu->beamforming.dig_bf_interface = 0; + if (pusch_pdu->beamforming.num_prgs > 0) { + if (pusch_pdu->beamforming.prgs_list == NULL) { + pusch_pdu->beamforming.prgs_list = calloc(pusch_pdu->beamforming.num_prgs, sizeof(*pusch_pdu->beamforming.prgs_list)); + } + if (pusch_pdu->beamforming.dig_bf_interface > 0) { + if (pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) { + pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list = + calloc(pusch_pdu->beamforming.dig_bf_interface, sizeof(*pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list)); + } + } + pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + } int num_dmrs_symb = 0; for(int i = start_symbol_index; i < start_symbol_index+nr_of_symbols; i++) num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1; @@ -1279,6 +1303,12 @@ static void nr_generate_Msg2(module_id_t module_idP, dl_req->nPDUs+=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + pdsch_pdu_rel15->precodingAndBeamforming.num_prgs = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0; + pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 9a554dc0bb..22a2b034e6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -426,6 +426,12 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, dl_req->nPDUs += 1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=0; + pdsch_pdu_rel15->precodingAndBeamforming.prg_size=0; + pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; pdsch_pdu_rel15->pduBitmap = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 97c42c57f0..e8c0a33c3b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1066,6 +1066,10 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->qamModOrder[0] = Qm; pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs; pdsch_pdu->mcsTable[0] = current_BWP->mcsTableIdx; + // NVIDIA: Workaround for MCSTableIdx mismatch error + if (nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx) != R) { + pdsch_pdu->mcsTable[0] = 0; + } AssertFatal(harq!=NULL,"harq is null\n"); AssertFatal(harq->rounddl_bler.harq_round_max,"%d",harq->round); pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4]; @@ -1090,8 +1094,11 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->StartSymbolIndex = tda_info->startSymbolIndex; pdsch_pdu->NrOfSymbols = tda_info->nrOfSymbols; // Precoding + pdsch_pdu->precodingAndBeamforming.num_prgs = 0; pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; + pdsch_pdu->precodingAndBeamforming.dig_bf_interfaces = 0; pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index; + pdsch_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; // TBS_LBRM according to section 5.4.2.1 of 38.212 // TODO: verify the case where maxMIMO_Layers is NULL, in which case // in principle maxMIMO_layers should be given by the maximum number of layers @@ -1146,6 +1153,13 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_pdu->CceIndex = sched_ctrl->cce_index; dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->powerControlOffsetSS = 1; + + dci_pdu->precodingAndBeamforming.num_prgs = 0; + dci_pdu->precodingAndBeamforming.prg_size = 0; + dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + /* DCI payload */ dci_pdu_rel15_t dci_payload; memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9199327501..2ebfa874db 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -57,6 +57,7 @@ #define DEBUG_gNB_SCHEDULER 1 #include "common/ran_context.h" +#include "nfapi/oai_integration/vendor_ext.h" //#define DEBUG_DCI @@ -227,13 +228,23 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc, switch (Layers) { case 1: +#ifdef ENABLE_AERIAL + dmrs.dmrs_ports_id = 3; + dmrs.numDmrsCdmGrpsNoData = 2; +#else dmrs.dmrs_ports_id = 0; dmrs.numDmrsCdmGrpsNoData = 1; +#endif frontloaded_symb = 1; break; case 2: +#ifdef ENABLE_AERIAL + dmrs.dmrs_ports_id = 7; + dmrs.numDmrsCdmGrpsNoData = 2; +#else dmrs.dmrs_ports_id = 2; dmrs.numDmrsCdmGrpsNoData = 1; +#endif frontloaded_symb = 1; break; case 3: @@ -606,10 +617,14 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc, NR_pusch_dmrs_t dmrs = {0}; // TODO setting of cdm groups with no data to be redone for MIMO - if (ul_bwp->transform_precoding && Layers < 3) - dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2; - else + if(NFAPI_MODE == NFAPI_MODE_AERIAL) { dmrs.num_dmrs_cdm_grps_no_data = 2; + } else { + if (ul_bwp->transform_precoding && Layers < 3) + dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2; + else + dmrs.num_dmrs_cdm_grps_no_data = 2; + } NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ? (tda_info->mapping_type == typeA ? @@ -738,7 +753,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 // Antenna Ports - dci_pdu_rel15->antenna_ports.val = 0; + + dci_pdu_rel15->antenna_ports.val = NFAPI_MODE == NFAPI_MODE_AERIAL ? 2 : 0; // DMRS sequence initialization dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; @@ -1031,6 +1047,22 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu, pucch_pdu->sr_flag = O_sr; pucch_pdu->prb_size=1; } + // Beamforming + pucch_pdu->beamforming.num_prgs = 0; + pucch_pdu->beamforming.prg_size = 0; // pucch_pdu->prb_size; + pucch_pdu->beamforming.dig_bf_interface = 0; + if (pucch_pdu->beamforming.num_prgs > 0) { + if (pucch_pdu->beamforming.prgs_list == NULL) { + pucch_pdu->beamforming.prgs_list = calloc(pucch_pdu->beamforming.num_prgs, sizeof(*pucch_pdu->beamforming.prgs_list)); + } + if (pucch_pdu->beamforming.dig_bf_interface > 0) { + if (pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) { + pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list = + calloc(pucch_pdu->beamforming.dig_bf_interface, sizeof(*pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list)); + } + } + pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; + } } void set_r_pucch_parms(int rsetindex, @@ -2580,9 +2612,9 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); } -uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { - // al values passed to this function are x10 - int snrx10 = (cqi*5) - 640; +uint8_t nr_get_tpc(int target, int snrx10, int incr) +{ + // all values passed to this function are in dB x10 if (snrx10 > target + incr) return 0; // decrease 1dB if (snrx10 < target - (3*incr)) return 3; // increase 3dB if (snrx10 < target - incr) return 2; // increase 1dB diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index aef5b11340..e949d84dca 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1042,11 +1042,11 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, } // tpc (power control) only if we received AckNack - if (uci_01->harq.harq_confidence_level==0) - sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, uci_01->ul_cqi, 30); - else - sched_ctrl->tpc1 = 3; - sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; + if (uci_01->harq.harq_confidence_level == 0 && uci_01->ul_cqi != 0xff) { + sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; + sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, sched_ctrl->pucch_snrx10, 30); + } else + sched_ctrl->tpc1 = 1; } // check scheduling request result, confidence_level == 0 is good @@ -1085,10 +1085,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, // tpc (power control) // TODO PUCCH2 SNR computation is not correct -> ignore the following - //sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, - // uci_234->ul_cqi, - // 30); - //sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640; + if (uci_234->ul_cqi != 0xff) { + sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640; + sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, sched_ctrl->pucch_snrx10, 30); + } // TODO: handle SR if (uci_234->pduBitmap & 0x1) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b3aadd816d..4eb43081b2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -625,11 +625,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // if not missed detection (10dB threshold for now) if (rssi>0) { - UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); + if (ul_cqi != 0xff) { + UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; + UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30); + } if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->raw_rssi = rssi; - UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); } @@ -670,7 +672,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; } - if (ul_cqi <= 128) { + if (ul_cqi == 0xff || ul_cqi <= 128) { UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++; UE->mac_stats.ulsch_DTX++; } @@ -756,7 +758,10 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl; - UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, ul_cqi, 30); + if (ul_cqi != 0xff) { + UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; + UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30); + } if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->raw_rssi = rssi; @@ -2245,11 +2250,15 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data; /* FAPI: DMRS */ + pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data; + pusch_pdu->dmrs_ports = ((1<nrOfLayers) - 1); pusch_pdu->ul_dmrs_symb_pos = sched_pusch->dmrs_info.ul_dmrs_symb_pos; pusch_pdu->dmrs_config_type = sched_pusch->dmrs_info.dmrs_config_type; + pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] const NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = get_DMRS_UplinkConfig(current_BWP->pusch_Config, &sched_pusch->tda_info); if (pusch_pdu->transform_precoding) { // transform precoding disabled long *scramblingid=NULL; + pusch_pdu->pusch_identity = *scc->physCellId; if (NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; else if (NR_DMRS_UplinkConfig) @@ -2356,7 +2365,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus]; memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t)); ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + ul_dci_request_pdu->PDUSize = (uint8_t)(4+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 61ce2c49f9..5f19d60458 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -272,7 +272,7 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc, const NR_tda_info_t *tda_info, const int Layers); -uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); +uint8_t nr_get_tpc(int target, int snrx10, int incr); int get_spf(nfapi_nr_config_request_scf_t *cfg); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 37bedddf46..57d7c05b2b 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -202,12 +202,12 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) UL_info->CC_id, UL_info->rx_ind.sfn, UL_info->rx_ind.slot, - rx->rnti, + crc->rnti, crc->tb_crc_status ? NULL : rx->pdu, rx->pdu_length, - rx->timing_advance, - rx->ul_cqi, - rx->rssi); + crc->timing_advance, + crc->ul_cqi, + crc->rssi); handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc); } } @@ -440,7 +440,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { nfapi_nr_uci_indication_t *uci_ind = NULL; nfapi_nr_rx_data_indication_t *rx_ind = NULL; nfapi_nr_crc_indication_t *crc_ind = NULL; - if (get_softmodem_params()->emulate_l1) + if (get_softmodem_params()->emulate_l1 || NFAPI_MODE == NFAPI_MODE_AERIAL) { if (gnb_rach_ind_queue.num_items > 0) { LOG_D(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items); @@ -483,7 +483,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { handle_nr_ulsch(UL_info); handle_nr_srs(UL_info); - if (get_softmodem_params()->emulate_l1) { + if (get_softmodem_params()->emulate_l1 || NFAPI_MODE == NFAPI_MODE_AERIAL) { free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind); } } diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index 68d390f097..f7af67ba8b 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -26,7 +26,7 @@ void handle_rach(UL_IND_t *UL_info) { int i; int j = UL_info->subframe; AssertFatal(j < sizeof(UL_RCC_INFO.rach_ind) / sizeof(UL_RCC_INFO.rach_ind[0]), "j index out of range of index of rach_ind\n"); - if (NFAPI_MODE == NFAPI_MODE_VNF) + if (NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) { if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 0) { @@ -97,7 +97,7 @@ void handle_sr(UL_IND_t *UL_info) { if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) { oai_nfapi_sr_indication(&UL_info->sr_ind); } - } else if(NFAPI_MODE == NFAPI_MODE_VNF) { + } else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) { for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0) { assert(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); @@ -140,7 +140,7 @@ void handle_cqi(UL_IND_t *UL_info) { oai_nfapi_cqi_indication(&UL_info->cqi_ind); UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; } - } else if (NFAPI_MODE == NFAPI_MODE_VNF) { + } else if (NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) { for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0) { assert(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); @@ -187,7 +187,7 @@ void handle_harq(UL_IND_t *UL_info) { } UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; - } else if(NFAPI_MODE == NFAPI_MODE_VNF) { + } else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) { for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0) { assert(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); @@ -232,7 +232,7 @@ void handle_ulsch(UL_IND_t *UL_info) { oai_nfapi_rx_ind(&UL_info->rx_ind); UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } - } else if(NFAPI_MODE == NFAPI_MODE_VNF) { + } else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) { for(uint8_t k = 0; k < NUM_NFAPI_SUBFRAME; k++) { if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) { assert(UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf new file mode 100644 index 0000000000..149aaedb4c --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf @@ -0,0 +1,262 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +sa = 1; +nfapi = "AERIAL"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ + mcc = 001; + mnc = 01; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + } + ); + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pusch_AntennaPorts = 2; + do_CSIRS = 1; + do_SRS = 0; + min_rxtxtime = 2; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741) + absoluteFrequencySSB = 649920; + #652860; #should be 649920 +#647520; +#647540; +#649920; +#650208; +#647540; + dl_frequencyBand = 78; + # this is 3300.24 MHz + dl_absoluteFrequencyPointA = 646724; +#649104; +#646724; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) + initialDLBWPlocationAndBandwidth = 1099; + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 159;# testMAC 158; OAI gNB 98 +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + 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 = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + 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 = 5; #6; + nrofDownlinkSlots = 3; #7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 1; #2; + nrofUplinkSymbols = 0; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "192.168.70.132"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50011; // vnf p7 port [!] + remote_s_portd = 50010; // pnf p7 port [!] + tr_s_preference = "aerial"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; #150; + pucch_TargetSNRx10 = 200; #200; + ulsch_max_frame_inactivity = 10; + dl_max_mcs = 28; + ul_max_mcs = 28; +} +); + + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; From 78cc3d4967cf17b3856b152062f141ecd2c7f8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20da=20Silva?= Date: Thu, 7 Mar 2024 10:17:27 +0000 Subject: [PATCH 35/41] Remove double pusch_snrx10 calculation in _nr_rx_sdu function --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 3 +-- 1 file changed, 1 insertion(+), 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 4eb43081b2..1aee6f613e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -625,8 +625,8 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // if not missed detection (10dB threshold for now) if (rssi>0) { + UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; if (ul_cqi != 0xff) { - UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30); } if (timing_advance != 0xffff) @@ -765,7 +765,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->raw_rssi = rssi; - UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); if (ra->cfra) { LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); From 4b3ea3f46912c799534c3b4be5b03f1f5568402f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20da=20Silva?= Date: Wed, 7 Feb 2024 10:09:34 +0000 Subject: [PATCH 36/41] Add Aerial tutorial, describing usage with docker-compose --- doc/Aerial_FAPI_Split_Tutorial.md | 266 ++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 doc/Aerial_FAPI_Split_Tutorial.md diff --git a/doc/Aerial_FAPI_Split_Tutorial.md b/doc/Aerial_FAPI_Split_Tutorial.md new file mode 100644 index 0000000000..063c733fb7 --- /dev/null +++ b/doc/Aerial_FAPI_Split_Tutorial.md @@ -0,0 +1,266 @@ + + + + + +
+ + + + + + OAI 7.2 Fronthaul Interface 5G SA Tutorial +
+ +**Table of Contents** + +[[_TOC_]] + +# Prerequisites + +The hardware on which we have tried this tutorial: + +| Hardware (CPU,RAM) |Operating System (kernel) | NIC (Vendor,Driver,Firmware) | +|----------------------------------------------------------------------------|----------------------------------|--------------------------------------------------| +| Gigabyte Edge E251-U70 (Intel Xeon Gold 6240R, 2.4GHz, 24C48T, 96GB DDR4) |Ubuntu 22.04.3 LTS (5.15.0-72-lowlatency)| NVIDIA ConnectX®-6 Dx 22.38.1002 | +| Dell PowerEdge R750 (Dual Intel Xeon Gold 6336Y CPU @ 2.4G, 24C/48T (185W), 512GB RDIMM, 3200MT/s) |Ubuntu 22.04.3 LTS (5.15.0-72-lowlatency)| NVIDIA Converged Accelerator A100X (24.39.2048) | + +**NOTE**: These are not minimum hardware requirements. This is the configuration of our servers. The NIC card should support hardware PTP time stamping. + +PTP enabled switches and grandmaster clock we have tested with: + +| Vendor | Software Version | +|--------------------------|------------------| +| Fibrolan Falcon-RX/812/G | 8.0.25.4 | +| CISCO C93180YC-FX3 | 10.2(4) | +| Qulsar Qg2 (Grandmaster) | 12.1.27 | + + +These are the radio units we've used for testing: + +| Vendor | Software Version | +|-------------|------------------| +| Foxconn RPQN-7801E RU | 2.6.9r254 | +| Foxconn RPQN-7801E RU | 3.1.15_0p4 | + + +The UEs that have been tested and confirmed working with Aerial are the following: + +| Vendor | Model | +|-----------------|-------------------------------| +| Sierra Wireless | EM9191 | +| Quectel | RM500Q-GL | +| Apaltec | Tributo 5G-Dongle | +| OnePlus | Nord (AC2003) | +| Apple iPhone | 14 Pro (MQ0G3RX/A) (iOS 17.3) | + + +## Configure your server + +The first step is to obtain the NVIDIA Aerial SDK, you'll need to request access [here](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/aerial-sdk). + +After obtaining access to the SDK, you can refer to [this instructions page](https://docs.nvidia.com/aerial/aerial-research-cloud/current/index.html) to setup the L1 components using NVIDIAs' SDK manager, or to [this instructions page](https://developer.nvidia.com/docs/gputelecom/aerial-sdk/aerial-sdk-archive/aerial-sdk-23-2/index.html) in order to setup and install the components manually. + +The currently used Aerial Version is 23-2, which is also the one currently used by the SDK Manager. + + +### CPU allocation + +Currently, the CPU isolation is setup the following: + +| Server brand | Model | Nº of CPU Cores | Isolated CPUs | +|--------------|-----------|:---------------:|:--------------:| +| Gigabyte | Edge E251-U70 | 24 | 2-10 | + + +**Gigabyte Edge E251-U70** + +| Applicative Threads | Allocated CPUs | +|------------------------|----------------| +| Aerial L1 | 2,3,4,5,6,7,8 | +| PTP & PHC2SYS Services | 9 | +| OAI `nr-softmodem` | 13-20 | + + +## PTP configuration + +1. You need to install the `linuxptp` debian package. It will install both ptp4l and phc2sys. + +```bash +#Ubuntu +sudo apt install linuxptp -y +``` + +Once installed you can use this configuration file for ptp4l (`/etc/ptp4l.conf`). Here the clock domain is 24 so you can adjust it according to your PTP GM clock domain + +``` +[global] +domainNumber 24 +slaveOnly 1 +time_stamping hardware +tx_timestamp_timeout 1 +logging_level 6 +summary_interval 0 +#priority1 127 + +[your_PTP_ENABLED_NIC] +network_transport L2 +hybrid_e2e 0 + +``` + +The service of ptp4l (`/lib/systemd/system/ptp4l.service`) should be configured as below: +``` +[Unit] +Description=Precision Time Protocol (PTP) service +Documentation=man:ptp4l + +[Service] +Restart=always +RestartSec=5s +Type=simple +ExecStart=taskset -c 9 /usr/sbin/ptp4l -f /etc/ptp.conf + +[Install] +WantedBy=multi-user.target + +``` + +and service of phc2sys (`/lib/systemd/system/phc2sys.service`) should be configured as below: +``` +[Unit] +Description=Synchronize system clock or PTP hardware clock (PHC) +Documentation=man:phc2sys +After=ntpdate.service +Requires=ptp4l.service +After=ptp4l.service + +[Service] +Restart=always +RestartSec=5s +Type=simple +ExecStart=/usr/sbin/phc2sys -a -r -r -n 24 + +[Install] +WantedBy=multi-user.target + +``` + +# Build OAI gNB + +If installing with the Aerial SDK, you should already have the repository cloned in `~/openairinterface5g`, if +Clone OAI code base in a suitable repository, here we are cloning in `~/openairinterface5g` directory, + +```bash +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g +cd ~/openairinterface5g/ +git checkout Aerial_Integration +``` + +## Get nvIPC sources from the L1 container +The library used for communication between L1 and L2 components is called nvIPC, and was developed by NVIDIA, as such, it is not open-source and can't be freely distributed. +In order to be able to use this library to achieve communication, we need to obtain the nvIPC source files from the L1 container (cuBB) and place it in out gNB project directory `~/openairinterface5g`. +This allows us to build and install this library when building the L2 docker container. + +Check whether your L1 container is running: +```bash +~$ docker container ls -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +a9681a0c4a10 14dca2002237 "/opt/nvidia/nvidia_…" 3 months ago Exited (137) 10 days ago cuBB + +``` +If it is not running, you may start it and logging into the container by running the following: +```bash +~$ docker start cuBB +cuBB +~$ docker exec -it cuBB bash +root@c_aerial_aerial:/opt/nvidia/cuBB# +``` + +After logging into the container, we need to pack the nvIPC sources and copy them to the host ( the command creates a tar.gz file with the following name format: nvipc_src.yyyy.mm.dd.tar.gz) +```bash +~$ docker exec -it cuBB bash +root@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs +root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh +nvipc_src.****.**.**/ +... +--------------------------------------------- +Pack nvipc source code finished: +/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.****.**.**.tar.gz +root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# cp nvipc_src.****.**.**.tar.gz /opt/cuBB/share/ +root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# exit +``` + +The file should now be present in the `~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/` directory, from where it is moved into `~/openairinterface5g` +```bash +~$ mv ~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/nvipc_src.****.**.**.tar.gz ~/openairinterface5g/ +``` +With the nvIPC sources in the project directory, the docker image can be built. + +## Building OAI gNB docker image + +In order to build the final image, there is an intermediary image to be built (ran-base) +```bash +~$ cd ~/openairinterface5g/ +~/openairinterface5g$ docker build . -f docker/Dockerfile.base.ubuntu20 --tag ran-base:latest +~/openairinterface5g$ docker build . -f docker/Dockerfile.gNB.aerial.ubuntu20 --tag oai-gnb-aerial:latest +``` + + +## Running the setup +In order to use Docker compose to automatically start and stop the setup, we need to first create a ready-made image of the L1, after compiling the L1 software and making the necessary adjustments to its configuration files. +The process of preparing the L1 is covered on NVIDIAs' documentation, and falls outside the scope of this document. + +### Prepare the L1 image +After preparing the L1 software, the container needs to be committed in order for an image in which the L1 is ready to be executed, and that can be referenced by a docker-compose.yaml file later: +```bash +~$ docker commit nv-cubb cubb-build:23-2 +~$ docker image ls +.. +cubb-build 23-2 824156e0334c 2 weeks ago 40.1GB +.. +``` + +## Adapt the OAI-gNB configuration file to your system/workspace + +Edit the sample OAI gNB configuration file and check following parameters: + +* `gNBs` section + * The PLMN section shall match the one defined in the AMF + * `amf_ip_address` shall be the correct AMF IP address in your system + * `GNB_INTERFACE_NAME_FOR_NG_AMF` and `GNB_IPV4_ADDRESS_FOR_NG_AMF` shall match your DU N2 interface name and IP address + * `GNB_INTERFACE_NAME_FOR_NGU` and `GNB_IPV4_ADDRESS_FOR_NGU` shall match your DU N3 interface name and IP address + +The default amf_ip_address:ipv4 value is 192.168.70.132, when installing the CN5G following [this tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_OAI_CN5G.md) +Both 'GNB_INTERFACE_NAME_FOR_NG_AMF' and 'GNB_INTERFACE_NAME_FOR_NGU' need to be set to the network interface name used by the gNB host to connect to the CN5G. +Both 'GNB_IPV4_ADDRESS_FOR_NG_AMF' and 'GNB_IPV4_ADDRESS_FOR_NGU' need to be set to the IP address of the NIC referenced previously. + + +### Running docker compose +#### Aerial L1 entrypoint script +Before running docker-compose, we can check which L1 configuration file is to be used by cuphycontroller_scf, this is set in the script [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh), which is used by the L1 container in order to start the L1 software, this begins by installing a module 'gdrcopy', setting up some environment variables, restarting NVIDIA MPS, and finally running cuphycontroller with an argument that represent which L1 configuration file is to be used, this argument may be changed by providing an argument in docker-compose.yaml. +When no argument is provided (this is the default behaviour), it uses "P5G_SCF_FXN" as a cuphycontroller_scf argument. + +After building the gNB image, and preparing the configuration file, the setup can be run with the following command: + +```bash +cd ci-scripts/yaml_files/sa_gnb_aerial/ +docker compose up -d + +``` +This will start both containers, beginning with 'nv-cubb' and only after it being ready it starts 'oai-gnb-aerial'. + +The gNB logs can be followed with: + +```bash +docker logs -f oai-gnb-aerial +``` + +### Stopping the setup + +Running the following command, will stop both containers, leaving the system ready to be run later: +```bash +cd ci-scripts/yaml_files/sa_gnb_aerial/ +docker compose down + +``` From 1fadd7adb6e1da8864e5cf2a887207b2261cbe1c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 8 Mar 2024 15:50:22 +0100 Subject: [PATCH 37/41] Add Aerial platform into CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - create XML files for the Aerial pipeline - create docker-compose to automate deployment - add documentation - add to main Jenkinsfile Signed-off-by: Raphael Defosseux Co-authored-by: Jaroslava Fiedlerova Co-authored-by: Rúben Soares da Silva --- ci-scripts/Jenkinsfile-GitLab-Container | 23 ++ ci-scripts/ci_ueinfra.yaml | 11 + ci-scripts/cls_containerize.py | 34 ++- .../gnb-vnf.sa.band78.273prb.aerial.conf | 262 ++++++++++++++++++ ci-scripts/epc.py | 6 +- .../xml_files/container_sa_aerial_quectel.xml | 139 ++++++++++ .../container_sa_aerial_quectel_cleanup.xml | 52 ++++ .../xml_files/fr1_cn5g_basic_deploy.xml | 45 +++ .../xml_files/fr1_cn5g_basic_undeploy.xml | 39 +++ .../sa_gnb_aerial/aerial_l1_entrypoint.sh | 37 +++ .../sa_gnb_aerial/docker-compose.yaml | 65 +++++ doc/TESTBenches.md | 7 +- 12 files changed, 703 insertions(+), 17 deletions(-) create mode 100644 ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf create mode 100644 ci-scripts/xml_files/container_sa_aerial_quectel.xml create mode 100644 ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml create mode 100644 ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml create mode 100644 ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml create mode 100755 ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh create mode 100644 ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index 61972c7226..762894f277 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -562,6 +562,29 @@ pipeline { } } } + stage ("SA-AERIAL-CN5G") { + when { expression {do5Gtest} } + steps { + script { + triggerSlaveJob ('RAN-SA-AERIAL-CN5G', 'SA-AERIAL-CN5G') + } + } + post { + always { + script { + // Using a unique variable name for each test stage to avoid overwriting on a global variable + // due to parallel-time concurrency + saAERIALStatus = finalizeSlaveJob('RAN-SA-AERIAL-CN5G') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + failingStages += saAERIALStatus + } + } + } + } stage ("SA-OAIUE-CN5G") { when { expression {do5Gtest} } steps { diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index deef3718ec..8d822141f3 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -18,6 +18,17 @@ up2: IF: wwan0 MTU: 1500 +sphex_quectel: + Host: sphex + InitScript: sudo stdbuf -oL /home/oaicicd/quectel-CM/quectel-CM -4 -s oai.ipv4 &> /tmp/quecel-cm.log & + TermScript: sudo -S killall --signal SIGKILL quectel-CM + AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB3 wup + DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB3 detach + NetworkScript: ip a show dev wwan0 + IF: wwan0 + MTU: 1500 + LogStore: /media/ci_qlogs + adb_ue_1: Host: nano InitScript: /home/oaicicd/ci_ctl_adb.sh initialize R3CM40LZPHT diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 60d0ccf568..a01afa596e 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -58,7 +58,7 @@ import cls_oaicitest # Helper functions used here and in other classes # (e.g., cls_cluster.py) #----------------------------------------------------------- -IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-gnb-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan'] +IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-gnb-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan', 'oai-gnb-aerial'] def CreateWorkspace(sshSession, sourcePath, ranRepository, ranCommitID, ranTargetBranch, ranAllowMerge): if ranCommitID == '': @@ -383,6 +383,7 @@ class Containerize(): imageNames.append(('oai-physim', 'phySim', 'oai-physim', '')) if self.host == 'Ubuntu': imageNames.append(('oai-lte-ru', 'lteRU', 'oai-lte-ru', '')) + imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', '')) # Building again the 5G images with Address Sanitizer imageNames.append(('ran-build', 'build', 'ran-build-asan', '--build-arg "BUILD_OPTION=--sanitize"')) imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"')) @@ -480,7 +481,11 @@ class Containerize(): cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}') elif image != 'ran-build': cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}') + if image == 'oai-gnb-aerial': + cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2023.11.28.tar.gz .') ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > cmake_targets/log/{name}.log 2>&1', timeout=1200) + if image == 'oai-gnb-aerial': + cmd.run('rm -f nvipc_src.2023.11.28.tar.gz') if image == 'ran-build' and ret.returncode == 0: cmd.run(f"docker run --name test-log -d {name}:{imageTag} /bin/true") cmd.run(f"docker cp test-log:/oai-ran/cmake_targets/log/ cmake_targets/log/{name}/") @@ -959,7 +964,7 @@ class Containerize(): # Checking Status grep = '' - if svcName != '': grep = f' | grep -A3 {svcName}' + if svcName != '': grep = f' | grep -A3 --color=never {svcName}' mySSH.command(f'docker compose --file ci-docker-compose.yml config {grep}', '\$', 5) result = re.search('container_name: (?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) unhealthyNb = 0 @@ -1008,8 +1013,8 @@ class Containerize(): if healthyNb == 1: cnt = 0 while (cnt < 20): - mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting"', '\$', 30) - result = re.search('got sync|Starting E1AP at CU UP|Starting F1AP at CU|Got sync|Waiting for RUs to be configured', mySSH.getBefore()) + mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting|ready"', '\$', 30) + result = re.search('got sync|Starting E1AP at CU UP|Starting F1AP at CU|Got sync|Waiting for RUs to be configured|cuPHYController initialized|Received CONFIG.response, gNB is ready', mySSH.getBefore()) if result is None: time.sleep(6) cnt += 1 @@ -1096,9 +1101,6 @@ class Containerize(): filename = f'{svcName}-{HTML.testCase_id}.log' mySSH.run(f'docker compose -f {yamlDir}/ci-docker-compose.yml logs --no-log-prefix -- {svcName} &> {lSourcePath}/cmake_targets/log/{filename}') copyin_res = mySSH.copyin(f'{lSourcePath}/cmake_targets/log/{filename}', f'{filename}') and copyin_res - # when nv-cubb container is available, copy L1 pcap, OAI Aerial pipeline - if 'nv-cubb' in allServices: - mySSH.run(f'cp {lSourcePath}/cmake_targets/share/gnb_nvipc.pcap {lSourcePath}/cmake_targets/gnb_nvipc.pcap') mySSH.run(f'docker compose -f {yamlDir}/ci-docker-compose.yml down -v') @@ -1119,14 +1121,18 @@ class Containerize(): HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK) else: for svcName in services: - filename = f'{svcName}-{HTML.testCase_id}.log' - logging.debug(f'\u001B[1m Analyzing logfile {filename}\u001B[0m') - logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers) - if (logStatus < 0): - HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus) - self.exitStatus = 1 + if svcName == 'nv-cubb': + msg = 'Undeploy PNF/Nvidia CUBB' + HTML.CreateHtmlTestRow(msg, 'OK', CONST.ALL_PROCESSES_OK) else: - HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + filename = f'{svcName}-{HTML.testCase_id}.log' + logging.debug(f'\u001B[1m Analyzing logfile {filename}\u001B[0m') + logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers) + if (logStatus < 0): + HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus) + self.exitStatus = 1 + else: + HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) # all the xNB run logs shall be on the server 0 for logCollecting if self.eNB_serverId[self.eNB_instance] != '0': mySSH.copyout(f'./*.log', f'{lSourcePath}/cmake_targets/', recursive=True) diff --git a/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf b/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf new file mode 100644 index 0000000000..f1615c0247 --- /dev/null +++ b/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf @@ -0,0 +1,262 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +sa = 1; +nfapi = "AERIAL"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ + mcc = 208; + mnc = 97; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + } + ); + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pusch_AntennaPorts = 2; + do_CSIRS = 1; + do_SRS = 0; + min_rxtxtime = 2; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741) + absoluteFrequencySSB = 649920; + #652860; #should be 649920 +#647520; +#647540; +#649920; +#650208; +#647540; + dl_frequencyBand = 78; + # this is 3300.24 MHz + dl_absoluteFrequencyPointA = 646724; +#649104; +#646724; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) + initialDLBWPlocationAndBandwidth = 1099; + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 159;# testMAC 158; OAI gNB 98 +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + 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 = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + 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 = 5; #6; + nrofDownlinkSlots = 3; #7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 1; #2; + nrofUplinkSymbols = 0; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "192.168.71.132"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "eno1"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.131"; + GNB_INTERFACE_NAME_FOR_NGU = "eno"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.131"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50011; // vnf p7 port [!] + remote_s_portd = 50010; // pnf p7 port [!] + tr_s_preference = "aerial"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; # 150; + pucch_TargetSNRx10 = 200; #200; + ulsch_max_frame_inactivity = 10; + dl_max_mcs = 28; + ul_max_mcs = 28; +} +); + + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 33c8ae0e25..b2434e196a 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -262,10 +262,12 @@ class EPCManagement(): logging.debug('Starting OAI CN5G') mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5) mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5) - mySSH.command('cd /opt/oai-cn5g-fed-v1.5/docker-compose', '\$', 5) + mySSH.command(f'cd {self.SourceCodePath}/docker-compose', '\$', 5) mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60) if re.search('start-mini-as-ue', self.cfgDeploy): dFile = 'docker-compose-mini-nrf-asue.yaml' + elif re.search('basic', self.cfgDeploy):\ + dFile = 'docker-compose-basic-nrf.yaml' else: dFile = 'docker-compose-mini-nrf.yaml' mySSH.command('docker-compose -f ' + dFile + ' ps -a', '\$', 60) @@ -582,7 +584,7 @@ class EPCManagement(): mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5) logging.debug('Terminating OAI CN5G') - mySSH.command('cd /opt/oai-cn5g-fed-v1.5/docker-compose', '\$', 5) + mySSH.command(f'cd {self.SourceCodePath}/docker-compose', '\$', 5) mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60) mySSH.command('docker volume prune --force || true', '\$', 60) time.sleep(2) diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml new file mode 100644 index 0000000000..51817790dd --- /dev/null +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -0,0 +1,139 @@ + + + TEST-AERIAL-SA + AERIAL 100 MHz TDD SA + tasks + 1 + + 111111 + 000222 + 001111 + 002222 + 002223 + 000111 + 100000 + 000011 + 000022 + 000033 + 000222 + 003333 + 222222 + + + + + Pull_Local_Registry + Pull Images from Local Registry + 0 + oai-gnb-aerial + + + + Initialize_UE + Initialize Quectel + sphex_quectel + + + + Deploy_Object + Deploy PNF/Nvidia CUBB in a container + ci-scripts/yaml_files/sa_gnb_aerial + nv-cubb + 0 + 0 + + + + Deploy_Object + Deploy VNF in a container + ci-scripts/yaml_files/sa_gnb_aerial + oai-gnb-aerial + 0 + 0 + + + + Attach_UE + Attach Quectel + sphex_quectel + + + + Custom_Command + Adding a IP route + sphex + sudo ip route add 192.168.71.128/26 via 12.1.1.151 dev wwan0 + + + + Ping + Ping: 100pings in 20sec + sphex_quectel + -c 100 -i 0.2 %cn_ip% + 5 + + + + Iperf + iperf (DL/UDP/80M)(30 sec)(single-ue profile) + -u -b 80M -t 30 -R + IPERF3 + sphex_quectel + 25 + 80 + + + + Iperf + iperf (UL/UDP/40M)(30 sec)(single-ue profile) + -u -b 40M -t 30 + IPERF3 + sphex_quectel + 25 + 80 + + + + Detach_UE + Detach Quectel + sphex_quectel + + + + Terminate_UE + Terminate Quectel + sphex_quectel + + + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_gnb_aerial + 0 + 0 + 20,100,100,100 + 20,100,100,100 + + + diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml b/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml new file mode 100644 index 0000000000..2a84098875 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml @@ -0,0 +1,52 @@ + + + test-aerial-cleanup + CleanUp AERIAL + trash + + 111111 + 222222 + 333333 + + + + + Clean_Test_Server_Images + Clean Test Images on Test Server + 0 + + + + Detach_UE + Terminate UE + sphex_quectel + + + + Terminate_UE + Terminate UE + sphex_quectel + + + diff --git a/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml b/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml new file mode 100644 index 0000000000..0ea2311a1f --- /dev/null +++ b/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml @@ -0,0 +1,45 @@ + + + cn5g-start-tab + CN5G-Start + log-in + + 000100 + 000200 + + + + + + Terminate_5GCN + Terminate 5G Core + --type stop-basic + + + + Initialize_5GCN + Initialize 5G Core + --type start-basic + + diff --git a/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml b/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml new file mode 100644 index 0000000000..592a60c620 --- /dev/null +++ b/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml @@ -0,0 +1,39 @@ + + + cn5g-start-tab + CN5G-Start + log-in + + 000300 + + + + + + Terminate_5GCN + Terminate 5G Core + --type stop-basic + + + diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh b/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh new file mode 100755 index 0000000000..25ba483694 --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Check if cuBB_SDK is defined, if not, use default path +cuBB_Path="${cuBB_SDK:-/opt/nvidia/cuBB}" + +# Run gdrcopy insmod +cd "$cuBB_Path"/cuPHY-CP/external/gdrcopy/ || exit 1 + +./insmod.sh +cd "$cuBB_Path" || exit 1 +# Add gdrcopy to LD_LIBRARY_PATH +export LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/opt/mellanox/dpdk/lib/x86_64-linux-gnu:/opt/mellanox/doca/lib/x86_64-linux-gnu:/opt/nvidia/cuBB/cuPHY-CP/external/gdrcopy/build/x86_64/ + +# Restart MPS +# Export variables +export CUDA_DEVICE_MAX_CONNECTIONS=8 +export CUDA_MPS_PIPE_DIRECTORY=/var +export CUDA_MPS_LOG_DIRECTORY=/var + +# Stop existing MPS +echo quit | nvidia-cuda-mps-control + +# Start MPS +nvidia-cuda-mps-control -d +echo start_server -uid 0 | nvidia-cuda-mps-control + +# Start cuphycontroller_scf +# Check if an argument is provided +if [ $# -eq 0 ]; then + # No argument provided, use default value + argument="P5G_SCF_FXN" +else + # Argument provided, use it + argument="$1" +fi + +"$cuBB_Path"/build/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf "$argument" \ No newline at end of file diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml new file mode 100644 index 0000000000..a13062705a --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml @@ -0,0 +1,65 @@ +version: "3.8" +services: + nv-cubb: + container_name: nv-cubb + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: + - gpu + network_mode: host + shm_size: 4096m + privileged: true + stdin_open: true + tty: true + volumes: + - /lib/modules:/lib/modules + - /dev/hugepages:/dev/hugepages + - /usr/src:/usr/src + - ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh + - /var/log/aerial:/var/log/aerial + - ../../../cmake_targets/share:/opt/cuBB/share + userns_mode: host + ipc: "shareable" + image: cubb-build:23-2 + environment: + - cuBB_SDK=/opt/nvidia/cuBB + command: bash -c " rm -rf /tmp/phy.log && chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh" + healthcheck: + test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1'] + interval: 20s + timeout: 5s + retries: 5 + oai-gnb-aerial: + cpuset: "13-20" + image: oai-gnb-aerial:latest + depends_on: + nv-cubb: + condition: service_healthy + privileged: true + ipc: "container:nv-cubb" + environment: + USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: + - gpu + network_mode: host + shm_size: 4096m + stdin_open: true + tty: true + volumes: + - ../../conf_files/gnb-vnf.sa.band78.273prb.aerial.conf:/opt/oai-gnb/etc/gnb.conf + container_name: oai-gnb-aerial + healthcheck: + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index fa488a42f7..36639371b3 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -22,7 +22,8 @@ | nokiabox | 172.21.19.39 | _None_ | gNB (Nokia), 5GC | _Nokia RF integrated_ | | avra | 172.21.16.124 | CI-Avra-Usage | gNB (n78) | AW2S Jaguar (192.168.80.239) | | orion | 172.21.16.134 | CI-Orion-Build-Sanity-Check-Deploy-Test, CI-Orion-DsTester-Deploy-Test | Build | | -| bellatrix | 172.21.16.104 | CI-Bellatrix-RAN-Docker | Static Code Analysis | -- | +| aerial2 | 172.21.16.131 | CI-Aerial2-Usage | gNB (PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial SDK integrated_ | +| sphex | 172.21.17.54 | CI-Sphex-Usage | Quectel | Quectel module | Note: The available resources, and their current usage, is indicated here: - [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/): @@ -188,6 +189,10 @@ information on how the images are built. ~5G-NR - 5G-NR SA test setup: gNB on avra(RHEL9.2) + N310, OAIUE on caracal(RHEL9.1) + N310, OAI CN5G - OpenShift cluster for CN deployment and container images for gNB and UE deployment +- [RAN-SA-AERIAL-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/) + ~5G-NR + - 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 (U22) + Foxconn RU, COTS UE (Quctel RM500Q), OAI CN5G + - container images for gNB deployment ### RAN-CI-NSA-Trigger From 782a850159ea72523d9d2bffd462994806c66af5 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 5 Mar 2024 12:20:27 +0100 Subject: [PATCH 38/41] tx_timestamp computation doesnt count slots from rx timestamp, and a small simplification just after --- executables/nr-ru.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 92fdc57e00..0bbc211fe8 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1331,11 +1331,10 @@ void *ru_thread( void *param ) { reset_meas(&ru->tx_fhaul); } proc->timestamp_tx = proc->timestamp_rx; - int sl=proc->tti_tx; - for (int slidx=0;slidxsl_ahead;slidx++) - proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp); - proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (proc->frame_rx + 1) & 1023 : proc->frame_rx; + for (int i = proc->tti_rx; i < proc->tti_rx + ru->sl_ahead; i++) + proc->timestamp_tx += fp->get_samples_per_slot(i % fp->slots_per_frame, fp); proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame; + proc->frame_tx = proc->tti_rx > proc->tti_tx ? (proc->frame_rx + 1) & 1023 : proc->frame_rx; int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp); int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]); @@ -1349,27 +1348,6 @@ void *ru_thread( void *param ) { if (ru->idx != 0) proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023; - LOG_D(NR_PHY, "In %d.%d: Checking L1 status\n", proc->frame_rx, proc->tti_rx); - for (int n = 0; n < RU_RX_SLOT_DEPTH; n++) - LOG_D(NR_PHY, "slot n %d => %d\n", n, rx_tti_busy[n]); - // handle potential race by blocking if rxdataF is being used by L1 - // collect all pending msg in L1 return fifo to not down the memory is available (rx_tti_busy[slot] boolean array) - notifiedFIFO_elt_t *res = pollNotifiedFIFO(&gNB->L1_rx_out); - LOG_D(NR_PHY, "%d.%d Polling L1_rx_out %p\n", proc->frame_rx, proc->tti_rx, res); - while (res) { - processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res); - LOG_D(NR_PHY, - "%d.%d res %d.%d completed, clearing %d\n", - proc->frame_rx, - proc->tti_rx, - info->frame_rx, - info->slot_rx, - info->slot_rx % RU_RX_SLOT_DEPTH); - - rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false; - res = pollNotifiedFIFO(&gNB->L1_rx_out); - } - LOG_D(NR_PHY, "%d.%d Done polling\n", proc->frame_rx, proc->tti_rx); // do RX front-end processing (frequency-shift, dft) if needed int slot_type = nr_slot_select(cfg, proc->frame_rx, proc->tti_rx); if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { @@ -1379,6 +1357,7 @@ void *ru_thread( void *param ) { LOG_D(NR_PHY, "%d.%d Waiting to access RX slot %d\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH); // now we block and wait our slot memory zone is freed from previous slot processing // as we can get other slots ending, we loop on the queue + notifiedFIFO_elt_t *res = NULL; while (not_done) { res = pullNotifiedFIFO(&gNB->L1_rx_out); if (!res) @@ -1414,17 +1393,16 @@ void *ru_thread( void *param ) { proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP); // Do PRACH RU processing - int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST); - uint8_t prachStartSymbol,N_dur; + int prach_id = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); if (prach_id>=0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0), T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2)); - N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt); + int N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt); for (int prach_oc = 0; prach_ocprach_list[prach_id].num_prach_ocas; prach_oc++) { - prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur; + int prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol + prach_oc * N_dur; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. rx_nr_prach_ru(ru, ru->prach_list[prach_id].fmt, //could also use format From 1ab3b8dd8e0a073079a8b0117274572a7bd498ba Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 6 Mar 2024 16:37:44 +0100 Subject: [PATCH 39/41] add version signature in core files to be able to compare with the ELF one --- executables/lte-softmodem.c | 5 +++-- executables/lte-uesoftmodem.c | 8 +++----- executables/main_ru.c | 6 +++--- executables/nr-cuup.c | 5 +++-- executables/nr-softmodem.c | 7 +++---- executables/nr-uesoftmodem.c | 8 ++++---- 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 69c67c950d..9e1adf1cbe 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -474,9 +474,10 @@ int main ( int argc, char **argv ) // to make a graceful exit when ctrl-c is pressed set_softmodem_sighandler(); #ifndef PACKAGE_VERSION -# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + // strdup to put the sring in the core file for post mortem identification + LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION)); /* Read configuration */ if (RC.nb_inst > 0) { diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index e26e10d6ee..a8f6d01227 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -76,9 +76,6 @@ #include "lte-softmodem.h" #include "executables/softmodem-common.h" -/* temporary compilation wokaround (UE/eNB split */ - - pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex @@ -579,9 +576,10 @@ int main( int argc, char **argv ) { // to make a graceful exit when ctrl-c is pressed set_softmodem_sighandler(); #ifndef PACKAGE_VERSION -# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + // strdup to put the sring in the core file for post mortem identification + LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION)); // init the parameters for (CC_id=0; CC_id Date: Fri, 8 Mar 2024 17:50:01 +0100 Subject: [PATCH 40/41] CI: mark as failed if UE log analysis fails --- ci-scripts/cls_containerize.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 60d0ccf568..0130ab07b1 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -1113,8 +1113,8 @@ class Containerize(): logging.debug(f'Analyzing UE logfile {filename}') logStatus = cls_oaicitest.OaiCiTest().AnalyzeLogFile_UE(f'{filename}', HTML, RAN) if (logStatus < 0): - fullStatus = False HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus) + self.exitStatus = 1 else: HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK) else: @@ -1385,6 +1385,7 @@ class Containerize(): logStatus = UE.AnalyzeLogFile_UE(f'{logPath}/{filename}', HTML, RAN) if (logStatus < 0): fullStatus = False + self.exitStatus = 1 HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus) else: HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK) From 73509757ad512f09fe4cb0654b34cb80a63905a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20da=20Silva?= Date: Mon, 11 Mar 2024 16:05:36 +0100 Subject: [PATCH 41/41] Move Aerial nFAPI enum entry to end Some places (e.g., 4G eNB/UE nfapi mode) use numbers for the FAPI mode, directly mapping to an enum. Aerial being in the middle messes up these numbers. Put it at the end to limit possible problems. --- nfapi/oai_integration/vendor_ext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nfapi/oai_integration/vendor_ext.h b/nfapi/oai_integration/vendor_ext.h index fe9117cad0..1bc8409bc4 100644 --- a/nfapi/oai_integration/vendor_ext.h +++ b/nfapi/oai_integration/vendor_ext.h @@ -68,10 +68,10 @@ typedef enum { NFAPI_MONOLITHIC=0, NFAPI_MODE_PNF, NFAPI_MODE_VNF, - NFAPI_MODE_AERIAL, NFAPI_UE_STUB_PNF, NFAPI_UE_STUB_OFFNET, NFAPI_MODE_STANDALONE_PNF, + NFAPI_MODE_AERIAL, NFAPI_MODE_UNKNOWN } nfapi_mode_t;