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..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 @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { @@ -48,7 +50,7 @@ gNBs = initialDLBWPsubcarrierSpacing = 0; #pdcch-ConfigCommon initialDLBWPcontrolResourceSetZero = 2; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPsearchSpaceZero = 2; #uplinkConfigCommon #frequencyInfoUL diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index fdb3cc7ffc..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 @@ -93,6 +94,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/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 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/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/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/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 4d8c4fcccf..5767a06d95 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; } } @@ -2109,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; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 377a4a8be0..cbb46f0132 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; @@ -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,31 @@ static nr_redcap_config_t *get_redcap_config(int gnb_idx) return rc; } +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; + + 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; @@ -1693,17 +1727,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; @@ -1847,6 +1882,31 @@ 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 (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; + + seq_arr_t *SIBs = malloc(sizeof(seq_arr_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 + // 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); + 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(nr_SIBs_t)); + } + return SIBs; +} + static void fill_neighbour_cell_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc) { char gnbpath[MAX_OPTNAME_SIZE + 8]; @@ -2086,6 +2146,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_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 7f7fccbd8f..c76b6bc143 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -139,6 +139,8 @@ 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_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" @@ -150,6 +152,8 @@ 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" +#define GNB_CONFIG_HLP_DU_SIBS "List of DU generated SIBs to be transmitted" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ @@ -195,6 +199,8 @@ 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}, \ +{GNB_CONFIG_STRING_DU_SIB_LIST, GNB_CONFIG_HLP_DU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ } // clang-format on @@ -236,6 +242,8 @@ 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 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} @@ -279,6 +287,8 @@ typedef enum { { .s1 = { config_check_intval, NUM_UL_HARQ_OKVALUES,2 } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ 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/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/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/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 8457cad135..34ef533884 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) @@ -445,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); @@ -469,44 +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; - } - 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); - 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; } @@ -549,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 20745a5e25..572202d044 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -300,18 +300,22 @@ 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"); 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 */), @@ -319,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); + } } /* @@ -742,8 +747,10 @@ 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) + + if (mac->get_sib1) dlsch_pdu->rb_offset -= dlsch_pdu->BWPStart; /* TIME_DOM_RESOURCE_ASSIGNMENT */ @@ -2993,7 +3000,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 +3016,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 +3320,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 diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 19efd1d401..26319a6049 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" @@ -863,30 +864,98 @@ 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) +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_SearchSpaceId_t *osi_SearchSpace = pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation; - if (osi_SearchSpace) { - nrmac->sched_osi = CALLOC(1, sizeof(*nrmac->sched_osi)); + 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 */ - 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; + 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]); } - AssertFatal(nrmac->sched_osi->search_space != NULL, "SearchSpace cannot be null for OSI\n"); } + + 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) @@ -897,21 +966,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..e14004edc3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -219,8 +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); - 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); + 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..71ebc7d8a9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -274,76 +274,75 @@ 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; } -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, @@ -353,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]; @@ -382,7 +380,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, @@ -397,92 +398,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 +424,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)); @@ -532,7 +460,7 @@ static void nr_fill_nfapi_dl_SIB_pdu(int Mod_idP, 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; @@ -598,7 +526,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_; @@ -696,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, @@ -707,17 +636,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 +695,227 @@ 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 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); + LOG_D(NR_MAC,"tda_info.startSymbolIndex: %d, tda_info.nrOfSymbols: %d\n", tda_info.startSymbolIndex, tda_info.nrOfSymbols); - // there is no reason to execute further if sched_osi not initialized - if (!gNB_mac->sched_osi) - return; + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1); - // 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; + 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 } - 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"); + 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); + 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); + + AssertFatal(cce_index >= 0, "Could not find CCE for otherSIB DCI\n"); + + // 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_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); + } + + 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 3925ed6ea0..4e292b916b 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; @@ -859,12 +859,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; @@ -873,19 +869,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 4f8ab8f51d..c4cfd4181e 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 65c5aba9f1..c8b809a8cb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -54,10 +54,8 @@ 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); -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); @@ -97,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*); @@ -215,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, @@ -474,4 +467,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 25a182dddb..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,7 +165,15 @@ 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"); + // 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)); AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7e79ac356b..3a01ecfbfb 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 @@ -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; @@ -929,9 +916,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/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/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index beb8de2e3a..07343488a2 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -197,51 +197,37 @@ 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_SSB_MTC_t *ssbmtc) { - asn_enc_rval_t enc_rval; - SystemInformation_IEs__sib_TypeAndInfo__Member *sib2 = NULL; - SystemInformation_IEs__sib_TypeAndInfo__Member *sib3 = NULL; + 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; + sib2->intraFreqCellReselectionInfo.smtc = ssbmtc; - 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; - 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; - 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); - - //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_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..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_SIB23_NR(rrc_gNB_carrier_data_t *carrier); +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/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); } diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index e39dd3581f..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; @@ -2349,6 +2348,107 @@ 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)); + // 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; + 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 +2478,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 +2529,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 +2754,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 +2772,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 c30f8856bc..f0dfc2ec02 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]; @@ -378,7 +369,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 +376,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..b93e08e79f 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -215,29 +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)) { - 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"); - } - - 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) { @@ -277,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 6c7c157374..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,6 +406,26 @@ 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++) { + 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); + } + } + } + if (du->mib != NULL && du->sib1 != NULL) label_intra_frequency_neighbours(rrc, du, cell_info); 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 dc1cb72baa..57ba669aeb 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -185,62 +185,62 @@ 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; + 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; @@ -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; } @@ -332,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; } @@ -649,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); @@ -736,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); @@ -783,39 +752,28 @@ 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) { - SI_info->sib1_validity = SIB_REQUESTED; + if (!SI_info->sib1_validity) 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; } } } @@ -861,12 +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()) && 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; + 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) { // 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); @@ -956,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, @@ -980,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)) { @@ -1006,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) @@ -2617,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 ee46a343d7..d300d2a7b8 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -104,59 +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 { - uint32_t default_otherSI_map_r17; - 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 { - uint32_t default_otherSI_map; - SIB_validity_t sib1_validity; + bool sib_pending; + uint32_t default_otherSI_map[MAX_SI_GROUPS]; + 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) 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..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 @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { @@ -47,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 5a14f4fae6..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 @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { @@ -47,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 c4213eb0d3..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 @@ -19,6 +19,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; + cu_sibs = [2]; + du_sibs = [19]; servingCellConfigCommon = ( { @@ -47,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