Merge remote-tracking branch 'origin/NR_gNB_SIB2' into integration_2025_w15 (!3184)
NR SIB2 - Transmission of SIB2 - Fixes for transmission and reception of SIB19 Closes #901
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 } }, \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__*/
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+113
-98
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+118
-153
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user