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