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:
committed by
Robert Schmidt
parent
b92af6b6be
commit
e73e04543a
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user