From bc27d1e6912f7b710e3c310f00c8d87cfea11d4d Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 18 Dec 2024 15:57:55 +0100 Subject: [PATCH 01/19] improvements in SIB2 message (info taken from commercial gNB) --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 79 ++++++++++++++++++----------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index beb8de2e3a..d0224300e2 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -199,49 +199,68 @@ int xer_nr_sprint(char *string, size_t string_size, asn_TYPE_descriptor_t *td, v int do_SIB23_NR(rrc_gNB_carrier_data_t *carrier) { - asn_enc_rval_t enc_rval; - SystemInformation_IEs__sib_TypeAndInfo__Member *sib2 = NULL; - SystemInformation_IEs__sib_TypeAndInfo__Member *sib3 = NULL; - - NR_BCCH_DL_SCH_Message_t *sib_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); + NR_BCCH_DL_SCH_Message_t *sib_message = calloc(1,sizeof(NR_BCCH_DL_SCH_Message_t)); sib_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; - sib_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); + sib_message->message.choice.c1 = calloc(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); sib_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation; - sib_message->message.choice.c1->choice.systemInformation = CALLOC(1,sizeof(struct NR_SystemInformation)); + sib_message->message.choice.c1->choice.systemInformation = calloc(1,sizeof(struct NR_SystemInformation)); struct NR_SystemInformation *sib = sib_message->message.choice.c1->choice.systemInformation; sib->criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation; - sib->criticalExtensions.choice.systemInformation = CALLOC(1, sizeof(struct NR_SystemInformation_IEs)); + sib->criticalExtensions.choice.systemInformation = calloc(1, sizeof(struct NR_SystemInformation_IEs)); struct NR_SystemInformation_IEs *ies = sib->criticalExtensions.choice.systemInformation; - sib2 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member)); - sib2->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2; - sib2->choice.sib2 = CALLOC(1, sizeof(struct NR_SIB2)); - sib2->choice.sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB1; - sib2->choice.sib2->cellReselectionServingFreqInfo.threshServingLowP = 2; // INTEGER (0..31) - sib2->choice.sib2->cellReselectionServingFreqInfo.cellReselectionPriority = 2; // INTEGER (0..7) - sib2->choice.sib2->intraFreqCellReselectionInfo.q_RxLevMin = -50; // INTEGER (-70..-22) - sib2->choice.sib2->intraFreqCellReselectionInfo.s_IntraSearchP = 2; // INTEGER (0..31) - sib2->choice.sib2->intraFreqCellReselectionInfo.t_ReselectionNR = 2; // INTEGER (0..7) - sib2->choice.sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell = true; + SystemInformation_IEs__sib_TypeAndInfo__Member *sib2_ie = calloc(1, sizeof(*sib2_ie)); + sib2_ie->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2; + NR_SIB2_t *sib2 = calloc(1, sizeof(*sib2)); + sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB0; + struct NR_SIB2__cellReselectionInfoCommon__speedStateReselectionPars *speed = calloc(1, sizeof(*speed)); + NR_MobilityStateParameters_t mobilityStateParameters = {0}; + mobilityStateParameters.t_Evaluation = NR_MobilityStateParameters__t_Evaluation_s30; + mobilityStateParameters.t_HystNormal = NR_MobilityStateParameters__t_HystNormal_s30; + mobilityStateParameters.n_CellChangeMedium = 1; + mobilityStateParameters.n_CellChangeHigh = 2; + speed->mobilityStateParameters = mobilityStateParameters; + struct NR_SIB2__cellReselectionInfoCommon__speedStateReselectionPars__q_HystSF qhyst = {0}; + qhyst.sf_Medium = NR_SIB2__cellReselectionInfoCommon__speedStateReselectionPars__q_HystSF__sf_Medium_dB_4; + qhyst.sf_High = NR_SIB2__cellReselectionInfoCommon__speedStateReselectionPars__q_HystSF__sf_High_dB_6; + speed->q_HystSF = qhyst; + sib2->cellReselectionInfoCommon.speedStateReselectionPars = speed; + sib2->cellReselectionServingFreqInfo.cellReselectionPriority = 0; // INTEGER (0..7) + sib2->cellReselectionServingFreqInfo.threshServingLowP = 0; + NR_ReselectionThresholdQ_t *threshServingLowQ = calloc(1, sizeof(*threshServingLowQ)); + *threshServingLowQ = 0; + sib2->cellReselectionServingFreqInfo.threshServingLowQ = threshServingLowQ; + sib2->intraFreqCellReselectionInfo.q_RxLevMin = -56; // INTEGER (-70..-22) + sib2->intraFreqCellReselectionInfo.s_IntraSearchP = 22; // INTEGER (0..31) + sib2->intraFreqCellReselectionInfo.t_ReselectionNR = 1; // INTEGER (0..7) + sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell = true; + NR_SSB_MTC_t *ssbmtc = calloc(1, sizeof(*ssbmtc)); + ssbmtc->duration = NR_SSB_MTC__duration_sf5; + ssbmtc->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20; + ssbmtc->periodicityAndOffset.choice.sf20 = 0; + sib2->intraFreqCellReselectionInfo.smtc = ssbmtc; + sib2_ie->choice.sib2 = sib2; asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib2); - sib3 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member)); - sib3->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3; - sib3->choice.sib3 = CALLOC(1, sizeof(struct NR_SIB3)); - asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib3); + SystemInformation_IEs__sib_TypeAndInfo__Member *sib3_ie = calloc(1, sizeof(*sib3_ie)); + sib3_ie->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3; + sib3_ie->choice.sib3 = calloc(1, sizeof(*sib3_ie->choice.sib3)); + asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib3_ie); //encode SIB to data // carrier->SIB23 = (uint8_t *) malloc16(128); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, - NULL, - (void *)sib_message, - carrier->SIB23, - 100); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, + NULL, + (void *)sib_message, + carrier->SIB23, + 100); + AssertFatal (enc_rval.encoded > 0, + "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, + enc_rval.encoded); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, sib_message); - return((enc_rval.encoded+7)/8); + return((enc_rval.encoded + 7) / 8); } int do_RRCReject(uint8_t *const buffer) From 4b23c7ea65859c244dd2b86ede4354bdf91b2fff Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 18 Dec 2024 18:00:07 +0100 Subject: [PATCH 02/19] F1 transmission from CU to DU of SIB2 --- openair2/GNB_APP/gnb_config.c | 24 ++++++++++++ openair2/GNB_APP/gnb_paramdef.h | 5 +++ .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 4 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 39 +++---------------- openair2/RRC/NR/MESSAGES/asn1_msg.h | 2 +- openair2/RRC/NR/nr_rrc_defs.h | 17 ++++---- openair2/RRC/NR/rrc_gNB.c | 14 ++++--- openair2/RRC/NR/rrc_gNB_du.c | 11 ++++++ 8 files changed, 64 insertions(+), 52 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index deb8835157..34fd7a7f2b 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1846,6 +1846,28 @@ static int sort_neighbour_cell_config_by_cell_id(const void *a, const void *b) return 0; } +static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray) +{ + if (!config_isparamset(GNBparamarray, GNB_CU_SIBS_IDX)) + return NULL; + + seq_arr_t *SIBs = malloc(sizeof(seq_arr_t)); + seq_arr_init(SIBs, sizeof(rrc_SIBs_t)); + for (int i = 0; i < GNBparamarray[GNB_CU_SIBS_IDX].numelt; i++) { + int sib_value = GNBparamarray[GNB_CU_SIBS_IDX].iptr[i]; + // SIB10, SIB12, SIB13, SIB14, SIB15, SIB17, SIB18, SIB19 and SIB20 are generated by the DU + // all the rest in the CU + AssertFatal((sib_value > 1 && sib_value < 10) || sib_value == 11 || sib_value == 16, + "SIB%d is not a CU SIB, to be configured in DU section\n", + sib_value); + rrc_SIBs_t *cu_sib = calloc_or_fail(1, sizeof(*cu_sib)); + cu_sib->SIB_type = sib_value; + LOG_I(GNB_APP, "activate SIB%d at CU\n", sib_value); + seq_arr_push_back(SIBs, cu_sib, sizeof(rrc_SIBs_t)); + } + return SIBs; +} + static void fill_neighbour_cell_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc) { char gnbpath[MAX_OPTNAME_SIZE + 8]; @@ -2085,6 +2107,8 @@ gNB_RRC_INST *RCconfig_NRRRC() fill_measurement_configuration(k, rrc); + rrc->SIBs = fill_cu_sibs(GNBParamList.paramarray[i]); + paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 7f7fccbd8f..e8d36c55ae 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -139,6 +139,7 @@ typedef enum { #define GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES "num_ulharq" #define GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST "beam_weights" #define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels" +#define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs" #define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n" #define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support" @@ -150,6 +151,7 @@ typedef enum { #define GNB_CONFIG_HLP_NUM_DL_HARQ "Set Num DL harq processes. Valid values 2,4,6,8,10,12,16,32. Default 16" #define GNB_CONFIG_HLP_NUM_UL_HARQ "Set Num UL harq processes. Valid values 16,32. Default 16" #define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1" +#define GNB_CONFIG_HLP_CU_SIBS "List of CU generated SIBs to be transmitted" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ @@ -195,6 +197,7 @@ typedef enum { {GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ {GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST, \ GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \ +{GNB_CONFIG_STRING_CU_SIB_LIST, GNB_CONFIG_HLP_CU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ } // clang-format on @@ -236,6 +239,7 @@ typedef enum { #define GNB_NUM_UL_HARQ_IDX 34 #define GNB_BEAMWEIGHTS_IDX 35 #define GNB_UESS_AGG_LEVEL_LIST_IDX 36 +#define GNB_CU_SIBS_IDX 37 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32} @@ -279,6 +283,7 @@ typedef enum { { .s1 = { config_check_intval, NUM_UL_HARQ_OKVALUES,2 } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ 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 25a182dddb..9d19fe1c65 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -165,7 +165,9 @@ void f1_setup_response(const f1ap_setup_resp_t *resp) AssertFatal(check_plmn_identity(&du_cell->plmn, &cu_cell->plmn), "PLMN mismatch\n"); AssertFatal(du_cell->nr_pci == cu_cell->nrpci, "PCI mismatch: DU %d vs CU %d\n", du_cell->nr_pci, cu_cell->nrpci); - AssertFatal(cu_cell->num_SI == 0, "handling of CU-provided SIBs: not implemented\n"); + for (int i = 0; i < cu_cell->num_SI; i++) { + // TODO implement handling reception of SIBs in DU + } mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp)); AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n"); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index d0224300e2..0b811b11ad 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -197,21 +197,8 @@ int xer_nr_sprint(char *string, size_t string_size, asn_TYPE_descriptor_t *td, v //------------------------------------------------------------------------------ -int do_SIB23_NR(rrc_gNB_carrier_data_t *carrier) +int do_SIB2_NR(uint8_t **msg_SIB2) { - NR_BCCH_DL_SCH_Message_t *sib_message = calloc(1,sizeof(NR_BCCH_DL_SCH_Message_t)); - sib_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; - sib_message->message.choice.c1 = calloc(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); - sib_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation; - sib_message->message.choice.c1->choice.systemInformation = calloc(1,sizeof(struct NR_SystemInformation)); - - struct NR_SystemInformation *sib = sib_message->message.choice.c1->choice.systemInformation; - sib->criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation; - sib->criticalExtensions.choice.systemInformation = calloc(1, sizeof(struct NR_SystemInformation_IEs)); - - struct NR_SystemInformation_IEs *ies = sib->criticalExtensions.choice.systemInformation; - SystemInformation_IEs__sib_TypeAndInfo__Member *sib2_ie = calloc(1, sizeof(*sib2_ie)); - sib2_ie->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2; NR_SIB2_t *sib2 = calloc(1, sizeof(*sib2)); sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB0; struct NR_SIB2__cellReselectionInfoCommon__speedStateReselectionPars *speed = calloc(1, sizeof(*speed)); @@ -240,27 +227,11 @@ int do_SIB23_NR(rrc_gNB_carrier_data_t *carrier) ssbmtc->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20; ssbmtc->periodicityAndOffset.choice.sf20 = 0; sib2->intraFreqCellReselectionInfo.smtc = ssbmtc; - sib2_ie->choice.sib2 = sib2; - asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib2); - SystemInformation_IEs__sib_TypeAndInfo__Member *sib3_ie = calloc(1, sizeof(*sib3_ie)); - sib3_ie->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3; - sib3_ie->choice.sib3 = calloc(1, sizeof(*sib3_ie->choice.sib3)); - asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib3_ie); - - //encode SIB to data - // carrier->SIB23 = (uint8_t *) malloc16(128); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, - NULL, - (void *)sib_message, - carrier->SIB23, - 100); - AssertFatal (enc_rval.encoded > 0, - "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, - enc_rval.encoded); - ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, sib_message); - return((enc_rval.encoded + 7) / 8); + ssize_t size = uper_encode_to_new_buffer(&asn_DEF_NR_SIB2, NULL, (void *)sib2, (void **)msg_SIB2); + AssertFatal (size > 0, "ASN1 message encoding failed (encoded %lu bytes)!\n", size); + ASN_STRUCT_FREE(asn_DEF_NR_SIB2, sib2); + return size; } int do_RRCReject(uint8_t *const buffer) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index a6c5e25aec..3916305171 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -66,7 +66,7 @@ struct asn_TYPE_descriptor_s; */ int xer_sprint_NR(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr); -int do_SIB23_NR(rrc_gNB_carrier_data_t *carrier); +int do_SIB2_NR(uint8_t **msg_SIB2); int do_RRCReject(uint8_t *const buffer); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index c30f8856bc..51f2d427e5 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -268,15 +268,6 @@ typedef struct rrc_gNB_ue_context_s { struct gNB_RRC_UE_s ue_context; } rrc_gNB_ue_context_t; -typedef struct { - - uint8_t *SIB23; - int sizeof_SIB23; - -} rrc_gNB_carrier_data_t; -//--------------------------------------------------- - - typedef struct { /* nea0 = 0, nea1 = 1, ... */ int ciphering_algorithms[4]; @@ -370,6 +361,12 @@ typedef struct nr_rrc_cuup_container_t { sctp_assoc_t assoc_id; } nr_rrc_cuup_container_t; +typedef struct { + uint8_t *SIB_buffer; + int SIB_size; + int SIB_type; +} rrc_SIBs_t; + //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -378,7 +375,6 @@ typedef struct gNB_RRC_INST_s { char *node_name; int module_id; eth_params_t eth_params_s; - rrc_gNB_carrier_data_t carrier; uid_allocator_t uid_allocator; RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti /// NR cell id @@ -386,6 +382,7 @@ typedef struct gNB_RRC_INST_s { // RRC configuration gNB_RrcConfigurationReq configuration; + seq_arr_t *SIBs; // gNB N3 GTPU instance instance_t e1_inst; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7eef21c810..0acba1797c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -221,13 +221,15 @@ static void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, static void init_NR_SI(gNB_RRC_INST *rrc) { if (!NODE_IS_DU(rrc->node_type)) { - rrc->carrier.SIB23 = (uint8_t *) malloc16(100); - AssertFatal(rrc->carrier.SIB23 != NULL, "cannot allocate memory for SIB"); - rrc->carrier.sizeof_SIB23 = do_SIB23_NR(&rrc->carrier); - LOG_I(NR_RRC, "do_SIB23_NR, size %d\n", rrc->carrier.sizeof_SIB23); - AssertFatal(rrc->carrier.sizeof_SIB23 != 255,"FATAL, RC.nrrrc[mod].carrier[CC_id].sizeof_SIB23 == 255"); + seq_arr_t *sibs = rrc->SIBs; + if (sibs) { + for (int i = 0; i < sibs->size; i++) { + rrc_SIBs_t *sib = (rrc_SIBs_t *)seq_arr_at(sibs, i); + AssertFatal(sib->SIB_type == 2, "Only SIB2 currently implemented\n"); + sib->SIB_size = do_SIB2_NR(&sib->SIB_buffer); + } + } } - if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n"); rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 6c7c157374..10113c21aa 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -397,6 +397,17 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) .num_SI = 0, }; + seq_arr_t *sibs = rrc->SIBs; + if (sibs) { + for (int i = 0; i < sibs->size; i++) { + rrc_SIBs_t *si = (rrc_SIBs_t *)seq_arr_at(sibs, i); + cell.SI_msg[cell.num_SI].SI_container = si->SIB_buffer; + cell.SI_msg[cell.num_SI].SI_container_length = si->SIB_size; + cell.SI_msg[cell.num_SI].SI_type = si->SIB_type; + cell.num_SI++; + } + } + if (du->mib != NULL && du->sib1 != NULL) label_intra_frequency_neighbours(rrc, du, cell_info); From 535d8e77657bac1b87e7cd7f5770abfb50fa5bbd Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 19 Dec 2024 19:29:23 +0100 Subject: [PATCH 03/19] other SIBs scheduling configuration in SIB1 --- common/utils/nr/nr_common.h | 6 + executables/nr-softmodem.c | 13 +- openair2/GNB_APP/gnb_config.c | 56 ++++- openair2/GNB_APP/gnb_config.h | 8 +- openair2/GNB_APP/gnb_paramdef.h | 5 + openair2/LAYER2/NR_MAC_gNB/config.c | 102 ++++++++- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 - openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 7 +- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 10 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 8 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 6 +- openair2/RRC/NR/MESSAGES/asn1_msg.h | 2 +- openair2/RRC/NR/nr_rrc_config.c | 208 ++++++++++-------- openair2/RRC/NR/nr_rrc_config.h | 10 +- openair2/RRC/NR/nr_rrc_defs.h | 6 - openair2/RRC/NR/rrc_gNB.c | 36 +-- openair2/RRC/NR/rrc_gNB_du.c | 28 ++- 17 files changed, 315 insertions(+), 198 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index fdb3cc7ffc..d064b522b9 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -93,6 +93,12 @@ static inline const char *rnti_types(nr_rnti_type_t rr) // the total shift is 2 * 15, in dB scale thats 10log10(2^(15*2)) #define SQ15_SQUARED_NORM_FACTOR_DB 90.3089986992 +typedef struct { + uint8_t *SIB_buffer; + int SIB_size; + int SIB_type; +} nr_SIBs_t; + typedef struct nr_bandentry_s { int16_t band; uint64_t ul_min; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 482da9a1cf..4f9ae49c42 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -464,23 +464,14 @@ int start_L1L2(module_id_t gnb_id) NR_BCCH_BCH_Message_t *mib = mac->common_channels[0].mib; const NR_BCCH_DL_SCH_Message_t *sib1 = mac->common_channels[0].sib1; - - /* update existing config in F1 Setup request structures */ f1ap_setup_req_t *sr = mac->f1_config.setup_req; DevAssert(sr->num_cells_available == 1); f1ap_served_cell_info_t *info = &sr->cell[0].info; DevAssert(info->mode == F1AP_MODE_TDD); + /* update existing config in F1 Setup request structures */ DevAssert(scc->tdd_UL_DL_ConfigurationCommon != NULL); info->tdd = read_tdd_config(scc); /* updates radio config */ - /* send gNB-DU configuration update to RRC */ - f1ap_gnb_du_configuration_update_t update = { - .transaction_id = 1, - .num_cells_to_modify = 1, - }; - update.cell_to_modify[0].old_nr_cellid = info->nr_cellid; - update.cell_to_modify[0].info = *info; - update.cell_to_modify[0].sys_info = get_sys_info(mib, sib1); - mac->mac_rrc.gnb_du_configuration_update(&update); + prepare_du_configuration_update(mac, info, mib, sib1); init_NR_RU(config_get_if(), NULL); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 34fd7a7f2b..5a58f23006 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1312,7 +1312,7 @@ static f1ap_fdd_info_t read_fdd_config(const NR_ServingCellConfigCommon_t *scc) return fdd; } -f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1) +f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1, seq_arr_t *du_SIBs) { int buf_len = 3; f1ap_gnb_du_system_info_t *sys_info = calloc_or_fail(1, sizeof(*sys_info)); @@ -1329,15 +1329,24 @@ f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCC AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); sys_info->sib1_length = (enc_rval.encoded + 7) / 8; + if (du_SIBs) { + for (int i = 0; i < du_SIBs->size; i++) { + nr_SIBs_t *si = (nr_SIBs_t *)seq_arr_at(du_SIBs, i); + // other SIB in gNB-DU System Information not implemented yet + // only DU SIB not included in this message is SIB19 + AssertFatal(si->SIB_type == 19, "Cannot handle SIB%d in gNB-DU System Information\n", si->SIB_type); + } + } return sys_info; } -f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, +static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, const char *name, const f1ap_served_cell_info_t *info, const NR_ServingCellConfigCommon_t *scc, NR_BCCH_BCH_Message_t *mib, - const NR_BCCH_DL_SCH_Message_t *sib1) + const NR_BCCH_DL_SCH_Message_t *sib1, + seq_arr_t *du_SIBs) { f1ap_setup_req_t *req = calloc(1, sizeof(*req)); AssertFatal(req != NULL, "out of memory\n"); @@ -1381,7 +1390,7 @@ f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, if (IS_SA_MODE(get_softmodem_params())) { // in NSA we don't transmit SIB1, so cannot fill DU system information // so cannot send MIB either - req->cell[0].sys_info = get_sys_info(mib, sib1); + req->cell[0].sys_info = get_sys_info(mib, sib1, du_SIBs); } int num = read_version(TO_STRING(NR_RRC_VERSION), &req->rrc_ver[0], &req->rrc_ver[1], &req->rrc_ver[2]); @@ -1421,6 +1430,28 @@ static nr_redcap_config_t *get_redcap_config(int gnb_idx) return rc; } +static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray) +{ + if (!config_isparamset(GNBparamarray, GNB_DU_SIBS_IDX)) + return NULL; + + seq_arr_t *du_SIBs = malloc(sizeof(seq_arr_t)); + seq_arr_init(du_SIBs, sizeof(nr_SIBs_t)); + for (int i = 0; i < GNBparamarray[GNB_DU_SIBS_IDX].numelt; i++) { + int sib_value = GNBparamarray[GNB_DU_SIBS_IDX].iptr[i]; + // SIB10, SIB12, SIB13, SIB14, SIB15, SIB17, SIB18, SIB19 and SIB20 are generated by the DU + // all the rest in the DU + AssertFatal((sib_value > 9 && sib_value < 21) && sib_value != 11 && sib_value != 16, + "SIB%d is not a DU SIB, to be configured in DU section\n", + sib_value); + nr_SIBs_t *du_sib = calloc_or_fail(1, sizeof(nr_SIBs_t)); + du_sib->SIB_type = sib_value; + LOG_I(GNB_APP, "activate SIB%d at DU\n", sib_value); + seq_arr_push_back(du_SIBs, du_sib, sizeof(nr_SIBs_t)); + } + return du_SIBs; +} + void RCconfig_nr_macrlc(configmodule_interface_t *cfg) { int j = 0; @@ -1692,17 +1723,18 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) f1ap_served_cell_info_t info; read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1); - if (IS_SA_MODE(get_softmodem_params())) { + NR_COMMON_channels_t *cc = &RC.nrmac[0]->common_channels[0]; + cc->du_SIBs = fill_du_sibs(GNBParamList.paramarray[0]); + + if (IS_SA_MODE(get_softmodem_params())) nr_mac_configure_sib1(RC.nrmac[0], &info.plmn, info.nr_cellid, *info.tac); - if (scc->ext2 && scc->ext2->ntn_Config_r17) - nr_mac_configure_sib19(RC.nrmac[0]); - } // read F1 Setup information from config and generated MIB/SIB1 // and store it at MAC for sending later NR_BCCH_BCH_Message_t *mib = RC.nrmac[0]->common_channels[0].mib; const NR_BCCH_DL_SCH_Message_t *sib1 = RC.nrmac[0]->common_channels[0].sib1; - f1ap_setup_req_t *req = RC_read_F1Setup(gnb_du_id, name, &info, scc, mib, sib1); + seq_arr_t *du_SIBs = RC.nrmac[0]->common_channels[0].du_SIBs; + f1ap_setup_req_t *req = RC_read_F1Setup(gnb_du_id, name, &info, scc, mib, sib1, du_SIBs); AssertFatal(req != NULL, "could not read F1 Setup information\n"); RC.nrmac[0]->f1_config.setup_req = req; RC.nrmac[0]->f1_config.gnb_id = gnb_id; @@ -1852,7 +1884,7 @@ static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray) return NULL; seq_arr_t *SIBs = malloc(sizeof(seq_arr_t)); - seq_arr_init(SIBs, sizeof(rrc_SIBs_t)); + seq_arr_init(SIBs, sizeof(nr_SIBs_t)); for (int i = 0; i < GNBparamarray[GNB_CU_SIBS_IDX].numelt; i++) { int sib_value = GNBparamarray[GNB_CU_SIBS_IDX].iptr[i]; // SIB10, SIB12, SIB13, SIB14, SIB15, SIB17, SIB18, SIB19 and SIB20 are generated by the DU @@ -1860,10 +1892,10 @@ static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray) AssertFatal((sib_value > 1 && sib_value < 10) || sib_value == 11 || sib_value == 16, "SIB%d is not a CU SIB, to be configured in DU section\n", sib_value); - rrc_SIBs_t *cu_sib = calloc_or_fail(1, sizeof(*cu_sib)); + nr_SIBs_t *cu_sib = calloc_or_fail(1, sizeof(*cu_sib)); cu_sib->SIB_type = sib_value; LOG_I(GNB_APP, "activate SIB%d at CU\n", sib_value); - seq_arr_push_back(SIBs, cu_sib, sizeof(rrc_SIBs_t)); + seq_arr_push_back(SIBs, cu_sib, sizeof(nr_SIBs_t)); } return SIBs; } diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index baf4ad5d94..f9d23ccba4 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -95,14 +95,8 @@ gNB_RRC_INST *RCconfig_NRRRC(); int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); void wait_f1_setup_response(void); -f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, - const char *name, - const f1ap_served_cell_info_t *info, - const NR_ServingCellConfigCommon_t *scc, - NR_BCCH_BCH_Message_t *mib, - const NR_BCCH_DL_SCH_Message_t *sib1); f1ap_tdd_info_t read_tdd_config(const NR_ServingCellConfigCommon_t *scc); -f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1); +f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1, seq_arr_t *du_SIBs); int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update); MessageDef *RCconfig_NR_CU_E1(const E1_t *entity); ngran_node_t get_node_type(void); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index e8d36c55ae..c76b6bc143 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -140,6 +140,7 @@ typedef enum { #define GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST "beam_weights" #define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels" #define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs" +#define GNB_CONFIG_STRING_DU_SIB_LIST "du_sibs" #define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n" #define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support" @@ -152,6 +153,7 @@ typedef enum { #define GNB_CONFIG_HLP_NUM_UL_HARQ "Set Num UL harq processes. Valid values 16,32. Default 16" #define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1" #define GNB_CONFIG_HLP_CU_SIBS "List of CU generated SIBs to be transmitted" +#define GNB_CONFIG_HLP_DU_SIBS "List of DU generated SIBs to be transmitted" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ @@ -198,6 +200,7 @@ typedef enum { {GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST, \ GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \ {GNB_CONFIG_STRING_CU_SIB_LIST, GNB_CONFIG_HLP_CU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ +{GNB_CONFIG_STRING_DU_SIB_LIST, GNB_CONFIG_HLP_DU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ } // clang-format on @@ -240,6 +243,7 @@ typedef enum { #define GNB_BEAMWEIGHTS_IDX 35 #define GNB_UESS_AGG_LEVEL_LIST_IDX 36 #define GNB_CU_SIBS_IDX 37 +#define GNB_DU_SIBS_IDX 38 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32} @@ -284,6 +288,7 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 19efd1d401..c9a58a4e4a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -38,6 +38,7 @@ #include "BIT_STRING.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "GNB_APP/gnb_config.h" #include "NR_MIB.h" #include "NR_MAC_gNB/nr_mac_gNB.h" #include "NR_BCCH-BCH-Message.h" @@ -889,6 +890,94 @@ void nr_fill_sched_osi(gNB_MAC_INST *nrmac, const struct NR_SetupRelease_PDCCH_C } } +bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]) +{ + NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; + seq_arr_t *du_SIBs = nrmac->common_channels[0].du_SIBs; + int num_du_sib = 0; + if (du_SIBs) + num_du_sib = du_SIBs->size; + if (num_cu_sib + num_du_sib == 0) + return false; /* no updates */ + + int config_sibs[num_cu_sib + num_du_sib]; + NR_SystemInformation_IEs_t *sysInfo = calloc(1, sizeof(*sysInfo)); //for SIB up to 14 included + NR_SystemInformation_IEs_t *sysInfov17 = calloc(1, sizeof(*sysInfov17)); // for othersibs + for (int i = 0; i < num_cu_sib; i++) { + config_sibs[i] = cu_sib[i].SI_type; + switch (config_sibs[i]) { + case 2: { + struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type = calloc(1, sizeof(*type)); + type->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2; + // SIB2 coming from CU need to decode it + NR_SIB2_t *sib2 = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_SIB2, + (void **)&sib2, + cu_sib[i].SI_container, + cu_sib[i].SI_container_length, + 0, + 0); + if (dec_rval.code != RC_OK) { + LOG_E(NR_MAC, "cannot decode SIB%d from CU\n", config_sibs[i]); + ASN_STRUCT_FREE(asn_DEF_NR_SIB2, cu_sib[i].SI_container); + } + type->choice.sib2 = sib2; + add_sib_to_systeminformation(sysInfo, type); + break; + } + default : + AssertFatal(false, "Invalid or not supported SIB%d\n", config_sibs[i]); + } + } + + for (int i = 0; i < num_du_sib; i++) { + nr_SIBs_t *si = (nr_SIBs_t *)seq_arr_at(du_SIBs, i); + int sib_idx = i + num_cu_sib; + config_sibs[sib_idx] = si->SIB_type; + switch (config_sibs[sib_idx]) { + case 19: { + struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type_du = calloc(1, sizeof(*type_du)); + type_du->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700; + NR_SIB19_r17_t *sib19 = get_SIB19_NR(cc->ServingCellConfigCommon); + type_du->choice.sib19_v1700 = sib19; + add_sib_to_systeminformation(sysInfov17, type_du); + break; + } + default : + AssertFatal(false, "Invalid or not supported SIB%d\n", sib_idx); + } + } + + update_SIB1_NR_SI(cc->sib1, num_cu_sib + num_du_sib, config_sibs); + cc->sib1_bcch_length = encode_SIB_NR(cc->sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu)); + AssertFatal(cc->sib1_bcch_length > 0, "could not encode SIB1\n"); + + // generate otherSIB payloads + cc->other_sib_bcch_length[0] = encode_sysinfo_ie(sysInfo, cc->other_sib_bcch_pdu[0], sizeof(cc->other_sib_bcch_pdu[0])); + cc->other_sib_bcch_length[1] = encode_sysinfo_ie(sysInfov17, cc->other_sib_bcch_pdu[1], sizeof(cc->other_sib_bcch_pdu[1])); + + ASN_STRUCT_FREE(asn_DEF_NR_SystemInformation_IEs, sysInfo); + ASN_STRUCT_FREE(asn_DEF_NR_SystemInformation_IEs, sysInfov17); + return true; +} + +void prepare_du_configuration_update(gNB_MAC_INST *mac, + f1ap_served_cell_info_t *info, + NR_BCCH_BCH_Message_t *mib, + const NR_BCCH_DL_SCH_Message_t *sib1) +{ + /* send gNB-DU configuration update to RRC */ + f1ap_gnb_du_configuration_update_t update = { + .transaction_id = 1, + .num_cells_to_modify = 1, + }; + update.cell_to_modify[0].old_nr_cellid = info->nr_cellid; + update.cell_to_modify[0].info = *info; + update.cell_to_modify[0].sys_info = get_sys_info(mib, sib1, NULL); + mac->mac_rrc.gnb_du_configuration_update(&update); +} + void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_t cellID, int tac) { AssertFatal(IS_SA_MODE(get_softmodem_params()), "error: SIB1 only applicable for SA\n"); @@ -897,21 +986,10 @@ void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(scc, plmn, cellID, tac, &nrmac->radio_config); cc->sib1 = sib1; - cc->sib1_bcch_length = encode_SIB1_NR(sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu)); + cc->sib1_bcch_length = encode_SIB_NR(sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu)); AssertFatal(cc->sib1_bcch_length > 0, "could not encode SIB1\n"); } -void nr_mac_configure_sib19(gNB_MAC_INST *nrmac) -{ - AssertFatal(IS_SA_MODE(get_softmodem_params()), "error: SIB19 only applicable for SA\n"); - NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_BCCH_DL_SCH_Message_t *sib19 = get_SIB19_NR(scc); - cc->sib19 = sib19; - cc->sib19_bcch_length = encode_SIB19_NR(sib19, cc->sib19_bcch_pdu, sizeof(cc->sib19_bcch_pdu)); - AssertFatal(cc->sib19_bcch_length > 0, "could not encode SIB19\n"); -} - bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup) { /* ideally, instead of this function, "users" of this function should call diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 65928fbea3..f86812f893 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -219,8 +219,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo // SIB19 will be scheduled if ntn_Config_r17 is initialized if (IS_SA_MODE(get_softmodem_params())) { schedule_nr_sib1(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req); - if (cc->sib19) - schedule_nr_sib19(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req, cc->sib19_bcch_length, cc->sib19_bcch_pdu); } // This schedule PRACH if we are not in phy_test mode diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 65c5aba9f1..2a6ee13a2b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -56,8 +56,7 @@ void nr_mac_send_f1_setup_req(void); void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *mac_config); void nr_fill_sched_osi(gNB_MAC_INST *nrmac, const struct NR_SetupRelease_PDCCH_ConfigCommon *pdcch_ConfigCommon); void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_t cellID, int tac); -void nr_mac_configure_sib19(gNB_MAC_INST *nrmac); - +bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]); bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); @@ -474,4 +473,8 @@ bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid); bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti); void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected); +void prepare_du_configuration_update(gNB_MAC_INST *mac, + f1ap_served_cell_info_t *info, + NR_BCCH_BCH_Message_t *mib, + const NR_BCCH_DL_SCH_Message_t *sib1); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ 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 9d19fe1c65..ca07d1555a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -165,8 +165,14 @@ void f1_setup_response(const f1ap_setup_resp_t *resp) AssertFatal(check_plmn_identity(&du_cell->plmn, &cu_cell->plmn), "PLMN mismatch\n"); AssertFatal(du_cell->nr_pci == cu_cell->nrpci, "PCI mismatch: DU %d vs CU %d\n", du_cell->nr_pci, cu_cell->nrpci); - for (int i = 0; i < cu_cell->num_SI; i++) { - // TODO implement handling reception of SIBs in DU + // we can configure other SIB only after having received the ones generated by CU + bool update = nr_mac_configure_other_sib(mac, cu_cell->num_SI, cu_cell->SI_msg); + if (update) { + f1ap_setup_req_t *sr = mac->f1_config.setup_req; + DevAssert(sr->num_cells_available == 1); + f1ap_served_cell_info_t *info = &sr->cell[0].info; + NR_COMMON_channels_t *cc = &mac->common_channels[0]; + prepare_du_configuration_update(mac, info, cc->mib, cc->sib1); } mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp)); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 65812ae0f5..fe7222b2c6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -276,7 +276,7 @@ typedef struct { frame_type_t frame_type; NR_BCCH_BCH_Message_t *mib; NR_BCCH_DL_SCH_Message_t *sib1; - NR_BCCH_DL_SCH_Message_t *sib19; + seq_arr_t *du_SIBs; NR_ServingCellConfigCommon_t *ServingCellConfigCommon; /// pre-configured ServingCellConfig that is default for every UE NR_ServingCellConfig_t *pre_ServingCellConfig; @@ -285,9 +285,9 @@ typedef struct { /// Outgoing BCCH pdu for PHY uint8_t sib1_bcch_pdu[NR_MAX_SIB_LENGTH / 8]; int sib1_bcch_length; - /// used for sib19 data - uint8_t sib19_bcch_pdu[NR_MAX_SIB_LENGTH / 8]; - int sib19_bcch_length; + /// used for otherSIB data + uint8_t other_sib_bcch_pdu[2][NR_MAX_SIB_LENGTH / 8]; + int other_sib_bcch_length[2]; /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 0b811b11ad..07343488a2 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -197,7 +197,7 @@ int xer_nr_sprint(char *string, size_t string_size, asn_TYPE_descriptor_t *td, v //------------------------------------------------------------------------------ -int do_SIB2_NR(uint8_t **msg_SIB2) +int do_SIB2_NR(uint8_t **msg_SIB2, NR_SSB_MTC_t *ssbmtc) { NR_SIB2_t *sib2 = calloc(1, sizeof(*sib2)); sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB0; @@ -222,10 +222,6 @@ int do_SIB2_NR(uint8_t **msg_SIB2) sib2->intraFreqCellReselectionInfo.s_IntraSearchP = 22; // INTEGER (0..31) sib2->intraFreqCellReselectionInfo.t_ReselectionNR = 1; // INTEGER (0..7) sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell = true; - NR_SSB_MTC_t *ssbmtc = calloc(1, sizeof(*ssbmtc)); - ssbmtc->duration = NR_SSB_MTC__duration_sf5; - ssbmtc->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20; - ssbmtc->periodicityAndOffset.choice.sf20 = 0; sib2->intraFreqCellReselectionInfo.smtc = ssbmtc; ssize_t size = uper_encode_to_new_buffer(&asn_DEF_NR_SIB2, NULL, (void *)sib2, (void **)msg_SIB2); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 3916305171..2d703912e2 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -66,7 +66,7 @@ struct asn_TYPE_descriptor_s; */ int xer_sprint_NR(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr); -int do_SIB2_NR(uint8_t **msg_SIB2); +int do_SIB2_NR(uint8_t **msg_SIB2, NR_SSB_MTC_t *ssbmtc); int do_RRCReject(uint8_t *const buffer); diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index e39dd3581f..5c2efdd3c8 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2349,6 +2349,105 @@ static long get_NR_UE_TimersAndConstants_t319(const nr_mac_timers_t *timer_confi } } +void add_sib_to_systeminformation(NR_SystemInformation_IEs_t *si, struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type) +{ + asn1cSeqAdd(&si->sib_TypeAndInfo.list, type); +} + +void update_SIB1_NR_SI(NR_BCCH_DL_SCH_Message_t *sib1_bcch, int num_sibs, int sibs[num_sibs]) +{ + NR_SIB1_t *sib1 = sib1_bcch->message.choice.c1->choice.systemInformationBlockType1; + //si-SchedulingInfo + NR_SI_SchedulingInfo_t *info = calloc(1, sizeof(*info)); + info->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40; + NR_SchedulingInfo_t *schedulingInfo = calloc(1, sizeof(*schedulingInfo)); + schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting; + schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf16; + bool reg_sib = false; + NR_SI_SchedulingInfo_v1700_t *si_schedulingInfo_v17 = NULL; + NR_SchedulingInfo2_r17_t *schedulingInfo2_r17 = NULL; + bool v17_sib = false; + for (int i = 0; i < num_sibs; i++) { + int sib_num = sibs[i]; + AssertFatal(sib_num > 1 && sib_num < 21, "other SIB invalid type\n"); + if (sib_num < 15) { + reg_sib = true; + NR_SIB_TypeInfo_t *mapping = calloc(1, sizeof(*mapping)); + // NR_SIB_TypeInfo__type_sibType2 = 0 + // NR_SIB_TypeInfo__type_sibType3 = 1 + // and so on + mapping->type = sib_num - 2; + // The field is mandatory present if the type is different from SIB6, SIB7 or SIB8. For SIB6, SIB7 and SIB8 it is absent. + if (sib_num != 6 && sib_num != 7 && sib_num != 8) { + mapping->valueTag = calloc(1, sizeof(*mapping->valueTag)); + *mapping->valueTag = 0; + } + asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list, mapping); + } else { + if (v17_sib == false) { + si_schedulingInfo_v17 = calloc(1, sizeof(*si_schedulingInfo_v17)); + schedulingInfo2_r17 = calloc(1, sizeof(*schedulingInfo2_r17)); + schedulingInfo2_r17->si_BroadcastStatus_r17 = NR_SchedulingInfo2_r17__si_BroadcastStatus_r17_broadcasting; + schedulingInfo2_r17->si_Periodicity_r17 = NR_SchedulingInfo2_r17__si_Periodicity_r17_rf16; + schedulingInfo2_r17->si_WindowPosition_r17 = 2; + } + NR_SIB_TypeInfo_v1700_t *mapping17 = calloc(1, sizeof(*mapping17)); + mapping17->sibType_r17.present = NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17; + // NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType15 = 0 + // and so on + mapping17->sibType_r17.choice.type1_r17 = sib_num - 15; + mapping17->valueTag_r17 = calloc(1, sizeof(*mapping17->valueTag_r17)); + *mapping17->valueTag_r17 = 0; + asn1cSeqAdd(&schedulingInfo2_r17->sib_MappingInfo_r17.list, mapping17); + } + } + AssertFatal(reg_sib, "At least 1 SIB from SchedulingInfo (SIB2 to SIB14 included) needs to be present\n"); + asn1cSeqAdd(&info->schedulingInfoList.list, schedulingInfo); + sib1->si_SchedulingInfo = info; + if (si_schedulingInfo_v17) { + asn1cSeqAdd(&si_schedulingInfo_v17->schedulingInfoList2_r17.list, schedulingInfo2_r17); + NR_SIB1_v1610_IEs_t *sib1_v1610 = NULL; + if (sib1->nonCriticalExtension) + sib1_v1610 = sib1->nonCriticalExtension; + else { + sib1_v1610 = calloc_or_fail(1, sizeof(*sib1_v1610)); + sib1->nonCriticalExtension = sib1_v1610; + } + NR_SIB1_v1630_IEs_t *sib1_v1630 = NULL; + if (sib1_v1610->nonCriticalExtension) + sib1_v1630 = sib1_v1610->nonCriticalExtension; + else { + sib1_v1630 = calloc_or_fail(1, sizeof(*sib1_v1630)); + sib1_v1610->nonCriticalExtension = sib1_v1630; + } + NR_SIB1_v1700_IEs_t *sib1_v17 = NULL; + if (sib1_v1630->nonCriticalExtension) + sib1_v17 = sib1_v1630->nonCriticalExtension; + else { + sib1_v17 = calloc_or_fail(1, sizeof(*sib1_v17)); + sib1_v1630->nonCriticalExtension = sib1_v17; + } + sib1_v17->si_SchedulingInfo_v1700 = si_schedulingInfo_v17; + } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message, sib1_bcch); + } +} + +int encode_sysinfo_ie(NR_SystemInformation_IEs_t *sysInfo, uint8_t *buf, int len) +{ + if (sysInfo->sib_TypeAndInfo.list.count == 0) + return 0; + NR_SystemInformation_t si = {.criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation}; + si.criticalExtensions.choice.systemInformation = sysInfo; + struct NR_BCCH_DL_SCH_MessageType__c1 c1 = {.present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation}; + c1.choice.systemInformation = &si; + NR_BCCH_DL_SCH_MessageType_t message_type = {.present = NR_BCCH_DL_SCH_MessageType_PR_c1}; + message_type.choice.c1 = &c1; + NR_BCCH_DL_SCH_Message_t sib_message = {.message = message_type}; + return encode_SIB_NR(&sib_message, buf, len); +} + static bool is_ntn_band(int band) { // TS 3GPP 38.101-5 V1807 Section 5.2.2 @@ -2378,7 +2477,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1)); AssertFatal(sib1_message->message.choice.c1->choice.systemInformationBlockType1 != NULL, "out of memory\n"); - struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; + NR_SIB1_t *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; // cellSelectionInfo sib1->cellSelectionInfo = CALLOC(1,sizeof(*sib1->cellSelectionInfo)); @@ -2429,37 +2528,6 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, // connEstFailureControl // TODO: add connEstFailureControl - //si-SchedulingInfo - /*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); - asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list); - sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40; - struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo)); - schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting; - schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf8; - asn_set_empty(&schedulingInfo->sib_MappingInfo.list); - - NR_SIB_TypeInfo_t *sib_type3 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type3->type = NR_SIB_TypeInfo__type_sibType3; - sib_type3->valueTag = CALLOC(1,sizeof(sib_type3->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type3); - - NR_SIB_TypeInfo_t *sib_type5 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type5->type = NR_SIB_TypeInfo__type_sibType5; - sib_type5->valueTag = CALLOC(1,sizeof(sib_type5->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type5); - - NR_SIB_TypeInfo_t *sib_type4 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type4->type = NR_SIB_TypeInfo__type_sibType4; - sib_type4->valueTag = CALLOC(1,sizeof(sib_type4->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type4); - - NR_SIB_TypeInfo_t *sib_type2 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type2->type = NR_SIB_TypeInfo__type_sibType2; - sib_type2->valueTag = CALLOC(1,sizeof(sib_type2->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type2); - - asn1cSeqAdd(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ - // servingCellConfigCommon asn1cCalloc(sib1->servingCellConfigCommon, ServCellCom); NR_BWP_DownlinkCommon_t *initialDownlinkBWP = &ServCellCom->downlinkConfigCommon.initialDownlinkBWP; @@ -2685,29 +2753,9 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, *sib1_1700->intraFreqReselectionRedCap_r17 = redcap_config->intraFreqReselectionRedCap_r17; } - // sib19 scheduling info - // ensure ntn-config is initialized - if (scc->ext2 && scc->ext2->ntn_Config_r17) { - struct NR_SI_SchedulingInfo_v1700 *sib_v17_scheduling_info = CALLOC(1, sizeof(struct NR_SI_SchedulingInfo_v1700)); - - struct NR_SchedulingInfo2_r17 *si_schedulinginfo2_r17 = CALLOC(1, sizeof(struct NR_SchedulingInfo2_r17)); - si_schedulinginfo2_r17->si_BroadcastStatus_r17 = NR_SchedulingInfo2_r17__si_BroadcastStatus_r17_broadcasting; - si_schedulinginfo2_r17->si_WindowPosition_r17 = 2; - si_schedulinginfo2_r17->si_Periodicity_r17 = NR_SchedulingInfo2_r17__si_Periodicity_r17_rf8; - - struct NR_SIB_TypeInfo_v1700 *sib_type_info = CALLOC(1, sizeof(struct NR_SIB_TypeInfo_v1700)); - sib_type_info->sibType_r17.present = NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17; - sib_type_info->sibType_r17.choice.type1_r17 = NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19; - - asn1cSeqAdd(&si_schedulinginfo2_r17->sib_MappingInfo_r17.list, sib_type_info); - asn1cSeqAdd(&sib_v17_scheduling_info->schedulingInfoList2_r17.list, si_schedulinginfo2_r17); - sib1_1700->si_SchedulingInfo_v1700 = sib_v17_scheduling_info; - - if (is_ntn_band(band)) { - // If cell provides NTN access, set cellBarredNTN to notBarred. - sib1_1700->cellBarredNTN_r17 = CALLOC(1, sizeof(long)); - *sib1_1700->cellBarredNTN_r17 = NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred; - } + if (is_ntn_band(band)) { + // If cell provides NTN access, set cellBarredNTN to notBarred. + asn1cCallocOne(sib1_1700->cellBarredNTN_r17, NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred); } } @@ -2723,57 +2771,23 @@ void free_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1) ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, sib1); } -int encode_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1, uint8_t *buffer, int max_buffer_size) +int encode_SIB_NR(NR_BCCH_DL_SCH_Message_t *sib, uint8_t *buffer, int max_buffer_size) { AssertFatal(max_buffer_size <= NR_MAX_SIB_LENGTH / 8, - "%s(): maximum buffer size too large: 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the " - "maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n", - __func__); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib1, buffer, max_buffer_size); + "Maximum buffer size too large: 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the " + "maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n"); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib, buffer, max_buffer_size); AssertFatal(enc_rval.encoded > 0 && enc_rval.encoded <= max_buffer_size * 8, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); return (enc_rval.encoded + 7) / 8; } -NR_BCCH_DL_SCH_Message_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc) +NR_SIB19_r17_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc) { - NR_BCCH_DL_SCH_Message_t *sib_message = CALLOC(1, sizeof(NR_BCCH_DL_SCH_Message_t)); - sib_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; - sib_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); - sib_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation; - sib_message->message.choice.c1->choice.systemInformation = CALLOC(1,sizeof(struct NR_SystemInformation)); - - struct NR_SystemInformation *sib = sib_message->message.choice.c1->choice.systemInformation; - sib->criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation; - sib->criticalExtensions.choice.systemInformation = CALLOC(1, sizeof(struct NR_SystemInformation_IEs)); - - struct NR_SystemInformation_IEs *ies = sib->criticalExtensions.choice.systemInformation; - - SystemInformation_IEs__sib_TypeAndInfo__Member *sib19 = NULL; - sib19 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member)); - sib19->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700; - sib19->choice.sib19_v1700 = CALLOC(1, sizeof(struct NR_SIB19_r17)); - + NR_SIB19_r17_t *sib19 = calloc(1, sizeof(*sib19)); // use ntn-config from NR_ServingCellConfigCommon_t - const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **) &sib19->choice.sib19_v1700->ntn_Config_r17, scc->ext2->ntn_Config_r17); + const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **) &sib19->ntn_Config_r17, scc->ext2->ntn_Config_r17); AssertFatal(copy_result == 0, "Was unable to copy ntn_Config_r17 from scc to SIB19 structure\n"); - - asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib19); - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message, sib_message); - } - - return sib_message; -} - -int encode_SIB19_NR(NR_BCCH_DL_SCH_Message_t *sib19, uint8_t *buffer, int max_buffer_size) -{ - asn_enc_rval_t enc_rval; - - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib19, buffer, 150); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - - return ((enc_rval.encoded + 7) / 8); + return sib19; } void free_SIB19_NR(NR_BCCH_DL_SCH_Message_t *sib19) diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 707e46cd66..d56db4b0cf 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -83,12 +83,12 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, uint64_t cellID, int tac, const nr_mac_config_t *mac_config); +void update_SIB1_NR_SI(NR_BCCH_DL_SCH_Message_t *sib1, int num_sibs, int sibs[num_sibs]); +int encode_sysinfo_ie(NR_SystemInformation_IEs_t *sysInfo, uint8_t *buf, int len); void free_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1); -int encode_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1, uint8_t *buffer, int max_buffer_size); - -NR_BCCH_DL_SCH_Message_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc); -int encode_SIB19_NR(NR_BCCH_DL_SCH_Message_t *sib19, uint8_t *buffer, int max_buffer_size); -void free_SIB19_NR(NR_BCCH_DL_SCH_Message_t *sib19); +int encode_SIB_NR(NR_BCCH_DL_SCH_Message_t *sib, uint8_t *buffer, int max_buffer_size); +void add_sib_to_systeminformation(NR_SystemInformation_IEs_t *si, struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type); +NR_SIB19_r17_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc); NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 51f2d427e5..f0dfc2ec02 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -361,12 +361,6 @@ typedef struct nr_rrc_cuup_container_t { sctp_assoc_t assoc_id; } nr_rrc_cuup_container_t; -typedef struct { - uint8_t *SIB_buffer; - int SIB_size; - int SIB_type; -} rrc_SIBs_t; - //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 0acba1797c..b93e08e79f 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -215,31 +215,6 @@ static void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, #endif } -///---------------------------------------------------------------------------------------------------------------/// -///---------------------------------------------------------------------------------------------------------------/// - -static void init_NR_SI(gNB_RRC_INST *rrc) -{ - if (!NODE_IS_DU(rrc->node_type)) { - seq_arr_t *sibs = rrc->SIBs; - if (sibs) { - for (int i = 0; i < sibs->size; i++) { - rrc_SIBs_t *sib = (rrc_SIBs_t *)seq_arr_at(sibs, i); - AssertFatal(sib->SIB_type == 2, "Only SIB2 currently implemented\n"); - sib->SIB_size = do_SIB2_NR(&sib->SIB_buffer); - } - } - } - if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { - AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n"); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc); - LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); - if (!NODE_IS_CU(rrc->node_type)) { - rrc_add_nsa_user(rrc,ue_context_p,NULL); - } - } -} - static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc) { switch (rrc->node_type) { @@ -279,8 +254,15 @@ void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *c RB_INIT(&rrc->cuups); RB_INIT(&rrc->dus); rrc->configuration = *configuration; - /// System Information INIT - init_NR_SI(rrc); + + if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { + AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n"); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc); + LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); + if (!NODE_IS_CU(rrc->node_type)) { + rrc_add_nsa_user(rrc,ue_context_p,NULL); + } + } } static void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 10113c21aa..f34ca13e6c 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -61,6 +61,15 @@ int get_ssb_scs(const struct f1ap_served_cell_info_t *cell_info) return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs; } +static NR_SSB_MTC_t *get_ssb_mtc(const NR_MeasurementTimingConfiguration_t *mtc) +{ + // TODO verify which element of the list to pick + NR_MeasTimingList_t *mtlist = mtc->criticalExtensions.choice.c1->choice.measTimingConf->measTiming; + NR_SSB_MTC_t *ssb_mtc = calloc(1, sizeof(*ssb_mtc)); + *ssb_mtc = mtlist->list.array[0]->frequencyAndTiming->ssb_MeasurementTimingConfiguration; + return ssb_mtc; +} + static int ssb_arfcn_mtc(const NR_MeasurementTimingConfiguration_t *mtc) { /* format has been verified when accepting MeasurementTimingConfiguration */ @@ -397,14 +406,23 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) .num_SI = 0, }; + // Encode CU SIBs and configure setup response with sysinfo seq_arr_t *sibs = rrc->SIBs; if (sibs) { for (int i = 0; i < sibs->size; i++) { - rrc_SIBs_t *si = (rrc_SIBs_t *)seq_arr_at(sibs, i); - cell.SI_msg[cell.num_SI].SI_container = si->SIB_buffer; - cell.SI_msg[cell.num_SI].SI_container_length = si->SIB_size; - cell.SI_msg[cell.num_SI].SI_type = si->SIB_type; - cell.num_SI++; + nr_SIBs_t *sib = (nr_SIBs_t *)seq_arr_at(sibs, i); + switch (sib->SIB_type) { + case 2: { + NR_SSB_MTC_t *ssbmtc = get_ssb_mtc(mtc); + sib->SIB_size = do_SIB2_NR(&sib->SIB_buffer, ssbmtc); + cell.SI_msg[cell.num_SI].SI_container = sib->SIB_buffer; + cell.SI_msg[cell.num_SI].SI_container_length = sib->SIB_size; + cell.SI_msg[cell.num_SI].SI_type = sib->SIB_type; + cell.num_SI++; + } break; + default: + AssertFatal(false, "SIB%d not handled yet\n", sib->SIB_type); + } } } From 04213f29815fb75ef6d9ac8e1909fe89b5d15339 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 26 Dec 2024 11:20:57 +0100 Subject: [PATCH 04/19] schedule SIBs other than 1 (including fixes for SIB19) --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 68 +++ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 1 + .../NR_MAC_UE/nr_ue_dci_configuration.c | 70 --- openair2/LAYER2/NR_MAC_gNB/config.c | 20 - openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 78 +-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 452 +++++++++--------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 26 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 18 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 16 +- openair2/RRC/NR/nr_rrc_config.c | 4 +- 13 files changed, 337 insertions(+), 421 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 38b65a8158..44c6673f2f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1505,6 +1505,74 @@ void find_aggregation_candidates(uint8_t *aggregation_level, } } +void get_monitoring_period_offset(const NR_SearchSpace_t *ss, int *period, int *offset) +{ + switch(ss->monitoringSlotPeriodicityAndOffset->present) { + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: + *period = 1; + *offset = 0; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: + *period = 2; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: + *period = 4; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: + *period = 5; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: + *period = 8; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: + *period = 10; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: + *period = 16; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: + *period = 20; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: + *period = 40; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: + *period = 80; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: + *period = 160; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: + *period = 320; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: + *period = 640; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: + *period = 1280; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: + *period = 2560; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; + break; + default: + AssertFatal(1==0,"Invalid monitoring slot periodicity value\n"); + break; + } +} void set_monitoring_periodicity_offset(NR_SearchSpace_t *ss, uint16_t period, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 487e81ac40..8e0e57d3a6 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -213,6 +213,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset); +void get_monitoring_period_offset(const NR_SearchSpace_t *ss, int *period, int *offset); uint32_t nr_compute_tbslbrm(uint16_t table, uint16_t nb_rb, 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 8457cad135..f3a132669f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -343,76 +343,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, dl_config->number_pdus += 1; } - -void get_monitoring_period_offset(const NR_SearchSpace_t *ss, int *period, int *offset) -{ - switch(ss->monitoringSlotPeriodicityAndOffset->present) { - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: - *period = 1; - *offset = 0; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: - *period = 2; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: - *period = 4; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: - *period = 5; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: - *period = 8; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: - *period = 10; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: - *period = 16; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: - *period = 20; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: - *period = 40; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: - *period = 80; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: - *period = 160; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: - *period = 320; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: - *period = 640; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: - *period = 1280; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: - *period = 2560; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; - break; - default: - AssertFatal(1==0,"Invalid monitoring slot periodicity value\n"); - break; - } -} - bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per_frame, const NR_SearchSpace_t *ss) { if (!ss) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index c9a58a4e4a..26319a6049 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -864,32 +864,12 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c NR_RA_t *ra = &cc->ra[n]; nr_clear_ra_proc(ra); } - - nr_fill_sched_osi(nrmac, scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon); NR_SCHED_UNLOCK(&nrmac->sched_lock); if (IS_SA_MODE(get_softmodem_params())) config_sched_ctrlCommon(nrmac); } -void nr_fill_sched_osi(gNB_MAC_INST *nrmac, const struct NR_SetupRelease_PDCCH_ConfigCommon *pdcch_ConfigCommon) -{ - NR_SearchSpaceId_t *osi_SearchSpace = pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation; - if (osi_SearchSpace) { - nrmac->sched_osi = CALLOC(1, sizeof(*nrmac->sched_osi)); - - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = - pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); - for (int i = 0; i < commonSearchSpaceList->list.count; i++) { - NR_SearchSpace_t *ss = commonSearchSpaceList->list.array[i]; - if (ss->searchSpaceId == *osi_SearchSpace) - nrmac->sched_osi->search_space = ss; - } - AssertFatal(nrmac->sched_osi->search_space != NULL, "SearchSpace cannot be null for OSI\n"); - } -} - bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]) { NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index f86812f893..e14004edc3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -219,6 +219,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo // SIB19 will be scheduled if ntn_Config_r17 is initialized if (IS_SA_MODE(get_softmodem_params())) { schedule_nr_sib1(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req); + schedule_nr_other_sib(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req); } // This schedule PRACH if we are not in phy_test mode diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 147b8abc6c..017dc3cd4f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -878,7 +878,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch, false); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -1250,81 +1250,11 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, slot_ nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); } - -static void find_monitoring_periodicity_offset_common(const NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset) -{ - switch (ss->monitoringSlotPeriodicityAndOffset->present) { - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: - *slot_period = 1; - *offset = 0; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: - *slot_period = 2; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: - *slot_period = 4; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: - *slot_period = 5; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: - *slot_period = 8; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: - *slot_period = 10; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: - *slot_period = 16; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: - *slot_period = 20; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: - *slot_period = 40; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: - *slot_period = 80; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: - *slot_period = 160; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: - *slot_period = 320; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: - *slot_period = 640; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: - *slot_period = 1280; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; - break; - case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: - *slot_period = 2560; - *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; - break; - default: - AssertFatal(1 == 0, "Invalid monitoring slot periodicity and offset value\n"); - break; - } -} - static bool check_msg2_monitoring(const NR_RA_t *ra, int slots_per_frame, int current_frame, int current_slot) { // check if the slot is not among the PDCCH monitored ones (38.213 10.1) - uint16_t monitoring_slot_period, monitoring_offset; - find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + int monitoring_slot_period, monitoring_offset; + get_monitoring_period_offset(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); if ((current_frame * slots_per_frame + current_slot - monitoring_offset) % monitoring_slot_period != 0) return false; return true; @@ -1432,7 +1362,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch, false); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 32647cbe65..ce3b8a7e13 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -397,92 +397,22 @@ static uint32_t schedule_control_sib1(module_id_t module_id, return TBS; } -static uint32_t schedule_control_other_si(module_id_t module_id, - int CC_id, - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - int time_domain_allocation, - NR_pdsch_dmrs_t *dmrs_parms, - NR_tda_info_t *tda_info, - uint8_t candidate_idx, - int beam, - uint16_t num_total_bytes) +static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, + NR_sched_pdsch_t *pdsch, + NR_sched_pdcch_t *pdcch, + NR_SearchSpace_t *search_space, + NR_ControlResourceSet_t *coreset, + int aggregation_level, + int cce_index, + nfapi_nr_dl_tti_request_body_t *dl_req, + int pdu_index, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + uint32_t TBS, + int StartSymbolIndex, + int NrOfSymbols, + bool is_sib1, + int beam_index) { - gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; - NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - uint16_t *vrb_map = cc->vrb_map[beam]; - - if (!gNB_mac->sched_osi->coreset) { - gNB_mac->sched_osi->coreset = - get_coreset(gNB_mac, scc, NULL, gNB_mac->sched_osi->search_space, NR_SearchSpace__searchSpaceType_PR_common); - gNB_mac->sched_osi->sched_pdcch = - set_pdcch_structure(NULL, gNB_mac->sched_osi->search_space, gNB_mac->sched_osi->coreset, scc, NULL, type0_PDCCH_CSS_config); - } - - NR_sched_pdsch_t *pdsch = &gNB_mac->sched_osi->sched_pdsch; - pdsch->time_domain_allocation = time_domain_allocation; - pdsch->dmrs_parms = *dmrs_parms; - pdsch->tda_info = *tda_info; - pdsch->mcs = 0; // starting from mcs 0 - gNB_mac->sched_osi->num_total_bytes = num_total_bytes; - - uint8_t nr_of_candidates; - - for (int i = 0; i < 3; i++) { - find_aggregation_candidates(&gNB_mac->sched_osi->aggregation_level, - &nr_of_candidates, - gNB_mac->sched_ctrlCommon->search_space, - 4 << i); - if (nr_of_candidates > 0) - break; // choosing the lower value of aggregation level available - } - AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n"); - gNB_mac->sched_osi->cce_index = find_pdcch_candidate(gNB_mac, - CC_id, - gNB_mac->sched_osi->aggregation_level, - nr_of_candidates, - beam, - &gNB_mac->sched_osi->sched_pdcch, - gNB_mac->sched_osi->coreset, - 0); - - AssertFatal(gNB_mac->sched_osi->cce_index >= 0, "Could not find CCE for coreset0\n"); - - // Calculate number of PRB_DMRS - uint32_t TBS = get_tbs(type0_PDCCH_CSS_config, &gNB_mac->sched_osi->sched_pdsch, gNB_mac->sched_osi->num_total_bytes, vrb_map); - // Mark the corresponding RBs as used - fill_pdcch_vrb_map(gNB_mac, - CC_id, - &gNB_mac->sched_osi->sched_pdcch, - gNB_mac->sched_osi->cce_index, - gNB_mac->sched_osi->aggregation_level, - beam); - for (int rb = 0; rb < pdsch->rbSize; rb++) { - vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); - } - return TBS; -} - -static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, - NR_UE_sched_osi_ctrl_t *sched_osi, - NR_UE_sched_ctrl_t *sched_ctrlCommon, - nfapi_nr_dl_tti_request_body_t *dl_req, - int pdu_index, - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - uint32_t TBS, - int StartSymbolIndex, - int NrOfSymbols, - int beam_index) -{ - // will set data according to SIB type (SIB1/OtherSI) - NR_sched_pdsch_t *pdsch = (sched_ctrlCommon ? &sched_ctrlCommon->sched_pdsch : &sched_osi->sched_pdsch); - NR_sched_pdcch_t *pdcch = (sched_ctrlCommon ? &sched_ctrlCommon->sched_pdcch : &sched_osi->sched_pdcch); - NR_SearchSpace_t *search_space = (sched_ctrlCommon ? sched_ctrlCommon->search_space : sched_osi->search_space); - NR_ControlResourceSet_t *coreset = (sched_ctrlCommon ? sched_ctrlCommon->coreset : sched_osi->coreset); - uint8_t aggregation_level = (sched_ctrlCommon ? sched_ctrlCommon->aggregation_level : sched_osi->aggregation_level); - int cce_index = (sched_ctrlCommon ? sched_ctrlCommon->cce_index : sched_osi->cce_index); - - gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = gNB_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int mcsTableIdx = 0; @@ -493,10 +423,7 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, 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, - coreset, - pdcch, - sched_ctrlCommon ? false : true); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, pdcch); nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset(dl_tti_pdsch_pdu, 0, sizeof(*dl_tti_pdcch_pdu)); @@ -598,7 +525,7 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, dci_payload.pdsch_to_harq_feedback_timing_indicator.val = 0; dci_payload.antenna_ports.val = 0; dci_payload.dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; - dci_payload.system_info_indicator = sched_ctrlCommon ? 0 : 1; + dci_payload.system_info_indicator = is_sib1 ? 0 : 1; int dci_format = NR_DL_DCI_FORMAT_1_0; int rnti_type = TYPE_SI_RNTI_; @@ -707,17 +634,21 @@ void schedule_nr_sib1(module_id_t module_idP, nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; - LOG_D(NR_MAC, "%s() %4d.%2d\n", __func__, frameP, slotP); - nr_fill_nfapi_dl_SIB_pdu(module_idP, - NULL, - gNB_mac->sched_ctrlCommon, - dl_req, - pdu_index, - type0_PDCCH_CSS_config, - TBS, - tda_info.startSymbolIndex, - tda_info.nrOfSymbols, - beam_index); + nr_fill_nfapi_dl_SIB_pdu(gNB_mac, + &gNB_mac->sched_ctrlCommon->sched_pdsch, + &gNB_mac->sched_ctrlCommon->sched_pdcch, + gNB_mac->sched_ctrlCommon->search_space, + gNB_mac->sched_ctrlCommon->coreset, + gNB_mac->sched_ctrlCommon->aggregation_level, + gNB_mac->sched_ctrlCommon->cce_index, + dl_req, + pdu_index, + type0_PDCCH_CSS_config, + TBS, + tda_info.startSymbolIndex, + tda_info.nrOfSymbols, + true, + beam_index); const int ntx_req = TX_req->Number_of_PDUs; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; @@ -762,133 +693,226 @@ struct NR_SchedulingInfo2_r17 *find_sib19_sched_info(const struct NR_SI_Scheduli return NULL; } -void schedule_nr_sib19(module_id_t module_idP, - frame_t frameP, - slot_t slotP, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req, - int sib19_bcch_length, - uint8_t *sib19_bcch_pdu) +static void other_sib_sched_control(module_id_t module_idP, + frame_t frame, + slot_t slot, + int beam_index, + NR_SearchSpace_t *ss, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req, + int payload_idx) { - /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ - - const int CC_id = 0; - uint8_t candidate_idx = 0; - gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; - NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; + NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[0].ServingCellConfigCommon; + int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame; + NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, beam_index, n_slots_frame); + AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index); + LOG_D(NR_MAC, "(%d.%d) otherSIB transmission for ssb number %d\n", frame, slot, beam_index); + + NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup; + int time_domain_allocation = 1; + NR_tda_info_t tda_info = set_tda_info_from_list(pdsch_ConfigCommon->pdsch_TimeDomainAllocationList, time_domain_allocation); + LOG_D(NR_MAC,"tda_info.startSymbolIndex: %d, tda_info.nrOfSymbols: %d\n", tda_info.startSymbolIndex, tda_info.nrOfSymbols); + + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1); + + uint8_t aggregation_level = 0; + uint8_t nr_of_candidates = 0; + for (int i = 0; i < 5; i++) { + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss, 16 >> i); + if (nr_of_candidates > 0) + break; // choosing the higher value of aggregation level available + } + + AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n"); + NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common); NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]]; + if (!gNB_mac->sched_pdcch_otherSI) { + gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI)); + *gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config); + } + int cce_index = find_pdcch_candidate(gNB_mac, + 0, + aggregation_level, + nr_of_candidates, + beam.idx, + gNB_mac->sched_pdcch_otherSI, + coreset, + 0); - // there is no reason to execute further if sched_osi not initialized - if (!gNB_mac->sched_osi) - return; + AssertFatal(cce_index >= 0, "Could not find CCE for otherSIB DCI\n"); - // get sib19 scheduling info from sib1 - struct NR_SI_SchedulingInfo_v1700 *si_schedulinginfo2_r17 = cc->sib1->message.choice.c1->choice.systemInformationBlockType1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700; - if (!si_schedulinginfo2_r17) { - LOG_E(GNB_APP, "SIB1 does not contain si_SchedulingInfo_v1700\n"); - return; + // Mark the corresponding RBs as used + fill_pdcch_vrb_map(gNB_mac, 0, gNB_mac->sched_pdcch_otherSI, cce_index, aggregation_level, beam.idx); + + NR_sched_pdsch_t sched_pdsch_otherSI = {0}; + sched_pdsch_otherSI.time_domain_allocation = time_domain_allocation; + sched_pdsch_otherSI.dmrs_parms = dmrs_parms; + sched_pdsch_otherSI.tda_info = tda_info; + sched_pdsch_otherSI.mcs = 0; // starting from mcs 0 + + uint16_t *vrb_map = cc->vrb_map[beam.idx]; + uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx]; + int num_total_bytes = cc->other_sib_bcch_length[payload_idx]; + uint32_t TBS = get_tbs(type0_PDCCH_CSS_config, &sched_pdsch_otherSI, num_total_bytes, vrb_map); + + for (int rb = 0; rb < sched_pdsch_otherSI.rbSize; rb++) { + vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); } - struct NR_SchedulingInfo2_r17 *sib19_sched_info = find_sib19_sched_info(si_schedulinginfo2_r17); - if (!sib19_sched_info) { - LOG_D(GNB_APP, "SIB1 does not contain scheduling info for SIB19\n"); + int pdu_index = gNB_mac->pdu_index[0]++; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; + nr_fill_nfapi_dl_SIB_pdu(gNB_mac, + &sched_pdsch_otherSI, + gNB_mac->sched_pdcch_otherSI, + ss, + coreset, + aggregation_level, + cce_index, + dl_req, + pdu_index, + type0_PDCCH_CSS_config, + TBS, + tda_info.startSymbolIndex, + tda_info.nrOfSymbols, + false, + beam_index); + + const int ntx_req = TX_req->Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; + + // Data to be transmitted + memcpy(tx_req->TLVs[0].value.direct, sib_bcch_pdu, TBS); + + tx_req->PDU_length = TBS; + tx_req->PDU_index = pdu_index; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = TBS + 2; + TX_req->Number_of_PDUs++; + TX_req->SFN = frame; + TX_req->Slot = slot; + + T(T_GNB_MAC_DL_PDU_WITH_DATA, + T_INT(module_idP), + T_INT(0), + T_INT(SI_RNTI), + T_INT(frame), + T_INT(slot), + T_INT(0), // harq_pid + T_BUFFER(sib_bcch_pdu, num_total_bytes)); +} + +// This function verifies if we need to schedule otherSIB in frame and slot +static bool test_other_sib_sched_occasion(int window_pos, + int window_len, + int period, + int n_slots_frame, + int frame, + int slot, + int rel_frame, + int rel_slot) +{ + int x = window_pos * window_len; + int T = 8 << period; + int test_frame = (frame - rel_frame) % MAX_FRAME_NUMBER; + int si_slot = (x % n_slots_frame) + rel_slot; + bool res = ((test_frame % T) != (x / n_slots_frame)) || (si_slot != slot); + return res; +} + +void schedule_nr_other_sib(module_id_t module_idP, + frame_t frame, + slot_t slot, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req) +{ + gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; + NR_SIB1_t *sib1 = cc->sib1->message.choice.c1->choice.systemInformationBlockType1; + NR_SI_SchedulingInfo_t *schedInfo = sib1->si_SchedulingInfo; + if (!schedInfo) return; + + NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[0].ServingCellConfigCommon; + NR_PDCCH_ConfigCommon_t *pdcch_common = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup; + NR_SearchSpaceId_t *ss_id = pdcch_common->searchSpaceOtherSystemInformation; + AssertFatal(ss_id, "searchSpaceOtherSystemInformation not present\n"); + NR_SearchSpace_t *ss = NULL; + for (int i = 0; i < pdcch_common->commonSearchSpaceList->list.count; i++) { + if (pdcch_common->commonSearchSpaceList->list.array[i]->searchSpaceId == *ss_id) + ss = pdcch_common->commonSearchSpaceList->list.array[i]; + } + AssertFatal(ss, "searchSpaceOtherSystemInformation not found\n"); + + NR_SI_SchedulingInfo_v1700_t *schedInfo17 = NULL; + if (sib1->nonCriticalExtension) { + NR_SIB1_v1610_IEs_t *sib1_v1610 = sib1->nonCriticalExtension; + if (sib1_v1610 && sib1_v1610->nonCriticalExtension && sib1_v1610->nonCriticalExtension->nonCriticalExtension) { + NR_SIB1_v1700_IEs_t *sib1_v17 = sib1_v1610->nonCriticalExtension->nonCriticalExtension; + schedInfo17 = sib1_v17->si_SchedulingInfo_v1700; + } } - // convert periodicity enum type into actual frames number - int frame = 8 << sib19_sched_info->si_Periodicity_r17; - - int time_domain_allocation = 1; // row 0 of pdsch tda common table - int L_max; - switch (scc->ssb_PositionsInBurst->present) { - case 1: - L_max = 4; - break; - case 2: - L_max = 8; - break; - case 3: - L_max = 64; - break; - default: - AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n", - scc->ssb_PositionsInBurst->present); + int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame; + int window_length_sl = 5 << schedInfo->si_WindowLength; + int window_length_f = (window_length_sl / n_slots_frame) + ((window_length_sl % n_slots_frame) > 0); + int num_ssb = cc->num_active_ssb; + // number of PDCCH monitoring occasions in SI-window + int period, offset; + get_monitoring_period_offset(ss, &period, &offset); + // The UE assumes that, in the SI window, PDCCH for an SI message is transmitted + // in at least one PDCCH monitoring occasion corresponding to each transmitted SSB + // frame and slot relative to start of window + // The [x×N+K]th PDCCH monitoring occasion(s) for SI message in SI-window corresponds to the Kth transmitted SSB + // in our implmentation we transmit only once per SSB per window so N = 1 + // Section 5.2.2.3.2 of 38.331 + int temp_slot = offset % n_slots_frame; + int temp_frame = offset / n_slots_frame; + int rel_slot[num_ssb]; + int rel_frame[num_ssb]; + int ssb = 0; + while (ssb < num_ssb) { + AssertFatal(temp_frame < window_length_f, "Couldn't fit %d SSB in window length of %d slots\n", num_ssb, window_length_sl); + if (is_dl_slot(temp_slot, &gNB_mac->frame_structure)) { + rel_slot[ssb] = temp_slot; + rel_frame[ssb] = temp_frame; + ssb++; + } + temp_frame += (temp_slot + period) / n_slots_frame; + temp_slot = (temp_slot + period) % n_slots_frame; } - const int window_length = 10; - for (int i = 0; i < L_max; i++) { + for (int ssb = 0; ssb < num_ssb; ssb++) { + for (int i = 0; i < schedInfo->schedulingInfoList.list.count; i++) { + NR_SchedulingInfo_t *schedulingInfo = schedInfo->schedulingInfoList.list.array[i]; + if (test_other_sib_sched_occasion(i, + window_length_sl, + schedulingInfo->si_Periodicity, + n_slots_frame, + frame, + slot, + rel_frame[ssb], + rel_slot[ssb])) + continue; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[i]; - if(((frameP - 1) % frame == 0) && - (slotP == ((sib19_sched_info->si_WindowPosition_r17 % window_length) - 1)) && - (type0_PDCCH_CSS_config->num_rbs > 0)) { + other_sib_sched_control(module_idP, frame, slot, ssb, ss, DL_req, TX_req, 0); + } + if (!schedInfo17) + continue; + for (int i = 0; i < schedInfo17->schedulingInfoList2_r17.list.count; i++) { + NR_SchedulingInfo2_r17_t *schedulingInfo2_r17 = schedInfo17->schedulingInfoList2_r17.list.array[i]; + if (test_other_sib_sched_occasion(schedulingInfo2_r17->si_WindowPosition_r17, + window_length_sl, + schedulingInfo2_r17->si_Periodicity_r17, + n_slots_frame, + frame, + slot, + rel_frame[ssb], + rel_slot[ssb])) + continue; - const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame; - int beam_index = get_fapi_beamforming_index(gNB_mac, i); - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame); - AssertFatal(beam.idx >= 0, "Cannot allocate SIB19 corresponding to SSB %d in any available beam\n", i); - LOG_D(NR_MAC,"(%d.%d) SIB19 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index); - - NR_tda_info_t tda_info = set_tda_info_from_list(scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, time_domain_allocation); - LOG_D(NR_MAC,"tda_info.startSymbolIndex: %d, tda_info.nrOfSymbols: %d\n", tda_info.startSymbolIndex, tda_info.nrOfSymbols); - - AssertFatal((tda_info.startSymbolIndex + tda_info.nrOfSymbols) < 14, "SIB19 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n", time_domain_allocation); - - NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, - NULL, - &tda_info, - 1); - - // Configure sched_osi for SIB19 - uint32_t TBS = schedule_control_other_si(module_idP, - CC_id, - type0_PDCCH_CSS_config, - time_domain_allocation, - &dmrs_parms, - &tda_info, - candidate_idx, - beam.idx, - sib19_bcch_length); - - nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; - int pdu_index = gNB_mac->pdu_index[0]++; - - nr_fill_nfapi_dl_SIB_pdu(module_idP, - gNB_mac->sched_osi, - NULL, - dl_req, - pdu_index, - type0_PDCCH_CSS_config, - TBS, - tda_info.startSymbolIndex, - tda_info.nrOfSymbols, - beam_index); - - const int ntx_req = TX_req->Number_of_PDUs; - nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; - - // Data to be transmitted - memcpy(tx_req->TLVs[0].value.direct, sib19_bcch_pdu, TBS); - - tx_req->PDU_length = TBS; - tx_req->PDU_index = pdu_index; - tx_req->num_TLV = 1; - tx_req->TLVs[0].length = TBS + 2; - TX_req->Number_of_PDUs++; - TX_req->SFN = frameP; - TX_req->Slot = slotP; - - type0_PDCCH_CSS_config->active = false; - - T(T_GNB_MAC_DL_PDU_WITH_DATA, - T_INT(module_idP), - T_INT(CC_id), - T_INT(SI_RNTI), - T_INT(frameP), - T_INT(slotP), - T_INT(0 /* harq_pid */), - T_BUFFER(sib19_bcch_pdu, sib19_bcch_length)); + other_sib_sched_control(module_idP, frame, slot, ssb, ss, DL_req, TX_req, 1); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 2a5b979f5a..b69490fbc9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1045,7 +1045,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid); NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; - nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch, false); + nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch); gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3c7c9ebd39..4ad2514ab2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -281,8 +281,8 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx) NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc, const NR_UE_DL_BWP_t *dl_bwp, const NR_tda_info_t *tda_info, - const int Layers) { - + const int Layers) +{ NR_pdsch_dmrs_t dmrs = {0}; int frontloaded_symb = 1; // default value nr_dci_format_t dci_format = dl_bwp ? dl_bwp->dci_format : NR_DL_DCI_FORMAT_1_0; @@ -865,12 +865,8 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) { return(default_pucch_csset[pucch_ResourceCommon]); } -void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, - NR_ControlResourceSet_t *coreset, - NR_sched_pdcch_t *pdcch, - bool otherSI) { - - +void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ControlResourceSet_t *coreset, NR_sched_pdcch_t *pdcch) +{ pdcch_pdu->BWPSize = pdcch->BWPSize; pdcch_pdu->BWPStart = pdcch->BWPStart; pdcch_pdu->SubcarrierSpacing = pdcch->SubcarrierSpacing; @@ -879,19 +875,23 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, pdcch_pdu->DurationSymbols = coreset->duration; - for (int i=0;i<6;i++) + for (int i = 0; i < 6; i++) pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i]; - LOG_D(MAC,"Coreset : BWPstart %d, BWPsize %d, SCS %d, freq %x, , duration %d\n", - pdcch_pdu->BWPStart,pdcch_pdu->BWPSize,(int)pdcch_pdu->SubcarrierSpacing,(int)coreset->frequencyDomainResources.buf[0],(int)coreset->duration); + LOG_D(NR_MAC, + "Coreset : BWPstart %d, BWPsize %d, SCS %d, freq %x, , duration %ld\n", + pdcch_pdu->BWPStart, + pdcch_pdu->BWPSize, + pdcch_pdu->SubcarrierSpacing, + coreset->frequencyDomainResources.buf[0], + coreset->duration); pdcch_pdu->CceRegMappingType = pdcch->CceRegMappingType; pdcch_pdu->RegBundleSize = pdcch->RegBundleSize; pdcch_pdu->InterleaverSize = pdcch->InterleaverSize; pdcch_pdu->ShiftIndex = pdcch->ShiftIndex; - pdcch_pdu->CoreSetType = - (otherSI || coreset->controlResourceSetId != 0) ? NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG : NFAPI_NR_CSET_CONFIG_MIB_SIB1; + pdcch_pdu->CoreSetType = coreset->controlResourceSetId != 0 ? NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG : NFAPI_NR_CSET_CONFIG_MIB_SIB1; //precoderGranularity pdcch_pdu->precoderGranularity = coreset->precoderGranularity; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b6e86fa6b7..7bef14b365 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2680,7 +2680,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, slot_t slot, nfapi_ 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, false); + nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch); pdcch_pdu_coreset[coresetid] = pdcch_pdu; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 2a6ee13a2b..c8b809a8cb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -54,7 +54,6 @@ void mac_top_init_gNB(ngran_node_t node_type, void nr_mac_send_f1_setup_req(void); void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *mac_config); -void nr_fill_sched_osi(gNB_MAC_INST *nrmac, const struct NR_SetupRelease_PDCCH_ConfigCommon *pdcch_ConfigCommon); void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_t cellID, int tac); bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]); bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); @@ -96,13 +95,11 @@ void schedule_nr_sib1(module_id_t module_idP, nfapi_nr_dl_tti_request_t *DL_req, nfapi_nr_tx_data_request_t *TX_req); -void schedule_nr_sib19(module_id_t module_idP, - frame_t frameP, - slot_t slotP, - nfapi_nr_dl_tti_request_t *DL_req, - nfapi_nr_tx_data_request_t *TX_req, - int sib19_bcch_length, - uint8_t *sib19_bcch_pdu); +void schedule_nr_other_sib(module_id_t module_idP, + frame_t frame, + slot_t slot, + nfapi_nr_dl_tti_request_t *DL_req, + nfapi_nr_tx_data_request_t *TX_req); struct NR_SchedulingInfo2_r17* find_sib19_sched_info(const struct NR_SI_SchedulingInfo_v1700*); @@ -214,10 +211,7 @@ void find_search_space(int ss_type, NR_BWP_Downlink_t *bwp, NR_SearchSpace_t *ss); -void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, - NR_ControlResourceSet_t *coreset, - NR_sched_pdcch_t *pdcch, - bool otherSI); +void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ControlResourceSet_t *coreset, NR_sched_pdcch_t *pdcch); NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, NR_SearchSpace_t *ss, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index fe7222b2c6..8365cba37b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -691,19 +691,6 @@ typedef struct { float pdcch_cl_adjust; } NR_UE_sched_ctrl_t; -typedef struct { - NR_SearchSpace_t *search_space; - NR_ControlResourceSet_t *coreset; - - NR_sched_pdcch_t sched_pdcch; - NR_sched_pdsch_t sched_pdsch; - - uint32_t num_total_bytes; - - int cce_index; - uint8_t aggregation_level; -} NR_UE_sched_osi_ctrl_t; - typedef struct { uicc_t *uicc; } NRUEcontext_t; @@ -927,9 +914,8 @@ typedef struct gNB_MAC_INST_s { nr_mac_config_t radio_config; - NR_UE_sched_osi_ctrl_t *sched_osi; NR_UE_sched_ctrl_t *sched_ctrlCommon; - + NR_sched_pdcch_t *sched_pdcch_otherSI; uint16_t cset0_bwp_start; uint16_t cset0_bwp_size; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64]; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 5c2efdd3c8..2047f108c5 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2359,7 +2359,9 @@ void update_SIB1_NR_SI(NR_BCCH_DL_SCH_Message_t *sib1_bcch, int num_sibs, int si NR_SIB1_t *sib1 = sib1_bcch->message.choice.c1->choice.systemInformationBlockType1; //si-SchedulingInfo NR_SI_SchedulingInfo_t *info = calloc(1, sizeof(*info)); - info->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40; + // TODO need to compute optimal SI-windowlength automatically + // based on the number of SSBs, TDD configuration and SS configuration + info->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s10; NR_SchedulingInfo_t *schedulingInfo = calloc(1, sizeof(*schedulingInfo)); schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting; schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf16; From 6af70bd4b9b031a0e1dc811647b8120cbf9d878b Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 27 Dec 2024 16:45:35 +0100 Subject: [PATCH 05/19] fix buggy TBS function for SIB and set additional candidate for common search space --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 110 +++++++++--------- openair2/RRC/NR/nr_rrc_config.c | 1 - 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index ce3b8a7e13..a00db6585c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -274,72 +274,71 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi } } -uint32_t get_tbs(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - NR_sched_pdsch_t *pdsch, - uint32_t num_total_bytes, - uint16_t *vrb_map) +static uint32_t get_tbs_bch(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + NR_sched_pdsch_t *pdsch, + uint32_t num_total_bytes, + uint16_t *vrb_map) { NR_tda_info_t *tda_info = &pdsch->tda_info; - const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs; - int rbStart = type0_PDCCH_CSS_config->cset_start_rb; - // Calculate number of PRB_DMRS uint8_t N_PRB_DMRS = pdsch->dmrs_parms.N_PRB_DMRS; - uint16_t dmrs_length = pdsch->dmrs_parms.N_DMRS_SLOT; LOG_D(MAC, "dlDmrsSymbPos %x\n", pdsch->dmrs_parms.dl_dmrs_symb_pos); int mcsTableIdx = 0; - int rbSize = 0; uint32_t TBS = 0; - do { - if (rbSize < bwpSize && !(vrb_map[rbStart + rbSize] & SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols))) - rbSize++; + const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); + int bwpSize = type0_PDCCH_CSS_config->num_rbs; + int bwpStart = type0_PDCCH_CSS_config->cset_start_rb; + int rbStop = bwpSize - 1; + int rbStart = 0; + uint16_t rbSize = 0; + while (rbStart < rbStop) { + if (vrb_map[rbStart + bwpStart] & slbitmap) + rbStart++; else { - if (pdsch->mcs < 10) - pdsch->mcs++; - else - break; - } - TBS = nr_compute_tbs(nr_get_Qm_dl(pdsch->mcs, mcsTableIdx), - nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx), - rbSize, - tda_info->nrOfSymbols, - N_PRB_DMRS * dmrs_length, - 0, - 0, - 1) - >> 3; - } while (TBS < num_total_bytes); + int max_rbSize = 0; + while (rbStart + max_rbSize <= rbStop && !(vrb_map[rbStart + max_rbSize + bwpStart] & slbitmap)) + max_rbSize++; - if (TBS < num_total_bytes) { - for (int rb = 0; rb < bwpSize; rb++) - LOG_I(NR_MAC, "vrb_map[%d] %x\n", rbStart + rb, vrb_map[rbStart + rb]); + bool res = false; + while (res == false && pdsch->mcs < 10) { + res = nr_find_nb_rb(nr_get_Qm_dl(pdsch->mcs, mcsTableIdx), + nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx), + 1, // no transform precoding for DL + 1, // single layer + tda_info->nrOfSymbols, + pdsch->dmrs_parms.N_PRB_DMRS * pdsch->dmrs_parms.N_DMRS_SLOT, + num_total_bytes, + 1, // min_rbSize + max_rbSize, + &TBS, + &rbSize); + if (!res) + pdsch->mcs++; + } + break; + } } - AssertFatal( - TBS >= num_total_bytes, - "Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d SLmask %x - [%d,%d])\n", - num_total_bytes, - rbStart, - rbSize, - bwpSize, - SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols), - tda_info->startSymbolIndex, - tda_info->nrOfSymbols); + AssertFatal(TBS >= num_total_bytes, + "Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n", + num_total_bytes, + rbStart, + rbSize, + bwpSize); pdsch->rbSize = rbSize; - pdsch->rbStart = 0; + pdsch->rbStart = rbStart; - LOG_D( - NR_MAC, - "mcs=%i, startSymbolIndex = %i, nrOfSymbols = %i, rbSize = %i, TBS = %i, dmrs_length %d, N_PRB_DMRS = %d, mappingtype = %d\n", - pdsch->mcs, - tda_info->startSymbolIndex, - tda_info->nrOfSymbols, - pdsch->rbSize, - TBS, - dmrs_length, - N_PRB_DMRS, - tda_info->mapping_type); + LOG_D(NR_MAC, + "mcs=%i, startSymbolIndex = %i, nrOfSymbols = %i, rbSize = %i, TBS = %i, dmrs_length %d, N_PRB_DMRS = %d, mappingtype = %d\n", + pdsch->mcs, + tda_info->startSymbolIndex, + tda_info->nrOfSymbols, + rbSize, + TBS, + pdsch->dmrs_parms.N_DMRS_SLOT, + N_PRB_DMRS, + tda_info->mapping_type); return TBS; } @@ -382,7 +381,10 @@ static uint32_t schedule_control_sib1(module_id_t module_id, AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n"); - uint32_t TBS = get_tbs(type0_PDCCH_CSS_config, &gNB_mac->sched_ctrlCommon->sched_pdsch, gNB_mac->sched_ctrlCommon->num_total_bytes, vrb_map); + uint32_t TBS = get_tbs_bch(type0_PDCCH_CSS_config, + &gNB_mac->sched_ctrlCommon->sched_pdsch, + gNB_mac->sched_ctrlCommon->num_total_bytes, + vrb_map); // Mark the corresponding RBs as used fill_pdcch_vrb_map(gNB_mac, @@ -755,7 +757,7 @@ static void other_sib_sched_control(module_id_t module_idP, uint16_t *vrb_map = cc->vrb_map[beam.idx]; uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx]; int num_total_bytes = cc->other_sib_bcch_length[payload_idx]; - uint32_t TBS = get_tbs(type0_PDCCH_CSS_config, &sched_pdsch_otherSI, num_total_bytes, vrb_map); + uint32_t TBS = get_tbs_bch(type0_PDCCH_CSS_config, &sched_pdsch_otherSI, num_total_bytes, vrb_map); for (int rb = 0; rb < sched_pdsch_otherSI.rbSize; rb++) { vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 2047f108c5..d377b2aff3 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -277,7 +277,6 @@ NR_SearchSpace_t *rrc_searchspace_config(bool is_common, ss->nrofCandidates->aggregationLevel4 = num_agg_level_candidates[PDCCH_AGG_LEVEL4]; ss->nrofCandidates->aggregationLevel8 = num_agg_level_candidates[PDCCH_AGG_LEVEL8]; ss->nrofCandidates->aggregationLevel16 = num_agg_level_candidates[PDCCH_AGG_LEVEL16]; - ss->searchSpaceType = calloc(1,sizeof(*ss->searchSpaceType)); if (is_common) { ss->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; From c633fa58550a1fab904fc27bd783a375fe24f308 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 11 Apr 2025 09:13:46 +0200 Subject: [PATCH 06/19] increase number of candidates for otherSIB --- openair2/GNB_APP/gnb_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 5a58f23006..24b1fb0c8b 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1141,7 +1141,7 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1; } else { css_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - css_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + css_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2; css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; } css_num_agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; From 5e8f64996343ffd379e147640cfd4f91f1abfbe0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 29 Dec 2024 09:10:43 +0100 Subject: [PATCH 07/19] check multiple DCI candidates with same length if SIB RNTI --- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 5 ++++- openair2/RRC/NR_UE/rrc_UE.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 36bd5a1ce7..bc87b3de7f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -640,6 +640,9 @@ void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, { int e_rx_cand_idx = 0; *dci_ind = (fapi_nr_dci_indication_t){.SFN = proc->frame_rx, .slot = proc->nr_slot_rx}; + // if DCI for SIB we don't break after finding 1st DCI with that RNTI + // there might be SIB1 and otherSIB in the same slot with the same length + bool is_SI = rel15->rnti == SI_RNTI; for (int j = 0; j < rel15->number_of_candidates; j++) { int CCEind = rel15->CCE[j]; @@ -653,7 +656,7 @@ void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, int dci_length = rel15->dci_length_options[k]; int ind; for (ind = 0; ind < dci_ind->number_of_dcis; ind++) { - if (rel15->rnti == dci_ind->dci_list[ind].rnti && dci_length == dci_ind->dci_list[ind].payloadSize) { + if (!is_SI && rel15->rnti == dci_ind->dci_list[ind].rnti && dci_length == dci_ind->dci_list[ind].payloadSize) { break; } } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index dc1cb72baa..e321c1dd5b 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -185,7 +185,7 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) { SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo; typeandinfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i]; - LOG_I(NR_RRC, "Found SIB%d\n", typeandinfo->present + 1); + LOG_A(NR_RRC, "Found SIB%d\n", typeandinfo->present + 1); switch(typeandinfo->present) { case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2: SI_info->sib2_validity = SIB_VALID; From 97ca739be22633b03c01c1d8cadcf029398b7f97 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 27 Dec 2024 18:30:08 +0100 Subject: [PATCH 08/19] remove hardcoded window size for otherSI in UE --- openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c | 1 - 1 file changed, 1 deletion(-) 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 f3a132669f..1a816c64f6 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -429,7 +429,6 @@ bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, if ((frame % T == floor(x / slots_per_frame)) && (slot == x % slots_per_frame)) mac->si_SchedInfo.si_window_start = abs_slot; } - window_slots = 10; // TODO window length hardcoded to 10 at gNB for NTN check_valid = is_window_valid(mac, window_slots, abs_slot); if (check_valid && (config->si_WindowPosition - 1) == slot) return search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame); From e4cb8be02342172fb86b29f9f7a67196c4ee04ed Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 29 Dec 2024 08:51:17 +0100 Subject: [PATCH 09/19] do not schedule reception of DLSCH associated with DCI for SIB1 if no SIB1 is scheduled for reception in this scenario we proably were scheduling reception of otherSIB in the same slot as SIB1 was present --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 20745a5e25..995d987304 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2993,7 +2993,7 @@ static void extract_10_ra_rnti(dci_pdu_rel15_t *dci_pdu_rel15, const uint8_t *dc EXTRACT_DCI_ITEM(dci_pdu_rel15->tb_scaling, 2); } -static void extract_10_si_rnti(dci_pdu_rel15_t *dci_pdu_rel15, const uint8_t *dci_pdu, int pos, const int N_RB) +static uint8_t extract_10_si_rnti(dci_pdu_rel15_t *dci_pdu_rel15, const uint8_t *dci_pdu, int pos, const int N_RB) { LOG_D(NR_MAC_DCI, "Received dci 1_0 SI rnti\n"); @@ -3009,6 +3009,7 @@ static void extract_10_si_rnti(dci_pdu_rel15_t *dci_pdu_rel15, const uint8_t *dc EXTRACT_DCI_ITEM(dci_pdu_rel15->rv, 2); // System information indicator 1 bit EXTRACT_DCI_ITEM(dci_pdu_rel15->system_info_indicator, 1); + return dci_pdu_rel15->system_info_indicator; } static bool extract_10_c_rnti(NR_UE_MAC_INST_t *mac, @@ -3312,7 +3313,10 @@ static nr_dci_format_t nr_extract_dci_00_10(NR_UE_MAC_INST_t *mac, n_RB = get_nrb_for_dci(mac, format, ss_type); if (n_RB == 0) return NR_DCI_NONE; - extract_10_si_rnti(dci_pdu_rel15, dci_pdu, pos, n_RB); + uint8_t sys_info = extract_10_si_rnti(dci_pdu_rel15, dci_pdu, pos, n_RB); + // sys info = 0 for SIB1 and 1 for other SIB + if (mac->get_sib1 == 0 && sys_info == 0) + return NR_DCI_NONE; break; case TYPE_C_RNTI_ : // Identifier for DCI formats From 08da0bd2cc8716105d3a59a1eb717f81d600c156 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 30 Dec 2024 15:13:44 +0100 Subject: [PATCH 10/19] improvements at UE to receive multiple instances of otherSIB for example SIB2 and SIB19 which are scheduled in separate messages --- common/utils/nr/nr_common.h | 1 + openair2/LAYER2/NR_MAC_UE/config_ue.c | 9 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 3 +- .../NR_MAC_UE/nr_ue_dci_configuration.c | 71 ++++++++-------- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 18 +++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 13 +-- openair2/RRC/NR_UE/rrc_UE.c | 84 ++++++++++--------- openair2/RRC/NR_UE/rrc_defs.h | 3 +- 9 files changed, 108 insertions(+), 96 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index d064b522b9..ef04daaad1 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -38,6 +38,7 @@ #include "assertions.h" #include "common/utils/utils.h" +#define MAX_SI_GROUPS 3 #define NR_MAX_PDSCH_TBS 3824 #define MAX_NUM_BEAM_PERIODS 4 #define MAX_BWP_SIZE 275 diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 1b5518f0bc..46e126ed97 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -936,10 +936,7 @@ static void update_mib_conf(NR_MIB_t *target, NR_MIB_t *source) target->intraFreqReselection = source->intraFreqReselection; } -void nr_rrc_mac_config_req_mib(module_id_t module_id, - int cc_idP, - NR_MIB_t *mib, - int sched_sib) +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -952,8 +949,8 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, mac->phy_config.CC_id = cc_idP; if (sched_sib == 1) mac->get_sib1 = true; - else if (sched_sib == 2) - mac->get_otherSI = true; + else if (sched_sib > 1) + mac->get_otherSI[sched_sib - 2] = true; nr_ue_decode_mib(mac, cc_idP); ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 838d1989f0..3241235bd3 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -539,7 +539,7 @@ typedef struct NR_UE_MAC_INST_s { int servCellIndex; long physCellId; bool get_sib1; - bool get_otherSI; + bool get_otherSI[MAX_SI_GROUPS]; NR_MIB_t *mib; si_schedInfo_t si_SchedInfo; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 6c744e8275..1ca4168b6f 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -56,7 +56,8 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) LOG_I(NR_MAC, "[UE%d] Initializing MAC\n", mac->ue_id); nr_ue_reset_sync_state(mac); mac->get_sib1 = false; - mac->get_otherSI = false; + for (int i = 0; i < MAX_SI_GROUPS; i++) + mac->get_otherSI[i] = false; memset(&mac->phy_config, 0, sizeof(mac->phy_config)); mac->si_SchedInfo.si_window_start = -1; mac->servCellIndex = 0; 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 1a816c64f6..34ef533884 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -375,7 +375,6 @@ bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac, if (((frame * slots_per_frame + slot - offset - i) % period) == 0) { int N = mac->ssb_list.nb_tx_ssb; int K = mac->ssb_list.nb_ssb_per_index[mac->mib_ssb]; - // numbering current frame and slot in terms of monitoring occasions in window int rel_slot = abs_slot - mac->si_SchedInfo.si_window_start; int current_monitor_occasion = (rel_slot % period) + (duration * rel_slot / period); @@ -399,43 +398,41 @@ bool is_window_valid(NR_UE_MAC_INST_t *mac, int window_slots, int abs_slot) return true; } -bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, - const NR_SearchSpace_t *ss, - const int slots_per_frame, - const int frame, - const int slot) +static bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, + const NR_SearchSpace_t *ss, + const int si_idx, + const int slots_per_frame, + const int frame, + const int slot) { // according to 5.2.2.3.2 in 331 const int abs_slot = frame * slots_per_frame + slot; - for (int i = 0; i < mac->si_SchedInfo.si_SchedInfo_list.count; i++) { - si_schedinfo_config_t *config = mac->si_SchedInfo.si_SchedInfo_list.array[i]; - int window_slots = 5 << mac->si_SchedInfo.si_WindowLength; - int x = (config->si_WindowPosition - 1) * window_slots; - int T = 8 << config->si_Periodicity; // radio frame periodicity - bool check_valid; - switch (config->type) { - case NR_SI_INFO : - if (mac->si_SchedInfo.si_window_start == -1) { - if ((frame % T) == (x / slots_per_frame) && (x % slots_per_frame == 0)) - mac->si_SchedInfo.si_window_start = abs_slot; // in terms of absolute slot number - } - check_valid = is_window_valid(mac, window_slots, abs_slot); - if (check_valid && search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame)) - return true; - break; - case NR_SI_INFO_v1700 : - if (mac->si_SchedInfo.si_window_start == -1) { - if ((frame % T == floor(x / slots_per_frame)) && (slot == x % slots_per_frame)) - mac->si_SchedInfo.si_window_start = abs_slot; - } - check_valid = is_window_valid(mac, window_slots, abs_slot); - if (check_valid && (config->si_WindowPosition - 1) == slot) - return search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame); - break; - default : - AssertFatal(false, "Invalid SI-SchedulingInfo case\n"); - } + si_schedinfo_config_t *config = mac->si_SchedInfo.si_SchedInfo_list.array[si_idx]; + int window_slots = 5 << mac->si_SchedInfo.si_WindowLength; + int x = (config->si_WindowPosition - 1) * window_slots; + int T = 8 << config->si_Periodicity; // radio frame periodicity + bool check_valid; + switch (config->type) { + case NR_SI_INFO : + if (mac->si_SchedInfo.si_window_start == -1) { + if ((frame % T) == (x / slots_per_frame) && (x % slots_per_frame == 0)) + mac->si_SchedInfo.si_window_start = abs_slot; // in terms of absolute slot number + } + check_valid = is_window_valid(mac, window_slots, abs_slot); + if (check_valid && search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame)) + return true; + break; + case NR_SI_INFO_v1700 : + if (mac->si_SchedInfo.si_window_start == -1) { + if ((frame % T == floor(x / slots_per_frame)) && (slot == x % slots_per_frame)) + mac->si_SchedInfo.si_window_start = abs_slot; + } + if (is_window_valid(mac, window_slots, abs_slot)) + return search_space_monitoring_ocasion_other_si(mac, ss, abs_slot, frame, slot, slots_per_frame); + break; + default : + AssertFatal(false, "Invalid SI-SchedulingInfo case\n"); } return false; } @@ -478,13 +475,15 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, mac->search_space_zero); } } - if (mac->get_otherSI) { + for (int i = 0; i < MAX_SI_GROUPS; i++) { + if (!mac->get_otherSI[i]) + continue; // If searchSpaceOtherSystemInformation is set to zero, // PDCCH monitoring occasions for SI message reception in SI-window // are same as PDCCH monitoring occasions for SIB1 const NR_SearchSpace_t *ss = pdcch_config->otherSI_SS ? pdcch_config->otherSI_SS : mac->search_space_zero; // TODO configure SI-window - if (monitor_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) { + if (monitor_dci_for_other_SI(mac, ss, i, slots_per_frame, frame, slot)) { LOG_D(NR_MAC_DCI, "Monitoring DCI for other SIs in frame %d slot %d\n", frame, slot); config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, ss); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 995d987304..9d2f702a16 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -310,8 +310,12 @@ int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); - mac->get_sib1 = false; - mac->get_otherSI = false; + if (mac->get_sib1) + mac->get_sib1 = false; + for (int i = 0; i < MAX_SI_GROUPS; i++) { + if (mac->get_otherSI[i]) + mac->get_otherSI[i] = false; + } T(T_NRUE_MAC_DL_PDU_WITH_DATA, T_INT(SI_RNTI), T_INT(-1 /* frame, unavailable here */), @@ -742,8 +746,16 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); return -1; } + dlsch_pdu->rb_offset = dlsch_pdu->start_rb + dlsch_pdu->BWPStart; - if (mac->get_sib1 || mac->get_otherSI) + bool otherSI = false; + for (int i = 0; i < MAX_SI_GROUPS; i++) { + if (mac->get_otherSI[i]) { + otherSI = true; + break; + } + } + if (mac->get_sib1 || otherSI) dlsch_pdu->rb_offset -= dlsch_pdu->BWPStart; /* TIME_DOM_RESOURCE_ASSIGNMENT */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index a00db6585c..39cb665c21 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -342,7 +342,7 @@ static uint32_t get_tbs_bch(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, return TBS; } -static uint32_t schedule_control_sib1(module_id_t module_id, +static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, int CC_id, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, int time_domain_allocation, @@ -352,7 +352,6 @@ static uint32_t schedule_control_sib1(module_id_t module_id, int beam, uint16_t num_total_bytes) { - gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n"); NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; uint16_t *vrb_map = cc->vrb_map[beam]; @@ -625,7 +624,8 @@ void schedule_nr_sib1(module_id_t module_idP, NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; // Configure sched_ctrlCommon for SIB1 - uint32_t TBS = schedule_control_sib1(module_idP, CC_id, + uint32_t TBS = schedule_control_sib1(gNB_mac, + CC_id, type0_PDCCH_CSS_config, time_domain_allocation, &dmrs_parms, @@ -709,8 +709,11 @@ static void other_sib_sched_control(module_id_t module_idP, int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame; NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index); - LOG_D(NR_MAC, "(%d.%d) otherSIB transmission for ssb number %d\n", frame, slot, beam_index); + LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index); + NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]]; + AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n"); NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup; int time_domain_allocation = 1; NR_tda_info_t tda_info = set_tda_info_from_list(pdsch_ConfigCommon->pdsch_TimeDomainAllocationList, time_domain_allocation); @@ -728,8 +731,6 @@ static void other_sib_sched_control(module_id_t module_idP, AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n"); NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common); - NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]]; if (!gNB_mac->sched_pdcch_otherSI) { gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI)); *gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index e321c1dd5b..30c0e548a7 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -282,28 +282,34 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) } static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, - struct NR_SI_SchedulingInfo *si_SchedulingInfo, - struct NR_SI_SchedulingInfo_v1700 *si_SchedulingInfo_v1700) + NR_SI_SchedulingInfo_t *si_SchedulingInfo, + NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700) { + for (int i = 0; i < MAX_SI_GROUPS; i++) + SI_info->default_otherSI_map[i] = 0; + int nb_groups = 0; if (si_SchedulingInfo) { - SI_info->default_otherSI_map = 0; - for (int i = 0; i < si_SchedulingInfo->schedulingInfoList.list.count; i++) { - struct NR_SchedulingInfo *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i]; + nb_groups = si_SchedulingInfo->schedulingInfoList.list.count; + AssertFatal(nb_groups <= MAX_SI_GROUPS, "Exceeding max number of SI groups configured\n"); + for (int i = 0; i < nb_groups; i++) { + NR_SchedulingInfo_t *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i]; for (int j = 0; j < schedulingInfo->sib_MappingInfo.list.count; j++) { - struct NR_SIB_TypeInfo *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j]; - SI_info->default_otherSI_map |= 1 << sib_Type->type; + NR_SIB_TypeInfo_t *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j]; + SI_info->default_otherSI_map[i] |= 1 << sib_Type->type; } } } if (si_SchedulingInfo_v1700) { - SI_info->SInfo_r17.default_otherSI_map_r17 = 0; + int start_idx = nb_groups; + nb_groups += si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count; + AssertFatal(nb_groups <= MAX_SI_GROUPS, "Exceeding max number of SI groups configured\n"); for (int i = 0; i < si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.count; i++) { - struct NR_SchedulingInfo2_r17 *schedulingInfo2 = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[i]; + NR_SchedulingInfo2_r17_t *schedulingInfo2 = si_SchedulingInfo_v1700->schedulingInfoList2_r17.list.array[i]; for (int j = 0; j < schedulingInfo2->sib_MappingInfo_r17.list.count; j++) { - struct NR_SIB_TypeInfo_v1700 *sib_TypeInfo_v1700 = schedulingInfo2->sib_MappingInfo_r17.list.array[j]; + NR_SIB_TypeInfo_v1700_t *sib_TypeInfo_v1700 = schedulingInfo2->sib_MappingInfo_r17.list.array[j]; if (sib_TypeInfo_v1700->sibType_r17.present == NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17) { - SI_info->SInfo_r17.default_otherSI_map_r17 |= 1 << sib_TypeInfo_v1700->sibType_r17.choice.type1_r17; + SI_info->default_otherSI_map[start_idx + i] |= 1 << (sib_TypeInfo_v1700->sibType_r17.choice.type1_r17 + 13); } } } @@ -318,11 +324,14 @@ static bool verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1 && *sib1_v1700->cellBarredNTN_r17 == NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred) ntn_access = true; - uint32_t sib19_mask = 1 << NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19; - int sib19_present = SI_info->SInfo_r17.default_otherSI_map_r17 & sib19_mask; - + uint32_t sib19_mask = 1 << (NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19 + 13); + int sib19_present = false; + for (int i = 0; i < MAX_SI_GROUPS; i++) { + sib19_present = SI_info->default_otherSI_map[i] & sib19_mask; + if (sib19_present) + break; + } AssertFatal(!ntn_access || sib19_present, "NTN cell, but SIB19 not configured.\n"); - return ntn_access && sib19_present; } @@ -783,7 +792,7 @@ bool check_si_validity_r17(NR_UE_RRC_SI_INFO_r17 *SI_info, int si_type) return true; } -int check_si_status(NR_UE_RRC_SI_INFO *SI_info) +static int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { // schedule reception of SIB1 if RRC doesn't have it if (SI_info->sib1_validity == SIB_NOT_VALID) { @@ -791,31 +800,22 @@ int check_si_status(NR_UE_RRC_SI_INFO *SI_info) return 1; } else { - if (SI_info->default_otherSI_map) { + for (int j = 0; j < MAX_SI_GROUPS; j++) { + if (!SI_info->default_otherSI_map[j]) + continue; // Check if RRC has configured default SI - // from SIB2 to SIB14 as current ASN1 version // TODO can be used for on demand SI when (if) implemented - for (int i = 2; i < 15; i++) { - int si_index = i - 2; - if ((SI_info->default_otherSI_map >> si_index) & 0x01) { - // if RRC has no valid version of one of the default configured SI - // Then schedule reception of otherSI - if (!check_si_validity(SI_info, si_index)) - return 2; - } - } - } - - // Check if RRC has configured default SI - // from SIB15 to SIB21 as current r17 version - if (SI_info->SInfo_r17.default_otherSI_map_r17) { - for (int i = 15; i < 22; i++) { - int si_index = i - 15; - if ((SI_info->SInfo_r17.default_otherSI_map_r17 >> si_index) & 0x01) { - // if RRC has no valid version of one of the default configured SI - // Then schedule reception of otherSI - if (!check_si_validity_r17(&SI_info->SInfo_r17, si_index)) - return 2; + for (int i = 2; i < 22; i++) { + if (!((SI_info->default_otherSI_map[j] >> (i - 2)) & 0x01)) + continue; + // if RRC has no valid version of one of the default configured SI + // Then schedule reception of otherSI + if (i < 15) { + if (!check_si_validity(SI_info, i - 2)) + return 2 + j; + } else { + if (!check_si_validity_r17(&SI_info->SInfo_r17, i - 15)) + return 2 + j; } } } @@ -862,8 +862,10 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, } int get_sib = 0; - if (IS_SA_MODE(get_softmodem_params()) && bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib - && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && rrc->nrRrcState != RRC_STATE_DETACH_NR) { + if (IS_SA_MODE(get_softmodem_params()) + && bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib + && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred + && rrc->nrRrcState != RRC_STATE_DETACH_NR) { NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index ee46a343d7..c9b14b3ae5 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -111,7 +111,6 @@ typedef enum { } SIB_validity_t; typedef struct UE_RRC_SI_INFO_NR_r17_s { - uint32_t default_otherSI_map_r17; SIB_validity_t sib15_validity; NR_timer_t sib15_timer; SIB_validity_t sib16_validity; @@ -129,7 +128,7 @@ typedef struct UE_RRC_SI_INFO_NR_r17_s { } NR_UE_RRC_SI_INFO_r17; typedef struct UE_RRC_SI_INFO_NR_s { - uint32_t default_otherSI_map; + uint32_t default_otherSI_map[MAX_SI_GROUPS]; SIB_validity_t sib1_validity; NR_timer_t sib1_timer; SIB_validity_t sib2_validity; From 2228c3966f7be42d9dfd181794d4299cf06018cb Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 30 Dec 2024 15:29:23 +0100 Subject: [PATCH 11/19] enabling configuration of transmitted SIBs in NTN config file --- ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf | 2 ++ .../GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf | 2 ++ .../GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf | 2 ++ .../GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf | 2 ++ 4 files changed, 8 insertions(+) diff --git a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf index 1d0bba606d..002d790e61 100644 --- a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf index 67be3dbb44..df06f0483b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf index 5a14f4fae6..34c31460ee 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf index c4213eb0d3..7b87bb3e98 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { From 3b22c4a566542ebcaba50db195999f8baf91f1da Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 29 Jan 2025 10:39:26 +0100 Subject: [PATCH 12/19] Revert tentative fix for double sib1 decoding because it doesn't behave as expected. Instead a new pending_sib variable is used for the same goal. This reverts commit 35e9d1e0c246b43cb2cad20123678d839e7f3bae. --- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 12 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 17 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 3 +- openair2/RRC/NR_UE/L2_interface_ue.c | 37 ++-- openair2/RRC/NR_UE/rrc_UE.c | 185 +++++++----------- openair2/RRC/NR_UE/rrc_defs.h | 49 +++-- openair2/RRC/NR_UE/rrc_timers_and_constants.c | 100 +++++++--- 7 files changed, 207 insertions(+), 196 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index a2b2e0f777..693ce4eb5a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -68,12 +68,12 @@ void release_common_ss_cset(NR_BWP_PDCCH_t *pdcch); \param sibs_mask sibs mask \param pduP pointer to pdu \param pdu_length length of pdu */ -int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, - int cc_id, - unsigned int gNB_index, - uint8_t ack_nack, - uint8_t *pduP, - uint32_t pdu_len); +void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, + int cc_id, + unsigned int gNB_index, + uint8_t ack_nack, + uint8_t *pduP, + uint32_t pdu_len); void release_dl_BWP(NR_UE_MAC_INST_t *mac, int index); void release_ul_BWP(NR_UE_MAC_INST_t *mac, int index); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 9d2f702a16..e282c380b0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -300,12 +300,12 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc } } -int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, - int cc_id, - unsigned int gNB_index, - uint8_t ack_nack, - uint8_t *pduP, - uint32_t pdu_len) +void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, + int cc_id, + unsigned int gNB_index, + uint8_t ack_nack, + uint8_t *pduP, + uint32_t pdu_len) { if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); @@ -323,9 +323,10 @@ int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, T_INT(0 /* harq_pid */), T_BUFFER(pduP, pdu_len)); } - else + else { LOG_E(NR_MAC, "Got NACK on NR-BCCH-DL-SCH-Message (%s)\n", mac->get_sib1 ? "SIB1" : "other SI"); - return 0; + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, NULL, 0); + } } /* diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 14916062b2..dfb0a0d942 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1108,7 +1108,8 @@ static int handle_bcch_dlsch(NR_UE_MAC_INST_t *mac, uint8_t *pduP, uint32_t pdu_len) { - return nr_ue_decode_BCCH_DL_SCH(mac, cc_id, gNB_index, ack_nack, pduP, pdu_len); + nr_ue_decode_BCCH_DL_SCH(mac, cc_id, gNB_index, ack_nack, pduP, pdu_len); + return 0; } // L2 Abstraction Layer diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 3bfe1d34e0..7202943322 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -59,15 +59,19 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id, const sdu_size_t pdu_len) { sdu_size_t sdu_size = 0; - + MessageDef *message_p; switch(channel) { case NR_BCCH_BCH: case NR_BCCH_DL_SCH: - if (pdu_len>0) { - LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET, + message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND); + memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + if (pdu_len > 0) { + LOG_T(NR_RRC, + "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", + module_id, + channel & RAB_OFFSET, gNB_index); - MessageDef *message_p; int msg_sdu_size = BCCH_SDU_SIZE; if (pdu_len > msg_sdu_size) { @@ -77,25 +81,23 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id, sdu_size = pdu_len; } - message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND); - memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size); - NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP - NR_RRC_MAC_BCCH_DATA_IND (message_p).slot = slot; NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; - NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; - NR_RRC_MAC_BCCH_DATA_IND (message_p).phycellid = cellid; - NR_RRC_MAC_BCCH_DATA_IND (message_p).ssb_arfcn = arfcn; - NR_RRC_MAC_BCCH_DATA_IND (message_p).is_bch = (channel == NR_BCCH_BCH); - itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); } + else { + NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = 0; + } + NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP + NR_RRC_MAC_BCCH_DATA_IND (message_p).slot = slot; + NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; + NR_RRC_MAC_BCCH_DATA_IND (message_p).phycellid = cellid; + NR_RRC_MAC_BCCH_DATA_IND (message_p).ssb_arfcn = arfcn; + NR_RRC_MAC_BCCH_DATA_IND (message_p).is_bch = (channel == NR_BCCH_BCH); + itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); break; - case NR_SBCCH_SL_BCH: if (pdu_len > 0) { LOG_T(NR_RRC, "[UE %d] Received SL-MIB for NR_SBCCH_SL_BCH.\n", module_id); - - MessageDef *message_p; int msg_sdu_size = BCCH_SDU_SIZE; if (pdu_len > msg_sdu_size) { @@ -115,9 +117,8 @@ void 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; - default: - break; + AssertFatal(false, "Invalid channel in data indication\n"); } } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 30c0e548a7..57ba669aeb 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -188,59 +188,59 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, LOG_A(NR_RRC, "Found SIB%d\n", typeandinfo->present + 1); switch(typeandinfo->present) { case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2: - SI_info->sib2_validity = SIB_VALID; + SI_info->sib2_validity = true; nr_timer_start(&SI_info->sib2_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3: - SI_info->sib3_validity = SIB_VALID; + SI_info->sib3_validity = true; nr_timer_start(&SI_info->sib3_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4: - SI_info->sib4_validity = SIB_VALID; + SI_info->sib4_validity = true; nr_timer_start(&SI_info->sib4_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5: - SI_info->sib5_validity = SIB_VALID; + SI_info->sib5_validity = true; nr_timer_start(&SI_info->sib5_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6: - SI_info->sib6_validity = SIB_VALID; + SI_info->sib6_validity = true; nr_timer_start(&SI_info->sib6_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7: - SI_info->sib7_validity = SIB_VALID; + SI_info->sib7_validity = true; nr_timer_start(&SI_info->sib7_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8: - SI_info->sib8_validity = SIB_VALID; + SI_info->sib8_validity = true; nr_timer_start(&SI_info->sib8_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9: - SI_info->sib9_validity = SIB_VALID; + SI_info->sib9_validity = true; nr_timer_start(&SI_info->sib9_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610: - SI_info->sib10_validity = SIB_VALID; + SI_info->sib10_validity = true; nr_timer_start(&SI_info->sib10_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610: - SI_info->sib11_validity = SIB_VALID; + SI_info->sib11_validity = true; nr_timer_start(&SI_info->sib11_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610: - SI_info->sib12_validity = SIB_VALID; + SI_info->sib12_validity = true; nr_timer_start(&SI_info->sib12_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610: - SI_info->sib13_validity = SIB_VALID; + SI_info->sib13_validity = true; nr_timer_start(&SI_info->sib13_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610: - SI_info->sib14_validity = SIB_VALID; + SI_info->sib14_validity = true; nr_timer_start(&SI_info->sib14_timer); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700: - SI_info->SInfo_r17.sib19_validity = SIB_VALID; + SI_info->SInfo_r17.sib19_validity = true; if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700); sib19 = typeandinfo->choice.sib19_v1700; @@ -341,7 +341,7 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) sib1); LOG_A(NR_RRC, "SIB1 decoded\n"); nr_timer_start(&SI_info->sib1_timer); - SI_info->sib1_validity = SIB_VALID; + SI_info->sib1_validity = true; if (rrc->nrRrcState == RRC_STATE_IDLE_NR) { rrc->ra_trigger = RRC_CONNECTION_SETUP; } @@ -658,82 +658,56 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) { switch (si_type) { case NR_SIB_TypeInfo__type_sibType2: - if (SI_info->sib2_validity == SIB_NOT_VALID) { - SI_info->sib2_validity = SIB_REQUESTED; + if (!SI_info->sib2_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType3: - if (SI_info->sib3_validity == SIB_NOT_VALID) { - SI_info->sib3_validity = SIB_REQUESTED; + if (!SI_info->sib3_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType4: - if (SI_info->sib4_validity == SIB_NOT_VALID) { - SI_info->sib4_validity = SIB_REQUESTED; + if (!SI_info->sib4_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType5: - if (SI_info->sib5_validity == SIB_NOT_VALID) { - SI_info->sib5_validity = SIB_REQUESTED; + if (!SI_info->sib5_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType6: - if (SI_info->sib6_validity == SIB_NOT_VALID) { - SI_info->sib6_validity = SIB_REQUESTED; + if (!SI_info->sib6_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType7: - if (SI_info->sib7_validity == SIB_NOT_VALID) { - SI_info->sib7_validity = SIB_REQUESTED; + if (!SI_info->sib7_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType8: - if (SI_info->sib8_validity == SIB_NOT_VALID) { - SI_info->sib8_validity = SIB_REQUESTED; + if (!SI_info->sib8_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType9: - if (SI_info->sib9_validity == SIB_NOT_VALID) { - SI_info->sib9_validity = SIB_REQUESTED; + if (!SI_info->sib9_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType10_v1610: - if (SI_info->sib10_validity == SIB_NOT_VALID) { - SI_info->sib10_validity = SIB_REQUESTED; + if (!SI_info->sib10_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType11_v1610: - if (SI_info->sib11_validity == SIB_NOT_VALID) { - SI_info->sib11_validity = SIB_REQUESTED; + if (!SI_info->sib11_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType12_v1610: - if (SI_info->sib12_validity == SIB_NOT_VALID) { - SI_info->sib12_validity = SIB_REQUESTED; + if (!SI_info->sib12_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType13_v1610: - if (SI_info->sib13_validity == SIB_NOT_VALID) { - SI_info->sib13_validity = SIB_REQUESTED; + if (!SI_info->sib13_validity) return false; - } break; case NR_SIB_TypeInfo__type_sibType14_v1610: - if (SI_info->sib14_validity == SIB_NOT_VALID) { - SI_info->sib14_validity = SIB_REQUESTED; + if (!SI_info->sib14_validity) return false; - } break; default : AssertFatal(false, "Invalid SIB type %d\n", si_type); @@ -745,46 +719,32 @@ bool check_si_validity_r17(NR_UE_RRC_SI_INFO_r17 *SI_info, int si_type) { switch (si_type) { case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType15: - if (SI_info->sib15_validity == SIB_NOT_VALID) { - SI_info->sib15_validity = SIB_REQUESTED; + if (!SI_info->sib15_validity) return false; - } break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType16: - if (SI_info->sib16_validity == SIB_NOT_VALID) { - SI_info->sib16_validity = SIB_REQUESTED; + if (!SI_info->sib16_validity) return false; - } break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType17: - if (SI_info->sib17_validity == SIB_NOT_VALID) { - SI_info->sib17_validity = SIB_REQUESTED; + if (!SI_info->sib17_validity) return false; - } break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType18: - if (SI_info->sib18_validity == SIB_NOT_VALID) { - SI_info->sib18_validity = SIB_REQUESTED; + if (!SI_info->sib18_validity) return false; - } break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19: - if (SI_info->sib19_validity == SIB_NOT_VALID) { - SI_info->sib19_validity = SIB_REQUESTED; + if (!SI_info->sib19_validity) return false; - } break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType20: - if (SI_info->sib20_validity == SIB_NOT_VALID) { - SI_info->sib20_validity = SIB_REQUESTED; + if (!SI_info->sib20_validity) return false; - } break; case NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType21: - if (SI_info->sib21_validity == SIB_NOT_VALID) { - SI_info->sib21_validity = SIB_REQUESTED; + if (!SI_info->sib21_validity) return false; - } break; default : AssertFatal(false, "Invalid SIB r17 type %d\n", si_type); @@ -795,10 +755,8 @@ bool check_si_validity_r17(NR_UE_RRC_SI_INFO_r17 *SI_info, int si_type) static int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { // schedule reception of SIB1 if RRC doesn't have it - if (SI_info->sib1_validity == SIB_NOT_VALID) { - SI_info->sib1_validity = SIB_REQUESTED; + if (!SI_info->sib1_validity) return 1; - } else { for (int j = 0; j < MAX_SI_GROUPS; j++) { if (!SI_info->default_otherSI_map[j]) @@ -861,14 +819,17 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, // not used } + NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; int get_sib = 0; if (IS_SA_MODE(get_softmodem_params()) + && !SI_info->sib_pending && bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && rrc->nrRrcState != RRC_STATE_DETACH_NR) { - NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); + if (get_sib) + SI_info->sib_pending = true; } if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_MIB); @@ -958,18 +919,20 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) } } -static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, - const uint8_t gNB_index, - uint8_t *const Sdu, - const uint8_t Sdu_len, - const uint8_t rsrq, - const uint8_t rsrp) +static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, + const uint8_t gNB_index, + uint8_t *const Sdu, + const uint8_t Sdu_len, + const uint8_t rsrq, + const uint8_t rsrp) { - NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; - NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN); + SI_info->sib_pending = false; + if (Sdu_len == 0) // decoding failed in L2 + return; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN); + NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_DL_SCH_Message, (void **)&bcch_message, @@ -982,7 +945,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, // free the memory SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); - return -1; + return; } if (LOG_DEBUGFLAG(DEBUG_ASN1)) { @@ -1008,7 +971,6 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, } SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, bcch_message, ASFM_FREE_EVERYTHING); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); - return 0; } static void nr_rrc_signal_maxrtxindication(int ue_id) @@ -2619,27 +2581,28 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, rrcPerNB_t *nb = &rrc->perNB[i]; NR_UE_RRC_SI_INFO *SI_info = &nb->SInfo; init_SI_timers(SI_info); - SI_info->sib1_validity = SIB_NOT_VALID; - SI_info->sib2_validity = SIB_NOT_VALID; - SI_info->sib3_validity = SIB_NOT_VALID; - SI_info->sib4_validity = SIB_NOT_VALID; - SI_info->sib5_validity = SIB_NOT_VALID; - SI_info->sib6_validity = SIB_NOT_VALID; - SI_info->sib7_validity = SIB_NOT_VALID; - SI_info->sib8_validity = SIB_NOT_VALID; - SI_info->sib9_validity = SIB_NOT_VALID; - SI_info->sib10_validity = SIB_NOT_VALID; - SI_info->sib11_validity = SIB_NOT_VALID; - SI_info->sib12_validity = SIB_NOT_VALID; - SI_info->sib13_validity = SIB_NOT_VALID; - SI_info->sib14_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib15_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib16_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib17_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib18_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib19_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib20_validity = SIB_NOT_VALID; - SI_info->SInfo_r17.sib21_validity = SIB_NOT_VALID; + SI_info->sib_pending = false; + SI_info->sib1_validity = false; + SI_info->sib2_validity = false; + SI_info->sib3_validity = false; + SI_info->sib4_validity = false; + SI_info->sib5_validity = false; + SI_info->sib6_validity = false; + SI_info->sib7_validity = false; + SI_info->sib8_validity = false; + SI_info->sib9_validity = false; + SI_info->sib10_validity = false; + SI_info->sib11_validity = false; + SI_info->sib12_validity = false; + SI_info->sib13_validity = false; + SI_info->sib14_validity = false; + SI_info->SInfo_r17.sib15_validity = false; + SI_info->SInfo_r17.sib16_validity = false; + SI_info->SInfo_r17.sib17_validity = false; + SI_info->SInfo_r17.sib18_validity = false; + SI_info->SInfo_r17.sib19_validity = false; + SI_info->SInfo_r17.sib20_validity = false; + SI_info->SInfo_r17.sib21_validity = false; } if (rrc->nrRrcState == RRC_STATE_DETACH_NR) { diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index c9b14b3ae5..d300d2a7b8 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -104,58 +104,53 @@ typedef enum RA_trigger_e { BEAM_FAILURE_RECOVERY, } RA_trigger_t; -typedef enum { - SIB_NOT_VALID, - SIB_VALID, - SIB_REQUESTED, -} SIB_validity_t; - typedef struct UE_RRC_SI_INFO_NR_r17_s { - SIB_validity_t sib15_validity; + bool sib15_validity; NR_timer_t sib15_timer; - SIB_validity_t sib16_validity; + bool sib16_validity; NR_timer_t sib16_timer; - SIB_validity_t sib17_validity; + bool sib17_validity; NR_timer_t sib17_timer; - SIB_validity_t sib18_validity; + bool sib18_validity; NR_timer_t sib18_timer; - SIB_validity_t sib19_validity; + bool sib19_validity; NR_timer_t sib19_timer; - SIB_validity_t sib20_validity; + bool sib20_validity; NR_timer_t sib20_timer; - SIB_validity_t sib21_validity; + bool sib21_validity; NR_timer_t sib21_timer; } NR_UE_RRC_SI_INFO_r17; typedef struct UE_RRC_SI_INFO_NR_s { + bool sib_pending; uint32_t default_otherSI_map[MAX_SI_GROUPS]; - SIB_validity_t sib1_validity; + bool sib1_validity; NR_timer_t sib1_timer; - SIB_validity_t sib2_validity; + bool sib2_validity; NR_timer_t sib2_timer; - SIB_validity_t sib3_validity; + bool sib3_validity; NR_timer_t sib3_timer; - SIB_validity_t sib4_validity; + bool sib4_validity; NR_timer_t sib4_timer; - SIB_validity_t sib5_validity; + bool sib5_validity; NR_timer_t sib5_timer; - SIB_validity_t sib6_validity; + bool sib6_validity; NR_timer_t sib6_timer; - SIB_validity_t sib7_validity; + bool sib7_validity; NR_timer_t sib7_timer; - SIB_validity_t sib8_validity; + bool sib8_validity; NR_timer_t sib8_timer; - SIB_validity_t sib9_validity; + bool sib9_validity; NR_timer_t sib9_timer; - SIB_validity_t sib10_validity; + bool sib10_validity; NR_timer_t sib10_timer; - SIB_validity_t sib11_validity; + bool sib11_validity; NR_timer_t sib11_timer; - SIB_validity_t sib12_validity; + bool sib12_validity; NR_timer_t sib12_timer; - SIB_validity_t sib13_validity; + bool sib13_validity; NR_timer_t sib13_timer; - SIB_validity_t sib14_validity; + bool sib14_validity; NR_timer_t sib14_timer; NR_UE_RRC_SI_INFO_r17 SInfo_r17; } NR_UE_RRC_SI_INFO; diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index 39e73fa5a4..6629055b3a 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -43,33 +43,83 @@ void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo) nr_timer_setup(&SInfo->SInfo_r17.sib19_timer, 10800000, 10); } -static SIB_validity_t check_sib_timer_validity(SIB_validity_t sib_validity, NR_timer_t *sib_timer) -{ - if (sib_validity == SIB_VALID) { - bool sib_expired = nr_timer_tick(sib_timer); - if (sib_expired) - return SIB_NOT_VALID; - } - return sib_validity; -} - void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) { - SInfo->sib1_validity = check_sib_timer_validity(SInfo->sib1_validity, &SInfo->sib1_timer); - SInfo->sib2_validity = check_sib_timer_validity(SInfo->sib2_validity, &SInfo->sib2_timer); - SInfo->sib3_validity = check_sib_timer_validity(SInfo->sib3_validity, &SInfo->sib3_timer); - SInfo->sib4_validity = check_sib_timer_validity(SInfo->sib4_validity, &SInfo->sib4_timer); - SInfo->sib5_validity = check_sib_timer_validity(SInfo->sib5_validity, &SInfo->sib5_timer); - SInfo->sib6_validity = check_sib_timer_validity(SInfo->sib6_validity, &SInfo->sib6_timer); - SInfo->sib7_validity = check_sib_timer_validity(SInfo->sib7_validity, &SInfo->sib7_timer); - SInfo->sib8_validity = check_sib_timer_validity(SInfo->sib8_validity, &SInfo->sib8_timer); - SInfo->sib9_validity = check_sib_timer_validity(SInfo->sib9_validity, &SInfo->sib9_timer); - SInfo->sib10_validity = check_sib_timer_validity(SInfo->sib10_validity, &SInfo->sib10_timer); - SInfo->sib11_validity = check_sib_timer_validity(SInfo->sib11_validity, &SInfo->sib11_timer); - SInfo->sib12_validity = check_sib_timer_validity(SInfo->sib12_validity, &SInfo->sib12_timer); - SInfo->sib13_validity = check_sib_timer_validity(SInfo->sib13_validity, &SInfo->sib13_timer); - SInfo->sib14_validity = check_sib_timer_validity(SInfo->sib14_validity, &SInfo->sib14_timer); - SInfo->SInfo_r17.sib19_validity = check_sib_timer_validity(SInfo->SInfo_r17.sib19_validity, &SInfo->SInfo_r17.sib19_timer); + if (SInfo->sib1_validity) { + bool sib1_expired = nr_timer_tick(&SInfo->sib1_timer); + if (sib1_expired) + SInfo->sib1_validity = false; + } + if (SInfo->sib2_validity) { + bool sib2_expired = nr_timer_tick(&SInfo->sib2_timer); + if (sib2_expired) + SInfo->sib2_validity = false; + } + if (SInfo->sib3_validity) { + bool sib3_expired = nr_timer_tick(&SInfo->sib3_timer); + if (sib3_expired) + SInfo->sib3_validity = false; + } + if (SInfo->sib4_validity) { + bool sib4_expired = nr_timer_tick(&SInfo->sib4_timer); + if (sib4_expired) + SInfo->sib4_validity = false; + } + if (SInfo->sib5_validity) { + bool sib5_expired = nr_timer_tick(&SInfo->sib5_timer); + if (sib5_expired) + SInfo->sib5_validity = false; + } + if (SInfo->sib6_validity) { + bool sib6_expired = nr_timer_tick(&SInfo->sib6_timer); + if (sib6_expired) + SInfo->sib6_validity = false; + } + if (SInfo->sib7_validity) { + bool sib7_expired = nr_timer_tick(&SInfo->sib7_timer); + if (sib7_expired) + SInfo->sib7_validity = false; + } + if (SInfo->sib8_validity) { + bool sib8_expired = nr_timer_tick(&SInfo->sib8_timer); + if (sib8_expired) + SInfo->sib8_validity = false; + } + if (SInfo->sib9_validity) { + bool sib9_expired = nr_timer_tick(&SInfo->sib9_timer); + if (sib9_expired) + SInfo->sib9_validity = false; + } + if (SInfo->sib10_validity) { + bool sib10_expired = nr_timer_tick(&SInfo->sib10_timer); + if (sib10_expired) + SInfo->sib10_validity = false; + } + if (SInfo->sib11_validity) { + bool sib11_expired = nr_timer_tick(&SInfo->sib11_timer); + if (sib11_expired) + SInfo->sib11_validity = false; + } + if (SInfo->sib12_validity) { + bool sib12_expired = nr_timer_tick(&SInfo->sib12_timer); + if (sib12_expired) + SInfo->sib12_validity = false; + } + if (SInfo->sib13_validity) { + bool sib13_expired = nr_timer_tick(&SInfo->sib13_timer); + if (sib13_expired) + SInfo->sib13_validity = false; + } + if (SInfo->sib14_validity) { + bool sib14_expired = nr_timer_tick(&SInfo->sib14_timer); + if (sib14_expired) + SInfo->sib14_validity = false; + } + if (SInfo->SInfo_r17.sib19_validity) { + bool sib19_expired = nr_timer_tick(&SInfo->SInfo_r17.sib19_timer); + if (sib19_expired) + SInfo->SInfo_r17.sib19_validity = false; + } } void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) From a9e9dfbd060f4271b109d28cbc4f558ff89ca8b5 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 9 Apr 2025 17:38:22 +0200 Subject: [PATCH 13/19] assertions for wrong node type SIB input --- openair2/GNB_APP/gnb_config.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 24b1fb0c8b..7a5ea5df93 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1432,6 +1432,9 @@ static nr_redcap_config_t *get_redcap_config(int gnb_idx) static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray) { + if (NODE_IS_DU(get_node_type())) + AssertFatal(GNBparamarray[GNB_CU_SIBS_IDX].numelt == 0, "This is DU, do not input CU SIBs\n"); + if (!config_isparamset(GNBparamarray, GNB_DU_SIBS_IDX)) return NULL; @@ -1880,6 +1883,9 @@ static int sort_neighbour_cell_config_by_cell_id(const void *a, const void *b) static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray) { + if (NODE_IS_CU(get_node_type())) + AssertFatal(GNBparamarray[GNB_DU_SIBS_IDX].numelt == 0, "This is CU, do not input DU SIBs\n"); + if (!config_isparamset(GNBparamarray, GNB_CU_SIBS_IDX)) return NULL; From 7edf52ca5bfa3e864afa60fbce4bd390b839b4a8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 10 Apr 2025 16:35:36 +0200 Subject: [PATCH 14/19] Use cp_f1ap_() functions to properly copy F1 messages --- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 8a84a7f85d..ff89f61160 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -53,10 +53,7 @@ static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_ MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP); msg->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_resp_t *f1ap_msg = &F1AP_SETUP_RESP(msg); - *f1ap_msg = *resp; - if (resp->gNB_CU_name != NULL) - f1ap_msg->gNB_CU_name = strdup(resp->gNB_CU_name); - free_f1ap_setup_response(resp); + *f1ap_msg = cp_f1ap_setup_response(resp); itti_send_msg_to_task(TASK_CU_F1, 0, msg); } @@ -65,7 +62,7 @@ static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failur MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_FAILURE); msg->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_failure_t *f1ap_msg = &F1AP_SETUP_FAILURE(msg); - *f1ap_msg = *fail; + *f1ap_msg = cp_f1ap_setup_failure(fail); itti_send_msg_to_task(TASK_CU_F1, 0, msg); } @@ -74,7 +71,7 @@ static void gnb_du_configuration_update_ack_f1ap(sctp_assoc_t assoc_id, const f1 MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE); msg->ittiMsgHeader.originInstance = assoc_id; f1ap_gnb_du_configuration_update_acknowledge_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg); - *f1ap_msg = *ack; + *f1ap_msg = cp_f1ap_du_configuration_update_acknowledge(ack); itti_send_msg_to_task(TASK_CU_F1, 0, msg); } From 463942d90edc8f6e52fe1fed8f029adc04b73359 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 10 Apr 2025 16:46:23 +0200 Subject: [PATCH 15/19] F1AP: correctly encode SI containers - encode all SI containers the encoding function gets (it's not the encoding function's job to enforce semantics) - Fixes: 30628b820c3 ("Add encoding/decoding lib for F1AP Setup Response (Interface Management)") --- openair2/F1AP/lib/f1ap_interface_management.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 4d8c4fcccf..32a1f28b58 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -653,11 +653,9 @@ static void encode_cells_to_activate(const served_cells_to_activate_t *cell, F1A &cells_to_be_activated_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; const f1ap_sib_msg_t *SI_msg = &cell->SI_msg[n]; if (SI_msg->SI_container != NULL) { - if (SI_msg->SI_type > 6 && SI_msg->SI_type != 9) { - asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); - sib_item->sIBtype = SI_msg->SI_type; - OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container, SI_msg->SI_container_length); - } + asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); + sib_item->sIBtype = SI_msg->SI_type; + OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container, SI_msg->SI_container_length); } } } @@ -1221,7 +1219,7 @@ f1ap_setup_resp_t cp_f1ap_setup_response(const f1ap_setup_resp_t *msg) const f1ap_sib_msg_t *b_SI_msg = &msg_cell->SI_msg[j]; cp_SI_msg->SI_container_length = b_SI_msg->SI_container_length; cp_SI_msg->SI_container = malloc_or_fail(cp_SI_msg->SI_container_length); - *cp_SI_msg->SI_container = *b_SI_msg->SI_container; + memcpy(cp_SI_msg->SI_container, b_SI_msg->SI_container, b_SI_msg->SI_container_length); cp_SI_msg->SI_type = b_SI_msg->SI_type; } } From e73f1f6220e74814a0ce40acea2cf206a1de72c0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 10 Apr 2025 16:50:43 +0200 Subject: [PATCH 16/19] F1AP: Correctly encode DU configuration update acknowledge SI container Fixes: b91e1b0a12e ("Add enc/dec lib for F1AP gNB-DU Configuration Update Acknowledge (Interface Management)") --- openair2/F1AP/lib/f1ap_interface_management.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 32a1f28b58..5767a06d95 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -2107,8 +2107,12 @@ f1ap_gnb_du_configuration_update_acknowledge_t cp_f1ap_du_configuration_update_a for (int i = 0; i < cp.num_cells_to_activate; i++) { cp.cells_to_activate[i] = msg->cells_to_activate[i]; for (int s = 0; s < cp.cells_to_activate[i].num_SI; s++) { - cp.cells_to_activate[i].SI_msg[s].SI_container = calloc_or_fail(1, sizeof(*cp.cells_to_activate[i].SI_msg[s].SI_container)); - *cp.cells_to_activate[i].SI_msg[s].SI_container = *msg->cells_to_activate[i].SI_msg[s].SI_container; + f1ap_sib_msg_t *cp_sib = &cp.cells_to_activate[i].SI_msg[s]; + const f1ap_sib_msg_t *msg_sib = &msg->cells_to_activate[i].SI_msg[s]; + cp_sib->SI_type = msg_sib->SI_type; + cp_sib->SI_container_length = msg_sib->SI_container_length; + cp_sib->SI_container = calloc_or_fail(cp_sib->SI_container_length, sizeof(*cp_sib->SI_container)); + memcpy(cp_sib->SI_container, msg_sib->SI_container, cp_sib->SI_container_length); } } return cp; From f3724ec4513e5c845ff9ee7335771e82fd741cda Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 11 Apr 2025 16:05:24 +0200 Subject: [PATCH 17/19] Add SIBs in configuration doc and feature set --- doc/FEATURE_SET.md | 5 +++-- doc/MAC/mac-usage.md | 6 +++++- doc/RRC/rrc-usage.md | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 5dd5d8b8b3..3c7490d937 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -105,7 +105,7 @@ These modes of operation are supported: - MAC -> PHY configuration using NR FAPI P5 interface - MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU -- Scheduler procedures for SIB1 +- Generation of and scheduler procedures for MIB/SIB1 - Scheduler procedures for RA - 4-Step RA - Contention Free RA procedure @@ -140,6 +140,7 @@ These modes of operation are supported: - MAC scheduling of SR reception - Intra-frequency handover - Initial support for RedCap +- Scheduling of SIBs (2, 19) ## gNB RLC @@ -174,7 +175,7 @@ These modes of operation are supported: - NR RRC (38.331) Rel 17 messages using new [asn1c](https://github.com/mouse07410/asn1c) - LTE RRC (36.331) also updated to Rel 15 -- Generation of MIB/SIB1 (received from DU) +- Generation of system information (SIB2) - RRC can configure PDCP, RLC, MAC - Interface with GTP-U (tunnel creation/handling for S1-U (NSA), N3 (SA), F1 interfaces) - Integration of RRC messages and procedures supporting UE 5G SA connection diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index 6804ca4543..e4d6ebc098 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -232,7 +232,9 @@ In the `MACRLCs` section of the gNB/DU configuration file: In the `gNBs` section of the gNB/DU configuration file: some of the parameters affect RRC configuration (CellGroupConfig) of a UE, and are therefore listed -here, *also they pertain to the DU*, i.e., the scheduler. +here, *also they pertain to the DU*, i.e., the scheduler. Note also that some +SIBs are configured at the DU and some at the CU; please consult the [RRC +configuration](../RRC/rrc-usage.md) as well for SIB configuration. * `pdsch_AntennaPorts_XP` (default 1): number of XP logical antenna ports in PDSCH (see also [`RUNMODEM.md`](../RUNMODEM.md)) @@ -267,6 +269,8 @@ here, *also they pertain to the DU*, i.e., the scheduler. options are 2, 4, 6, 8, 10, 12, 32; **32 is a Rel-17 features**) * `num_ulharq` (default 16): as `num_dlharq` for UL (other valid option is 32; **32 is i Rel-17 feature**) +- `du_sibs` (default `[]`): list of SIBs to transmit in the cell. Currently, + SIB19 (for NTN) is supported. ## ServingCellConfigCommon parameters diff --git a/doc/RRC/rrc-usage.md b/doc/RRC/rrc-usage.md index 668c106a0d..09c8952889 100644 --- a/doc/RRC/rrc-usage.md +++ b/doc/RRC/rrc-usage.md @@ -67,6 +67,9 @@ RRC-specific configuration ### cell-specific options +Note that some SIBS are configured at the CU and some at the DU; please consult +the [MAC configuration](../MAC/mac-usage.md) as well for SIB configuration. + - `gNB_ID` and `gNB_name`: ID and name of the gNB - `tracking_area_code`: the current tracking area code in the range `[0x0001, 0xfffd]` @@ -84,6 +87,8 @@ RRC-specific configuration - `enable_sdap` (default: false): enable the use of the SDAP layer. If deactivated, a transparent SDAP header is prepended to packets, but no further processing is being done. +- `cu_sibs` (default: `[]`) list of SIBs to give to the DU for transmission. + Currently, SIB2 is supported. ### UE-specific configuration From 9185c29e33c541876b97ee5eb043255cbc2ac46a Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 13 Apr 2025 09:43:28 +0200 Subject: [PATCH 18/19] change ss0 configuration to schedule multiple sibs in ntn config files with small bw --- ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf | 2 +- .../CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf | 4 ++-- .../CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf | 4 ++-- .../CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf index 002d790e61..198ac12833 100644 --- a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf @@ -50,7 +50,7 @@ gNBs = initialDLBWPsubcarrierSpacing = 0; #pdcch-ConfigCommon initialDLBWPcontrolResourceSetZero = 2; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPsearchSpaceZero = 2; #uplinkConfigCommon #frequencyInfoUL diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf index df06f0483b..dd3307d32c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf @@ -49,8 +49,8 @@ gNBs = # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 0; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPcontrolResourceSetZero = 2; + initialDLBWPsearchSpaceZero = 2; #uplinkConfigCommon #frequencyInfoUL diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf index 34c31460ee..7c2c3805ee 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf @@ -49,8 +49,8 @@ gNBs = # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 0; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 0; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPcontrolResourceSetZero = 2; + initialDLBWPsearchSpaceZero = 2; #uplinkConfigCommon #frequencyInfoUL diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf index 7b87bb3e98..b720d6d720 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf @@ -49,8 +49,8 @@ gNBs = # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 0; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 0; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPcontrolResourceSetZero = 2; + initialDLBWPsearchSpaceZero = 2; #uplinkConfigCommon #frequencyInfoUL From 7c4eabdb6eeb27cc8ce6a480e3bbb89b8b09bee2 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 14 Apr 2025 11:28:00 +0200 Subject: [PATCH 19/19] fix for DLSCH DMRS reference point (regression at the OAI UE introduced when testing with OAI gNB for a missing implementation in OAI gNB) --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 ++-------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 30ce9cdc5e..aed99ff358 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -730,7 +730,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC #endif } uint32_t dmrs_idx = rel15->rbStart; - if (rel15->rnti != SI_RNTI) + if (rel15->refPoint == 0) dmrs_idx += rel15->BWPStart; dmrs_idx *= dmrs_Type == NFAPI_NR_DMRS_TYPE1 ? 6 : 4; c16_t txdataF_precoding[rel15->nrOfLayers][symbol_sz] __attribute__((aligned(64))); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index e282c380b0..572202d044 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -749,14 +749,8 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, } dlsch_pdu->rb_offset = dlsch_pdu->start_rb + dlsch_pdu->BWPStart; - bool otherSI = false; - for (int i = 0; i < MAX_SI_GROUPS; i++) { - if (mac->get_otherSI[i]) { - otherSI = true; - break; - } - } - if (mac->get_sib1 || otherSI) + + if (mac->get_sib1) dlsch_pdu->rb_offset -= dlsch_pdu->BWPStart; /* TIME_DOM_RESOURCE_ASSIGNMENT */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 39cb665c21..71ebc7d8a9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -460,7 +460,7 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; - pdsch_pdu_rel15->refPoint = 1; + pdsch_pdu_rel15->refPoint = is_sib1; pdsch_pdu_rel15->dmrsConfigType = 0; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0;