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);