Merge remote-tracking branch 'origin/RA_2-Step' into integration_2024_w41

This commit is contained in:
Jaroslava Fiedlerova
2024-10-14 14:47:19 +02:00
25 changed files with 1275 additions and 202 deletions
+1
View File
@@ -54,6 +54,7 @@
R(TYPE_P_RNTI_) /* Paging RNTI */ \
R(TYPE_SI_RNTI_) /* System information RNTI */ \
R(TYPE_RA_RNTI_) /* Random Access RNTI */ \
R(TYPE_MSGB_RNTI_) /* Random Access MsgB RNTI */ \
R(TYPE_SP_CSI_RNTI_) /* Semipersistent CSI reporting on PUSCH */ \
R(TYPE_SFI_RNTI_) /* Slot Format Indication on the given cell */ \
R(TYPE_INT_RNTI_) /* Indication pre-emption in DL */ \
+21 -7
View File
@@ -105,10 +105,18 @@ These modes of operation are supported:
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
- Scheduler procedures for SIB1
- Scheduler procedures for RA
- Contention Free RA procedure
- Contention Based RA procedure
- Msg3 can transfer uplink CCCH, DTCH or DCCH messages
- CBRA can be performed using MAC CE or C-RNTI
- 4-Step RA
- Contention Free RA procedure
- Contention Based RA procedure
- Msg3 can transfer uplink CCCH, DTCH or DCCH messages
- CBRA can be performed using MAC CE for C-RNTI
- Is not possible to use 2-Step RA and 4-Step RA at the same time
- 2-Step RA
- Contention Based RA procedure
- MsgA can transfer uplink CCCH, DTCH or DCCH messages
- CBRA can be performed using MAC CE for C-RNTI
- Is not possible to use 2-Step RA and 4-Step RA at the same time
- Fallback not supported
- Scheduler procedures for CSI-RS
- MAC downlink scheduler
- phy-test scheduler (fixed allocation and usable also without UE)
@@ -310,9 +318,15 @@ These modes of operation are supported:
* Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY)
- Mapping SSBs to multiple ROs
- Scheduling of PRACH
- Processing of RAR
- Transmission and re-transmission of Msg3
- Msg4 and contention resolution
- 4-Step RA
- Processing of RAR
- Transmission and re-transmission of Msg3
- Msg4 and contention resolution
- 2-Step RA
- Transmission of MsgA-PUSCH
- Reception of MsgB
- Processing of SuccessRAR
- Fallback not supported
* DCI processing
- format 10 (RA-RNTI, C-RNTI, SI-RNTI, TC-RNTI)
- format 00 (C-RNTI, TC-RNTI)
+3 -1
View File
@@ -225,7 +225,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
k += kbar;
k *= 2;
LOG_I(PHY, "PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, msg1 frequency start %d (k1 %d), preamble_offset %d, first_nonzero_root_idx %d\n",
LOG_I(PHY,
"PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, Msg1/MsgA-Preamble frequency start %d (k1 %d), "
"preamble_offset %d, first_nonzero_root_idx %d\n",
Mod_id,
frame,
slot,
@@ -65,6 +65,7 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0
void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL,int N_RB_UL,int mu_dl,int mu_ul);
void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap);
void prepare_scc(NR_ServingCellConfigCommon_t *scc);
void prepare_msgA_scc(NR_ServingCellConfigCommon_t *scc);
void prepare_scd(NR_ServingCellConfig_t *scd);
uint32_t ngap_generate_gNB_id(void) {return 0;}
+37
View File
@@ -90,6 +90,22 @@
#define GNB_CONFIG_STRING_P0NOMINAL "p0_nominal"
#define GNB_CONFIG_STRING_PUCCHRES "pucch_ResourceCommon"
#define GNB_CONFIG_STRING_MSGBRESPONSEWINDOW_R16 "msgB_ResponseWindow_r16"
#define GNB_CONFIG_STRING_MSGARSRPTHRESHOLD_R16 "msgA_RSRP_Threshold_r16"
#define GNB_CONFIG_STRING_MSGACBPREAMBLESPERSHAREDRO_R16 "msgA_CB_PreamblesPerSSB_PerSharedRO_r16"
#define GNB_CONFIG_STRING_MSGAMCS_R16 "msgA_MCS_r16"
#define GNB_CONFIG_STRING_NROFSLOTSMSGAPUSCH_R16 "nrofSlotsMsgA_PUSCH_r16"
#define GNB_CONFIG_STRING_NROFMSGAPOPERSLOT_R16 "nrofMsgA_PO_PerSlot_r16"
#define GNB_CONFIG_STRING_MSGAPUSCHTIMEDOMAINOFFSET_R16 "msgA_PUSCH_TimeDomainOffset_r16"
#define GNB_CONFIG_STRING_STARTSYMBOLANDLENGTHMSGA_PO_R16 "startSymbolAndLengthMsgA_PO_r16"
#define GNB_CONFIG_STRING_MAPPINGTYPEMSGAPUSCH_R16 "mappingTypeMsgA_PUSCH_r16"
#define GNB_CONFIG_STRING_GUARDBANDMSGAPUSCH_R16 "guardBandMsgA_PUSCH_r16"
#define GNB_CONFIG_STRING_FREQUENCYSTARTMSGAPUSCH_R16 "frequencyStartMsgA_PUSCH_r16"
#define GNB_CONFIG_STRING_NROFPRBSPERMSGAPO_R16 "nrofPRBs_PerMsgA_PO_r16"
#define GNB_CONFIG_STRING_NROFMSGAPOFDM_R16 "nrofMsgA_PO_FDM_r16"
#define GNB_CONFIG_STRING_MSGAPUSCHNROFPORTS_R16 "msgA_PUSCH_NrofPorts_r16"
#define GNB_CONFIG_STRING_NROFDMRSSEQUENCES_R16 "nrofDMRS_Sequences_r16"
#define GNB_CONFIG_STRING_MSGATRANSFORMPRECODER_R16 "msgA_TransformPrecoder_r16"
#define GNB_CONFIG_STRING_SSBPOSITIONSINBURST "ssb_PositionsInBurst_Bitmap"
#define GNB_CONFIG_STRING_SSBPERIODICITYSERVINGCELL "ssb_periodicityServingCell"
@@ -295,4 +311,25 @@
{GNB_CONFIG_STRING_LOCATIONANDBANDWIDTH_ULBWP4,NULL,0,.i64ptr=&scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[3]->bwp_Common->genericParameters.locationAndBandwidth,.defint64val=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_DEFAULTDLBWP_ID,NULL,0,.i64ptr=scd->defaultDownlinkBWP_Id,.defint64val=0,TYPE_INT64,0}}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Serving Cell Config Common configuration parameters to apply in RA 2-Step */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define MSGASCCPARAMS_DESC(scc) { \
{GNB_CONFIG_STRING_MSGBRESPONSEWINDOW_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16.rach_ConfigGenericTwoStepRA_r16.msgB_ResponseWindow_r16,.defintval=-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_MSGARSRPTHRESHOLD_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16.msgA_RSRP_Threshold_r16,.defintval=19,TYPE_INT64,0},\
{GNB_CONFIG_STRING_MSGAMCS_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->msgA_MCS_r16,.defintval=2,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFSLOTSMSGAPUSCH_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->nrofSlotsMsgA_PUSCH_r16,.defintval=1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFMSGAPOPERSLOT_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->nrofMsgA_PO_PerSlot_r16,.defintval=NR_MsgA_PUSCH_Resource_r16__nrofMsgA_PO_PerSlot_r16_one,TYPE_INT64,0},\
{GNB_CONFIG_STRING_MSGAPUSCHTIMEDOMAINOFFSET_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16,.defintval=0,TYPE_INT64,0},\
{GNB_CONFIG_STRING_STARTSYMBOLANDLENGTHMSGA_PO_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->startSymbolAndLengthMsgA_PO_r16,.defintval=38,TYPE_INT64,0},\
{GNB_CONFIG_STRING_MAPPINGTYPEMSGAPUSCH_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->mappingTypeMsgA_PUSCH_r16,.defintval=0,TYPE_INT64,0},\
{GNB_CONFIG_STRING_GUARDBANDMSGAPUSCH_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->guardBandMsgA_PUSCH_r16,.defintval=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_FREQUENCYSTARTMSGAPUSCH_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->frequencyStartMsgA_PUSCH_r16,.defintval=0,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_NROFPRBSPERMSGAPO_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->nrofPRBs_PerMsgA_PO_r16,.defintval=8,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_NROFMSGAPOFDM_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->nrofMsgA_PO_FDM_r16,.defintval=NR_MsgA_PUSCH_Resource_r16__nrofMsgA_PO_FDM_r16_one,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_MSGAPUSCHNROFPORTS_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->msgA_DMRS_Config_r16.msgA_PUSCH_NrofPorts_r16,.defintval=1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFDMRSSEQUENCES_R16,NULL,0,.i64ptr=&scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16->nrofDMRS_Sequences_r16,.defintval=1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_MSGATRANSFORMPRECODER_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16,.defintval=NR_MsgA_PUSCH_Config_r16__msgA_TransformPrecoder_r16_disabled,TYPE_INT64,0},\
{GNB_CONFIG_STRING_MSGACBPREAMBLESPERSHAREDRO_R16,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->rach_ConfigCommonTwoStepRA_r16.msgA_CB_PreamblesPerSSB_PerSharedRO_r16,.defintval=1,TYPE_INT64,0}}
#endif
+38 -2
View File
@@ -150,6 +150,28 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc)
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 =
calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17));
}
void prepare_msgA_scc(NR_ServingCellConfigCommon_t *scc) {
NR_BWP_UplinkCommon_t *initialUplinkBWP = scc->uplinkConfigCommon->initialUplinkBWP;
// Add the struct ext1
initialUplinkBWP->ext1 = calloc(1, sizeof(*initialUplinkBWP->ext1));
initialUplinkBWP->ext1->msgA_ConfigCommon_r16 = calloc(1, sizeof(*initialUplinkBWP->ext1->msgA_ConfigCommon_r16));
initialUplinkBWP->ext1->msgA_ConfigCommon_r16->present = NR_SetupRelease_MsgA_ConfigCommon_r16_PR_setup;
initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup =
calloc(1, sizeof(*initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup));
NR_MsgA_ConfigCommon_r16_t *NR_MsgA_ConfigCommon_r16 = initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
NR_MsgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16.rach_ConfigGenericTwoStepRA_r16.msgB_ResponseWindow_r16 =
calloc(1, sizeof(long));
NR_MsgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16.msgA_RSRP_Threshold_r16 = calloc(1, sizeof(NR_RSRP_Range_t));
NR_MsgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16.msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = calloc(1, sizeof(long));
NR_MsgA_ConfigCommon_r16->msgA_PUSCH_Config_r16 = calloc(1, sizeof(NR_MsgA_PUSCH_Config_r16_t));
NR_MsgA_PUSCH_Config_r16_t *msgA_PUSCH_Config_r16 = NR_MsgA_ConfigCommon_r16->msgA_PUSCH_Config_r16;
msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16 = calloc(1, sizeof(NR_MsgA_PUSCH_Resource_r16_t));
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16 = calloc(1, sizeof(long));
msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16 = calloc(1, sizeof(long));
}
// Section 4.1 in 38.213
NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR get_ssb_len(NR_ServingCellConfigCommon_t *scc)
@@ -271,7 +293,7 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N
rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present = NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139;
rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139 = 0;
rach_ConfigCommon->choice.setup->restrictedSetConfig = NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet;
*rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = -1;
*rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = mu_ul;
struct NR_SetupRelease_PUSCH_ConfigCommon *pusch_ConfigCommon = initialUplinkBWP->pusch_ConfigCommon;
asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list, add_PUSCH_TimeDomainResourceAllocation(55));
@@ -389,6 +411,14 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL;
}
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1
&& (int)scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16
->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16
== 0) {
free(scc->uplinkConfigCommon->initialUplinkBWP->ext1);
scc->uplinkConfigCommon->initialUplinkBWP->ext1 = NULL;
}
if ((int)*scc->n_TimingAdvanceOffset == -1) {
free(scc->n_TimingAdvanceOffset);
scc->n_TimingAdvanceOffset = NULL;
@@ -940,14 +970,20 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf
uint64_t ssb_bitmap=0xff;
prepare_scc(scc);
paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
prepare_msgA_scc(scc);
paramdef_t MsgASCCsParams[] = MSGASCCPARAMS_DESC(scc);
paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
paramlist_def_t MsgASCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
config_getlist(cfg, &SCCsParamList, NULL, 0, aprefix);
if (SCCsParamList.numelt > 0) {
config_getlist(cfg, &MsgASCCsParamList, NULL, 0, aprefix);
if (SCCsParamList.numelt > 0 || MsgASCCsParamList.numelt > 0) {
sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0);
config_get(cfg, SCCsParams, sizeofArray(SCCsParams), aprefix);
config_get(cfg, MsgASCCsParams, sizeofArray(MsgASCCsParams), aprefix);
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
LOG_I(RRC,
"Read in ServingCellConfigCommon (PhysCellId %d, ABSFREQSSB %d, DLBand %d, ABSFREQPOINTA %d, DLBW "
+61 -1
View File
@@ -244,6 +244,12 @@ typedef struct {
uint8_t E: 1;
} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID;
typedef struct {
uint8_t RAPID: 6;
uint8_t T1: 1;
uint8_t E: 1;
} __attribute__((__packed__)) NR_RA_HEADER_RAPID_MSGB;
/*!\brief RAR MAC subheader with Backoff Indicator */
typedef struct {
uint8_t BI: 4;
@@ -252,7 +258,23 @@ typedef struct {
uint8_t E: 1;
} __attribute__ ((__packed__)) NR_RA_HEADER_BI;
// TS 38.321 ch. 6.2.3
typedef struct {
uint8_t BI: 4;
uint8_t R: 1;
uint8_t T2: 1;
uint8_t T1: 1;
uint8_t E: 1;
} __attribute__((__packed__)) NR_RA_HEADER_BI_MSGB;
typedef struct {
uint8_t R: 4;
uint8_t S: 1;
uint8_t T2: 1;
uint8_t T1: 1;
uint8_t E: 1;
} __attribute__((__packed__)) NR_RA_HEADER_SUCCESS_RAR_MSGB;
// TS 38.321 Sec. 6.2.3
typedef struct {
uint8_t TA1: 7; // octet 1 [6:0]
uint8_t R: 1; // octet 1 [7]
@@ -265,6 +287,38 @@ typedef struct {
uint8_t TCRNTI_2: 8; // octet 7 [7:0]
} __attribute__ ((__packed__)) NR_MAC_RAR;
// TS 38.321 Sec. 6.2.3
typedef struct {
uint8_t TA1: 7; // octet 1 [6:0]
uint8_t R: 1; // octet 1 [7]
uint8_t UL_GRANT_1: 3; // octet 2 [2:0]
uint8_t TA2: 5; // octet 2 [7:3]
uint8_t UL_GRANT_2: 8; // octet 3 [7:0]
uint8_t UL_GRANT_3: 8; // octet 4 [7:0]
uint8_t UL_GRANT_4: 8; // octet 5 [7:0]
uint8_t TCRNTI_1: 8; // octet 6 [7:0]
uint8_t TCRNTI_2: 8; // octet 7 [7:0]
} __attribute__((__packed__)) NR_MAC_RAR_MSGB;
// TS 38.321 Sec. 6.2.3
typedef struct {
uint8_t CONT_RES_1: 8; // octet 1 [7:0]
uint8_t CONT_RES_2: 8; // octet 2 [7:0]
uint8_t CONT_RES_3: 8; // octet 3 [7:0]
uint8_t CONT_RES_4: 8; // octet 4 [7:0]
uint8_t CONT_RES_5: 8; // octet 5 [7:0]
uint8_t CONT_RES_6: 8; // octet 6 [7:0]
uint8_t HARQ_FTI: 3; // octet 7 [2:0]
uint8_t TPC: 2; // octet 7 [4:3]
uint8_t CH_ACESS_CPEXT: 2; // octet 7 [6:5]
uint8_t R: 1; // octet 7 [7]
uint8_t TA1: 4; // octet 8 [3:0]
uint8_t PUCCH_RI: 4; // octet 8 [7:4]
uint8_t TA2: 8; // octet 9 [7:0]
uint8_t CRNTI_1: 8; // octet 10 [7:0]
uint8_t CRNTI_2: 8; // octet 11 [7:0]
} __attribute__((__packed__)) NR_MAC_SUCCESS_RAR;
// DCI pdu structures. Used by both gNB and UE.
typedef struct {
uint32_t val;
@@ -559,6 +613,7 @@ typedef struct NR_UE_UL_BWP {
uint16_t BWPSize;
uint16_t BWPStart;
NR_RACH_ConfigCommon_t *rach_ConfigCommon;
NR_MsgA_ConfigCommon_r16_t *msgA_ConfigCommon_r16;
NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList_Common;
NR_ConfiguredGrantConfig_t *configuredGrantConfig;
NR_PUSCH_Config_t *pusch_Config;
@@ -629,5 +684,10 @@ typedef struct NR_tda_info {
bool valid_tda;
} NR_tda_info_t;
typedef enum {
RA_4_STEP = 0,
RA_2_STEP = 1,
} nr_ra_type_t;
#endif /*__LAYER2_MAC_H__ */
@@ -655,6 +655,7 @@ NR_tda_info_t get_dl_tda_info(const NR_UE_DL_BWP_t *dl_BWP,
case TYPE_CS_RNTI_:
case TYPE_MCS_C_RNTI_:
case TYPE_RA_RNTI_:
case TYPE_MSGB_RNTI_:
case TYPE_TC_RNTI_:
if(tdalist)
tda_info = set_tda_info_from_list(tdalist, tda_index);
@@ -5313,6 +5314,15 @@ rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carri
return ra_rnti;
}
rnti_t nr_get_MsgB_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carrier_id)
{
// 3GPP TS 38.321 Section 5.1.3a
rnti_t MsgB_rnti = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id + 17920;
LOG_D(MAC, "f_id %d t_id %d s_id %d ul_carrier_id %d Computed MsgB_RNTI is 0x%04X\n", f_id, t_id, s_id, ul_carrier_id, MsgB_rnti);
return MsgB_rnti;
}
int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17, int harq_pid)
{
if (downlinkHARQ_FeedbackDisabled_r17 == NULL)
@@ -5323,3 +5333,20 @@ int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_Fe
return (downlinkHARQ_FeedbackDisabled_r17->buf[byte_index] >> (7 - bit_index)) & 1;
}
int nr_get_prach_mu(const NR_MsgA_ConfigCommon_r16_t *msgacc, const NR_RACH_ConfigCommon_t *rach_ConfigCommon)
{
int mu;
// if 2-Step configuration file exists
if (msgacc && msgacc->rach_ConfigCommonTwoStepRA_r16.msgA_SubcarrierSpacing_r16) {
// Choose Subcarrier Spacing of configuration file of 2-Step
mu = *msgacc->rach_ConfigCommonTwoStepRA_r16.msgA_SubcarrierSpacing_r16;
} else if (rach_ConfigCommon->msg1_SubcarrierSpacing) {
// Choose Subcarrier Spacing of configuration file of 4-Step
mu = *rach_ConfigCommon->msg1_SubcarrierSpacing;
} else
AssertFatal(false, "PRACH subcarrier spacing mandatory present for L139, not supported otherwise\n");
return mu;
}
@@ -317,6 +317,8 @@ uint32_t compute_PDU_length(uint32_t num_TLV, uint32_t total_length);
rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carrier_id);
rnti_t nr_get_MsgB_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carrier_id);
bool supported_bw_comparison(int bw_mhz, NR_SupportedBandwidth_t *supported_BW, long *support_90mhz);
int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17, int harq_pid);
@@ -325,4 +327,6 @@ int get_nrofHARQ_ProcessesForPDSCH(const NR_UE_ServingCell_Info_t *sc_info);
int get_nrofHARQ_ProcessesForPUSCH(const NR_UE_ServingCell_Info_t *sc_info);
int nr_get_prach_mu(const NR_MsgA_ConfigCommon_r16_t *msgacc, const NR_RACH_ConfigCommon_t *rach_ConfigCommon);
#endif
+6
View File
@@ -1540,6 +1540,12 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
NR_RACH_ConfigCommon_t,
asn_DEF_NR_RACH_ConfigCommon);
}
if (ul_common->ext1 && ul_common->ext1->msgA_ConfigCommon_r16) {
HANDLE_SETUPRELEASE_DIRECT(bwp->msgA_ConfigCommon_r16,
ul_common->ext1->msgA_ConfigCommon_r16,
NR_MsgA_ConfigCommon_r16_t,
asn_DEF_NR_MsgA_ConfigCommon_r16);
}
if (ul_common->pucch_ConfigCommon)
HANDLE_SETUPRELEASE_DIRECT(bwp->pucch_ConfigCommon,
ul_common->pucch_ConfigCommon,
+20 -13
View File
@@ -191,11 +191,6 @@ typedef enum {
RE_ESTABLISHMENT
} NR_UE_MAC_reset_cause_t;
typedef enum {
RA_2STEP = 0,
RA_4STEP
} nr_ra_type_e;
typedef struct {
// after multiplexing buffer remain for each lcid
int32_t LCID_buffer_remain;
@@ -268,16 +263,17 @@ typedef struct {
} NR_UE_SCHEDULING_INFO;
typedef enum {
nrRA_UE_IDLE = 0,
nrRA_GENERATE_PREAMBLE = 1,
nrRA_WAIT_RAR = 2,
nrRA_WAIT_CONTENTION_RESOLUTION = 3,
nrRA_SUCCEEDED = 4,
nrRA_FAILED = 5
nrRA_UE_IDLE,
nrRA_GENERATE_PREAMBLE,
nrRA_WAIT_RAR,
nrRA_WAIT_MSGB,
nrRA_WAIT_CONTENTION_RESOLUTION,
nrRA_SUCCEEDED,
nrRA_FAILED,
} nrRA_UE_state_t;
static const char *const nrra_ue_text[] =
{"UE_IDLE", "GENERATE_PREAMBLE", "WAIT_RAR", "WAIT_CONTENTION_RESOLUTION", "RA_SUCCEEDED", "RA_FAILED"};
{"UE_IDLE", "GENERATE_PREAMBLE", "WAIT_RAR", "WAIT_MSGB", "WAIT_CONTENTION_RESOLUTION", "RA_SUCCEEDED", "RA_FAILED"};
typedef struct {
/// PRACH format retrieved from prach_ConfigIndex
@@ -299,7 +295,7 @@ typedef struct {
///
uint8_t RA_SCALING_FACTOR_BI;
/// Indicating whether it is 2-step or 4-step RA
nr_ra_type_e RA_TYPE;
nr_ra_type_t RA_TYPE;
/// UE configured maximum output power
int RA_PCMAX;
} NR_PRACH_RESOURCES_t;
@@ -312,10 +308,21 @@ typedef struct {
nrRA_UE_state_t ra_state;
/// RA contention type
uint8_t cfra;
/// RA type
nr_ra_type_t ra_type;
/// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
uint8_t RA_offset;
/// MsgB SuccessRAR MAC subheader
int8_t MsgB_R;
int8_t MsgB_CH_ACESS_CPEXT;
uint8_t MsgB_TPC;
int8_t MsgB_HARQ_FTI;
uint16_t timing_advance_command;
int8_t PUCCH_RI;
/// RA-rnti
uint16_t ra_rnti;
/// MsgB RNTI
uint16_t MsgB_rnti;
/// Temporary CRNTI
uint16_t t_crnti;
/// number of attempt for rach
+7 -3
View File
@@ -304,6 +304,10 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot);
int16_t nr_get_RA_window_2Step(const NR_MsgA_ConfigCommon_r16_t *msgA_ConfigCommon_r16);
int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon);
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
@@ -331,7 +335,7 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac);
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac);
@@ -356,7 +360,7 @@ void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac);
void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac);
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac);
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac);
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
@@ -410,7 +414,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15_t *dci,
csi_payload_t *csi_report,
RAR_grant_t *rar_grant,
uint16_t rnti,
rnti_t rnti,
int ss_type,
const nr_dci_format_t dci_format);
+167 -60
View File
@@ -104,15 +104,19 @@ void init_RA(NR_UE_MAC_INST_t *mac,
prach_resources->POWER_OFFSET_2STEP_RA = 0;
prach_resources->RA_SCALING_FACTOR_BI = 1;
// Contention Free
if (rach_ConfigDedicated) {
if (rach_ConfigDedicated->cfra){
LOG_I(NR_MAC, "Initialization of 2-step contention-free random access procedure\n");
prach_resources->RA_TYPE = RA_2STEP;
LOG_I(MAC, "Initialization of 4-Step CFRA procedure\n");
prach_resources->RA_TYPE = RA_4_STEP;
ra->ra_type = RA_4_STEP;
ra->cfra = 1;
} else if (rach_ConfigDedicated->ext1){
if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
LOG_I(NR_MAC, "Setting RA type to 2-step...\n");
prach_resources->RA_TYPE = RA_2STEP;
if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16) {
LOG_I(MAC, "Initialization of 2-Step CFRA procedure\n");
prach_resources->RA_TYPE = RA_2_STEP;
ra->ra_type = RA_2_STEP;
ra->cfra = 1;
} else {
LOG_E(NR_MAC, "Config not handled\n");
@@ -120,10 +124,20 @@ void init_RA(NR_UE_MAC_INST_t *mac,
} else {
LOG_E(NR_MAC, "Config not handled\n");
}
} else {
LOG_I(NR_MAC, "Initialization of 4-step contention-based random access procedure\n");
prach_resources->RA_TYPE = RA_4STEP;
// Contention Based
} else if (mac->current_UL_BWP->msgA_ConfigCommon_r16) {
LOG_I(MAC, "Initialization of 2-Step CBRA procedure\n");
prach_resources->RA_TYPE = RA_2_STEP;
ra->ra_type = RA_2_STEP;
ra->cfra = 0;
} else if (nr_rach_ConfigCommon) {
LOG_I(MAC, "Initialization of 4-Step CBRA procedure\n");
prach_resources->RA_TYPE = RA_4_STEP;
ra->ra_type = RA_4_STEP;
ra->cfra = 0;
} else {
LOG_E(MAC, "Config not handled\n");
AssertFatal(false, "In %s: config not handled\n", __FUNCTION__);
}
switch (rach_ConfigGeneric->powerRampingStep){ // in dB
@@ -177,10 +191,28 @@ void init_RA(NR_UE_MAC_INST_t *mac,
break;
}
if (nr_rach_ConfigCommon->ext1) {
if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity_r16){
if (ra->ra_type == RA_2_STEP) {
if (nr_rach_ConfigCommon->ext1 && nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity_r16) {
LOG_D(MAC, "Missing implementation for Access Identity initialization procedures\n");
}
// Perform initialization of variables specific to Random Access type as specified in clause 5.1.1a of TS 38.321
NR_RACH_ConfigGenericTwoStepRA_r16_t nr_ra_ConfigGenericTwoStepRA_r16 =
mac->current_UL_BWP->msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16.rach_ConfigGenericTwoStepRA_r16;
// Takes the value of 2-Step RA variable
if (nr_ra_ConfigGenericTwoStepRA_r16.msgA_PreamblePowerRampingStep_r16) {
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = *nr_ra_ConfigGenericTwoStepRA_r16.msgA_PreamblePowerRampingStep_r16;
} else {
// If 2-Step variable does not exist, it takes the value of 4-Step RA variable
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep;
}
prach_resources->RA_SCALING_FACTOR_BI = 1;
// Takes the value of 2-Step RA variable
if (nr_ra_ConfigGenericTwoStepRA_r16.preambleTransMax_r16) {
ra->preambleTransMax = (int)*nr_ra_ConfigGenericTwoStepRA_r16.preambleTransMax_r16;
} else {
// If 2-Step variable does not exist, it takes the value of 4-Step RA variable
ra->preambleTransMax = (int)nr_rach_ConfigCommon->rach_ConfigGeneric.preambleTransMax;
}
}
}
@@ -623,7 +655,7 @@ static uint8_t *fill_msg3_crnti_pdu(RA_config_t *ra, uint8_t *pdu, uint16_t crnt
static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int TBS_max)
{
RA_config_t *ra = &mac->ra;
// regular MSG3 with PDU coming from higher layers
// regular Msg3/MsgA_PUSCH with PDU coming from higher layers
*(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_CCCH};
pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
tbs_size_t len = mac_rlc_data_req(mac->ue_id,
@@ -637,7 +669,7 @@ static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int
(char *)pdu,
0,
0);
AssertFatal(len > 0, "no data for Msg.3\n");
AssertFatal(len > 0, "no data for Msg3/MsgA_PUSCH\n");
// UE Contention Resolution Identity
// Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the
// Random Access Procedure has been successful after reception of Msg4
@@ -647,7 +679,7 @@ static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int
return pdu;
}
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
{
RA_config_t *ra = &mac->ra;
@@ -660,10 +692,10 @@ void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
uint8_t *pdu = buf;
if (ra->msg3_C_RNTI)
pdu = fill_msg3_crnti_pdu(ra, pdu, mac->crnti);
else
else
pdu = fill_msg3_pdu_from_rlc(mac, pdu, TBS_max);
AssertFatal(TBS_max >= pdu - buf, "Allocated resources are not enough for Msg3!\n");
AssertFatal(TBS_max >= pdu - buf, "Allocated resources are not enough for Msg3/MsgA_PUSCH!\n");
// Padding: fill remainder with 0
LOG_D(NR_MAC, "Remaining %ld bytes, filling with padding\n", pdu - buf);
while (pdu < buf + TBS_max - sizeof(NR_MAC_SUBHEADER_FIXED)) {
@@ -695,13 +727,24 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
if (ra->ra_state == nrRA_UE_IDLE) {
if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) &&
((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) {
ra->ra_state = nrRA_GENERATE_PREAMBLE;
} else {
LOG_D(NR_MAC,"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame);
return;
}
LOG_D(NR_MAC,
"ra->ra_state %d frame %d mac->first_sync_frame %d xxx %d",
ra->ra_state,
frame,
mac->first_sync_frame,
((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 10);
if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa)
&& ((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) {
ra->ra_state = nrRA_GENERATE_PREAMBLE;
LOG_D(NR_MAC, "PRACH Condition met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame);
} else {
LOG_D(NR_MAC,
"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n",
ra->ra_state,
frame,
mac->first_sync_frame);
return;
}
}
LOG_D(NR_MAC, "[UE %d][%d.%d]: ra_state %d, RA_active %d\n", mac->ue_id, frame, nr_slot_tx, ra->ra_state, ra->RA_active);
@@ -762,8 +805,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
nr_ra_succeeded(mac, gNB_id, frame, nr_slot_tx);
}
} else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
} else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found && ra->ra_state != nrRA_WAIT_MSGB) {
LOG_W(MAC, "[UE %d][%d:%d] RAR reception failed \n", mac->ue_id, frame, nr_slot_tx);
nr_ra_failed(mac, CC_id, prach_resources, frame, nr_slot_tx);
@@ -795,49 +837,102 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
}
}
int16_t nr_get_RA_window_2Step(const NR_MsgA_ConfigCommon_r16_t *msgA_ConfigCommon_r16)
{
int16_t ra_ResponseWindow = *msgA_ConfigCommon_r16->rach_ConfigCommonTwoStepRA_r16
.rach_ConfigGenericTwoStepRA_r16.msgB_ResponseWindow_r16;
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl1:
return 1;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl2:
return 2;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl4:
return 4;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl8:
return 8;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl10:
return 10;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl20:
return 20;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl40:
return 40;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl80:
return 80;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl160:
return 160;
break;
case NR_RACH_ConfigGenericTwoStepRA_r16__msgB_ResponseWindow_r16_sl320:
return 360;
break;
default:
AssertFatal(false, "illegal msgB_responseWindow value %d\n", ra_ResponseWindow);
break;
}
return 0;
}
int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon)
{
int16_t ra_ResponseWindow = rach_ConfigCommon->rach_ConfigGeneric.ra_ResponseWindow;
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
return 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
return 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
return 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
return 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
return 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
return 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
return 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
return 80;
break;
default:
AssertFatal(false, "illegal ra_ResponseWindow value %d\n", ra_ResponseWindow);
break;
}
return 0;
}
void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
{
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
const double ta_Common_ms = get_ta_Common_ms(mac->sc_info.ntn_Config_r17);
const int mu = mac->current_DL_BWP->scs;
const int slots_per_ms = nr_slots_per_frame[mu] / 10;
const int ra_Offset_slots = ra->RA_offset * nr_slots_per_frame[mu];
const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB
int ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
switch (ra_ResponseWindow) {
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
ra->RA_window_cnt += 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
ra->RA_window_cnt += 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
ra->RA_window_cnt += 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
ra->RA_window_cnt += 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
ra->RA_window_cnt += 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
ra->RA_window_cnt += 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
ra->RA_window_cnt += 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
ra->RA_window_cnt += 80;
break;
}
ra->RA_window_cnt += ra->ra_type == RA_2_STEP ? nr_get_RA_window_2Step(mac->current_UL_BWP->msgA_ConfigCommon_r16)
: nr_get_RA_window_4Step(mac->current_UL_BWP->rach_ConfigCommon);
}
////////////////////////////////////////////////////////////////////////////
@@ -855,7 +950,7 @@ void nr_ue_contention_resolution(NR_UE_MAC_INST_t *mac, int cc_id, frame_t frame
ra->t_crnti = 0;
nr_timer_stop(&ra->contention_resolution_timer);
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
LOG_E(MAC, "[UE %d] 4-Step CBRA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
}
}
@@ -869,14 +964,27 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
RA_config_t *ra = &mac->ra;
if (ra->cfra) {
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mac->ue_id, frame, slot);
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CFRA: RAR successfully received.\n", mac->ue_id, frame, slot);
ra->RA_window_cnt = -1;
} else if (ra->ra_type == RA_2_STEP) {
LOG_A(MAC,
"[UE %d][%d.%d][RAPROC] 2-Step RA procedure succeeded. CBRA: Contention Resolution is successful.\n",
mac->ue_id,
frame,
slot);
mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
LOG_D(MAC, "[UE %d][%d.%d] CBRA: cleared response window timer...\n", mac->ue_id, frame, slot);
} else {
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mac->ue_id, frame, slot);
LOG_A(MAC,
"[UE %d][%d.%d][RAPROC] 4-Step RA procedure succeeded. CBRA: Contention Resolution is successful.\n",
mac->ue_id,
frame,
slot);
nr_timer_stop(&ra->contention_resolution_timer);
mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
LOG_D(MAC, "[UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
LOG_D(MAC, "[UE %d][%d.%d] CBRA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
}
LOG_D(MAC, "[UE %d] clearing RA_active flag...\n", mac->ue_id);
@@ -931,7 +1039,6 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mac, prach_resources, CC_id);
} else {
// Resetting RA window
nr_get_RA_window(mac);
}
}
@@ -944,7 +1051,7 @@ void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac)
mac->ra.msg3_C_RNTI = true;
}
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
int sched_slot = current_harq->ul_slot;
@@ -266,6 +266,14 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
rel15->rnti = mac->ra.ra_rnti;
rel15->SubcarrierSpacing = current_DL_BWP->scs;
break;
case TYPE_MSGB_RNTI_:
// we use the initial DL BWP
sps = current_DL_BWP->cyclicprefix == NULL ? 14 : 12;
monitoringSymbolsWithinSlot =
(ss->monitoringSymbolsWithinSlot->buf[0] << (sps - 8)) | (ss->monitoringSymbolsWithinSlot->buf[1] >> (16 - sps));
rel15->rnti = mac->ra.MsgB_rnti;
rel15->SubcarrierSpacing = current_DL_BWP->scs;
break;
case TYPE_P_RNTI_:
break;
case TYPE_CS_RNTI_:
@@ -571,7 +579,12 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
if (mac->state == UE_PERFORMING_RA && mac->ra.ra_state >= nrRA_WAIT_RAR) {
// if RA is ongoing use RA search space
if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->ra_SS)) {
int rnti_type = mac->ra.ra_state == nrRA_WAIT_RAR ? TYPE_RA_RNTI_ : TYPE_TC_RNTI_;
nr_rnti_type_t rnti_type = 0;
if (mac->ra.ra_type == RA_4_STEP) {
rnti_type = mac->ra.ra_state == nrRA_WAIT_RAR ? TYPE_RA_RNTI_ : TYPE_TC_RNTI_;
} else {
rnti_type = TYPE_MSGB_RNTI_;
}
config_dci_pdu(mac, dl_config, rnti_type, slot, pdcch_config->ra_SS);
}
} else if (mac->state == UE_CONNECTED) {
+114 -14
View File
@@ -161,6 +161,8 @@ int get_rnti_type(const NR_UE_MAC_INST_t *mac, const uint16_t rnti)
if (rnti == ra->ra_rnti) {
rnti_type = TYPE_RA_RNTI_;
} else if (rnti == ra->MsgB_rnti && (ra->ra_state == nrRA_WAIT_MSGB || ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)) {
rnti_type = TYPE_MSGB_RNTI_;
} else if (rnti == ra->t_crnti && (ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)) {
rnti_type = TYPE_TC_RNTI_;
} else if (rnti == mac->crnti) {
@@ -3347,6 +3349,7 @@ static nr_dci_format_t nr_extract_dci_00_10(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15->format_indicator = format_indicator;
break;
case TYPE_TC_RNTI_ :
case TYPE_MSGB_RNTI_:
// Identifier for DCI formats
EXTRACT_DCI_ITEM(format_indicator, 1);
if (format_indicator == 1) {
@@ -3434,6 +3437,101 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in
nr_timer_start(&mac->time_alignment_timer);
}
static bool check_ra_contention_resolution(const uint8_t *pdu, const uint8_t *cont_res)
{
if (IS_SOFTMODEM_IQPLAYER) // Control is bypassed when replaying IQs (BMC)
return true;
for (int i = 0; i < 6; i++) {
if (pdu[i] != cont_res[i]) {
return false;
}
}
return true;
}
static int nr_ue_validate_successrar(uint8_t *pduP,
int32_t pdu_len,
NR_UE_MAC_INST_t *mac,
uint8_t gNB_index,
frame_t frameP,
int slot)
{
// TS 38.321 - Figure 6.1.5a-1: BI MAC subheader
// TS 38.321 - Figure 6.1.5a-3: SuccessRAR MAC subheader
int n = 0;
uint8_t E = 1;
uint8_t cont_res_id[6];
RA_config_t *ra = &mac->ra;
while (n < pdu_len && E) {
E = (pduP[n] >> 7) & 0x1;
uint8_t SUCESS_RAR_header_T1 = (pduP[n] >> 6) & 0x1;
if (SUCESS_RAR_header_T1 == 0) { // T2 exist
int SUCESS_RAR_header_T2 = (pduP[n] >> 5) & 0x1;
if (SUCESS_RAR_header_T2 == 0) { // BI
ra->RA_backoff_indicator = pduP[n] & 0x0F;
n++;
} else { // S
n++;
// TS 38.321 - Figure 6.2.3a-2: successRAR
for (int i = 0; i < 6; ++i)
cont_res_id[i] = pduP[n + i];
n += 6;
// Oct 7
ra->MsgB_R = 0;
ra->MsgB_CH_ACESS_CPEXT = (pduP[n] >> 5) & 0x3;
ra->MsgB_TPC = (pduP[n] >> 3) & 3;
ra->MsgB_HARQ_FTI = (int8_t)pduP[n] & 0x7;
// Oct 8
n++;
ra->PUCCH_RI = ((int8_t)pduP[n] >> 4) & 0x0F;
// Oct 8 and Oct 9
ra->timing_advance_command = ((uint16_t)(pduP[n] & 0xf) << 8) | pduP[n + 1];
n += 2;
// Oct 10 and Oct 11
ra->t_crnti = ((uint16_t)pduP[n] << 8) | pduP[n + 1];
n += 2;
LOG_D(NR_MAC,
"successRAR: Contention Resolution ID 0x%02x%02x%02x%02x%02x%02x R 0x%01x CH_ACESS_CPEXT 0x%02x TPC 0x%02x "
"HARQ_FTI 0x%03x PUCCH_RI 0x%04x TA 0x%012x CRNTI 0x%04x\n",
cont_res_id[0],
cont_res_id[1],
cont_res_id[2],
cont_res_id[3],
cont_res_id[4],
cont_res_id[5],
ra->MsgB_R,
ra->MsgB_CH_ACESS_CPEXT,
ra->MsgB_TPC,
ra->MsgB_HARQ_FTI,
ra->PUCCH_RI,
ra->timing_advance_command,
ra->t_crnti);
bool ra_success = check_ra_contention_resolution(cont_res_id, ra->cont_res_id);
if (ra->RA_active && ra_success) {
nr_ra_succeeded(mac, gNB_index, frameP, slot);
} else if (!ra_success) {
// nr_ra_failed(mac, CC_id, &ra->prach_resources, frameP, slot);
ra->ra_state = nrRA_UE_IDLE;
ra->RA_active = 0;
}
}
} else { // RAPID
int RAPID = pduP[n] & 0x3F;
n++;
LOG_D(MAC, "RAPID %d\n", RAPID);
AssertFatal(false, "FallbackRAR not implemented yet!\n");
}
}
const int ta = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
set_time_alignment(mac, ta, adjustment_ta, frameP, slot);
return n;
}
///////////////////////////////////
// brief: nr_ue_process_mac_pdu
// function: parsing DL PDU header
@@ -3457,9 +3555,12 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in
//
// |0|1|2|3|4|5|6|7| bit-wise
// |R|R| LCID |
// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described
// in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits;
// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders
// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the
// corresponding MAC CE or padding as described
// in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID
// field size is 6 bits;
// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field
// per MAC subheader except for subheaders
// corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field;
// F: lenght of L is 0:8 or 1:16 bits wide
// R: Reserved bit, set to zero.
@@ -3475,17 +3576,24 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
uint8_t done = 0;
RA_config_t *ra = &mac->ra;
if (!pduP){
if (!pduP) {
return;
}
LOG_D(MAC, "[%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n",
LOG_D(MAC,
"[%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n",
frameP,
slot,
pdu_id,
pdu_len,
dl_info->rx_ind->number_pdus);
if (ra->ra_type == RA_2_STEP && ra->ra_state == nrRA_WAIT_MSGB) {
int n = nr_ue_validate_successrar(pduP, pdu_len, mac, gNB_index, frameP, slot);
pduP += n;
pdu_len -= n;
}
while (!done && pdu_len > 0){
uint16_t mac_len = 0x0000;
uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
@@ -3618,15 +3726,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
pduP[5],
pduP[6]);
bool ra_success = true;
if (!IS_SOFTMODEM_IQPLAYER) { // Control is bypassed when replaying IQs (BMC)
for(int i = 0; i < mac_len; i++) {
if(ra->cont_res_id[i] != pduP[i + 1]) {
ra_success = false;
break;
}
}
}
bool ra_success = check_ra_contention_resolution(&pduP[1], ra->cont_res_id);
if (ra->RA_active && ra_success) {
nr_ra_succeeded(mac, gNB_index, frameP, slot);
+118 -12
View File
@@ -574,7 +574,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15_t *dci,
csi_payload_t *csi_report,
RAR_grant_t *rar_grant,
uint16_t rnti,
rnti_t rnti,
int ss_type,
const nr_dci_format_t dci_format)
{
@@ -584,6 +584,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
int rnti_type = get_rnti_type(mac, rnti);
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info;
int scs = current_UL_BWP->scs;
// Common configuration
pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1;
@@ -596,8 +597,69 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
int dmrslength = 1;
NR_PUSCH_Config_t *pusch_Config = current_UL_BWP->pusch_Config;
if (rar_grant) {
AssertFatal(!((mac->ra.ra_state < nrRA_SUCCEEDED && mac->ra.ra_type == RA_2_STEP) && rar_grant), "logic error: Is not possible to have both msgA_pusch_resource and rar_grant\n");
if (mac->ra.ra_state < nrRA_SUCCEEDED && mac->ra.ra_type == RA_2_STEP) {
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
int S = 0;
int L = 0;
SLIV2SL(*msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, &S, &L);
tda_info->k2 = msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16;
tda_info->startSymbolIndex = S;
tda_info->nrOfSymbols = L;
l_prime_mask = get_l_prime(tda_info->nrOfSymbols,
tda_info->mapping_type,
add_pos,
dmrslength,
tda_info->startSymbolIndex,
mac->dmrs_TypeA_Position);
LOG_I(NR_MAC,
"MSGA PUSCH start_sym:%d NR Symb:%d mappingtype:%d, DMRS_MASK:%x\n",
pusch_config_pdu->start_symbol_index,
pusch_config_pdu->nr_of_symbols,
tda_info->mapping_type,
l_prime_mask);
LOG_D(NR_MAC,
"sc_info->initial_ul_BWPStart = %d sc_info->initial_ul_BWPSize = %d\n",
sc_info->initial_ul_BWPStart,
sc_info->initial_ul_BWPSize);
pusch_config_pdu->handle = 0;
pusch_config_pdu->rb_size = msgA_PUSCH_Resource->nrofPRBs_PerMsgA_PO_r16;
pusch_config_pdu->mcs_table = 0;
pusch_config_pdu->frequency_hopping = msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 ? *msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 : 0;
pusch_config_pdu->dmrs_ports = 1; // is in SIB1 nrofDMRS_Sequences_r16?
pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
pusch_config_pdu->ul_dmrs_symb_pos = get_l_prime(3, 0, pusch_dmrs_pos2, pusch_len1, 10, mac->dmrs_TypeA_Position);
pusch_config_pdu->transform_precoding =
*mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16;
pusch_config_pdu->rb_bitmap[0] = 0;
pusch_config_pdu->rb_start = msgA_PUSCH_Resource->frequencyStartMsgA_PUSCH_r16; // rb_start depends on the RO
pusch_config_pdu->bwp_size = sc_info->initial_ul_BWPSize;
pusch_config_pdu->bwp_start = sc_info->initial_ul_BWPStart;
pusch_config_pdu->subcarrier_spacing = scs;
pusch_config_pdu->cyclic_prefix = 0;
pusch_config_pdu->uplink_frequency_shift_7p5khz = 0;
pusch_config_pdu->vrb_to_prb_mapping = 0;
pusch_config_pdu->dmrs_config_type = 0;
pusch_config_pdu->data_scrambling_id = mac->physCellId;
pusch_config_pdu->ul_dmrs_scrambling_id = mac->physCellId;
pusch_config_pdu->scid = 0;
pusch_config_pdu->resource_alloc = 1;
pusch_config_pdu->tx_direct_current_location = 0;
pusch_config_pdu->mcs_index = msgA_PUSCH_Resource->msgA_MCS_r16;
pusch_config_pdu->qam_mod_order = nr_get_Qm_dl(pusch_config_pdu->mcs_index, 0);
pusch_config_pdu->start_symbol_index = S;
pusch_config_pdu->nr_of_symbols = L;
pusch_config_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213
pusch_config_pdu->pusch_data.harq_process_id = 0;
pusch_config_pdu->pusch_data.num_cb = 0;
pusch_config_pdu->tbslbrm = 0;
pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, 0);
} else if (rar_grant) {
// Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0
int ibwp_start = sc_info->initial_ul_BWPStart;
int ibwp_size = sc_info->initial_ul_BWPSize;
@@ -1501,8 +1563,8 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
TBS_bytes,
ra->ra_state);
ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = NULL;
if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) {
nr_get_msg3_payload(mac, ulsch_input_buffer, TBS_bytes);
if ((ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_MSGB) && !ra->cfra) {
nr_get_Msg3_MsgA_PUSCH_payload(mac, ulsch_input_buffer, TBS_bytes);
for (int k = 0; k < TBS_bytes; k++) {
LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]);
}
@@ -1553,6 +1615,9 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index);
}
if (ra->ra_state == nrRA_WAIT_MSGB && !ra->cfra) {
LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-MsgA-PUSCH transmitted\n", frame_tx, slot_tx);
}
}
ulcfg_pdu++;
}
@@ -1739,13 +1804,6 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac)
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
int mu;
if (setup->msg1_SubcarrierSpacing)
mu = *setup->msg1_SubcarrierSpacing;
else
mu = mac->current_UL_BWP->scs;
msg1_FDM = rach_ConfigGeneric->msg1_FDM;
switch (msg1_FDM){
@@ -1765,6 +1823,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac)
int unpaired = mac->phy_config.config_req.cell_config.frame_duplex_type;
const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, unpaired);
int mu = nr_get_prach_mu(mac->current_UL_BWP->msgA_ConfigCommon_r16, setup);
// Identify the proper PRACH Configuration Index table according to the operating frequency
LOG_D(NR_MAC,"mu = %u, PRACH config index = %u, unpaired = %u\n", mu, config_index, unpaired);
@@ -2867,7 +2926,54 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_fra
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
nr_Msg1_transmitted(mac);
if (ra->ra_type == RA_4_STEP) {
nr_Msg1_transmitted(mac);
} else if (ra->ra_type == RA_2_STEP) {
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
int mu = nr_get_prach_mu(mac->current_UL_BWP->msgA_ConfigCommon_r16, setup);
const int n_slots_frame = nr_slots_per_frame[mu];
slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame;
frame_t msgA_pusch_frame =
(frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024;
fapi_nr_ul_config_request_pdu_t *pdu =
lockGet_ul_config(mac, msgA_pusch_frame, msgA_pusch_slot, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return;
// Config Msg3/MsgA-PUSCH PDU
NR_tda_info_t tda_info = {0};
AssertFatal(msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16,
"Only SLIV based on startSymbolAndLengthMsgA_PO_r16 implemented\n");
int ret = nr_config_pusch_pdu(mac,
&tda_info,
&pdu->pusch_config_pdu,
NULL,
NULL,
NULL,
mac->ra.ra_rnti,
NR_SearchSpace__searchSpaceType_PR_common,
NR_DCI_NONE);
if (ret != 0)
remove_ul_config_last_item(pdu);
release_ul_config(pdu, false);
// Compute MsgB RNTI
ra->MsgB_rnti =
nr_get_MsgB_rnti(prach_occasion_info_p->start_symbol, prach_occasion_info_p->slot, prach_occasion_info_p->fdm, 0);
LOG_D(NR_MAC, "ra->ra_state %s\n", nrra_ue_text[ra->ra_state]);
ra->ra_state = nrRA_WAIT_MSGB;
ra->t_crnti = 0;
mac->crnti = 0;
ra->ra_rnti = 0;
} else {
AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type);
}
// rnti = ra->t_crnti;
} // is_nr_prach_slot
} // if is_nr_UL_slot
}
+277 -51
View File
@@ -88,16 +88,15 @@ static int16_t ssb_index_from_prach(module_id_t module_idP,
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
uint16_t start_symbol_index = 0;
uint8_t mu,N_dur=0,N_t_slot=0,start_symbol = 0, temp_start_symbol = 0, N_RA_slot=0;
uint8_t N_dur=0,N_t_slot=0,start_symbol = 0, temp_start_symbol = 0, N_RA_slot=0;
uint16_t format,RA_sfn_index = -1;
uint8_t config_period = 1;
uint16_t prach_occasion_id = -1;
uint8_t num_active_ssb = cc->num_active_ssb;
if (rach_ConfigCommon->msg1_SubcarrierSpacing)
mu = *rach_ConfigCommon->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
NR_MsgA_ConfigCommon_r16_t *msgacc = NULL;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
int mu = nr_get_prach_mu(msgacc, rach_ConfigCommon);
get_nr_prach_info_from_index(config_index,
(int)frameP,
@@ -164,7 +163,7 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac)
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
uint8_t config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0;
uint8_t N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0;
uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0;
uint8_t num_active_ssb = 0;
uint8_t max_association_period = 1;
@@ -201,10 +200,10 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac)
break;
}
if (rach_ConfigCommon->msg1_SubcarrierSpacing)
mu = *rach_ConfigCommon->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
NR_MsgA_ConfigCommon_r16_t *msgacc = NULL;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
int mu = nr_get_prach_mu(msgacc, rach_ConfigCommon);
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
get_nr_prach_occasion_info_from_index(config_index,
@@ -253,8 +252,115 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac)
cc->max_association_period,
N_RA_sfn,
cc->total_prach_occasions_per_config_period);
}
}
static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon,
gNB_MAC_INST *nr_mac,
module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
nfapi_nr_prach_pdu_t *prach_pdu,
uint16_t dmrs_TypeA_Position,
NR_PhysCellId_t physCellId)
{
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice
.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
int mu = nr_get_prach_mu(uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup,
uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup);
const int n_slots_frame = nr_slots_per_frame[mu];
slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame;
frame_t msgA_pusch_frame = (frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024;
int index = ul_buffer_index((int)msgA_pusch_frame, (int)msgA_pusch_slot, mu, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &nr_mac[module_idP].UL_tti_req_ahead[0][index];
UL_tti_req->SFN = msgA_pusch_frame;
UL_tti_req->Slot = msgA_pusch_slot;
AssertFatal(is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[msgA_pusch_slot / 64], msgA_pusch_slot),
"Slot %d is not an Uplink slot, invalid msgA_PUSCH_TimeDomainOffset_r16 %ld\n",
msgA_pusch_slot,
msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
rnti_t ra_rnti = nr_get_ra_rnti(prach_pdu->prach_start_symbol, slotP, prach_pdu->num_ra, 0);
// Fill PUSCH PDU
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = ra_rnti;
pusch_pdu->handle = 0;
pusch_pdu->rb_size = msgA_PUSCH_Resource->nrofPRBs_PerMsgA_PO_r16;
pusch_pdu->mcs_table = 0;
pusch_pdu->frequency_hopping =
msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 ? *msgA_PUSCH_Resource->msgA_IntraSlotFrequencyHopping_r16 : 0;
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
AssertFatal(msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16,
"Only SLIV based on startSymbolAndLengthMsgA_PO_r16 implemented\n");
int S = 0;
int L = 0;
SLIV2SL(*msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, &S, &L);
pusch_pdu->start_symbol_index = S;
pusch_pdu->nr_of_symbols = L;
pusch_pdu->pusch_data.new_data_indicator = 1;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
pusch_pdu->ul_dmrs_symb_pos = get_l_prime(3, 0, pusch_dmrs_pos2, pusch_len1, 10, dmrs_TypeA_Position);
pusch_pdu->transform_precoding = *uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16->msgA_TransformPrecoder_r16;
pusch_pdu->rb_bitmap[0] = 0;
pusch_pdu->rb_start = msgA_PUSCH_Resource->frequencyStartMsgA_PUSCH_r16; // rb_start depends on the RO
int locationAndBandwidth = uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth;
pusch_pdu->bwp_size = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE);
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(locationAndBandwidth, MAX_BWP_SIZE);
pusch_pdu->subcarrier_spacing = 0;
pusch_pdu->cyclic_prefix = 0;
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
pusch_pdu->vrb_to_prb_mapping = 0;
pusch_pdu->dmrs_config_type = 0;
pusch_pdu->data_scrambling_id = 0;
if (msgA_PUSCH_Resource->msgA_DMRS_Config_r16.msgA_ScramblingID0_r16) {
pusch_pdu->ul_dmrs_scrambling_id = *msgA_PUSCH_Resource->msgA_DMRS_Config_r16.msgA_ScramblingID0_r16;
} else {
pusch_pdu->ul_dmrs_scrambling_id = physCellId;
}
pusch_pdu->scid =
0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
pusch_pdu->pusch_identity = 0;
pusch_pdu->resource_alloc = 1; // type 1
pusch_pdu->tx_direct_current_location = 0;
pusch_pdu->mcs_index = msgA_PUSCH_Resource->msgA_MCS_r16;
pusch_pdu->qam_mod_order = nr_get_Qm_dl(pusch_pdu->mcs_index, pusch_pdu->mcs_table);
int num_dmrs_symb = 0;
for (int i = 10; i < 10 + 3; i++)
num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1;
AssertFatal(pusch_pdu->mcs_index <= 28, "Exceeding MCS limit for MsgA PUSCH\n");
int R = nr_get_code_rate_ul(pusch_pdu->mcs_index, pusch_pdu->mcs_table);
pusch_pdu->target_code_rate = R;
int TBS = nr_compute_tbs(pusch_pdu->qam_mod_order,
R,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
num_dmrs_symb * 12, // nb dmrs set for no data in dmrs symbol
0, // nb_rb_oh
0, // to verify tb scaling
pusch_pdu->nrOfLayers)
>> 3;
pusch_pdu->pusch_data.tb_size = TBS;
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS << 3, R);
LOG_D(NR_MAC, "Scheduling MsgA PUSCH in %d.%d\n", msgA_pusch_frame, msgA_pusch_slot);
UL_tti_req->n_pdus += 1;
}
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
@@ -264,11 +370,10 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
int mu;
if (rach_ConfigCommon->msg1_SubcarrierSpacing)
mu = *rach_ConfigCommon->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
NR_MsgA_ConfigCommon_r16_t *msgacc = NULL;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
int mu = nr_get_prach_mu(msgacc, rach_ConfigCommon);
int index = ul_buffer_index(frameP, slotP, mu, gNB->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
@@ -436,6 +541,18 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
AssertFatal(1==0,"Invalid PRACH format");
}
}
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1
&& scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
if (gNB->UE_info.list[0] == NULL)
schedule_nr_MsgA_pusch(scc->uplinkConfigCommon,
gNB,
module_idP,
frameP,
slotP,
prach_pdu,
scc->dmrs_TypeA_Position,
*scc->physCellId);
}
}
}
}
@@ -455,6 +572,76 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
}
}
int nr_fill_successrar(const NR_UE_sched_ctrl_t *ue_sched_ctl,
rnti_t crnti,
const unsigned char *ue_cont_res_id,
uint8_t resource_indicator,
uint8_t timing_indicator,
unsigned char *mac_pdu,
int mac_pdu_length)
{
LOG_D(NR_MAC, "mac_pdu_length = %d\n", mac_pdu_length);
int timing_advance_cmd = ue_sched_ctl->ta_update;
// TS 38.321 - Figure 6.1.5a-1: BI MAC subheader
NR_RA_HEADER_BI_MSGB *bi = (NR_RA_HEADER_BI_MSGB *)&mac_pdu[mac_pdu_length];
mac_pdu_length += sizeof(NR_RA_HEADER_BI_MSGB);
bi->E = 1;
bi->T1 = 0;
bi->T2 = 0;
bi->R = 0;
bi->BI = 0; // BI = 0, 5ms
// TS 38.321 - Figure 6.1.5a-3: SuccessRAR MAC subheader
NR_RA_HEADER_SUCCESS_RAR_MSGB *SUCESS_RAR_header = (NR_RA_HEADER_SUCCESS_RAR_MSGB *)&mac_pdu[mac_pdu_length];
mac_pdu_length += sizeof(NR_RA_HEADER_SUCCESS_RAR_MSGB);
SUCESS_RAR_header->E = 0;
SUCESS_RAR_header->T1 = 0;
SUCESS_RAR_header->T2 = 1;
SUCESS_RAR_header->S = 0;
SUCESS_RAR_header->R = 0;
// TS 38.321 - Figure 6.2.3a-2: successRAR
NR_MAC_SUCCESS_RAR *successRAR = (NR_MAC_SUCCESS_RAR *)&mac_pdu[mac_pdu_length];
mac_pdu_length += sizeof(NR_MAC_SUCCESS_RAR);
successRAR->CONT_RES_1 = ue_cont_res_id[0];
successRAR->CONT_RES_2 = ue_cont_res_id[1];
successRAR->CONT_RES_3 = ue_cont_res_id[2];
successRAR->CONT_RES_4 = ue_cont_res_id[3];
successRAR->CONT_RES_5 = ue_cont_res_id[4];
successRAR->CONT_RES_6 = ue_cont_res_id[5];
successRAR->R = 0;
successRAR->CH_ACESS_CPEXT = 1;
successRAR->TPC = ue_sched_ctl->tpc0;
successRAR->HARQ_FTI = timing_indicator;
successRAR->PUCCH_RI = resource_indicator;
successRAR->TA1 = (uint8_t)(timing_advance_cmd >> 8); // 4 MSBs of timing advance;
successRAR->TA2 = (uint8_t)(timing_advance_cmd & 0xff); // 8 LSBs of timing advance;
successRAR->CRNTI_1 = (uint8_t)(crnti >> 8); // 8 MSBs of rnti
successRAR->CRNTI_2 = (uint8_t)(crnti & 0xff); // 8 LSBs of rnti
LOG_D(NR_MAC,
"successRAR: Contention Resolution ID 0x%02x%02x%02x%02x%02x%02x R 0x%01x CH_ACESS_CPEXT 0x%02x TPC 0x%02x HARQ_FTI 0x%03x "
"PUCCH_RI 0x%04x TA 0x%012x CRNTI 0x%04x\n",
successRAR->CONT_RES_1,
successRAR->CONT_RES_2,
successRAR->CONT_RES_3,
successRAR->CONT_RES_4,
successRAR->CONT_RES_5,
successRAR->CONT_RES_6,
successRAR->R,
successRAR->CH_ACESS_CPEXT,
successRAR->TPC,
successRAR->HARQ_FTI,
successRAR->PUCCH_RI,
timing_advance_cmd,
crnti);
LOG_D(NR_MAC, "mac_pdu_length = %d\n", mac_pdu_length);
return mac_pdu_length;
}
static bool ra_contains_preamble(const NR_RA_t *ra, uint16_t preamble_index)
{
for (int j = 0; j < ra->preambles.num_preambles; j++) {
@@ -544,18 +731,27 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->rnti = trial;
}
ra->ra_state = nrRA_Msg2;
ra->preamble_frame = frameP;
ra->preamble_slot = slotP;
ra->preamble_index = preamble_index;
ra->timing_offset = timing_offset;
uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
ra->RA_rnti = nr_get_ra_rnti(symbol, slotP, freq_index, ul_carrier_id);
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16) {
ra->ra_type = RA_2_STEP;
ra->ra_state = nrRA_WAIT_MsgA_PUSCH;
ra->MsgB_rnti = nr_get_MsgB_rnti(symbol, slotP, freq_index, ul_carrier_id);
} else {
ra->ra_type = RA_4_STEP;
ra->ra_state = nrRA_Msg2;
}
int index = ra - cc->ra;
LOG_I(NR_MAC, "%d.%d UE RA-RNTI %04x TC-RNTI %04x: Activating RA process index %d\n", frameP, slotP, ra->RA_rnti, ra->rnti, index);
// Configure RA BWP
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1);
// return current SSB order in the list of tranmitted SSBs
@@ -1741,32 +1937,31 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
LOG_D(NR_MAC, "numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
}
static void nr_generate_Msg4(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
static void nr_generate_Msg4_MsgB(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
// if it is a DL slot, if the RA is in MSG4 state
// if it is a DL slot, if the RA is in MSG4 state
if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) {
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_SearchSpace_t *ss = ra->ra_ss;
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
NR_ControlResourceSet_t *coreset = ra->coreset;
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n");
AssertFatal(coreset != NULL, "Coreset cannot be null for RA %s\n", ra_type_str);
uint16_t mac_sdu_length = 0;
NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
if (!UE) {
LOG_E(NR_MAC, "want to generate Msg4, but rnti %04x not in the table\n", ra->rnti);
LOG_E(NR_MAC, "want to generate %s, but rnti %04x not in the table\n", ra_type_str, ra->rnti);
return;
}
@@ -1862,7 +2057,8 @@ static void nr_generate_Msg4(module_id_t module_idP,
}
else {
uint8_t subheader_len = (mac_sdu_length < 256) ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG);
pdu_length = mac_sdu_length + subheader_len + 7; //7 is contetion resolution length
pdu_length = mac_sdu_length + subheader_len + 13; // 13 is contention resolution length of msgB. It is divided into 3 parts:
// BI MAC subheader (1 Oct) + SuccessRAR MAC subheader (1 Oct) + SuccessRAR (11 Oct)
}
// increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size
@@ -1877,7 +2073,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
rbSize, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3;
} while (tb_size < pdu_length && mcsIndex<=28);
AssertFatal(tb_size >= pdu_length,"Cannot allocate Msg4\n");
AssertFatal(tb_size >= pdu_length, "Cannot allocate %s\n", ra_type_str);
int i = 0;
uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx];
@@ -1940,9 +2136,22 @@ static void nr_generate_Msg4(module_id_t module_idP,
uint8_t *buf = (uint8_t *) harq->transportBlock;
// Bytes to be transmitted
if (harq->round == 0) {
// UE Contention Resolution Identity MAC CE
uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length);
uint16_t mac_pdu_length = 0;
if (ra->ra_type == RA_4_STEP) {
// UE Contention Resolution Identity MAC CE
mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
} else if (ra->ra_type == RA_2_STEP) {
mac_pdu_length = nr_fill_successrar(nr_mac->sched_ctrlCommon,
ra->rnti,
ra->cont_res_id,
pucch->resource_indicator,
pucch->timing_indicator,
buf,
mac_pdu_length);
} else {
AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type);
}
uint8_t buffer[CCCH_SDU_SIZE];
uint8_t mac_subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT);
// Get RLC data on the SRB (RRCSetup, RRCReestablishment)
@@ -1975,9 +2184,20 @@ static void nr_generate_Msg4(module_id_t module_idP,
memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length);
}
rnti_t rnti = ra->ra_type == RA_4_STEP ? ra->rnti : ra->MsgB_rnti;
const int pduindex = nr_mac->pdu_index[CC_id]++;
prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, pucch, dmrs_info, msg4_tda, aggregation_level, CCEIndex, tb_size, harq->ndi, sched_ctrl->tpc1, delta_PRI,
current_harq_pid, time_domain_assignment, CC_id, ra->rnti, harq->round, mcsIndex, tb_scaling, pduindex, rbStart, rbSize);
current_harq_pid,
time_domain_assignment,
CC_id,
rnti,
harq->round,
mcsIndex,
tb_scaling,
pduindex,
rbStart,
rbSize);
// Add padding header and zero rest out if there is space left
if (ra->mac_pdu_length < harq->tb_size) {
@@ -2016,7 +2236,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
if (pucch == NULL) {
LOG_A(NR_MAC, "(UE RNTI 0x%04x) Skipping Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti);
UE->Msg4_ACKed = true;
UE->Msg4_MsgB_ACKed = true;
// Pause scheduling according to:
// 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs
@@ -2027,17 +2247,18 @@ static void nr_generate_Msg4(module_id_t module_idP,
nr_clear_ra_proc(ra);
} else {
ra->ra_state = nrRA_WAIT_Msg4_ACK;
ra->ra_state = nrRA_WAIT_Msg4_MsgB_ACK;
LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size);
}
}
}
static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra)
static void nr_check_Msg4_MsgB_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra)
{
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti);
if (!UE) {
LOG_E(NR_MAC, "Cannot check Msg4 ACK/NACK, rnti %04x not in the table\n", ra->rnti);
LOG_E(NR_MAC, "Cannot check %s ACK/NACK, rnti %04x not in the table\n", ra_type_str, ra->rnti);
return;
}
const int current_harq_pid = ra->harq_pid;
@@ -2049,10 +2270,14 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
if (harq->is_waiting == 0) {
if (harq->round == 0) {
if (UE->Msg4_ACKed) {
LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti);
if (UE->Msg4_MsgB_ACKed) {
LOG_A(NR_MAC,
"%4d.%2d UE %04x: Received Ack of %s. CBRA procedure succeeded!\n",
frame, slot, ra->rnti, ra_type_str);
} else {
LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at Msg4!\n", frame, slot, ra->rnti);
LOG_I(NR_MAC,
"%4d.%2d UE %04x: RA Procedure failed at %s!\n",
frame, slot, ra->rnti, ra_type_str);
nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs);
}
@@ -2068,8 +2293,8 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
}
} else {
LOG_I(NR_MAC, "(UE %04x) Received Nack of RA-Msg4. Preparing retransmission!\n", ra->rnti);
ra->ra_state = nrRA_Msg4;
LOG_I(NR_MAC, "(UE %04x) Received Nack in %s, preparing retransmission!\n", ra->rnti, nrra_text[ra->ra_state]);
ra->ra_state = ra->ra_type == RA_4_STEP ? nrRA_Msg4 : nrRA_MsgB;
}
}
}
@@ -2222,7 +2447,7 @@ void nr_schedule_RA(module_id_t module_idP,
LOG_D(NR_MAC, "RA[state:%d]\n", ra->ra_state);
// Check RA Contention Resolution timer
if (ra->ra_state >= nrRA_WAIT_Msg3) {
if (ra->ra_type == RA_4_STEP && ra->ra_state >= nrRA_WAIT_Msg3) {
ra->contention_resolution_timer--;
if (ra->contention_resolution_timer < 0) {
LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti);
@@ -2241,10 +2466,11 @@ void nr_schedule_RA(module_id_t module_idP,
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
break;
case nrRA_Msg4:
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
case nrRA_MsgB:
nr_generate_Msg4_MsgB(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
break;
case nrRA_WAIT_Msg4_ACK:
nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
case nrRA_WAIT_Msg4_MsgB_ACK:
nr_check_Msg4_MsgB_Ack(module_idP, CC_id, frameP, slotP, ra);
break;
default:
break;
@@ -627,7 +627,7 @@ static void pf_dl(module_id_t module_id,
/* Loop UE_info->list to check retransmission */
UE_iterator(UE_list, UE) {
if (UE->Msg4_ACKed != true)
if (!UE->Msg4_MsgB_ACKed)
continue;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
@@ -2469,10 +2469,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
UE->uid = uid_linear_allocator_new(&UE_info->uid_allocator);
UE->CellGroup = CellGroup;
if (CellGroup)
UE->Msg4_ACKed = true;
else
UE->Msg4_ACKed = false;
UE->Msg4_MsgB_ACKed = CellGroup != NULL;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
memset(sched_ctrl, 0, sizeof(*sched_ctrl));
@@ -1041,8 +1041,8 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max);
if (!UE->Msg4_ACKed && harq_value == 0 && harq_confidence == 0)
UE->Msg4_ACKed = true;
if (!UE->Msg4_MsgB_ACKed && harq_value == 0 && harq_confidence == 0)
UE->Msg4_MsgB_ACKed = true;
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
}
@@ -596,7 +596,7 @@ void handle_nr_ul_harq(const int CC_idP,
}
}
NR_SCHED_UNLOCK(&nrmac->sched_lock);
LOG_E(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/PUSCH\n", crc_pdu->rnti);
LOG_D(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/MsgA-PUSCH\n", crc_pdu->rnti);
return;
}
if (nrmac->radio_config.disable_harq) {
@@ -819,7 +819,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
* it. */
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
if (ra->ra_state != nrRA_WAIT_Msg3)
if (ra->ra_type == RA_4_STEP && ra->ra_state != nrRA_WAIT_Msg3)
continue;
if (no_sig) {
@@ -827,22 +827,29 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
handle_msg3_failed_rx(ra, i, gNB_mac->ul_bler.harq_round_max);
continue;
}
// random access pusch with TC-RNTI
if (ra->rnti != current_rnti) {
LOG_D(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti);
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot)) {
LOG_W(NR_MAC,
"Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n",
i,
nrra_text[ra->ra_state],
ra->rnti,
current_rnti);
nr_clear_ra_proc(ra);
if (ra->ra_type == RA_2_STEP) {
// random access pusch with RA-RNTI
if (ra->RA_rnti != current_rnti) {
LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, current_rnti);
continue;
}
} else {
// random access pusch with TC-RNTI
if (ra->rnti != current_rnti) {
LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti);
continue;
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot)) {
LOG_W(NR_MAC,
"Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n",
i,
nrra_text[ra->ra_state],
ra->rnti,
current_rnti);
nr_clear_ra_proc(ra);
}
continue;
}
}
UE = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
@@ -882,7 +889,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, ra->CellGroup->rlc_BearerToAddModList);
nr_clear_ra_proc(ra);
} else {
LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n");
LOG_D(NR_MAC, "[RAPROC] Received %s:\n", ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "Msg3");
for (uint32_t k = 0; k < sdu_lenP; k++) {
LOG_D(NR_MAC, "(%i): 0x%x\n", k, sduP[k]);
}
@@ -914,7 +921,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
// The UE identified by C-RNTI still exists at the gNB
// Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration
UE->Msg4_ACKed = false;
UE->Msg4_MsgB_ACKed = false;
nr_mac_reset_ul_failure(&UE->UE_sched_ctrl);
// Reset HARQ processes
reset_dl_harq_list(&UE->UE_sched_ctrl);
@@ -949,8 +956,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
// the function is only called to decode the contention resolution sub-header
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1);
LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %s)\n", ra->rnti, nrra_text[ra->ra_state]);
ra->ra_state = nrRA_Msg4;
LOG_I(NR_MAC,
"Activating scheduling %s for TC_RNTI 0x%04x (state %s)\n",
ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4",
ra->rnti,
nrra_text[ra->ra_state]);
ra->ra_state = ra->ra_type == RA_2_STEP ? nrRA_MsgB : nrRA_Msg4;
LOG_D(NR_MAC, "TC_RNTI 0x%04x next RA state %s\n", ra->rnti, nrra_text[ra->ra_state]);
return;
}
}
@@ -1787,7 +1799,7 @@ static void pf_ul(module_id_t module_id,
UE_iterator(UE_list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure)
if (!UE->Msg4_MsgB_ACKed || sched_ctrl->ul_failure)
continue;
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti);
+13 -8
View File
@@ -113,16 +113,18 @@ typedef struct {
} NR_list_t;
typedef enum {
nrRA_gNB_IDLE = 0,
nrRA_Msg2 = 1,
nrRA_WAIT_Msg3 = 2,
nrRA_Msg3_retransmission = 3,
nrRA_Msg4 = 4,
nrRA_WAIT_Msg4_ACK = 5,
nrRA_gNB_IDLE,
nrRA_Msg2,
nrRA_WAIT_MsgA_PUSCH,
nrRA_WAIT_Msg3,
nrRA_Msg3_retransmission,
nrRA_Msg4,
nrRA_MsgB,
nrRA_WAIT_Msg4_MsgB_ACK,
} RA_gNB_state_t;
static const char *const nrra_text[] =
{"IDLE", "Msg2", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "WAIT_Msg4_ACK"};
{"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"};
typedef struct {
int idx;
@@ -221,6 +223,8 @@ typedef struct {
rnti_t rnti;
/// RA RNTI allocated from received PRACH
uint16_t RA_rnti;
/// MsgB RNTI allocated from received MsgA
uint16_t MsgB_rnti;
/// Received UE Contention Resolution Identifier
uint8_t cont_res_id[6];
/// Msg3 first RB
@@ -249,6 +253,7 @@ typedef struct {
/// Preambles for contention-free access
NR_preamble_ue_t preambles;
int contention_resolution_timer;
nr_ra_type_t ra_type;
/// CFRA flag
bool cfra;
// BWP for RA
@@ -755,7 +760,7 @@ typedef struct {
NR_UE_NR_Capability_t *capability;
// UE selected beam index
uint8_t UE_beam_index;
bool Msg4_ACKed;
bool Msg4_MsgB_ACKed;
float ul_thr_ue;
float dl_thr_ue;
long pdsch_HARQ_ACK_Codebook;
+1 -1
View File
@@ -1127,7 +1127,7 @@ void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nac
LOG_D(PHY,"Updating harq_status for harq_id %d, ack/nak %d\n", harq_pid, current_harq->ack);
// we can prepare feedback for MSG4 in advance
if (mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)
prepare_msg4_feedback(mac, harq_pid, ack_nack);
prepare_msg4_msgb_feedback(mac, harq_pid, ack_nack);
else {
current_harq->ack = ack_nack;
current_harq->ack_received = true;
+30
View File
@@ -71,6 +71,25 @@ static NR_SetupRelease_RACH_ConfigCommon_t *clone_rach_configcommon(const NR_Set
return clone;
}
static NR_SetupRelease_MsgA_ConfigCommon_r16_t *clone_msga_configcommon(const NR_SetupRelease_MsgA_ConfigCommon_r16_t *mcc)
{
if (mcc == NULL || mcc->present == NR_SetupRelease_MsgA_ConfigCommon_r16_PR_NOTHING)
return NULL;
NR_SetupRelease_MsgA_ConfigCommon_r16_t *clone = calloc_or_fail(1, sizeof(*clone));
clone->present = mcc->present;
if (clone->present == NR_SetupRelease_MsgA_ConfigCommon_r16_PR_release)
return clone;
uint8_t buf[1024];
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MsgA_ConfigCommon_r16, NULL, mcc->choice.setup, buf, sizeof(buf));
AssertFatal(enc_rval.encoded > 0 && enc_rval.encoded < sizeof(buf),
"could not clone NR_MsgA_ConfigCommon_r16: problem while encoding\n");
asn_dec_rval_t dec_rval =
uper_decode(NULL, &asn_DEF_NR_MsgA_ConfigCommon_r16, (void **)&clone->choice.setup, buf, enc_rval.encoded, 0, 0);
AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed == enc_rval.encoded,
"could not clone NR_MsgA_ConfigCommon_r16:: problem while decoding\n");
return clone;
}
static NR_SetupRelease_PUSCH_ConfigCommon_t *clone_pusch_configcommon(const NR_SetupRelease_PUSCH_ConfigCommon_t *pcc)
{
if (pcc == NULL || pcc->present == NR_SetupRelease_PUSCH_ConfigCommon_PR_NOTHING)
@@ -2351,6 +2370,17 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
UL->initialUplinkBWP.genericParameters = clone_generic_parameters(&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters);
UL->initialUplinkBWP.rach_ConfigCommon = clone_rach_configcommon(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon);
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1) {
NR_SetupRelease_MsgA_ConfigCommon_r16_t *msgA_configcommon =
clone_msga_configcommon(scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16);
if (msgA_configcommon) {
// Add the struct ext1
UL->initialUplinkBWP.ext1 = calloc(1, sizeof(*UL->initialUplinkBWP.ext1));
UL->initialUplinkBWP.ext1->msgA_ConfigCommon_r16 = msgA_configcommon;
}
}
UL->initialUplinkBWP.pusch_ConfigCommon = clone_pusch_configcommon(scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon);
free(UL->initialUplinkBWP.pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding);
UL->initialUplinkBWP.pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = NULL;
@@ -0,0 +1,278 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
nr_cellid = 12345678L;
////////// Physical parameters:
do_CSIRS = 1;
do_SRS = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# 0=sl1, 1=sl2, 2=sl4, 3=sl8, 4=sl10, 5=sl20, 6=sl40, 7=sl80, 8=sl160, 9=sl320
msgB_ResponseWindow_r16 = 2;
msgA_RSRP_Threshold_r16 = 19;
msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = 1;
msgA_MCS_r16 = 2;
nrofSlotsMsgA_PUSCH_r16 = 1;
# 0=one, 1=two, 2=three, 3=six
nrofMsgA_PO_PerSlot_r16 = 0;
msgA_PUSCH_TimeDomainOffset_r16 = 8;
startSymbolAndLengthMsgA_PO_r16 = 38;
mappingTypeMsgA_PUSCH_r16 = 0;
guardBandMsgA_PUSCH_r16 = 0;
frequencyStartMsgA_PUSCH_r16 = 0;
nrofPRBs_PerMsgA_PO_r16 = 8;
# 0=one, 1=two, 2=four, 3=eight
nrofMsgA_PO_FDM_r16 = 0;
msgA_PUSCH_NrofPorts_r16 = 1;
nrofDMRS_Sequences_r16 = 1;
# 0=enabled, 1=disabled
msgA_TransformPrecoder_r16 = 1;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "192.168.70.132"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 12;
att_rx = 12;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
clock_src = "internal";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = 4043;
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};
e2_agent = {
near_ric_ip_addr = "127.0.0.1";
#sm_dir = "/path/where/the/SMs/are/located/"
sm_dir = "/usr/local/lib/flexric/"
};