other SIBs scheduling configuration in SIB1

This commit is contained in:
francescomani
2025-04-14 10:15:45 +02:00
parent 4b23c7ea65
commit 535d8e7765
17 changed files with 315 additions and 198 deletions
+6
View File
@@ -93,6 +93,12 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
// the total shift is 2 * 15, in dB scale thats 10log10(2^(15*2))
#define SQ15_SQUARED_NORM_FACTOR_DB 90.3089986992
typedef struct {
uint8_t *SIB_buffer;
int SIB_size;
int SIB_type;
} nr_SIBs_t;
typedef struct nr_bandentry_s {
int16_t band;
uint64_t ul_min;
+2 -11
View File
@@ -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);
+44 -12
View File
@@ -1312,7 +1312,7 @@ static f1ap_fdd_info_t read_fdd_config(const NR_ServingCellConfigCommon_t *scc)
return fdd;
}
f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1)
f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1, seq_arr_t *du_SIBs)
{
int buf_len = 3;
f1ap_gnb_du_system_info_t *sys_info = calloc_or_fail(1, sizeof(*sys_info));
@@ -1329,15 +1329,24 @@ f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCC
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
sys_info->sib1_length = (enc_rval.encoded + 7) / 8;
if (du_SIBs) {
for (int i = 0; i < du_SIBs->size; i++) {
nr_SIBs_t *si = (nr_SIBs_t *)seq_arr_at(du_SIBs, i);
// other SIB in gNB-DU System Information not implemented yet
// only DU SIB not included in this message is SIB19
AssertFatal(si->SIB_type == 19, "Cannot handle SIB%d in gNB-DU System Information\n", si->SIB_type);
}
}
return sys_info;
}
f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
const char *name,
const f1ap_served_cell_info_t *info,
const NR_ServingCellConfigCommon_t *scc,
NR_BCCH_BCH_Message_t *mib,
const NR_BCCH_DL_SCH_Message_t *sib1)
const NR_BCCH_DL_SCH_Message_t *sib1,
seq_arr_t *du_SIBs)
{
f1ap_setup_req_t *req = calloc(1, sizeof(*req));
AssertFatal(req != NULL, "out of memory\n");
@@ -1381,7 +1390,7 @@ f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
if (IS_SA_MODE(get_softmodem_params())) {
// in NSA we don't transmit SIB1, so cannot fill DU system information
// so cannot send MIB either
req->cell[0].sys_info = get_sys_info(mib, sib1);
req->cell[0].sys_info = get_sys_info(mib, sib1, du_SIBs);
}
int num = read_version(TO_STRING(NR_RRC_VERSION), &req->rrc_ver[0], &req->rrc_ver[1], &req->rrc_ver[2]);
@@ -1421,6 +1430,28 @@ static nr_redcap_config_t *get_redcap_config(int gnb_idx)
return rc;
}
static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray)
{
if (!config_isparamset(GNBparamarray, GNB_DU_SIBS_IDX))
return NULL;
seq_arr_t *du_SIBs = malloc(sizeof(seq_arr_t));
seq_arr_init(du_SIBs, sizeof(nr_SIBs_t));
for (int i = 0; i < GNBparamarray[GNB_DU_SIBS_IDX].numelt; i++) {
int sib_value = GNBparamarray[GNB_DU_SIBS_IDX].iptr[i];
// SIB10, SIB12, SIB13, SIB14, SIB15, SIB17, SIB18, SIB19 and SIB20 are generated by the DU
// all the rest in the DU
AssertFatal((sib_value > 9 && sib_value < 21) && sib_value != 11 && sib_value != 16,
"SIB%d is not a DU SIB, to be configured in DU section\n",
sib_value);
nr_SIBs_t *du_sib = calloc_or_fail(1, sizeof(nr_SIBs_t));
du_sib->SIB_type = sib_value;
LOG_I(GNB_APP, "activate SIB%d at DU\n", sib_value);
seq_arr_push_back(du_SIBs, du_sib, sizeof(nr_SIBs_t));
}
return du_SIBs;
}
void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
{
int j = 0;
@@ -1692,17 +1723,18 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
f1ap_served_cell_info_t info;
read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1);
if (IS_SA_MODE(get_softmodem_params())) {
NR_COMMON_channels_t *cc = &RC.nrmac[0]->common_channels[0];
cc->du_SIBs = fill_du_sibs(GNBParamList.paramarray[0]);
if (IS_SA_MODE(get_softmodem_params()))
nr_mac_configure_sib1(RC.nrmac[0], &info.plmn, info.nr_cellid, *info.tac);
if (scc->ext2 && scc->ext2->ntn_Config_r17)
nr_mac_configure_sib19(RC.nrmac[0]);
}
// read F1 Setup information from config and generated MIB/SIB1
// and store it at MAC for sending later
NR_BCCH_BCH_Message_t *mib = RC.nrmac[0]->common_channels[0].mib;
const NR_BCCH_DL_SCH_Message_t *sib1 = RC.nrmac[0]->common_channels[0].sib1;
f1ap_setup_req_t *req = RC_read_F1Setup(gnb_du_id, name, &info, scc, mib, sib1);
seq_arr_t *du_SIBs = RC.nrmac[0]->common_channels[0].du_SIBs;
f1ap_setup_req_t *req = RC_read_F1Setup(gnb_du_id, name, &info, scc, mib, sib1, du_SIBs);
AssertFatal(req != NULL, "could not read F1 Setup information\n");
RC.nrmac[0]->f1_config.setup_req = req;
RC.nrmac[0]->f1_config.gnb_id = gnb_id;
@@ -1852,7 +1884,7 @@ static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray)
return NULL;
seq_arr_t *SIBs = malloc(sizeof(seq_arr_t));
seq_arr_init(SIBs, sizeof(rrc_SIBs_t));
seq_arr_init(SIBs, sizeof(nr_SIBs_t));
for (int i = 0; i < GNBparamarray[GNB_CU_SIBS_IDX].numelt; i++) {
int sib_value = GNBparamarray[GNB_CU_SIBS_IDX].iptr[i];
// SIB10, SIB12, SIB13, SIB14, SIB15, SIB17, SIB18, SIB19 and SIB20 are generated by the DU
@@ -1860,10 +1892,10 @@ static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray)
AssertFatal((sib_value > 1 && sib_value < 10) || sib_value == 11 || sib_value == 16,
"SIB%d is not a CU SIB, to be configured in DU section\n",
sib_value);
rrc_SIBs_t *cu_sib = calloc_or_fail(1, sizeof(*cu_sib));
nr_SIBs_t *cu_sib = calloc_or_fail(1, sizeof(*cu_sib));
cu_sib->SIB_type = sib_value;
LOG_I(GNB_APP, "activate SIB%d at CU\n", sib_value);
seq_arr_push_back(SIBs, cu_sib, sizeof(rrc_SIBs_t));
seq_arr_push_back(SIBs, cu_sib, sizeof(nr_SIBs_t));
}
return SIBs;
}
+1 -7
View File
@@ -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);
+5
View File
@@ -140,6 +140,7 @@ typedef enum {
#define GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST "beam_weights"
#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels"
#define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs"
#define GNB_CONFIG_STRING_DU_SIB_LIST "du_sibs"
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
@@ -152,6 +153,7 @@ typedef enum {
#define GNB_CONFIG_HLP_NUM_UL_HARQ "Set Num UL harq processes. Valid values 16,32. Default 16"
#define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1"
#define GNB_CONFIG_HLP_CU_SIBS "List of CU generated SIBs to be transmitted"
#define GNB_CONFIG_HLP_DU_SIBS "List of DU generated SIBs to be transmitted"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
@@ -198,6 +200,7 @@ typedef enum {
{GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST, \
GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \
{GNB_CONFIG_STRING_CU_SIB_LIST, GNB_CONFIG_HLP_CU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
{GNB_CONFIG_STRING_DU_SIB_LIST, GNB_CONFIG_HLP_DU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
}
// clang-format on
@@ -240,6 +243,7 @@ typedef enum {
#define GNB_BEAMWEIGHTS_IDX 35
#define GNB_UESS_AGG_LEVEL_LIST_IDX 36
#define GNB_CU_SIBS_IDX 37
#define GNB_DU_SIBS_IDX 38
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32}
@@ -284,6 +288,7 @@ typedef enum {
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
+90 -12
View File
@@ -38,6 +38,7 @@
#include "BIT_STRING.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "GNB_APP/gnb_config.h"
#include "NR_MIB.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_BCCH-BCH-Message.h"
@@ -889,6 +890,94 @@ void nr_fill_sched_osi(gNB_MAC_INST *nrmac, const struct NR_SetupRelease_PDCCH_C
}
}
bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib])
{
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
seq_arr_t *du_SIBs = nrmac->common_channels[0].du_SIBs;
int num_du_sib = 0;
if (du_SIBs)
num_du_sib = du_SIBs->size;
if (num_cu_sib + num_du_sib == 0)
return false; /* no updates */
int config_sibs[num_cu_sib + num_du_sib];
NR_SystemInformation_IEs_t *sysInfo = calloc(1, sizeof(*sysInfo)); //for SIB up to 14 included
NR_SystemInformation_IEs_t *sysInfov17 = calloc(1, sizeof(*sysInfov17)); // for othersibs
for (int i = 0; i < num_cu_sib; i++) {
config_sibs[i] = cu_sib[i].SI_type;
switch (config_sibs[i]) {
case 2: {
struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type = calloc(1, sizeof(*type));
type->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2;
// SIB2 coming from CU need to decode it
NR_SIB2_t *sib2 = NULL;
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_SIB2,
(void **)&sib2,
cu_sib[i].SI_container,
cu_sib[i].SI_container_length,
0,
0);
if (dec_rval.code != RC_OK) {
LOG_E(NR_MAC, "cannot decode SIB%d from CU\n", config_sibs[i]);
ASN_STRUCT_FREE(asn_DEF_NR_SIB2, cu_sib[i].SI_container);
}
type->choice.sib2 = sib2;
add_sib_to_systeminformation(sysInfo, type);
break;
}
default :
AssertFatal(false, "Invalid or not supported SIB%d\n", config_sibs[i]);
}
}
for (int i = 0; i < num_du_sib; i++) {
nr_SIBs_t *si = (nr_SIBs_t *)seq_arr_at(du_SIBs, i);
int sib_idx = i + num_cu_sib;
config_sibs[sib_idx] = si->SIB_type;
switch (config_sibs[sib_idx]) {
case 19: {
struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type_du = calloc(1, sizeof(*type_du));
type_du->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700;
NR_SIB19_r17_t *sib19 = get_SIB19_NR(cc->ServingCellConfigCommon);
type_du->choice.sib19_v1700 = sib19;
add_sib_to_systeminformation(sysInfov17, type_du);
break;
}
default :
AssertFatal(false, "Invalid or not supported SIB%d\n", sib_idx);
}
}
update_SIB1_NR_SI(cc->sib1, num_cu_sib + num_du_sib, config_sibs);
cc->sib1_bcch_length = encode_SIB_NR(cc->sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu));
AssertFatal(cc->sib1_bcch_length > 0, "could not encode SIB1\n");
// generate otherSIB payloads
cc->other_sib_bcch_length[0] = encode_sysinfo_ie(sysInfo, cc->other_sib_bcch_pdu[0], sizeof(cc->other_sib_bcch_pdu[0]));
cc->other_sib_bcch_length[1] = encode_sysinfo_ie(sysInfov17, cc->other_sib_bcch_pdu[1], sizeof(cc->other_sib_bcch_pdu[1]));
ASN_STRUCT_FREE(asn_DEF_NR_SystemInformation_IEs, sysInfo);
ASN_STRUCT_FREE(asn_DEF_NR_SystemInformation_IEs, sysInfov17);
return true;
}
void prepare_du_configuration_update(gNB_MAC_INST *mac,
f1ap_served_cell_info_t *info,
NR_BCCH_BCH_Message_t *mib,
const NR_BCCH_DL_SCH_Message_t *sib1)
{
/* send gNB-DU configuration update to RRC */
f1ap_gnb_du_configuration_update_t update = {
.transaction_id = 1,
.num_cells_to_modify = 1,
};
update.cell_to_modify[0].old_nr_cellid = info->nr_cellid;
update.cell_to_modify[0].info = *info;
update.cell_to_modify[0].sys_info = get_sys_info(mib, sib1, NULL);
mac->mac_rrc.gnb_du_configuration_update(&update);
}
void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_t cellID, int tac)
{
AssertFatal(IS_SA_MODE(get_softmodem_params()), "error: SIB1 only applicable for SA\n");
@@ -897,21 +986,10 @@ void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(scc, plmn, cellID, tac, &nrmac->radio_config);
cc->sib1 = sib1;
cc->sib1_bcch_length = encode_SIB1_NR(sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu));
cc->sib1_bcch_length = encode_SIB_NR(sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu));
AssertFatal(cc->sib1_bcch_length > 0, "could not encode SIB1\n");
}
void nr_mac_configure_sib19(gNB_MAC_INST *nrmac)
{
AssertFatal(IS_SA_MODE(get_softmodem_params()), "error: SIB19 only applicable for SA\n");
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_BCCH_DL_SCH_Message_t *sib19 = get_SIB19_NR(scc);
cc->sib19 = sib19;
cc->sib19_bcch_length = encode_SIB19_NR(sib19, cc->sib19_bcch_pdu, sizeof(cc->sib19_bcch_pdu));
AssertFatal(cc->sib19_bcch_length > 0, "could not encode SIB19\n");
}
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
{
/* ideally, instead of this function, "users" of this function should call
@@ -219,8 +219,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo
// SIB19 will be scheduled if ntn_Config_r17 is initialized
if (IS_SA_MODE(get_softmodem_params())) {
schedule_nr_sib1(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req);
if (cc->sib19)
schedule_nr_sib19(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req, cc->sib19_bcch_length, cc->sib19_bcch_pdu);
}
// This schedule PRACH if we are not in phy_test mode
+5 -2
View File
@@ -56,8 +56,7 @@ void nr_mac_send_f1_setup_req(void);
void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *mac_config);
void nr_fill_sched_osi(gNB_MAC_INST *nrmac, const struct NR_SetupRelease_PDCCH_ConfigCommon *pdcch_ConfigCommon);
void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_t cellID, int tac);
void nr_mac_configure_sib19(gNB_MAC_INST *nrmac);
bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]);
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
@@ -474,4 +473,8 @@ bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid);
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti);
void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected);
void prepare_du_configuration_update(gNB_MAC_INST *mac,
f1ap_served_cell_info_t *info,
NR_BCCH_BCH_Message_t *mib,
const NR_BCCH_DL_SCH_Message_t *sib1);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
@@ -165,8 +165,14 @@ void f1_setup_response(const f1ap_setup_resp_t *resp)
AssertFatal(check_plmn_identity(&du_cell->plmn, &cu_cell->plmn), "PLMN mismatch\n");
AssertFatal(du_cell->nr_pci == cu_cell->nrpci, "PCI mismatch: DU %d vs CU %d\n", du_cell->nr_pci, cu_cell->nrpci);
for (int i = 0; i < cu_cell->num_SI; i++) {
// TODO implement handling reception of SIBs in DU
// we can configure other SIB only after having received the ones generated by CU
bool update = nr_mac_configure_other_sib(mac, cu_cell->num_SI, cu_cell->SI_msg);
if (update) {
f1ap_setup_req_t *sr = mac->f1_config.setup_req;
DevAssert(sr->num_cells_available == 1);
f1ap_served_cell_info_t *info = &sr->cell[0].info;
NR_COMMON_channels_t *cc = &mac->common_channels[0];
prepare_du_configuration_update(mac, info, cc->mib, cc->sib1);
}
mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp));
+4 -4
View File
@@ -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
+1 -5
View File
@@ -197,7 +197,7 @@ int xer_nr_sprint(char *string, size_t string_size, asn_TYPE_descriptor_t *td, v
//------------------------------------------------------------------------------
int do_SIB2_NR(uint8_t **msg_SIB2)
int do_SIB2_NR(uint8_t **msg_SIB2, NR_SSB_MTC_t *ssbmtc)
{
NR_SIB2_t *sib2 = calloc(1, sizeof(*sib2));
sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB0;
@@ -222,10 +222,6 @@ int do_SIB2_NR(uint8_t **msg_SIB2)
sib2->intraFreqCellReselectionInfo.s_IntraSearchP = 22; // INTEGER (0..31)
sib2->intraFreqCellReselectionInfo.t_ReselectionNR = 1; // INTEGER (0..7)
sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell = true;
NR_SSB_MTC_t *ssbmtc = calloc(1, sizeof(*ssbmtc));
ssbmtc->duration = NR_SSB_MTC__duration_sf5;
ssbmtc->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20;
ssbmtc->periodicityAndOffset.choice.sf20 = 0;
sib2->intraFreqCellReselectionInfo.smtc = ssbmtc;
ssize_t size = uper_encode_to_new_buffer(&asn_DEF_NR_SIB2, NULL, (void *)sib2, (void **)msg_SIB2);
+1 -1
View File
@@ -66,7 +66,7 @@ struct asn_TYPE_descriptor_s;
*/
int xer_sprint_NR(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr);
int do_SIB2_NR(uint8_t **msg_SIB2);
int do_SIB2_NR(uint8_t **msg_SIB2, NR_SSB_MTC_t *ssbmtc);
int do_RRCReject(uint8_t *const buffer);
+111 -97
View File
@@ -2349,6 +2349,105 @@ static long get_NR_UE_TimersAndConstants_t319(const nr_mac_timers_t *timer_confi
}
}
void add_sib_to_systeminformation(NR_SystemInformation_IEs_t *si, struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type)
{
asn1cSeqAdd(&si->sib_TypeAndInfo.list, type);
}
void update_SIB1_NR_SI(NR_BCCH_DL_SCH_Message_t *sib1_bcch, int num_sibs, int sibs[num_sibs])
{
NR_SIB1_t *sib1 = sib1_bcch->message.choice.c1->choice.systemInformationBlockType1;
//si-SchedulingInfo
NR_SI_SchedulingInfo_t *info = calloc(1, sizeof(*info));
info->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40;
NR_SchedulingInfo_t *schedulingInfo = calloc(1, sizeof(*schedulingInfo));
schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting;
schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf16;
bool reg_sib = false;
NR_SI_SchedulingInfo_v1700_t *si_schedulingInfo_v17 = NULL;
NR_SchedulingInfo2_r17_t *schedulingInfo2_r17 = NULL;
bool v17_sib = false;
for (int i = 0; i < num_sibs; i++) {
int sib_num = sibs[i];
AssertFatal(sib_num > 1 && sib_num < 21, "other SIB invalid type\n");
if (sib_num < 15) {
reg_sib = true;
NR_SIB_TypeInfo_t *mapping = calloc(1, sizeof(*mapping));
// NR_SIB_TypeInfo__type_sibType2 = 0
// NR_SIB_TypeInfo__type_sibType3 = 1
// and so on
mapping->type = sib_num - 2;
// The field is mandatory present if the type is different from SIB6, SIB7 or SIB8. For SIB6, SIB7 and SIB8 it is absent.
if (sib_num != 6 && sib_num != 7 && sib_num != 8) {
mapping->valueTag = calloc(1, sizeof(*mapping->valueTag));
*mapping->valueTag = 0;
}
asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list, mapping);
} else {
if (v17_sib == false) {
si_schedulingInfo_v17 = calloc(1, sizeof(*si_schedulingInfo_v17));
schedulingInfo2_r17 = calloc(1, sizeof(*schedulingInfo2_r17));
schedulingInfo2_r17->si_BroadcastStatus_r17 = NR_SchedulingInfo2_r17__si_BroadcastStatus_r17_broadcasting;
schedulingInfo2_r17->si_Periodicity_r17 = NR_SchedulingInfo2_r17__si_Periodicity_r17_rf16;
schedulingInfo2_r17->si_WindowPosition_r17 = 2;
}
NR_SIB_TypeInfo_v1700_t *mapping17 = calloc(1, sizeof(*mapping17));
mapping17->sibType_r17.present = NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17;
// NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType15 = 0
// and so on
mapping17->sibType_r17.choice.type1_r17 = sib_num - 15;
mapping17->valueTag_r17 = calloc(1, sizeof(*mapping17->valueTag_r17));
*mapping17->valueTag_r17 = 0;
asn1cSeqAdd(&schedulingInfo2_r17->sib_MappingInfo_r17.list, mapping17);
}
}
AssertFatal(reg_sib, "At least 1 SIB from SchedulingInfo (SIB2 to SIB14 included) needs to be present\n");
asn1cSeqAdd(&info->schedulingInfoList.list, schedulingInfo);
sib1->si_SchedulingInfo = info;
if (si_schedulingInfo_v17) {
asn1cSeqAdd(&si_schedulingInfo_v17->schedulingInfoList2_r17.list, schedulingInfo2_r17);
NR_SIB1_v1610_IEs_t *sib1_v1610 = NULL;
if (sib1->nonCriticalExtension)
sib1_v1610 = sib1->nonCriticalExtension;
else {
sib1_v1610 = calloc_or_fail(1, sizeof(*sib1_v1610));
sib1->nonCriticalExtension = sib1_v1610;
}
NR_SIB1_v1630_IEs_t *sib1_v1630 = NULL;
if (sib1_v1610->nonCriticalExtension)
sib1_v1630 = sib1_v1610->nonCriticalExtension;
else {
sib1_v1630 = calloc_or_fail(1, sizeof(*sib1_v1630));
sib1_v1610->nonCriticalExtension = sib1_v1630;
}
NR_SIB1_v1700_IEs_t *sib1_v17 = NULL;
if (sib1_v1630->nonCriticalExtension)
sib1_v17 = sib1_v1630->nonCriticalExtension;
else {
sib1_v17 = calloc_or_fail(1, sizeof(*sib1_v17));
sib1_v1630->nonCriticalExtension = sib1_v17;
}
sib1_v17->si_SchedulingInfo_v1700 = si_schedulingInfo_v17;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message, sib1_bcch);
}
}
int encode_sysinfo_ie(NR_SystemInformation_IEs_t *sysInfo, uint8_t *buf, int len)
{
if (sysInfo->sib_TypeAndInfo.list.count == 0)
return 0;
NR_SystemInformation_t si = {.criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation};
si.criticalExtensions.choice.systemInformation = sysInfo;
struct NR_BCCH_DL_SCH_MessageType__c1 c1 = {.present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation};
c1.choice.systemInformation = &si;
NR_BCCH_DL_SCH_MessageType_t message_type = {.present = NR_BCCH_DL_SCH_MessageType_PR_c1};
message_type.choice.c1 = &c1;
NR_BCCH_DL_SCH_Message_t sib_message = {.message = message_type};
return encode_SIB_NR(&sib_message, buf, len);
}
static bool is_ntn_band(int band)
{
// TS 3GPP 38.101-5 V1807 Section 5.2.2
@@ -2378,7 +2477,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1;
sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1));
AssertFatal(sib1_message->message.choice.c1->choice.systemInformationBlockType1 != NULL, "out of memory\n");
struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1;
NR_SIB1_t *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1;
// cellSelectionInfo
sib1->cellSelectionInfo = CALLOC(1,sizeof(*sib1->cellSelectionInfo));
@@ -2429,37 +2528,6 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
// connEstFailureControl
// TODO: add connEstFailureControl
//si-SchedulingInfo
/*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo));
asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list);
sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40;
struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo));
schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting;
schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf8;
asn_set_empty(&schedulingInfo->sib_MappingInfo.list);
NR_SIB_TypeInfo_t *sib_type3 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type));
sib_type3->type = NR_SIB_TypeInfo__type_sibType3;
sib_type3->valueTag = CALLOC(1,sizeof(sib_type3->valueTag));
asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type3);
NR_SIB_TypeInfo_t *sib_type5 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type));
sib_type5->type = NR_SIB_TypeInfo__type_sibType5;
sib_type5->valueTag = CALLOC(1,sizeof(sib_type5->valueTag));
asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type5);
NR_SIB_TypeInfo_t *sib_type4 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type));
sib_type4->type = NR_SIB_TypeInfo__type_sibType4;
sib_type4->valueTag = CALLOC(1,sizeof(sib_type4->valueTag));
asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type4);
NR_SIB_TypeInfo_t *sib_type2 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type));
sib_type2->type = NR_SIB_TypeInfo__type_sibType2;
sib_type2->valueTag = CALLOC(1,sizeof(sib_type2->valueTag));
asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type2);
asn1cSeqAdd(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/
// servingCellConfigCommon
asn1cCalloc(sib1->servingCellConfigCommon, ServCellCom);
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = &ServCellCom->downlinkConfigCommon.initialDownlinkBWP;
@@ -2685,29 +2753,9 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
*sib1_1700->intraFreqReselectionRedCap_r17 = redcap_config->intraFreqReselectionRedCap_r17;
}
// sib19 scheduling info
// ensure ntn-config is initialized
if (scc->ext2 && scc->ext2->ntn_Config_r17) {
struct NR_SI_SchedulingInfo_v1700 *sib_v17_scheduling_info = CALLOC(1, sizeof(struct NR_SI_SchedulingInfo_v1700));
struct NR_SchedulingInfo2_r17 *si_schedulinginfo2_r17 = CALLOC(1, sizeof(struct NR_SchedulingInfo2_r17));
si_schedulinginfo2_r17->si_BroadcastStatus_r17 = NR_SchedulingInfo2_r17__si_BroadcastStatus_r17_broadcasting;
si_schedulinginfo2_r17->si_WindowPosition_r17 = 2;
si_schedulinginfo2_r17->si_Periodicity_r17 = NR_SchedulingInfo2_r17__si_Periodicity_r17_rf8;
struct NR_SIB_TypeInfo_v1700 *sib_type_info = CALLOC(1, sizeof(struct NR_SIB_TypeInfo_v1700));
sib_type_info->sibType_r17.present = NR_SIB_TypeInfo_v1700__sibType_r17_PR_type1_r17;
sib_type_info->sibType_r17.choice.type1_r17 = NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19;
asn1cSeqAdd(&si_schedulinginfo2_r17->sib_MappingInfo_r17.list, sib_type_info);
asn1cSeqAdd(&sib_v17_scheduling_info->schedulingInfoList2_r17.list, si_schedulinginfo2_r17);
sib1_1700->si_SchedulingInfo_v1700 = sib_v17_scheduling_info;
if (is_ntn_band(band)) {
// If cell provides NTN access, set cellBarredNTN to notBarred.
sib1_1700->cellBarredNTN_r17 = CALLOC(1, sizeof(long));
*sib1_1700->cellBarredNTN_r17 = NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred;
}
if (is_ntn_band(band)) {
// If cell provides NTN access, set cellBarredNTN to notBarred.
asn1cCallocOne(sib1_1700->cellBarredNTN_r17, NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred);
}
}
@@ -2723,57 +2771,23 @@ void free_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1)
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, sib1);
}
int encode_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1, uint8_t *buffer, int max_buffer_size)
int encode_SIB_NR(NR_BCCH_DL_SCH_Message_t *sib, uint8_t *buffer, int max_buffer_size)
{
AssertFatal(max_buffer_size <= NR_MAX_SIB_LENGTH / 8,
"%s(): maximum buffer size too large: 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the "
"maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n",
__func__);
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib1, buffer, max_buffer_size);
"Maximum buffer size too large: 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the "
"maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n");
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib, buffer, max_buffer_size);
AssertFatal(enc_rval.encoded > 0 && enc_rval.encoded <= max_buffer_size * 8, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
return (enc_rval.encoded + 7) / 8;
}
NR_BCCH_DL_SCH_Message_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc)
NR_SIB19_r17_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc)
{
NR_BCCH_DL_SCH_Message_t *sib_message = CALLOC(1, sizeof(NR_BCCH_DL_SCH_Message_t));
sib_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1;
sib_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1));
sib_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation;
sib_message->message.choice.c1->choice.systemInformation = CALLOC(1,sizeof(struct NR_SystemInformation));
struct NR_SystemInformation *sib = sib_message->message.choice.c1->choice.systemInformation;
sib->criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation;
sib->criticalExtensions.choice.systemInformation = CALLOC(1, sizeof(struct NR_SystemInformation_IEs));
struct NR_SystemInformation_IEs *ies = sib->criticalExtensions.choice.systemInformation;
SystemInformation_IEs__sib_TypeAndInfo__Member *sib19 = NULL;
sib19 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member));
sib19->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700;
sib19->choice.sib19_v1700 = CALLOC(1, sizeof(struct NR_SIB19_r17));
NR_SIB19_r17_t *sib19 = calloc(1, sizeof(*sib19));
// use ntn-config from NR_ServingCellConfigCommon_t
const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **) &sib19->choice.sib19_v1700->ntn_Config_r17, scc->ext2->ntn_Config_r17);
const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **) &sib19->ntn_Config_r17, scc->ext2->ntn_Config_r17);
AssertFatal(copy_result == 0, "Was unable to copy ntn_Config_r17 from scc to SIB19 structure\n");
asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib19);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message, sib_message);
}
return sib_message;
}
int encode_SIB19_NR(NR_BCCH_DL_SCH_Message_t *sib19, uint8_t *buffer, int max_buffer_size)
{
asn_enc_rval_t enc_rval;
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib19, buffer, 150);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
return ((enc_rval.encoded + 7) / 8);
return sib19;
}
void free_SIB19_NR(NR_BCCH_DL_SCH_Message_t *sib19)
+5 -5
View File
@@ -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,
-6
View File
@@ -361,12 +361,6 @@ typedef struct nr_rrc_cuup_container_t {
sctp_assoc_t assoc_id;
} nr_rrc_cuup_container_t;
typedef struct {
uint8_t *SIB_buffer;
int SIB_size;
int SIB_type;
} rrc_SIBs_t;
//---NR---(completely change)---------------------
typedef struct gNB_RRC_INST_s {
+9 -27
View File
@@ -215,31 +215,6 @@ static void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc,
#endif
}
///---------------------------------------------------------------------------------------------------------------///
///---------------------------------------------------------------------------------------------------------------///
static void init_NR_SI(gNB_RRC_INST *rrc)
{
if (!NODE_IS_DU(rrc->node_type)) {
seq_arr_t *sibs = rrc->SIBs;
if (sibs) {
for (int i = 0; i < sibs->size; i++) {
rrc_SIBs_t *sib = (rrc_SIBs_t *)seq_arr_at(sibs, i);
AssertFatal(sib->SIB_type == 2, "Only SIB2 currently implemented\n");
sib->SIB_size = do_SIB2_NR(&sib->SIB_buffer);
}
}
}
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n");
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc);
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
if (!NODE_IS_CU(rrc->node_type)) {
rrc_add_nsa_user(rrc,ue_context_p,NULL);
}
}
}
static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc)
{
switch (rrc->node_type) {
@@ -279,8 +254,15 @@ void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *c
RB_INIT(&rrc->cuups);
RB_INIT(&rrc->dus);
rrc->configuration = *configuration;
/// System Information INIT
init_NR_SI(rrc);
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n");
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc);
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
if (!NODE_IS_CU(rrc->node_type)) {
rrc_add_nsa_user(rrc,ue_context_p,NULL);
}
}
}
static void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m)
+23 -5
View File
@@ -61,6 +61,15 @@ int get_ssb_scs(const struct f1ap_served_cell_info_t *cell_info)
return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs;
}
static NR_SSB_MTC_t *get_ssb_mtc(const NR_MeasurementTimingConfiguration_t *mtc)
{
// TODO verify which element of the list to pick
NR_MeasTimingList_t *mtlist = mtc->criticalExtensions.choice.c1->choice.measTimingConf->measTiming;
NR_SSB_MTC_t *ssb_mtc = calloc(1, sizeof(*ssb_mtc));
*ssb_mtc = mtlist->list.array[0]->frequencyAndTiming->ssb_MeasurementTimingConfiguration;
return ssb_mtc;
}
static int ssb_arfcn_mtc(const NR_MeasurementTimingConfiguration_t *mtc)
{
/* format has been verified when accepting MeasurementTimingConfiguration */
@@ -397,14 +406,23 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
.num_SI = 0,
};
// Encode CU SIBs and configure setup response with sysinfo
seq_arr_t *sibs = rrc->SIBs;
if (sibs) {
for (int i = 0; i < sibs->size; i++) {
rrc_SIBs_t *si = (rrc_SIBs_t *)seq_arr_at(sibs, i);
cell.SI_msg[cell.num_SI].SI_container = si->SIB_buffer;
cell.SI_msg[cell.num_SI].SI_container_length = si->SIB_size;
cell.SI_msg[cell.num_SI].SI_type = si->SIB_type;
cell.num_SI++;
nr_SIBs_t *sib = (nr_SIBs_t *)seq_arr_at(sibs, i);
switch (sib->SIB_type) {
case 2: {
NR_SSB_MTC_t *ssbmtc = get_ssb_mtc(mtc);
sib->SIB_size = do_SIB2_NR(&sib->SIB_buffer, ssbmtc);
cell.SI_msg[cell.num_SI].SI_container = sib->SIB_buffer;
cell.SI_msg[cell.num_SI].SI_container_length = sib->SIB_size;
cell.SI_msg[cell.num_SI].SI_type = sib->SIB_type;
cell.num_SI++;
} break;
default:
AssertFatal(false, "SIB%d not handled yet\n", sib->SIB_type);
}
}
}