Add initial support for RedCap

RedCap SIB1-v17-IEs parameters implemented in SIB1
Create an configuration file for RedCap devices
This commit is contained in:
ndomingues
2025-03-20 18:13:12 +01:00
committed by Robert Schmidt
parent b92af6b6be
commit e73e04543a
7 changed files with 338 additions and 30 deletions
+33
View File
@@ -1392,6 +1392,37 @@ f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
return req;
}
static nr_redcap_config_t *get_redcap_config(int gnb_idx)
{
paramdef_t RedCap_Params[] = GNB_REDCAP_PARAMS_DESC;
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
sprintf(aprefix, "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, gnb_idx, GNB_CONFIG_STRING_REDCAP);
int ret = config_get(config_get_if(), RedCap_Params, sizeofArray(RedCap_Params), aprefix);
if (ret <= 0) {
printf("problem reading section \"%s\"\n", aprefix);
return NULL;
}
// Check for default/non-existing values in configuration file
if (*RedCap_Params[GNB_REDCAP_CELL_BARRED_REDCAP1_RX_R17_IDX].i8ptr == -1
|| *RedCap_Params[GNB_REDCAP_CELL_BARRED_REDCAP2_RX_R17_IDX].i8ptr == -1) {
LOG_I(NR_MAC, "No RedCap configuration found\n");
return NULL;
}
nr_redcap_config_t *rc = calloc_or_fail(1, sizeof(*rc));
rc->cellBarredRedCap1Rx_r17 = *RedCap_Params[GNB_REDCAP_CELL_BARRED_REDCAP1_RX_R17_IDX].i8ptr;
rc->cellBarredRedCap2Rx_r17 = *RedCap_Params[GNB_REDCAP_CELL_BARRED_REDCAP2_RX_R17_IDX].i8ptr;
rc->intraFreqReselectionRedCap_r17 = *RedCap_Params[GNB_REDCAP_INTRA_FREQ_RESELECTION_REDCAP_R17_IDX].u8ptr;
LOG_I(GNB_APP,
"cellBarredRedCap1Rx_r17 %d cellBarredRedCap2Rx_r17 %d intraFreqReselectionRedCap_r17 %d\n",
rc->cellBarredRedCap1Rx_r17,
rc->cellBarredRedCap2Rx_r17,
rc->intraFreqReselectionRedCap_r17);
return rc;
}
void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
{
int j = 0;
@@ -1478,6 +1509,8 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
int tot_ant = config.pdsch_AntennaPorts.N1 * config.pdsch_AntennaPorts.N2 * config.pdsch_AntennaPorts.XP;
AssertFatal(config.maxMIMO_layers != 0 && config.maxMIMO_layers <= tot_ant, "Invalid maxMIMO_layers %d\n", config.maxMIMO_layers);
config.redcap = get_redcap_config(0);
paramdef_t Timers_Params[] = GNB_TIMERS_PARAMS_DESC;
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
sprintf(aprefix, "%s.[0].%s", GNB_CONFIG_STRING_GNB_LIST, GNB_CONFIG_STRING_TIMERS_CONFIG);
+23
View File
@@ -485,6 +485,29 @@ typedef enum {
#define GNB_TIMERS_N311_IDX 8
#define GNB_TIMERS_T319_IDX 9
/*-------------------------------------------------------------------------------------------------------------------------------------*/
/* RedCap configuration parameters */
/*-------------------------------------------------------------------------------------------------------------------------------------*/
#define GNB_CONFIG_HLP_STRING_CELL_BARRED_REDCAP1_RX_R17 "Value barred means that the cell is barred for a RedCap UE supporting 1 Rx branch\n"
#define GNB_CONFIG_HLP_STRING_CELL_BARRED_REDCAP2_RX_R17 "Value barred means that the cell is barred for a RedCap UE supporting 2 Rx branches\n"
#define GNB_CONFIG_HLP_STRING_INTRA_FREQ_RESELECTION_REDCAP_R17 "Controls cell selection/reselection to intra-frequency cells for RedCap UEs when this cell is barred\n"
#define GNB_CONFIG_STRING_REDCAP "RedCap"
#define GNB_CONFIG_STRING_CELL_BARRED_REDCAP1_RX_R17 "cellBarredRedCap1Rx_r17"
#define GNB_CONFIG_STRING_CELL_BARRED_REDCAP2_RX_R17 "cellBarredRedCap2Rx_r17"
#define GNB_CONFIG_STRING_INTRA_FREQ_RESELECTION_REDCAP_R17 "intraFreqReselectionRedCap_r17"
#define GNB_REDCAP_PARAMS_DESC { \
{GNB_CONFIG_STRING_CELL_BARRED_REDCAP1_RX_R17, GNB_CONFIG_HLP_STRING_CELL_BARRED_REDCAP1_RX_R17, 0, .i8ptr=NULL, .defintval=-1, TYPE_INT8, 0},\
{GNB_CONFIG_STRING_CELL_BARRED_REDCAP2_RX_R17, GNB_CONFIG_HLP_STRING_CELL_BARRED_REDCAP2_RX_R17, 0, .i8ptr=NULL, .defintval=-1, TYPE_INT8, 0},\
{GNB_CONFIG_STRING_INTRA_FREQ_RESELECTION_REDCAP_R17, GNB_CONFIG_HLP_STRING_INTRA_FREQ_RESELECTION_REDCAP_R17, 0, .u8ptr=NULL, .defuintval=0, TYPE_UINT8, 0},\
}
#define GNB_REDCAP_CELL_BARRED_REDCAP1_RX_R17_IDX 0
#define GNB_REDCAP_CELL_BARRED_REDCAP2_RX_R17_IDX 1
#define GNB_REDCAP_INTRA_FREQ_RESELECTION_REDCAP_R17_IDX 2
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/* SCTP configuration parameters section name */
+1 -1
View File
@@ -848,7 +848,7 @@ void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(scc, plmn, cellID, tac, &nrmac->radio_config.timer_config);
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));
AssertFatal(cc->sib1_bcch_length > 0, "could not encode SIB1\n");
+7
View File
@@ -151,6 +151,12 @@ typedef struct nr_mac_timers {
int t319;
} nr_mac_timers_t;
typedef struct nr_redcap_config {
int8_t cellBarredRedCap1Rx_r17;
int8_t cellBarredRedCap2Rx_r17;
uint8_t intraFreqReselectionRedCap_r17;
} nr_redcap_config_t;
typedef struct nr_mac_config_t {
int sib1_tda;
nr_pdsch_AntennaPorts_t pdsch_AntennaPorts;
@@ -172,6 +178,7 @@ typedef struct nr_mac_config_t {
int nb_bfw[2];
int32_t *bw_list;
int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
nr_redcap_config_t *redcap;
} nr_mac_config_t;
typedef struct NR_preamble_ue {
+43 -28
View File
@@ -2366,7 +2366,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
const f1ap_plmn_t *plmn,
uint64_t cellID,
int tac,
const nr_mac_timers_t *timer_config)
const nr_mac_config_t *mac_config)
{
AssertFatal(cellID < (1l << 36), "cellID must fit within 36 bits, but is %lu\n", cellID);
@@ -2471,32 +2471,6 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
*sib1_v1700->cellBarredNTN_r17 = NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred;
}
// sib19 scheduling info
// ensure ntn-config is initialized
if (scc->ext2 && scc->ext2->ntn_Config_r17) {
if (sib1->nonCriticalExtension == NULL)
sib1->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1610_IEs));
if (sib1->nonCriticalExtension->nonCriticalExtension == NULL)
sib1->nonCriticalExtension->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1630_IEs));
if (sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension == NULL)
sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1700_IEs));
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->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700 = sib_v17_scheduling_info;
}
// servingCellConfigCommon
asn1cCalloc(sib1->servingCellConfigCommon, ServCellCom);
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = &ServCellCom->downlinkConfigCommon.initialDownlinkBWP;
@@ -2672,6 +2646,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
// ue-TimersAndConstants
sib1->ue_TimersAndConstants = CALLOC(1,sizeof(struct NR_UE_TimersAndConstants));
AssertFatal(sib1->ue_TimersAndConstants != NULL, "out of memory\n");
const nr_mac_timers_t *timer_config = &mac_config->timer_config;
sib1->ue_TimersAndConstants->t300 = get_NR_UE_TimersAndConstants_t300(timer_config);
sib1->ue_TimersAndConstants->t301 = get_NR_UE_TimersAndConstants_t301(timer_config);
sib1->ue_TimersAndConstants->t310 = get_NR_UE_TimersAndConstants_t310(timer_config);
@@ -2698,7 +2673,47 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
// TODO: add lateNonCriticalExtension
// nonCriticalExtension
// TODO: add nonCriticalExtension
if (mac_config->redcap || (scc->ext2 && scc->ext2->ntn_Config_r17)) {
sib1->nonCriticalExtension = calloc_or_fail(1, sizeof(*sib1->nonCriticalExtension));
NR_SIB1_v1610_IEs_t *sib1_1610 = sib1->nonCriticalExtension;
sib1_1610->nonCriticalExtension = calloc_or_fail(1, sizeof(*sib1_1610->nonCriticalExtension));
NR_SIB1_v1630_IEs_t *sib1_1630 = sib1_1610->nonCriticalExtension;
sib1_1630->nonCriticalExtension = calloc_or_fail(1, sizeof(*sib1_1630->nonCriticalExtension));
NR_SIB1_v1700_IEs_t *sib1_1700 = sib1_1630->nonCriticalExtension;
if (mac_config->redcap) {
sib1_1700->redCap_ConfigCommon_r17 = calloc_or_fail(1, sizeof(*sib1_1700->redCap_ConfigCommon_r17));
sib1_1700->redCap_ConfigCommon_r17->cellBarredRedCap_r17 =
calloc_or_fail(1, sizeof(*sib1_1700->redCap_ConfigCommon_r17->cellBarredRedCap_r17));
const nr_redcap_config_t *redcap_config = mac_config->redcap;
struct NR_RedCap_ConfigCommonSIB_r17__cellBarredRedCap_r17 *CellBarredRedCap_r17 =
sib1_1700->redCap_ConfigCommon_r17->cellBarredRedCap_r17;
CellBarredRedCap_r17->cellBarredRedCap1Rx_r17 = redcap_config->cellBarredRedCap1Rx_r17;
CellBarredRedCap_r17->cellBarredRedCap2Rx_r17 = redcap_config->cellBarredRedCap2Rx_r17;
sib1_1700->intraFreqReselectionRedCap_r17 = calloc_or_fail(1, sizeof(*sib1_1700->intraFreqReselectionRedCap_r17));
*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 (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message, sib1_message);
+1 -1
View File
@@ -82,7 +82,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
const f1ap_plmn_t *plmn,
uint64_t cellID,
int tac,
const nr_mac_timers_t *timer_config);
const nr_mac_config_t *mac_config);
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);