Merge branch 'develop' into enable_ta_for_phytest

Conflicts:
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
This commit is contained in:
Thomas Schlichter
2020-06-24 12:16:03 +02:00
190 changed files with 12239 additions and 8007 deletions
+1
View File
@@ -66,6 +66,7 @@ MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_m
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp)
MESSAGE_DEF(S1AP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_t , s1ap_path_switch_req)
MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_ack_t , s1ap_path_switch_req_ack)
MESSAGE_DEF(S1AP_E_RAB_MODIFICATION_IND , MESSAGE_PRIORITY_MED, s1ap_e_rab_modification_ind_t , s1ap_e_rab_modification_ind)
/* S1AP -> RRC messages */
MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas )
+37 -1
View File
@@ -45,6 +45,7 @@
#define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp
#define S1AP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req
#define S1AP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req_ack
#define S1AP_E_RAB_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modification_ind
#define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas
#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
@@ -277,12 +278,26 @@ typedef struct e_rab_tobe_added_s {
uint8_t drb_ID;
/* The transport layer address for the IP packets */
transport_layer_addr_t eNB_addr;
transport_layer_addr_t sgw_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} e_rab_tobe_added_t;
typedef struct e_rab_admitted_tobe_added_s {
/* Unique e_rab_id for the UE. */
uint8_t e_rab_id;
/* Unique drb_ID for the UE. */
uint8_t drb_ID;
/* The transport layer address for the IP packets */
transport_layer_addr_t gnb_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} e_rab_admitted_tobe_added_t;
typedef struct e_rab_tobeswitched_s {
@@ -642,6 +657,27 @@ typedef struct s1ap_path_switch_req_ack_s {
} s1ap_path_switch_req_ack_t;
typedef struct s1ap_e_rab_modification_ind_s {
unsigned eNB_ue_s1ap_id:24;
/* MME UE id */
uint32_t mme_ue_s1ap_id;
/* Number of e_rab setup-ed in the list */
uint8_t nb_of_e_rabs_tobemodified;
uint8_t nb_of_e_rabs_nottobemodified;
/* list of e_rab setup-ed by RRC layers */
e_rab_setup_t e_rabs_tobemodified[S1AP_MAX_E_RAB];
e_rab_setup_t e_rabs_nottobemodified[S1AP_MAX_E_RAB];
uint16_t ue_initial_id;
} s1ap_e_rab_modification_ind_t;
// S1AP --> RRC messages
typedef struct s1ap_ue_release_command_s {
+1 -1
View File
@@ -363,7 +363,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s {
uint8_t nb_e_rabs_admitted_tobeadded;
/* list of e_rab to be added by RRC layers */
e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
e_rab_admitted_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
+20 -18
View File
@@ -128,12 +128,13 @@
#define GNB_CONFIG_STRING_RARESPONSEWINDOW "ra_ResponseWindow"
#define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSBPR "ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR"
#define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSB "ssb_perRACH_OccasionAndCB_PreamblesPerSSB"
#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER "ra_ContentionResolutionTimer"
#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB "rsrp_ThresholdSSB"
#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR"
#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex"
#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing"
#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig"
#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER "ra_ContentionResolutionTimer"
#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB "rsrp_ThresholdSSB"
#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR"
#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex"
#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing"
#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig"
#define GNB_CONFIG_STRING_MSG3TRANSFPREC "msg3_transformPrecoder"
#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST "puschTimeDomainAllocationList"
#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE "msg3_DeltaPreamble"
#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT "p0_NominalWithGrant"
@@ -246,7 +247,7 @@
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:-1,TYPE_INT64,0/*17*/},\
{GNB_CONFIG_STRING_INITIALDLBWPK0_1,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->k0,defint64val:-1,TYPE_INT64,0/*18*/},\
{GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*19*/},\
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \
{GNB_CONFIG_STRING_INITIALDLBWPK0_2,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->k0,defint64val:-1,TYPE_INT64,0/*21*/},\
{GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*22*/},\
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength,defint64val:54,TYPE_INT64,0/*23*/},\
@@ -311,11 +312,12 @@
{GNB_CONFIG_STRING_RSRPTHRESHOLDSSB,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB,defint64val:19,TYPE_INT64,0/*82*/},\
{GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR,NULL,0,uptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present,defuintval:NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139,TYPE_UINT,0/*83*/},\
{GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139,defint64val:0,TYPE_INT64,0/*84*/},\
{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \
{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*86*/},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*87*/},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*88*/},\
{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*89*/}, \
{GNB_CONFIG_STRING_RESTRICTEDSETCONFIG,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \
{GNB_CONFIG_STRING_MSG3TRANSFPREC,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder,defintval:1,TYPE_INT64,0/*86*/}, \
{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*87*/},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*88*/},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*89*/},\
{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*90*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_2,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2,defint64val:-1,TYPE_INT64,0},\
@@ -325,7 +327,7 @@
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_4,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*99*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*100*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_5,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_5,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
@@ -335,7 +337,7 @@
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_6,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_7,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*109*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*110*/}, \
{GNB_CONFIG_STRING_INITIALULBWPK2_8,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
@@ -345,7 +347,7 @@
{GNB_CONFIG_STRING_INITIALULBWPK2_10,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*119*/}, \
{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*120*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_12,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->k2,defint64val:-1,TYPE_INT64,0},\
@@ -355,7 +357,7 @@
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_14,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*129*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*130*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_15,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_15,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
@@ -365,7 +367,7 @@
{GNB_CONFIG_STRING_PUCCHGROUPHOPPING, NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,defint64val:NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither,TYPE_INT64,0},\
{GNB_CONFIG_STRING_HOPPINGID, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId,defint64val:40,TYPE_INT64,0},\
{GNB_CONFIG_STRING_P0NOMINAL, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal,defint64val:1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*139*/}, \
{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*140*/}, \
{GNB_CONFIG_STRING_SSBPOSITIONSINBURST,NULL,0,u64ptr:&ssb_bitmap,defintval:0xff,TYPE_UINT64,0}, \
{GNB_CONFIG_STRING_REFERENCESUBCARRIERSPACING,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing,defint64val:NR_SubcarrierSpacing_kHz30,TYPE_INT64,0},\
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity,defint64val:NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5,TYPE_INT64,0},\
@@ -379,7 +381,7 @@
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,i64ptr:&scc->ss_PBCH_BlockPower,defint64val:20,TYPE_INT64,0}, \
{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0/*86*/}}
{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0}}
+10 -10
View File
@@ -71,30 +71,30 @@ static void configure_nr_rrc(uint32_t gnb_id)
/*------------------------------------------------------------------------------*/
/*
static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
{
uint32_t gnb_id;
MessageDef *msg_p;
//MessageDef *msg_p;
uint32_t register_gnb_pending = 0;
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
{
s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
//s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
// note: there is an implicit relationship between the data structure and the message name
msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
/*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
RCconfig_NR_S1(msg_p, gnb_id);
RCconfig_NR_S1(msg_p, gnb_id);*/
if (gnb_id == 0) RCconfig_nr_gtpu();
s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);
/*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/
LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
//itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
register_gnb_pending++;
}
@@ -102,7 +102,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
return register_gnb_pending;
}
*/
/*------------------------------------------------------------------------------*/
static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
@@ -175,7 +175,7 @@ void *gNB_app_task(void *args_p)
if (EPC_MODE_ENABLED) {
/* Try to register each gNB */
//registered_gnb = 0;
//register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
} else {
/* Start L2L1 task */
msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE);
+13 -9
View File
@@ -54,7 +54,8 @@
#include "common/config/config_userapi.h"
//#include "RRC_config_tools.h"
#include "gnb_paramdef.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_asn_constant.h"
#include "executables/thread-common.h"
#include "NR_SCS-SpecificCarrier.h"
@@ -254,10 +255,9 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = NULL;
}
// fix libconfig (asn1c uses long)
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower-=((long)1<<32);
*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant-=((long)1<<32);
*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal-=((long)1<<32);
// default value for msg3 precoder is NULL (0 means enabled)
if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0)
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL;
// fix DL and UL Allocation lists
@@ -714,10 +714,14 @@ int RCconfig_nr_gtpu(void ) {
if (address) {
MessageDef *message;
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,"");
IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
// LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(GTPU,"invalid address for S1U\n");
+83 -3
View File
@@ -41,6 +41,10 @@
#define NR_BCCH_BCH 5 // MIB
#define CCCH_PAYLOAD_SIZE_MAX 128
#define RAR_PAYLOAD_SIZE_MAX 128
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
@@ -86,17 +90,93 @@ typedef struct {
uint8_t R:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
// BSR MAC CEs
// TS 38.321 ch. 6.1.3.1
// Short BSR for a specific logical channel group ID
typedef struct {
uint8_t Buffer_size:5; // octet 1 LSB
uint8_t LcgID:3; // octet 1 MSB
} __attribute__ ((__packed__)) NR_BSR_SHORT;
typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
// Long BSR for all logical channel group ID
typedef struct {
uint8_t Buffer_size7:8;
uint8_t Buffer_size6:8;
uint8_t Buffer_size5:8;
uint8_t Buffer_size4:8;
uint8_t Buffer_size3:8;
uint8_t Buffer_size2:8;
uint8_t Buffer_size1:8;
uint8_t Buffer_size0:8;
uint8_t LcgID0:1;
uint8_t LcgID1:1;
uint8_t LcgID2:1;
uint8_t LcgID3:1;
uint8_t LcgID4:1;
uint8_t LcgID5:1;
uint8_t LcgID6:1;
uint8_t LcgID7:1;
} __attribute__ ((__packed__)) NR_BSR_LONG;
typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
// 38.321 ch. 6.1.3.4
typedef struct {
uint8_t TA_COMMAND:6; // octet 1 [5:0]
uint8_t TAGID:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_CE_TA;
// single Entry PHR MAC CE
// TS 38.321 ch. 6.1.3.8
typedef struct {
uint8_t PH:6;
uint8_t R1:2;
uint8_t PCMAX:6;
uint8_t R2:6;
} __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE;
//* RAR MAC subheader // TS 38.321 ch. 6.1.5, 6.2.2 *//
// - E: The Extension field is a flag indicating if the MAC subPDU including this MAC subheader is the last MAC subPDU or not in the MAC PDU
// - T: The Type field is a flag indicating whether the MAC subheader contains a Random Access Preamble ID or a Backoff Indicator (0, BI) (1, RAPID)
// - R: Reserved bit, set to "0"
// - BI: The Backoff Indicator field identifies the overload condition in the cell.
// - RAPID: The Random Access Preamble IDentifier field identifies the transmitted Random Access Preamble
/*!\brief RAR MAC subheader with RAPID */
typedef struct {
uint8_t RAPID:6;
uint8_t T:1;
uint8_t E:1;
} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID;
/*!\brief RAR MAC subheader with Backoff Indicator */
typedef struct {
uint8_t BI:4;
uint8_t R:2;
uint8_t T:1;
uint8_t E:1;
} __attribute__ ((__packed__)) NR_RA_HEADER_BI;
// TS 38.321 ch. 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;
// 38.321 ch6.2.1, 38.331
#define DL_SCH_LCID_CCCH 0x00
#define DL_SCH_LCID_DCCH 0x01
#define DL_SCH_LCID_DCCH1 0x02
#define DL_SCH_LCID_DTCH 0x03
#define DL_SCH_LCID_DTCH 0x04
#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F
#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30
#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31
@@ -118,8 +198,8 @@ typedef struct {
#define UL_SCH_LCID_CCCH 0x00
#define UL_SCH_LCID_SRB1 0x01
#define UL_SCH_LCID_SRB2 0x02
#define UL_SCH_LCID_DTCH 0x03
#define UL_SCH_LCID_SRB3 0x04
#define UL_SCH_LCID_SRB3 0x03
#define UL_SCH_LCID_DTCH 0x04
#define UL_SCH_LCID_CCCH_MSG3 0x21
#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35
#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36
File diff suppressed because it is too large Load Diff
@@ -32,13 +32,8 @@
#ifndef __LAYER2_NR_MAC_COMMON_H__
#define __LAYER2_NR_MAC_COMMON_H__
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
#include "NR_PDSCH-Config.h"
#include "NR_ServingCellConfigCommon.h"
typedef enum {
NR_DL_DCI_FORMAT_1_0 = 0,
@@ -67,4 +62,50 @@ typedef enum {
NR_RNTI_TPC_SRS
} nr_rnti_type_t;
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
uint16_t nr_dci_size(nr_dci_format_t format, nr_rnti_type_t rnti_type, uint16_t N_RB);
void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
uint16_t *slot_period,
uint16_t *offset);
int get_nr_prach_info_from_index(uint8_t index,
int frame,
int slot,
uint32_t pointa,
uint8_t mu,
uint8_t unpaired,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur);
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
uint8_t nb_preambles,
uint8_t unpaired);
int get_format0(uint8_t index, uint8_t unpaired);
uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config);
int get_num_dmrs(uint16_t dmrs_mask );
uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
#endif
+15 -8
View File
@@ -19,12 +19,12 @@
* contact@openairinterface.org
*/
/*! \file extern.h
/*! \file nr_mac_extern.h
* \brief NR mac externs
* \author G. Casati
* \author Navid Nikaein, Raymond Knopp, Guido Casati
* \date 2019
* \version 1.0
* \email guido.casati@iis.fraunhofer.de
* \email navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
@@ -32,10 +32,10 @@
#ifndef __NR_MAC_EXTERN_H__
#define __NR_MAC_EXTERN_H__
//#include "PHY/defs_common.h"
#include "nr_mac.h"
#include "RRC/LTE/rrc_defs.h"
#include "common/ran_context.h"
#include "nr_mac.h"
/*#include "PHY/defs_common.h"*/
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
@@ -43,8 +43,6 @@ extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern UE_RRC_INST *UE_rrc_inst;
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern const int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
@@ -52,6 +50,7 @@ extern mac_rlc_am_muilist_t rlc_am_mui;
extern SCHEDULER_MODES global_scheduler_mode;
extern unsigned char NB_UE_INST;*/
extern unsigned char NB_INST;
extern unsigned char NB_eNB_INST;
extern unsigned char NB_RN_INST;
@@ -60,8 +59,15 @@ extern unsigned short NODE_ID[1];
/* Scheduler */
extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode;
extern mac_rlc_am_muilist_t rlc_am_mui;
extern SCHEDULER_MODES global_scheduler_mode;
/*#if defined(PRE_SCD_THREAD)
extern const int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
#if defined(PRE_SCD_THREAD)
extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
extern uint8_t dlsch_ue_select_tbl_in_use;
extern uint8_t new_dlsch_ue_select_tbl_in_use;
@@ -69,4 +75,5 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
#endif*/
#endif //DEF_H
+66 -12
View File
@@ -31,11 +31,9 @@
*/
//#include "mac_defs.h"
#include "mac_proto.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC-CellGroupConfig.h"
#include "../NR_MAC_gNB/nr_mac_common.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "SCHED_NR/phy_frame_config_nr.h"
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
@@ -151,8 +149,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommon_t *scc = mac->scc;
int i;
mac->phy_config.Mod_id = module_id;
mac->phy_config.CC_id = cc_idP;
mac->phy_config.Mod_id = module_id;
mac->phy_config.CC_id = cc_idP;
// carrier config
@@ -203,12 +201,20 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
}
}
lte_frame_type_t frame_type;
uint16_t band;
int32_t offset;
get_band((cfg->carrier_config.dl_frequency)*1000,
&band,
&offset,
&frame_type);
// cell config
cfg->cell_config.phy_cell_id = *scc->physCellId;
cfg->cell_config.frame_duplex_type = 1;
cfg->cell_config.frame_duplex_type = frame_type;
// SSB config
cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
@@ -270,6 +276,53 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
LOG_I(PHY,"TDD has been properly configurated\n");
}
// PRACH configuration
uint8_t nb_preambles = 64;
if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
cfg->prach_config.prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
cfg->prach_config.prach_sub_c_spacing = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
cfg->prach_config.prach_sub_c_spacing = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
cfg->prach_config.restricted_set_config = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
case 0 :
cfg->prach_config.num_prach_fd_occasions = 1;
break;
case 1 :
cfg->prach_config.num_prach_fd_occasions = 2;
break;
case 2 :
cfg->prach_config.num_prach_fd_occasions = 4;
break;
case 3 :
cfg->prach_config.num_prach_fd_occasions = 8;
break;
default:
AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
}
cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
for (i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) {
cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
if (cfg->prach_config.prach_sequence_length)
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
else
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type);
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
}
cfg->prach_config.ssb_per_rach = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
}
@@ -297,10 +350,11 @@ int nr_rrc_mac_config_req_ue(
if(spCell_ConfigP != NULL ){
mac->servCellIndex = *spCell_ConfigP->servCellIndex;
if (spCell_ConfigP->reconfigurationWithSync) {
mac->scc = spCell_ConfigP->reconfigurationWithSync->spCellConfigCommon;
config_common_ue(mac,module_id,cc_idP);
mac->crnti = spCell_ConfigP->reconfigurationWithSync->newUE_Identity;
LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
mac->rach_ConfigDedicated = spCell_ConfigP->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
mac->scc = spCell_ConfigP->reconfigurationWithSync->spCellConfigCommon;
config_common_ue(mac,module_id,cc_idP);
mac->crnti = spCell_ConfigP->reconfigurationWithSync->newUE_Identity;
LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
}
mac->scd = spCell_ConfigP->spCellConfigDedicated;
+93 -17
View File
@@ -37,6 +37,21 @@
#include <stdlib.h>
#include <string.h>
#include "platform_types.h"
/* PHY */
#include "PHY/defs_nr_common.h"
/* IF */
#include "NR_IF_Module.h"
#include "fapi_nr_ue_interface.h"
/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "LAYER2/MAC/mac.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
/* RRC */
#include "NR_DRX-Config.h"
#include "NR_SchedulingRequestConfig.h"
#include "NR_BSR-Config.h"
@@ -48,11 +63,7 @@
#include "NR_PhysicalCellGroupConfig.h"
#include "NR_SpCellConfig.h"
#include "NR_ServingCellConfig.h"
#include "fapi_nr_ue_interface.h"
#include "NR_IF_Module.h"
#include "../NR_MAC_gNB/nr_mac_common.h"
#include "PHY/defs_nr_common.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
#define NB_NR_UE_MAC_INST 1
/*!\brief Maximum number of logical channl group IDs */
@@ -61,6 +72,7 @@
/*!\brief value for indicating BSR Timer is not running */
#define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
typedef enum {
SFN_C_MOD_2_EQ_0,
SFN_C_MOD_2_EQ_1,
@@ -133,24 +145,27 @@ typedef struct {
#define MAX_NUM_BWP 2
typedef enum {
RA_IDLE=0,
WAIT_RAR=1,
WAIT_CONTENTION_RESOLUTION=2
RA_UE_IDLE = 0,
WAIT_RAR = 1,
WAIT_CONTENTION_RESOLUTION = 2,
RA_SUCCEEDED = 3
} RA_state_t;
/*!\brief Top level UE MAC structure */
typedef struct {
NR_ServingCellConfigCommon_t *scc;
NR_ServingCellConfig_t *scd;
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated;
int servCellIndex;
//// MAC config
NR_DRX_Config_t *drx_Config;
NR_DRX_Config_t *drx_Config;
NR_SchedulingRequestConfig_t *schedulingRequestConfig;
NR_BSR_Config_t *bsr_Config;
NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI;
NR_MIB_t *mib;
NR_BSR_Config_t *bsr_Config;
NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI;
NR_MIB_t *mib;
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
@@ -163,14 +178,75 @@ typedef struct {
SFN_C_TYPE type0_pdcch_ss_sfn_c;
uint32_t type0_pdcch_ss_n_c;
uint32_t type0_pdcch_consecutive_slots;
int rnti_type;
/* PDUs */
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
ULSCH_PDU ulsch_pdu;
/* Random Access parameters */
/// state of RA procedure
RA_state_t ra_state;
/// RA-rnti
/// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
uint8_t RA_offset;
/// RA-rnti
uint16_t ra_rnti;
/// Temporary CRNTI
/// Temporary CRNTI
uint16_t t_crnti;
/// CRNTI
/// CRNTI
uint16_t crnti;
/// number of attempt for rach
uint8_t RA_attempt_number;
/// Random-access procedure flag
uint8_t RA_active;
/// Random-access window counter
int8_t RA_window_cnt;
/// Random-access Msg3 size in bytes
uint8_t RA_Msg3_size;
/// Random-access prachMaskIndex
uint8_t RA_prachMaskIndex;
/// Flag indicating Preamble set (A,B) used for first Msg3 transmission
uint8_t RA_usedGroupA;
/// BeamfailurerecoveryConfig
NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig;
/// Preamble Tx Counter
uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
/// Preamble Power Ramping Counter
uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER;
/// Random-access backoff counter
int16_t RA_backoff_indicator;
/// Random-access backoff counter
int16_t RA_backoff_cnt;
/// Random-access variable for window calculation (frame of last change in window counter)
uint32_t RA_tx_frame;
/// Random-access variable for window calculation (subframe of last change in window counter)
uint8_t RA_tx_subframe;
/// Scheduled RX frame for RA Msg2
uint16_t msg2_rx_frame;
/// Scheduled RX slot for RA Msg2
uint16_t msg2_rx_slot;
/// Random-access Group B maximum path-loss
/// Random-access variable for backoff (frame of last change in backoff counter)
uint32_t RA_backoff_frame;
/// Random-access variable for backoff (subframe of last change in backoff counter)
uint8_t RA_backoff_subframe;
/// Random-access Group B maximum path-loss
uint16_t RA_maxPL;
/// Random-access Contention Resolution Timer active flag
uint8_t RA_contention_resolution_timer_active;
/// Random-access Contention Resolution Timer count value
uint8_t RA_contention_resolution_cnt;
/// Msg3 Delta Preamble
int8_t deltaPreamble_Msg3;
/// Received TPC command (in dB) from RAR
int8_t Msg3_TPC;
/// Flag to monitor if matching RAPID was received in RAR
uint8_t RA_RAPID_found;
/// Flag to monitor if BI was received in RAR
uint8_t RA_BI_found;
/// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot
uint8_t generate_nr_prach;
//// FAPI-like interface message
fapi_nr_tx_request_t tx_request;
+108 -20
View File
@@ -84,23 +84,9 @@ NR_UE_MAC_INST_t *get_mac_inst(
/**\brief called at each slot, slot length based on numerology. now use u=0, scs=15kHz, slot=1ms
performs BSR/SR/PHR procedures, random access procedure handler and DLSCH/ULSCH procedures.
\param module_id module id
\param gNB_index corresponding gNB index
\param cc_id component carrier id
\param rx_frame receive frame number
\param rx_slot receive slot number
\param tx_frame transmit frame number
\param tx_slot transmit slot number*/
NR_UE_L2_STATE_t nr_ue_scheduler(
const module_id_t module_id,
const uint8_t gNB_index,
const int cc_id,
const frame_t rx_frame,
const slot_t rx_slot,
const int32_t ssb_index,
const frame_t tx_frame,
const slot_t tx_slot);
\param dl_info DL indication
\param ul_info UL indication*/
NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info);
/* \brief Get SR payload (0,1) from UE MAC
@param Mod_id Instance id of UE in machine
@@ -124,8 +110,6 @@ uint32_t get_ssb_slot(uint32_t ssb_index);
uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
/* \brief Get payload (MAC PDU) from UE PHY
@param module_idP Instance id of UE in machine
@param CC_id Component Carrier index
@@ -154,9 +138,23 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
uint8_t gNB_index,
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
uint8_t *pdu,
uint8_t num_sdus,
uint16_t *sdu_lengths,
uint8_t *sdu_lcids,
uint8_t power_headroom,
uint16_t crnti,
uint16_t truncated_bsr,
uint16_t short_bsr,
uint16_t long_bsr,
unsigned short post_padding,
uint16_t buflen);
int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len);
void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot);
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot);
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int dci_format,
@@ -175,5 +173,95 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
int nrofDownlinkSlots, int nrofDownlinkSymbols,
int nrofUplinkSlots, int nrofUplinkSymbols);
/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE
@returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
*/
int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t module_idP, uint8_t CC_id);
/** \brief Function to compute DELTA_PREAMBLE from 38.321 subclause 7.3
(for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE
@returns DELTA_PREAMBLE
*/
int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format);
/* Random Access */
/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x
and fills the PRACH PDU per each FD occasion.
@param module_idP Index of UE instance
@param frameP Frame index
@param slotP Slot index
@returns void
*/
void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance
@param CC_id Index to a component carrier
@param frame Frame index
@param ra_rnti RA_RNTI value
@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU
@param t_crnti Pointer to PHY variable containing the T_CRNTI
@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
random-access procedure
@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload
@returns timing advance or 0xffff if preamble doesn't match
*/
uint16_t nr_ue_process_rar(module_id_t mod_id,
int CC_id,
frame_t frameP,
uint8_t * dlsch_buffer,
rnti_t * t_crnti,
uint8_t preamble_index,
uint8_t * selected_rar_buffer);
void nr_process_rar(nr_downlink_indication_t *dl_info);
void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame);
void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
void nr_ra_succeeded(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
@param mod_id Index of UE instance
@param CC_id Component Carrier Index
@param frame
@param gNB_id gNB index
@param nr_tti_tx slot for PRACH transmission
@returns indication to generate PRACH to phy */
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_tti_tx);
/* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321).
@param module_idP Index of UE instance
@param CC_id Component Carrier Index
@param gNB_index gNB index
@param t_id
@param rach_ConfigDedicated
@returns void */
void nr_get_prach_resources(module_id_t mod_id,
int CC_id,
uint8_t gNB_id,
uint8_t t_id,
uint8_t first_Msg3,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
#endif
/** @}*/
+153
View File
@@ -0,0 +1,153 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nr_l1_helper.c
* \brief PHY helper functions for PRACH adapted to NR
* \author Guido Casati
* \date 2019
* \version 2.0
* \email guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
#include "PHY/defs_nr_common.h"
#include "mac_defs.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */
int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
int prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1;
uint8_t prachConfigIndex, mu;
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
// SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211
switch (scs){
case NR_SubcarrierSpacing_kHz15:
mu = 0;
break;
case NR_SubcarrierSpacing_kHz30:
mu = 1;
break;
case NR_SubcarrierSpacing_kHz60:
mu = 2;
break;
case NR_SubcarrierSpacing_kHz120:
mu = 3;
break;
case NR_SubcarrierSpacing_kHz240:
mu = 4;
break;
case NR_SubcarrierSpacing_spare3:
mu = 5;
break;
case NR_SubcarrierSpacing_spare2:
mu = 6;
break;
case NR_SubcarrierSpacing_spare1:
mu = 7;
break;
default:
AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %lu\n", scs);
}
// Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211
prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
if (prach_sequence_length == 0) {
switch (prach_format) {
AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format);
// long preamble formats
case 0:
case 3:
return 0;
case 1:
return -3;
case 2:
return -6;
}
} else {
switch (prach_format) { // short preamble formats
case 0:
case 3:
return 8 + 3*mu;
case 1:
case 4:
case 8:
return 5 + 3*mu;
case 2:
case 5:
return 3 + 3*mu;
case 6:
return 3*mu;
case 7:
return 5 + 3*mu;
default:
AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex);
}
}
return 0;
}
/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */
int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
int8_t receivedTargerPower, delta_preamble;
long preambleReceivedTargetPower;
AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id);
preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format);
receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (mac->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
return receivedTargerPower;
}
@@ -0,0 +1,643 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ra_procedures.c
* \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
* \author R. Knopp, Navid Nikaein, Guido Casati
* \date 2019
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
#include "mac.h"
/*
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
#include "SCHED_UE/sched_UE.h"
#include "COMMON/mac_rrc_primitives.h"
#include "RRC/LTE/rrc_extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "common/utils/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
/* Tools */
#include "SIMULATION/TOOLS/sim.h" // for taus
/* RRC */
#include "NR_RACH-ConfigCommon.h"
/* PHY */
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/defs_common.h"
#include "PHY/defs_nr_common.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern const uint16_t nr_slots_per_frame[5];
//extern uint8_t nfapi_mode;
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
// WIP
// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
void nr_get_prach_resources(module_id_t mod_id,
int CC_id,
uint8_t gNB_id,
uint8_t t_id,
uint8_t first_Msg3,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric;
// NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0;
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size;
AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric;
// NR_RSRP_Range_t rsrp_ThresholdSSB; // todo
///////////////////////////////////////////////////////////
//////////* UE Random Access Resource Selection *//////////
///////////////////////////////////////////////////////////
// todo:
// - switch initialisation cases
// -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
// --- SSB selection, set prach_resources->ra_PreambleIndex
// -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
// --- set PREAMBLE_INDEX to ra_preamble_index
// --- select the SSB signalled by PDCCH
// -- RA initiated for SI request:
// --- SSB selection, set prach_resources->ra_PreambleIndex
if (rach_ConfigDedicated) {
//////////* Contention free RA *//////////
// - the PRACH preamble for the UE to transmit is set through RRC configuration
// - this is the default mode in current implementation!
// Operation for contention-free RA resources when:
// - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
// - available CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
// - network controlled Mobility
uint8_t cfra_ssb_resource_idx = 0;
prach_resources->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex;
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-free random access procedure... \n", prach_resources->ra_PreambleIndex);
} else {
//////////* Contention-based RA preamble selection *//////////
// todo:
// - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
// - todo determine next available PRACH occasion
// rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
Msg3_size = mac->RA_Msg3_size;
numberOfRA_Preambles = 64;
if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
if (!nr_rach_ConfigCommon->groupBconfigured) {
noGroupB = 1;
} else {
// RA preambles group B is configured
// - Defining the number of RA preambles in RA Preamble Group A for each SSB */
sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
/* - Threshold to determine the groups of RA preambles */
case 0:
messageSizeGroupA = 56;
break;
case 1:
messageSizeGroupA = 144;
break;
case 2:
messageSizeGroupA = 208;
break;
case 3:
messageSizeGroupA = 256;
break;
case 4:
messageSizeGroupA = 282;
break;
case 5:
messageSizeGroupA = 480;
break;
case 6:
messageSizeGroupA = 640;
break;
case 7:
messageSizeGroupA = 800;
break;
case 8:
messageSizeGroupA = 1000;
break;
case 9:
messageSizeGroupA = 72;
break;
default:
AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
/* todo cases 10 -15*/
}
/* Power offset for preamble selection in dB */
messagePowerOffsetGroupB = -9999;
switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
case 0:
messagePowerOffsetGroupB = -9999;
break;
case 1:
messagePowerOffsetGroupB = 0;
break;
case 2:
messagePowerOffsetGroupB = 5;
break;
case 3:
messagePowerOffsetGroupB = 8;
break;
case 4:
messagePowerOffsetGroupB = 10;
break;
case 5:
messagePowerOffsetGroupB = 12;
break;
case 6:
messagePowerOffsetGroupB = 15;
break;
case 7:
messagePowerOffsetGroupB = 18;
break;
default:
AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
}
// todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
mac->deltaPreamble_Msg3 = 0;
deltaPreamble_Msg3 = mac->deltaPreamble_Msg3;
}
PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
/* Msg3 has not been transmitted yet */
if (first_Msg3 == 1) {
if (noGroupB == 1) {
// use Group A preamble
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
mac->RA_usedGroupA = 1;
} else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) {
// Group B is configured and RA preamble Group A is used
// - todo add condition on CCCH_sdu_size for initiation by CCCH
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
mac->RA_usedGroupA = 1;
} else {
// Group B preamble is configured and used
// the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
// the remaining belong to RA Preambles Group B
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
mac->RA_usedGroupA = 0;
}
} else { // Msg3 is being retransmitted
if (mac->RA_usedGroupA == 1 && noGroupB == 1) {
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
} else if (mac->RA_usedGroupA == 1 && noGroupB == 0){
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
} else {
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
}
}
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
}
// todo determine next available PRACH occasion
// - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
// - else if SSB is selected above
// - else if CSI-RS is selected above
/////////////////////////////////////////////////////////////////////////////
//////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
/////////////////////////////////////////////////////////////////////////////
// todo:
// - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
// - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
// - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded)
if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
mac->RA_PREAMBLE_POWER_RAMPING_COUNTER++;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
// 1) this does not apply to contention-free RA Preamble for beam failure recovery request
// 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex;
// ra_RNTI computation
// - todo: this is for TDD FR1 only
// - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
// - f_id: index of the PRACH occasion in the frequency domain
// - s_id is starting symbol of the PRACH occasion [0...14]
// - t_id is the first slot of the PRACH occasion in a system frame [0...80]
ul_carrier_id = 0; // NUL
f_id = rach_ConfigGeneric->msg1_FrequencyStart;
SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
// Pick the first slot of the PRACH occasion in a system frame
for (i = 0; i < 10; i++){
if (((SFN_nbr & (1 << i)) >> i) == 1){
t_id = 2*i;
break;
}
}
prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
mac->ra_rnti = prach_resources->ra_RNTI;
LOG_D(MAC, "Computed ra_RNTI is %x \n", prach_resources->ra_RNTI);
}
// TbD: RA_attempt_number not used
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
mac->ra_state = WAIT_RAR;
// Start contention resolution timer
mac->RA_attempt_number++;
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
// start contention resolution timer
mac->RA_contention_resolution_cnt = 0;
mac->RA_contention_resolution_timer_active = 1;
}
/////////////////////////////////////////////////////////////////////////
///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
/////////////////////////////////////////////////////////////////////////
/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
/// Only one RA procedure is ongoing at any point in time in a MAC entity
/// the RA procedure on a SCell shall only be initiated by PDCCH order
/// in the current implementation, RA is contention free only
// WIP
// todo TS 38.321:
// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX
// - BWP operation (subclause 5.15 TS 38.321)
// - handle initialization by beam failure recovery
// - handle initialization by handover
// - handle transmission on DCCH using PRACH (during handover, or sending SR for example)
// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader)
// - fix rrc data req logic
// - retrieve TBS
// - add mac_rrc_nr_data_req_ue, etc ...
// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_tti_tx){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload;
//uint8_t ra_ResponseWindow;
uint16_t size_sdu = 0;
unsigned short post_padding;
//fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
//NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = mac->rach_ConfigDedicated;
// int32_t frame_diff = 0;
uint8_t sdu_lcids[NB_RB_MAX] = {0};
uint16_t sdu_lengths[NB_RB_MAX] = {0};
int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax, mac_ce_len;
AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
if (UE_mode == PRACH && prach_resources->init_msg1) {
LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active);
AssertFatal(setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
if (mac->RA_active == 0) {
/* RA not active - checking if RRC is ready to initiate the RA procedure */
LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n");
mac->RA_RAPID_found = 0;
/* Set RA_PREAMBLE_POWER_RAMPING_STEP */
switch (rach_ConfigGeneric->powerRampingStep){ // in dB
case 0:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
break;
case 1:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
break;
case 2:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
break;
case 3:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
break;
}
prach_resources->RA_PREAMBLE_BACKOFF = 0;
prach_resources->RA_SCALING_FACTOR_BI = 1;
prach_resources->RA_PCMAX = 0; // currently hardcoded to 0
payload = (uint8_t*) &mac->CCCH_pdu.payload;
mac_ce_len = 0;
num_sdus = 1;
post_padding = 1;
if (0){
// initialisation by RRC
// CCCH PDU
// size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id,
// CC_id,
// frame,
// CCCH,
// 1,
// mac_sdus,
// gNB_id,
// 0);
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
} else {
// fill ulsch_buffer with random data
for (int i = 0; i < TBS_bytes; i++){
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
}
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
sdu_lcids[0] = lcid;
sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
header_length_total += 2 + (sdu_lengths[0] >= 128);
size_sdu += sdu_lengths[0];
}
//mac->RA_tx_frame = frame;
//mac->RA_tx_subframe = nr_tti_tx;
//mac->RA_backoff_frame = frame;
//mac->RA_backoff_subframe = nr_tti_tx;
if (size_sdu > 0) {
LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame);
mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
mac->RA_prachMaskIndex = 0;
// todo: add the backoff condition here
mac->RA_backoff_cnt = 0;
mac->RA_active = 1;
prach_resources->Msg3 = payload;
nr_get_RA_window(mac);
// Fill in preamble and PRACH resources
if (mac->generate_nr_prach)
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated);
offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
(uint8_t *) payload, // UL MAC pdu pointer
num_sdus, // num sdus
sdu_lengths, // sdu length
sdu_lcids, // sdu lcid
0, // power headroom
0, // crnti
0, // truncated bsr
0, // short bsr
0, // long_bsr
post_padding,
0);
// Padding: fill remainder with 0
if (post_padding > 0){
for (int j = 0; j < (TBS_bytes - offset); j++)
payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
}
}
} else { // RACH is active
////////////////////////////////////////////////////////////////
/////* Random Access Response reception (5.1.4 TS 38.321) */////
////////////////////////////////////////////////////////////////
// Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
// and RA_backoff_cnt
// todo:
// - handle beam failure recovery request
// - handle DL assignment on PDCCH for RA-RNTI
// - handle backoff and raResponseWindow params
// - disabled contention resolution as OAI NSA is contention-free based
// LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
// mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe);
if (mac->RA_BI_found){
prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator;
} else {
prach_resources->RA_PREAMBLE_BACKOFF = 0;
}
if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
// mac->ra_state = WAIT_CONTENTION_RESOLUTION;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR successfully received \n", mod_id, frame, nr_tti_tx);
} else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception failed \n", mod_id, frame, nr_tti_tx);
mac->ra_state = RA_UE_IDLE;
mac->RA_PREAMBLE_TRANSMISSION_COUNTER++;
preambleTransMax = -1;
switch (rach_ConfigGeneric->preambleTransMax) {
case 0:
preambleTransMax = 3;
break;
case 1:
preambleTransMax = 4;
break;
case 2:
preambleTransMax = 5;
break;
case 3:
preambleTransMax = 6;
break;
case 4:
preambleTransMax = 7;
break;
case 5:
preambleTransMax = 8;
break;
case 6:
preambleTransMax = 10;
break;
case 7:
preambleTransMax = 20;
break;
case 8:
preambleTransMax = 50;
break;
case 9:
preambleTransMax = 100;
break;
case 10:
preambleTransMax = 200;
break;
}
// Resetting RA window
nr_get_RA_window(mac);
if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
mac->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1; // 2 dB increment
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
}
// compute backoff parameters
// if (mac->RA_backoff_cnt > 0){
// frame_diff = (sframe_t) frame - mac->RA_backoff_frame;
// if (frame_diff < 0) frame_diff = -frame_diff;
// mac->RA_backoff_frame = frame;
// mac->RA_backoff_subframe = nr_tti_tx;
// }
// compute RA window parameters
// if (mac->RA_window_cnt > 0){
// frame_diff = (frame_t) frame - mac->RA_tx_frame;
// if (frame_diff < 0) frame_diff = -frame_diff;
// mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->RA_tx_subframe));
// LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, mac->RA_window_cnt);
// }
// mac->RA_tx_frame = frame;
// mac->RA_tx_subframe = nr_tti_tx;
// Fill in preamble and PRACH resources
if (mac->generate_nr_prach)
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
} else {
mac->RA_window_cnt--;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n",
mod_id,
frame,
nr_tti_tx,
mac->RA_window_cnt);
// Fill in preamble and PRACH resources
if (mac->generate_nr_prach)
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
}
}
} else if (UE_mode == PUSCH) {
LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id);
AssertFatal(1 == 0, "");
}
return mac->generate_nr_prach;
}
void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
uint8_t mu, ra_ResponseWindow;
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
if (setup->msg1_SubcarrierSpacing)
mu = *setup->msg1_SubcarrierSpacing;
else
mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
mac->RA_window_cnt = mac->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
switch (ra_ResponseWindow) {
case 0:
mac->RA_window_cnt += 1;
break;
case 1:
mac->RA_window_cnt += 2;
break;
case 2:
mac->RA_window_cnt += 4;
break;
case 3:
mac->RA_window_cnt += 8;
break;
case 4:
mac->RA_window_cnt += 10;
break;
case 5:
mac->RA_window_cnt += 20;
break;
case 6:
mac->RA_window_cnt += 40;
break;
case 7:
mac->RA_window_cnt += 80;
break;
}
}
@@ -21,11 +21,11 @@
/* \file nr_ue_dci_configuration.c
* \brief functions for generating dci search procedures based on RRC Serving Cell Group Configuration
* \author R. Knopp
* \author R. Knopp, G. Casati
* \date 2020
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \version 0.2
* \company Eurecom, Fraunhofer IIS
* \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
@@ -35,6 +35,8 @@
#include "assertions.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "mac_defs.h"
#include "common/utils/nr/nr_common.h"
#include "executables/softmodem-common.h"
#include <stdio.h>
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
@@ -59,125 +61,218 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd
}
void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot) {
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) {
// check if DL slot
if (is_nr_DL_slot(mac->scc,slot)==1) {
NR_ServingCellConfig_t *scd = mac->scd;
NR_BWP_Downlink_t *bwp;
NR_BWP_DownlinkCommon_t *bwp_Common;
NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated;
NR_SetupRelease_PDCCH_Config_t *pdcch_Config;
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon;
struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList;
struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList;
struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList;
NR_SearchSpace_t *NR_SearchSpace;
NR_ControlResourceSet_t *coreset;
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
uint8_t bwp_id = 1;
int ss_id, sps;
// get PDCCH configuration(s) (Coreset, SearchSpace, etc...) from BWP Dedicated in serving cell config dedicated (scd)
// get BWP 1, Coreset ID 0, SearchSpace ID 0 (i.e. configured in MIB and in ServingCellConfigCommon)
// Check dedicated DL BWP
if (mac->DLbwp[0] == NULL) {
NR_SearchSpace_t *ss;
int ss_id = 0;
AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n");
AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
dl_bwp_Dedicated = mac->DLbwp[0]->bwp_Dedicated;
AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n");
bwp_Common = mac->DLbwp[0]->bwp_Common;
AssertFatal(bwp_Common != NULL, "bwp_Common is null\n");
pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n");
pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n");
AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n");
controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList;
AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n");
AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count);
mac->coreset[0][0] = controlResourceSetToAddModList->list.array[0];
coreset = mac->coreset[0][0];
AssertFatal(coreset != NULL, "coreset[0][0] is null\n");
// get BWP 1, Coreset 0, SearchSpace 0
if (mac->DLbwp[0]==NULL) {
AssertFatal(mac->scd->downlinkBWP_ToAddModList!=NULL,"downlinkBWP_ToAddModList is null\n");
AssertFatal(mac->scd->downlinkBWP_ToAddModList->list.count==1,"downlinkBWP_ToAddModList->list->count is %d\n",
mac->scd->downlinkBWP_ToAddModList->list.count);
mac->DLbwp[0] = mac->scd->downlinkBWP_ToAddModList->list.array[0];
AssertFatal(mac->DLbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n");
AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config!=NULL,"pdcch_Config is null\n");
AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL,"controlResourceSetToAddModList is null\n");
AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count==1,"controlResourceSetToAddModList->list.count=%d\n",
mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count);
mac->coreset[0][0] = mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0];
AssertFatal(mac->coreset[0][0]!=NULL,"coreset[0][0] is null\n");
AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
NR_SearchSpace_t *ss;
int ss_id=0;
AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count<FAPI_NR_MAX_SS_PER_CORESET,
"too many searchpaces per coreset %d\n",
mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count);
for (int i=0;i<mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
ss=mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
AssertFatal(*ss->controlResourceSetId == mac->coreset[0][0]->controlResourceSetId,"ss->controlResourceSetId is unknown\n");
mac->SSpace[0][0][ss_id] = ss;
ss_id++;
}
}
if (mac->ULbwp[0]==NULL) {
AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList!=NULL,"uplinkBWP_ToAddModList is null\n");
AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count==1,"uplinkBWP_ToAddModList->list->count is %d\n",
mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count);
mac->ULbwp[0] = mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
AssertFatal(mac->ULbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n");
}
// check search spaces
int ss_id=0;
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
int sps =mac->DLbwp[0]->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
while(mac->SSpace[0][0][ss_id]!=NULL &&
ss_id < mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count) {
AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n");
AssertFatal(searchSpacesToAddModList->list.count > 0, "searchSpacesToAddModList is empty\n");
AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count);
for (int i = 0; i < searchSpacesToAddModList->list.count; i++) {
ss = searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
mac->SSpace[0][0][ss_id] = ss;
ss_id++;
}
if (mac->ra_state == WAIT_RAR) {
// check for RAR
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot);
dl_config->number_pdus = dl_config->number_pdus + 1;
}
// Check dedicated UL BWP
if (mac->ULbwp[0] == NULL) {
uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList;
AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n");
AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count);
mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[bwp_id - 1];
AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n");
}
bwp = mac->DLbwp[0];
bwp_Common = bwp->bwp_Common;
pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
dl_bwp_Dedicated = bwp->bwp_Dedicated;
pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
// check USSs
ss_id = 0;
NR_SearchSpace = mac->SSpace[0][0][ss_id];
while(NR_SearchSpace != NULL && ss_id < searchSpacesToAddModList->list.count) {
AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n");
AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n");
ss_id++;
}
if (mac->crnti > 0) {
NR_SearchSpace_t *css;
NR_SearchSpace_t *uss = NULL;
NR_ServingCellConfigCommon_t *scc;
NR_SearchSpaceId_t ra_SearchSpaceId;
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
uint16_t monitoringSymbolsWithinSlot;
uint8_t add_dci = 1;
AssertFatal(mac->scc != NULL, "scc is null\n");
scc = mac->scc;
rel15->dci_format = NR_DL_DCI_FORMAT_1_0;
// CoReSet configuration
coreset = mac->coreset[0][0];
rel15->coreset.duration = coreset->duration;
for (int i = 0; i < 6; i++)
rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i];
rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) {
struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved;
rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize);
rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize);
AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n");
rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId;
} else {
rel15->coreset.RegBundleSize = 0;
rel15->coreset.InterleaverSize = 0;
rel15->coreset.ShiftIndex = 0;
}
else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) {
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
rel15->coreset.CoreSetType = 1;
rel15->coreset.precoder_granularity = coreset->precoderGranularity;
if (mac->ra_state == WAIT_RAR){
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n");
ra_SearchSpaceId = *pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
// fetch the CSS for RA from the CSS list
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
css = commonSearchSpaceList->list.array[i];
if(css->searchSpaceId == ra_SearchSpaceId)
break;
}
// check CSSs
if(css != NULL) {
AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
}
if (frame == mac->msg2_rx_frame && slot == mac->msg2_rx_slot){
sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
rel15->rnti = mac->ra_rnti;
rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_RA, rel15->BWPSize);
for (int i = 0; i < sps; i++)
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
rel15->coreset.StartSymbolIndex = i;
break;
}
fill_dci_search_candidates(css, rel15);
} else {
add_dci = 0;
}
} else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION){
rel15->rnti = mac->t_crnti;
dl_config->number_pdus = dl_config->number_pdus + 1;
}
if (mac->crnti>0) {
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
} else {
rel15->rnti = mac->crnti;
rel15->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
rel15->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
rel15->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275);
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275);
rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_C, rel15->BWPSize);
// get UE-specific search space
for (ss_id=0;ss_id<FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id]!=NULL;ss_id++)
if (mac->SSpace[0][0][ss_id]->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break;
AssertFatal(ss_id<FAPI_NR_MAX_SS_PER_CORESET,"couldn't find a UE-specific SS\n");
// for SPS=14 8 MSBs in positions 13 downto 6,
uint16_t monitoringSymbolsWithinSlot = (mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
for (int i=0; i<sps; i++)
if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
rel15->coreset.StartSymbolIndex=i;
break;
}
rel15->coreset.duration = mac->coreset[0][0]->duration;
for (int i=0;i<6;i++)
rel15->coreset.frequency_domain_resource[i] = mac->coreset[0][0]->frequencyDomainResources.buf[i];
rel15->coreset.CceRegMappingType = mac->coreset[0][0]->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) {
rel15->coreset.RegBundleSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
rel15->coreset.InterleaverSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize);
AssertFatal(mac->scc->physCellId != NULL,"mac->scc->physCellId is null\n");
rel15->coreset.ShiftIndex = mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex : *mac->scc->physCellId;
for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id] != NULL; ss_id++){
uss = mac->SSpace[0][0][ss_id];
if (uss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break;
}
else {
rel15->coreset.RegBundleSize = 0;
rel15->coreset.InterleaverSize = 0;
rel15->coreset.ShiftIndex = 0;
}
rel15->coreset.CoreSetType = 1;
rel15->coreset.precoder_granularity = mac->coreset[0][0]->precoderGranularity;
if (mac->coreset[0][0]->pdcch_DMRS_ScramblingID)
rel15->coreset.pdcch_dmrs_scrambling_id = *mac->coreset[0][0]->pdcch_DMRS_ScramblingID;
AssertFatal(ss_id < FAPI_NR_MAX_SS_PER_CORESET, "couldn't find a UE-specific SS\n");
sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
// for SPS=14 8 MSBs in positions 13 down to 6
monitoringSymbolsWithinSlot = (uss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (uss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
for (int i = 0; i < sps; i++)
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
rel15->coreset.StartSymbolIndex = i;
break;
}
fill_dci_search_candidates(uss, rel15);
}
// Scrambling RNTI
if (coreset->pdcch_DMRS_ScramblingID) {
rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID;
rel15->coreset.scrambling_rnti = mac->t_crnti;
} else {
rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId;
if(mac->ra_state == WAIT_RAR)
rel15->coreset.scrambling_rnti = 0;
else
rel15->coreset.pdcch_dmrs_scrambling_id = *mac->scc->physCellId;
fill_dci_search_candidates(mac->SSpace[0][0][ss_id],rel15);
rel15->dci_format = NR_DL_DCI_FORMAT_1_0;
rel15->dci_length = nr_dci_size(rel15->dci_format,NR_RNTI_C,rel15->BWPSize);
rel15->coreset.scrambling_rnti = rel15->rnti;
}
if (add_dci){
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
dl_config->number_pdus = dl_config->number_pdus + 1;
}
}
}
+696 -162
View File
@@ -31,28 +31,38 @@
*/
/* MAC related headers */
#include "mac_proto.h"
#include <stdio.h>
#include <math.h>
/* exe */
#include "executables/nr-softmodem.h"
/* RRC*/
#include "RRC/NR_UE/rrc_proto.h"
#include "NR_RACH-ConfigCommon.h"
#include "NR_RACH-ConfigGeneric.h"
#include "NR_FrequencyInfoDL.h"
#include "NR_PDCCH-ConfigCommon.h"
/* MAC */
#include "mac_defs.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC_UE/mac_extern.h"
#include "common/utils/nr/nr_common.h"
//#include "LAYER2/MAC/mac_vars.h" // TODO Note that mac_vars.h is not NR specific and this should be updated
// also, the use of the same should be updated in nr-softmodem and nr-uesoftmodem
/* PHY UE related headers*/
/* PHY UE */
#include "SCHED_NR_UE/defs.h"
#include "RRC/NR_UE/rrc_proto.h"
#include "assertions.h"
#include "PHY/defs_nr_UE.h"
/*Openair Packet Tracer */
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "executables/softmodem-common.h"
/* log utils */
/* utils */
#include "assertions.h"
#include "common/utils/LOG/log.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
@@ -60,11 +70,12 @@
#include <stdio.h>
#include <math.h>
//int mbms_rab_id = 2047;
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
#define DEBUG_EXTRACT_DCI 1
extern const uint16_t nr_slots_per_frame[5];
extern void mac_rlc_data_ind (
const module_id_t module_idP,
const rnti_t rntiP,
@@ -641,100 +652,482 @@ uint32_t get_ssb_frame(uint32_t test){
// 1. TODO: Call RRC for link status return to PHY
// 2. TODO: Perform SR/BSR procedures for scheduling feedback
// 3. TODO: Perform PHR procedures
NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id,
const uint8_t gNB_index,
const int cc_id,
const frame_t rx_frame,
const slot_t rx_slot,
const int32_t ssb_index,
const frame_t tx_frame,
const slot_t tx_slot ){
NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info){
uint32_t search_space_mask = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
// check type0 from 38.213 13 if we have no CellGroupConfig
if ( mac->scd == NULL) {
if( ssb_index != -1){
if(mac->type0_pdcch_ss_mux_pattern == 1){
// 38.213 chapter 13
if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
if (dl_info){
module_id_t mod_id = dl_info->module_id;
uint32_t gNB_index = dl_info->gNB_index;
int cc_id = dl_info->cc_id;
frame_t rx_frame = dl_info->frame;
slot_t rx_slot = dl_info->slot;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
nr_scheduled_response_t scheduled_response;
nr_dcireq_t dcireq;
// check type0 from 38.213 13 if we have no CellGroupConfig
// TODO: implementation to be completed
if (mac->scd == NULL) {
if(dl_info->ssb_index != -1){
if(mac->type0_pdcch_ss_mux_pattern == 1){
// 38.213 chapter 13
if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
}
if(mac->type0_pdcch_ss_mux_pattern == 2){
// 38.213 Table 13-13, 13-14
if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
}
if(mac->type0_pdcch_ss_mux_pattern == 3){
// 38.213 Table 13-15
if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
}
} // ssb_index != -1
// Type0 PDCCH search space
if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1;
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config;
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
/*
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set
LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n",
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti,
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP);
*/
dl_config->number_pdus = dl_config->number_pdus + 1;
mac->scheduled_response.dl_config = dl_config;
}
if(mac->type0_pdcch_ss_mux_pattern == 2){
// 38.213 Table 13-13, 13-14
if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
} else { // we have an scd
dcireq.module_id = mod_id;
dcireq.gNB_index = gNB_index;
dcireq.cc_id = cc_id;
dcireq.frame = rx_frame;
dcireq.slot = rx_slot;
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
// we should have received a DL DCI here, so configure DL accordingly
scheduled_response.dl_config = &dcireq.dl_config_req;
scheduled_response.ul_config = NULL;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = mod_id;
scheduled_response.CC_id = cc_id;
scheduled_response.frame = rx_frame;
scheduled_response.slot = rx_slot;
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
if(mac->type0_pdcch_ss_mux_pattern == 3){
// 38.213 Table 13-15
if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
search_space_mask = search_space_mask | type0_pdcch;
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
}
}
} // ssb_index != -1
// Type0 PDCCH search space
if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){
mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1;
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config;
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
/*
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set
LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n",
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti,
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP);
*/
dl_config->number_pdus = dl_config->number_pdus + 1;
if(search_space_mask & type0a_pdcch){
}
if(search_space_mask & type1_pdcch){
}
if(search_space_mask & type2_pdcch){
}
if(search_space_mask & type3_pdcch){
}
*/
}
} else if (ul_info && ul_info->slot_tx == 8) {
module_id_t mod_id = ul_info->module_id;
uint32_t gNB_index = ul_info->gNB_index;
int cc_id = ul_info->cc_id;
frame_t rx_frame = ul_info->frame_rx;
slot_t rx_slot = ul_info->slot_rx;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
// program PUSCH. this should actually be done upon reception of an UL DCI
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
//--------------------------Temporary configuration-----------------------------//
uint16_t rnti = 0x1234;
uint32_t rb_size = 50;
uint32_t rb_start = 0;
uint8_t nr_of_symbols = 12;
uint8_t start_symbol_index = 2;
uint8_t nrOfLayers = 1;
uint8_t mcs_index = 9;
uint8_t mcs_table = 0;
uint8_t harq_process_id = 0;
uint8_t rv_index = 0;
uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
uint8_t dmrs_config_type = 0;
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
uint8_t ptrs_mcs3 = 10;
uint16_t n_rb0 = 25;
uint16_t n_rb1 = 75;
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
//------------------------------------------------------------------------------//
dcireq.module_id = mod_id;
dcireq.gNB_index = gNB_index;
dcireq.cc_id = cc_id;
dcireq.frame = rx_frame;
dcireq.slot = rx_slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = mod_id;
scheduled_response.CC_id = cc_id;
scheduled_response.frame = rx_frame;
scheduled_response.slot = rx_slot;
scheduled_response.ul_config->slot = ul_info->slot_tx;
scheduled_response.ul_config->number_pdus = 1;
scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
if (1 << ptrs_time_density >= nr_of_symbols) {
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
// TODO: expand
// Note: Contention resolution is currently not active
if (mac->RA_contention_resolution_timer_active == 1)
ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
}
else { // get PDCCH configuration(s) from SCGConfig
// get Coreset and SearchSpace Information from spCellConfigDedicated
/*
if(search_space_mask & type0a_pdcch){
}
if(search_space_mask & type1_pdcch){
}
if(search_space_mask & type2_pdcch){
}
if(search_space_mask & type3_pdcch){
}
*/
}
mac->scheduled_response.dl_config = dl_config;
return UE_CONNECTION_OK;
}
// Notes:
// - Type1-PDCCH CSS configuration from ra-SearchSpace.
// - Msg2 is scheduled in the mixed slot or in the last dl slot if they are allowed by the Type 1 Common Search Space configuration
// todo:
// - if Type1-PDCCH CSS is not configured in RRC message (Coreset and SearchSpace), UE searches in Type 0 PDCCH CSS.
void nr_ue_msg2_scheduler(module_id_t mod_id,
uint16_t rach_frame,
uint16_t rach_slot,
uint16_t *msg2_frame,
uint16_t *msg2_slot){
uint8_t bwp_id = 1;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_ServingCellConfig_t *scd = mac->scd;
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_BWP_Downlink_t *bwp = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
NR_SearchSpace_t *ss;
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
uint8_t mu = *scc->ssbSubcarrierSpacing;
uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
uint8_t slot_window, slot_limit, frame_limit;
uint16_t start_next_period, monitoring_slot_period, monitoring_offset;
// number of mixed slot or of last dl slot if there is no mixed slot
uint16_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
uint16_t nr_dl_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols;
uint16_t nr_ul_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
// lenght of tdd period in slots
uint16_t tdd_period_slot = last_dl_slot_period + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH common SearchSpace list has 0 elements\n");
LOG_D(MAC, "Frame %d, Slot %d: Scheduling Msg2 reception \n", rach_frame, rach_slot);
// Common searchspace list
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
ss = commonSearchSpaceList->list.array[i];
if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
// retrieving ra pdcch monitoring period and offset
find_monitoring_periodicity_offset_common(ss, &monitoring_slot_period, &monitoring_offset);
}
if (nr_dl_symbols == 0)
last_dl_slot_period--;
if ((nr_dl_symbols > 0) || (nr_ul_symbols > 0))
tdd_period_slot++;
// computing start of next period
start_next_period = (rach_slot - (rach_slot % tdd_period_slot) + tdd_period_slot) % nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = (*msg2_slot > rach_slot) ? rach_frame : (rach_frame +1);
switch(response_window){
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
slot_window = 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
slot_window = 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
slot_window = 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
slot_window = 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
slot_window = 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
slot_window = 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
slot_window = 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
slot_window = 80;
break;
default:
AssertFatal(1==0,"Invalid response window value %d\n",response_window);
}
AssertFatal(slot_window<=nr_slots_per_frame[mu], "Msg2 response window needs to be lower or equal to 10ms");
// slot and frame limit to transmit msg2 according to response window
slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
// go to previous slot if the current scheduled slot is beyond the response window
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
while ((*msg2_slot > slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu] + *msg2_slot - monitoring_offset) % monitoring_slot_period != 0)) {
if((*msg2_slot % tdd_period_slot) > 0)
(*msg2_slot)--;
else
AssertFatal(1 == 0, "No available DL slot to schedule reception of msg2 has been found");
}
LOG_D(MAC, "Scheduled Msg2 reception in Frame %d, Slot %d: \n", *msg2_frame, *msg2_slot);
}
// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
// It fills the PRACH PDU per each FD occasion.
// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
// - todo:
// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config
void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
uint8_t config_index, mu, N_dur, N_t_slot, start_symbol;
uint16_t format, format0, format1, ncs;
int msg1_FDM, is_nr_prach_slot, fdm;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
fapi_nr_ul_config_prach_pdu *prach_config_pdu;
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
mac->RA_offset = 2; // to compensate the rx frame offset at the gNB
if (is_nr_UL_slot(scc, slotP)) {
if (setup->msg1_SubcarrierSpacing)
mu = *setup->msg1_SubcarrierSpacing;
else
mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
is_nr_prach_slot = get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
frequencyInfoDL->absoluteFrequencyPointA,
mu,
cfg->cell_config.frame_duplex_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur);
if (is_nr_prach_slot && mac->ra_state == RA_UE_IDLE) {
mac->generate_nr_prach = 1;
fdm = rach_ConfigGeneric->msg1_FDM;
switch (fdm){
case 0:
case 1:
case 2:
case 3:
msg1_FDM = 1 << fdm;
break;
default:
AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", fdm);
}
format0 = format & 0xff; // single PRACH format
format1 = (format >> 8) & 0xff; // dual PRACH format
ul_config->sfn = frameP;
ul_config->slot = slotP;
for (int n = 0; n < msg1_FDM; n++) { // one structure per frequency domain occasion
ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH;
prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
ul_config->number_pdus += 1;
ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
// filling PRACH PDU for FAPI config request
prach_config_pdu->phys_cell_id = *scc->physCellId;
prach_config_pdu->num_prach_ocas = N_t_slot;
prach_config_pdu->prach_start_symbol = start_symbol;
prach_config_pdu->num_ra = n;
prach_config_pdu->num_cs = ncs;
prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[n].prach_root_sequence_index;
prach_config_pdu->restricted_set = prach_config->restricted_set_config;
prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[n].k1;
if (format1 != 0xff) {
switch(format0) { // dual PRACH format
case 0xa1:
prach_config_pdu->prach_format = 9;
break;
case 0xa2:
prach_config_pdu->prach_format = 10;
break;
case 0xa3:
prach_config_pdu->prach_format = 11;
break;
default:
AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
} else {
switch(format0) { // single PRACH format
case 0xa1:
prach_config_pdu->prach_format = 0;
break;
case 0xa2:
prach_config_pdu->prach_format = 1;
break;
case 0xa3:
prach_config_pdu->prach_format = 2;
break;
case 0xb1:
prach_config_pdu->prach_format = 3;
break;
case 0xb2:
prach_config_pdu->prach_format = 4;
break;
case 0xb3:
prach_config_pdu->prach_format = 5;
break;
case 0xb4:
prach_config_pdu->prach_format = 6;
break;
case 0xc0:
prach_config_pdu->prach_format = 7;
break;
case 0xc2:
prach_config_pdu->prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
break;
case 3:
// long formats are handled @ PHY
break;
default:
AssertFatal(1 == 0, "Invalid PRACH format");
}
}
}
} else {
mac->generate_nr_prach = 0;
}
mac->scheduled_response.ul_config = ul_config;
}
}
////////////////////////////////////////////////////////////////////////////
/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
////////////////////////////////////////////////////////////////////////////
// Handling contention resolution timer
// WIP todo:
// - beam failure recovery
// - RA completed
void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
if (mac->RA_contention_resolution_timer_active == 1) {
if (nr_rach_ConfigCommon){
LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n",
tx_frame,
mac->RA_contention_resolution_cnt,
((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3));
mac->RA_contention_resolution_cnt++;
if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) {
mac->t_crnti = 0;
mac->RA_active = 0;
mac->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %u] [RAPROC] Contention resolution timer expired, RA failed, discarded TC-RNTI\n", module_id);
nr_ra_failed(module_id, cc_id, gNB_index);
}
}
}
}
#if 0
uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue,
uint8_t slot,
@@ -1905,8 +2298,8 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,&dci_pdu_rel15);
nr_ue_process_dci(module_id, cc_id, gNB_index, &dci_pdu_rel15, dci->rnti, dci->dci_format);
return 0;
return (nr_ue_process_dci(module_id, cc_id, gNB_index, &dci_pdu_rel15, dci->rnti, dci->dci_format));
}
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
@@ -2400,7 +2793,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/
dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = dci->pdsch_to_harq_feedback_time_ind;
LOG_D(MAC,"(nr_ue_procedures.c) rnti=%d dl_config->number_pdus=%d\n",
LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n",
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti,
dl_config->number_pdus);
LOG_D(MAC,"(nr_ue_procedures.c) frequency_domain_resource_assignment=%d \t number_rbs=%d \t start_rb=%d\n",
@@ -2423,7 +2816,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
dlsch_config_pdu_1_0->pucch_resource_id,
dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind);
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
if (mac->ra_rnti == rnti)
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
else
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
// dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP;
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
@@ -2765,7 +3162,9 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu);
#endif
break;
mac->rnti_type = rnti_type;
case NR_RNTI_C:
// indicating a DL DCI format 1bit
@@ -3066,6 +3465,7 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
uint8_t *pdu_ptr = pduP, rx_lcid, done = 0;
int pdu_len = mac_pdu_len;
uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
//NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP);
//uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon;
@@ -3226,8 +3626,34 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
break;
case DL_SCH_LCID_CON_RES_ID:
// 38.321 Ch6.1.3.3
// WIP todo: handle CCCH_pdu
mac_ce_len = 6;
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pdu_ptr[0], pdu_ptr[1], pdu_ptr[2], pdu_ptr[3], pdu_ptr[4], pdu_ptr[5]);
if (mac->RA_active == 1) {
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP);
mac->RA_active = 0;
// // check if RA procedure has finished completely (no contention)
// tx_sdu = &mac->CCCH_pdu.payload[3];
// //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits)
// // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or // SCH_SUBHEADER_SHORT)
// for (i = 0; i < 6; i++)
// if (tx_sdu[i] != payload_ptr[i]) {
// LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP);
// nr_ra_failed(module_idP, CC_id, eNB_index);
// mac->RA_contention_resolution_timer_active = 0;
// return;
// }
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Cleared contention resolution timer. Set C-RNTI to TC-RNTI\n",
module_idP,
frameP);
mac->RA_contention_resolution_timer_active = 0;
nr_ra_succeeded(module_idP, CC_id, gNB_index);
mac->crnti = mac->t_crnti;
mac->t_crnti = 0;
mac->ra_state = RA_SUCCEEDED;
}
break;
case DL_SCH_LCID_PADDING:
done = 1;
@@ -3293,71 +3719,181 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
}
}
//---------------------------------------------------------------------------------
////////////////////////////////////////////////////////
/////* ULSCH MAC PDU generation (6.1.2 TS 38.321) */////
////////////////////////////////////////////////////////
uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
uint8_t *pdu,
uint8_t num_sdus,
uint16_t *sdu_lengths,
uint8_t *sdu_lcids,
uint8_t power_headroom,
uint16_t crnti,
uint16_t truncated_bsr,
uint16_t short_bsr,
uint16_t long_bsr,
unsigned short post_padding,
uint16_t buflen) {
uint16_t
nr_generate_ulsch_pdu(uint8_t *mac_pdu,
uint8_t *sdus_payload,
uint8_t num_sdus,
uint16_t *sdu_lengths,
uint8_t *sdu_lcids,
uint16_t *crnti,
uint16_t buflen) {
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu;
unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0;
int mac_ce_size;
uint16_t offset = 0;
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
unsigned char * ulsch_buffer_ptr = sdus_payload;
uint8_t last_size=0;
uint16_t sdu_length_total=0;
int i;
int offset=0;
LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus);
// 2) Generation of ULSCH MAC SDU subheaders
for (i = 0; i < num_sdus; i++) {
LOG_D(MAC, "[gNB] Generate ULSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]);
#ifdef DEBUG_HEADER_PARSING
if (sdu_lengths[i] < 128) {
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
last_size = 2;
} else {
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
last_size = 3;
}
for (i = 0; i < num_sdus; i++)
LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]);
mac_pdu_ptr += last_size;
#endif
// 3) cycle through SDUs, compute each relevant and place dlsch_buffer in
memcpy((void *) mac_pdu_ptr, (void *) ulsch_buffer_ptr, sdu_lengths[i]);
ulsch_buffer_ptr+= sdu_lengths[i];
sdu_length_total+= sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
}
// Generating UL MAC subPDUs including MAC SDU and subheader
offset = ((unsigned char *) mac_pdu_ptr - mac_pdu);
for (i = 0; i < num_sdus; i++) {
LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus);
// 4) Compute final offset for padding
uint16_t padding_bytes = buflen - offset;
LOG_D(MAC, "Number of padding bytes: %d \n", padding_bytes);
if (padding_bytes > 0) {
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
mac_pdu_ptr++;
if (sdu_lcids[i] != UL_SCH_LCID_CCCH){
if (sdu_lengths[i] < 128) {
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
last_size = 2;
} else {
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
last_size = 3;
}
} else { // UL CCCH SDU
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = sdu_lcids[i];
}
} else {
// no MAC subPDU with padding
}
mac_pdu_ptr += last_size;
// cycle through SDUs, compute each relevant and place ulsch_buffer in
memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]);
sdus_payload += sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
}
// Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
ce_ptr = &mac_header_control_elements[0];
if (power_headroom) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR;
mac_pdu_ptr++;
// PHR MAC CE (1 octet)
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0;
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
// Copying bytes for PHR MAC CEs to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
if (crnti) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = CRNTI;
mac_pdu_ptr++;
// C-RNTI MAC CE (2 octets)
* (uint16_t *) ce_ptr = crnti;
mac_ce_size = sizeof(uint16_t);
// Copying bytes for CRNTI MAC CE to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
if (truncated_bsr) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_S_TRUNCATED_BSR;
mac_pdu_ptr++;
// Short truncated BSR MAC CE (1 octet)
((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr;
((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
bsr = 1 ;
} else if (short_bsr) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_S_BSR;
mac_pdu_ptr++;
// Short truncated BSR MAC CE (1 octet)
((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr;
((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo
mac_ce_size = sizeof(NR_BSR_SHORT);
bsr = 1 ;
} else if (long_bsr) {
// MAC CE variable subheader
// todo ch 6.1.3.1. TS 38.321
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0;
// last_size = 2;
// mac_pdu_ptr += last_size;
// Short truncated BSR MAC CE (1 octet)
// ((NR_BSR_LONG *) ce_ptr)->Buffer_size0 = short_bsr;
// ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0;
// mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
}
if (bsr){
// Copying bytes for BSR MAC CE to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
// compute offset before adding padding (if necessary)
offset = ((unsigned char *) mac_pdu_ptr - pdu);
uint16_t padding_bytes = 0;
if(buflen > 0) // If the buflen is provided
padding_bytes = buflen - offset;
// Compute final offset for padding
if (post_padding > 0 || padding_bytes>0) {
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
mac_pdu_ptr++;
} else {
// no MAC subPDU with padding
}
// compute final offset
offset = ((unsigned char *) mac_pdu_ptr - pdu);
//printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - pdu));
return offset;
}
uint8_t
nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
sub_frame_t subframe, uint8_t eNB_index,
@@ -3430,13 +3966,6 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
sdu_length_total += sdu_lengths[num_sdus];
sdu_lcids[num_sdus] = lcid;
//Update total MAC Header size for RLC PDUs
/*if(sdu_lengths[num_sdus]<128)
total_rlc_pdu_header_len += 2;
else
total_rlc_pdu_header_len += 3;*/
total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last;
//Update number of SDU
@@ -3461,13 +3990,18 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
// Generate ULSCH PDU
if (num_sdus>0) {
payload_offset = nr_generate_ulsch_pdu(ulsch_buffer, // mac header
ulsch_sdus,
payload_offset = nr_generate_ulsch_pdu(ulsch_sdus,
ulsch_buffer, // mac header
num_sdus, // num sdus
sdu_lengths, // sdu length
sdu_lcids, // sdu lcid
NULL, // crnti
buflen); // long_bsr
0, // power_headroom
0, // crnti
0, // truncated_bsr
0, // short_bsr
0, // long_bsr
0, // post_padding
buflen); // TBS in bytes
}
else
return 0;
+208
View File
@@ -0,0 +1,208 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file rar_tools_nrUE.c
* \brief RA tools for NR UE
* \author Guido Casati
* \date 2019
* \version 1.0
* @ingroup _mac
*/
/* Sim */
#include "SIMULATION/TOOLS/sim.h"
/* Utils */
#include "common/utils/LOG/log.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "UTIL/OPT/opt.h"
/* Common */
#include "common/ran_context.h"
/* MAC */
#include "NR_MAC_UE/mac.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#define DEBUG_RAR
// table 7.2-1 TS 38.321
uint16_t table_7_2_1[16] = {
5, // row index 0
10, // row index 1
20, // row index 2
30, // row index 3
40, // row index 4
60, // row index 5
80, // row index 6
120, // row index 7
160, // row index 8
240, // row index 9
320, // row index 10
480, // row index 11
960, // row index 12
1920, // row index 13
};
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
// TS 38.321 ch 6.2.3 //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//| E | T | R A P I D |//
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |//
//| R | T A |//
//| T A | UL grant |//
//| UL grant |//
//| UL grant |//
//| UL grant |//
//| T C - R N T I |//
//| T C - R N T I |//
/////////////////////////////////////
// UL grant (27 bits) //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//|-------------------|FHF|F_alloc|//
//| Freq allocation |//
//| F_alloc |Time allocation|//
//| MCS | TPC |CSI|//
/////////////////////////////////////
// WIP todo:
// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213
// - apply tpc command, csi req, mcs
uint16_t nr_ue_process_rar(module_id_t mod_id,
int CC_id,
frame_t frameP,
uint8_t * dlsch_buffer,
rnti_t * t_crnti,
uint8_t preamble_index,
uint8_t * selected_rar_buffer){
NR_UE_MAC_INST_t *ue_mac = get_mac_inst(mod_id);
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer
uint8_t n_subPDUs = 0; // number of RAR payloads
uint8_t n_subheaders = 0; // number of MAC RAR subheaders
//uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req;
uint16_t ta_command = 0, msg3_f_alloc, bwp_size;
int f_alloc, mask;
AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n");
while (1) {
n_subheaders++;
if (rarh->T == 1) {
n_subPDUs++;
LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id);
} else {
n_subPDUs++;
ue_mac->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI];
ue_mac->RA_BI_found = 1;
LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ue_mac->RA_backoff_indicator);
}
if (rarh->RAPID == preamble_index) {
LOG_D(PHY, "[UE %d][RAPROC] Found RAR with the intended RAPID %d\n", mod_id, rarh->RAPID);
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
ue_mac->RA_RAPID_found = 1;
break;
}
if (rarh->E == 0) {
LOG_I(PHY, "No RAR found with the intended RAPID. \n");
break;
} else {
rarh += sizeof(NR_MAC_RAR) + 1;
}
};
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_subheaders, n_subPDUs);
// LOG_I(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
// mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
if (ue_mac->RA_RAPID_found) {
// TC-RNTI
*t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
ue_mac->t_crnti = *t_crnti;
ue_mac->rnti_type = NR_RNTI_TC;
// TA command
ta_command = rar->TA2 + (rar->TA1 << 5);
// CSI
csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
// TPC
tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
switch (tpc_command){
case 0:
ue_mac->Msg3_TPC = -6;
break;
case 1:
ue_mac->Msg3_TPC = -4;
break;
case 2:
ue_mac->Msg3_TPC = -2;
break;
case 3:
ue_mac->Msg3_TPC = 0;
break;
case 4:
ue_mac->Msg3_TPC = 2;
break;
case 5:
ue_mac->Msg3_TPC = 4;
break;
case 6:
ue_mac->Msg3_TPC = 6;
break;
case 7:
ue_mac->Msg3_TPC = 8;
break;
}
//MCS
mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
// time and frequency alloc
bwp_size = NRRIV2BW(ue_mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
if (bwp_size < 180)
mask = (1 << ((int) ceil(log2((bwp_size*(bwp_size+1))>>1)))) - 1;
else
mask = (1 << (28 - (int)(ceil(log2((bwp_size*(bwp_size+1))>>1))))) - 1;
f_alloc = msg3_f_alloc & mask;
// frequency hopping flag
freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
} else {
ue_mac->t_crnti = 0;
ta_command = (0xffff);
}
// move the selected RAR to the front of the RA_PDSCH buffer
memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1);
memcpy((void *) (selected_rar_buffer + 1), (void *) rar, sizeof(NR_MAC_RAR));
return ta_command;
}
+23 -6
View File
@@ -44,7 +44,7 @@
#include "SCHED_NR/phy_frame_config_nr.h"
#include "NR_MIB.h"
#include "nr_mac_common.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
extern RAN_CONTEXT_t RC;
//extern int l2_init_gNB(void);
@@ -121,13 +121,23 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
}
}
lte_frame_type_t frame_type;
uint16_t band;
int32_t offset;
get_band((cfg->carrier_config.dl_frequency.value)*1000,
&band,
&offset,
&frame_type);
RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
// Cell configuration
cfg->cell_config.phy_cell_id.value = *scc->physCellId;
cfg->cell_config.phy_cell_id.tl.tag = NFAPI_NR_CONFIG_PHY_CELL_ID_TAG;
cfg->num_tlv++;
cfg->cell_config.frame_duplex_type.value = 1;
cfg->cell_config.frame_duplex_type.value = frame_type;
cfg->cell_config.frame_duplex_type.tl.tag = NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG;
cfg->num_tlv++;
@@ -143,7 +153,11 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
// PRACH configuration
cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present;
uint8_t nb_preambles = 64;
if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
cfg->prach_config.prach_sequence_length.tl.tag = NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG;
cfg->num_tlv++;
@@ -153,7 +167,6 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.prach_sub_c_spacing.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
cfg->prach_config.prach_sub_c_spacing.tl.tag = NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG;
cfg->num_tlv++;
cfg->prach_config.restricted_set_config.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
cfg->prach_config.restricted_set_config.tl.tag = NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG;
cfg->num_tlv++;
@@ -192,13 +205,17 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,
nb_preambles, frame_type);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG;
cfg->num_tlv++;
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = ???
}
cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
cfg->prach_config.ssb_per_rach.tl.tag = NFAPI_NR_CONFIG_SSB_PER_RACH_TAG;
cfg->num_tlv++;
// SSB Table Configuration
int scs_scaling = 1<<(cfg->ssb_config.scs_common.value);
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
+11 -18
View File
@@ -33,9 +33,9 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
@@ -61,8 +61,6 @@
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
int CC_idP,
frame_t frameP,
@@ -259,18 +257,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
}
*/
/*
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
// schedule PRACH for iniital BWP
if (is_initialBWP_prach_subframe(frameP,subframeP)<0) return;
// fill FAPI
}
*/
/*
void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
@@ -408,10 +394,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
rnti = 0;//UE_RNTI(module_idP, i);
CC_id = 0;//UE_PCCID(module_idP, i);
} //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/
@@ -447,6 +432,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
}
if (get_softmodem_params()->phy_test == 0)
nr_schedule_RA(module_idP, frame_txP, slot_txP);
/*
// Allocate CCEs for good after scheduling is done
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
@@ -456,6 +444,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
} //is_nr_DL_slot
if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) {
if (get_softmodem_params()->phy_test == 0) {
schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP);
nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP);
}
if (get_softmodem_params()->phy_test && slot_rxP==8){
nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP);
}
+782 -26
View File
@@ -19,44 +19,800 @@
* contact@openairinterface.org
*/
/*! \file gNB_scheduler_RA.c
* \brief primitives used for random access
* \author
* \date
* \email:
/*! \file gNB_scheduler_RA.c
* \brief primitives used for random access
* \author Guido Casati
* \date 2019
* \email: guido.casati@iis.fraunhofer.de
* \version
*/
#include nr_mac_gNB.h
#include "platform_types.h"
void
schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
/* MAC */
#include "nr_mac_gNB.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc = mac->common_channels;
RA_t *ra;
uint8_t i;
/* Utils */
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/nr/nr_common.h"
#include "UTIL/OPT/opt.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
extern RAN_CONTEXT_t RC;
extern const uint16_t nr_slots_per_frame[5];
uint8_t DELTA[4]= {2,3,4,6};
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0];
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol;
uint16_t format;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur) ) {
int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM;
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int n=0; n<(1<<fdm); n++) { // one structure per frequency domain occasion
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = n;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 9;
break;
case 0xa2:
prach_pdu->prach_format = 10;
break;
case 0xa3:
prach_pdu->prach_format = 11;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
}
else{
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 0;
break;
case 0xa2:
prach_pdu->prach_format = 1;
break;
case 0xa3:
prach_pdu->prach_format = 2;
break;
case 0xb1:
prach_pdu->prach_format = 3;
break;
case 0xb2:
prach_pdu->prach_format = 4;
break;
case 0xb3:
prach_pdu->prach_format = 5;
break;
case 0xb4:
prach_pdu->prach_format = 6;
break;
case 0xc0:
prach_pdu->prach_format = 7;
break;
case 0xc2:
prach_pdu->prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
break;
case 3:
// long formats are handled @ PHY
break;
default:
AssertFatal(1==0,"Invalid PRACH format");
}
}
}
}
}
void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
uint16_t *msg2_frame, uint16_t *msg2_slot,
NR_ServingCellConfigCommon_t *scc,
uint16_t monitoring_slot_period,
uint16_t monitoring_offset){
// preferentially we schedule the msg2 in the mixed slot or in the last dl slot
// if they are allowed by search space configuration
uint8_t mu = *scc->ssbSubcarrierSpacing;
uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
uint8_t slot_window;
// number of mixed slot or of last dl slot if there is no mixed slot
uint8_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
// lenght of tdd period in slots
uint8_t tdd_period_slot = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols == 0)
last_dl_slot_period--;
if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0))
tdd_period_slot++;
// computing start of next period
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
switch(response_window){
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
slot_window = 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
slot_window = 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
slot_window = 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
slot_window = 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
slot_window = 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
slot_window = 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
slot_window = 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
slot_window = 80;
break;
default:
AssertFatal(1==0,"Invalid response window value %d\n",response_window);
}
AssertFatal(slot_window<=nr_slots_per_frame[mu],"Msg2 response window needs to be lower or equal to 10ms");
// slot and frame limit to transmit msg2 according to response window
uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
//uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
// go to previous slot if the current scheduled slot is beyond the response window
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
if((*msg2_slot%tdd_period_slot) > 0)
(*msg2_slot)--;
else
AssertFatal(1==0,"No available DL slot to schedule msg2 has been found");
}
}
void nr_initiate_ra_proc(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
uint16_t preamble_index,
uint8_t freq_index,
uint8_t symbol,
int16_t timing_offset){
uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
NR_SearchSpace_t *ss;
// ra_rnti from 5.1.3 in 38.321
uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_UE_list_t *UE_list = &nr_mac->UE_list;
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[0];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RA_t *ra = &cc->ra[0];
// This should be handled differently when we use the initialBWP for RA
ra->bwp_id=1;
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index);
if (ra->state == RA_IDLE) {
int loop = 0;
LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
ra->state = Msg2;
ra->timing_offset = timing_offset;
ra->preamble_slot = slotP;
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
AssertFatal(commonSearchSpaceList->list.count>0,
"common SearchSpace list has 0 elements\n");
// Common searchspace list
for (int i=0;i<commonSearchSpaceList->list.count;i++) {
ss=commonSearchSpaceList->list.array[i];
if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
ra->ra_ss=ss;
}
// retrieving ra pdcch monitoring period and offset
find_monitoring_periodicity_offset_common(ra->ra_ss,
&monitoring_slot_period,
&monitoring_offset);
nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset);
ra->Msg2_frame = msg2_frame;
ra->Msg2_slot = msg2_slot;
LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
do {
ra->rnti = (taus() % 65518) + 1;
loop++;
}
while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 65519));
if (loop == 100) {
LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
abort();
}
ra->RA_rnti = ra_rnti;
ra->preamble_index = preamble_index;
LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n",
module_idP,
CC_id,
frameP,
ra->Msg2_frame,
ra->Msg2_slot,
ra->RA_rnti);
return;
}
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
//uint8_t i = 0;
int CC_id = 0;
gNB_MAC_INST *mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_RA_t *ra = &cc->ra[0];
start_meas(&mac->schedule_ra);
//for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
LOG_D(MAC,"RA[state:%d]\n",ra->state);
switch (ra->state){
case Msg2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP);
break;
case Msg4:
//generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
break;
case WAIT_Msg4_ACK:
//check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra);
break;
default:
break;
}
//}
stop_meas(&mac->schedule_ra);
}
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
NR_BWP_Uplink_t *ubwp,
sub_frame_t current_slot,
frame_t current_frame,
NR_RA_t *ra) {
for (i = 0; i < NB_RA_PROC_MAX; i++) {
// msg3 is schedulend in mixed slot in the following TDD period
// for now we consider a TBS of 18 bytes
ra = (RA_t *) & cc[CC_id].ra[i];
//LOG_D(MAC,"RA[state:%d]\n",ra->state);
int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
ra->Msg3_tda_id = 16; // initialization to a value above limit
if (ra->state == MSG2)
generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == MSG4)
generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == WAITMSG4ACK)
check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra);
for (int i=0; i<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
// we want to transmit in the uplink symbols of mixed slot
if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
ra->Msg3_tda_id = i;
break;
}
}
AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
} // for i=0 .. N_RA_PROC-1
} // CC_id
uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
stop_meas(&mac->schedule_ra);
temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
if (nr_slots_per_frame[mu]>temp_slot)
ra->Msg3_frame = current_frame;
else
ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
ra->msg3_nb_rb = 18;
ra->msg3_first_rb = 0;
}
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
gNB_MAC_INST *mac = RC.nrmac[module_idP];
nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_RA_t *ra = &cc->ra[0];
if (ra->state == WAIT_Msg3) {
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot) ){
ul_req->SFN = ra->Msg3_frame;
ul_req->Slot = ra->Msg3_slot;
ul_req->pdus_list[ul_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu;
ul_req->n_pdus+=1;
}
}
}
void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
gNB_MAC_INST *mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RA_t *ra = &cc->ra[0];
NR_UE_list_t *UE_list = &mac->UE_list;
int UE_id = 0;
AssertFatal(ra->state != RA_IDLE, "RA is not active for RA %X\n", ra->rnti);
LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id);
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
frameP,
slotP,
ra->Msg3_frame,
ra->Msg3_slot,
ra->msg3_nb_rb,
ra->msg3_first_rb,
ra->msg3_round,
ra->rnti);
int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
int start_symbol_index,nr_of_symbols;
SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = ra->rnti;
pusch_pdu->handle = 0;
int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
pusch_pdu->bwp_start = abwp_start;
else
pusch_pdu->bwp_start = ibwp_start;
pusch_pdu->bwp_size = ibwp_size;
pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
pusch_pdu->cyclic_prefix = 0;
pusch_pdu->mcs_index = 0;
pusch_pdu->mcs_table = 0;
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_pdu->transform_precoding = 1;
else
pusch_pdu->transform_precoding = 0;
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->ul_dmrs_symb_pos = 1<<start_symbol_index; // ok for now but use fill dmrs mask later
pusch_pdu->dmrs_config_type = 0;
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
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->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
pusch_pdu->resource_alloc = 1; //type 1
pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
if (ra->msg3_nb_rb > pusch_pdu->bwp_size)
AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
else
pusch_pdu->rb_size = ra->msg3_nb_rb;
pusch_pdu->vrb_to_prb_mapping = 0;
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping == NULL)
pusch_pdu->frequency_hopping = 0;
else
pusch_pdu->frequency_hopping = 1;
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
//Resource Allocation in time domain
pusch_pdu->start_symbol_index = start_symbol_index;
pusch_pdu->nr_of_symbols = nr_of_symbols;
//Optional Data only included if indicated in pduBitmap
pusch_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 1; // new data
pusch_pdu->pusch_data.num_cb = 0;
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
12, // nb dmrs set for no data in dmrs symbol
0, //nb_rb_oh
0, // to verify tb scaling
pusch_pdu->nrOfLayers = 1)>>3;
// calling function to fill rar message
nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu);
}
// WIP
// todo:
// - fix me
// - get msg3 alloc (see nr_process_rar)
void nr_generate_Msg2(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP){
int UE_id = 0, dci_formats[2], rnti_types[2], CCEIndex, mcsIndex;
int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment;
int coreset_id, aggregation , search_space_type = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
NR_RA_t *ra = &cc->ra[0];
NR_UE_list_t *UE_list = &nr_mac->UE_list;
NR_SearchSpace_t *ss = ra->ra_ss;
uint16_t RA_rnti = ra->RA_rnti, numDlDci;
long locationAndBandwidth;
// uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id;
// check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD
// get the BW of the PDCCH for PDCCH size and RAR PDSCH size
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int dci10_bw;
if (ra->coreset0_configured == 1) {
AssertFatal(1==0,"This is a standalone condition\n");
}
else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP
locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth;
dci10_bw = NRRIV2BW(locationAndBandwidth,275);
}
if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu;
numDlDci = pdcch_pdu_rel15->numDlDci;
aggregation = find_aggregation_level(ss);
coreset_id = *ss->controlResourceSetId;
// Checking if the DCI allocation is feasible in current subframe
if (dl_req->nPDUs == NFAPI_NR_MAX_DL_TTI_PDUS) {
LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti);
return;
} else {
LOG_D(MAC, "[RAPROC] Subframe %d: Checking CCE feasibility format : (%x,%d) \n", slotP, RA_rnti, aggregation);
CCEIndex = allocate_nr_CCEs(nr_mac, ra->bwp_id, coreset_id, aggregation, search_space_type, UE_id, 0);
AssertFatal(CCEIndex >= 0,"CCEIndex is negative %d\n",CCEIndex);
}
LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
// This code from this point on will not work on initialBWP or CORESET0
AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
mcsIndex = 0; // Qm>2 not allowed for RAR
pdsch_pdu_rel15->pduBitmap = 0;
pdsch_pdu_rel15->rnti = RA_rnti;
pdsch_pdu_rel15->pduIndex = 0;
pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
pdsch_pdu_rel15->CyclicPrefix = 0;
pdsch_pdu_rel15->NrOfCodewords = 1;
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0);
pdsch_pdu_rel15->qamModOrder[0] = 2;
pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
pdsch_pdu_rel15->mcsTable[0] = 0;
else{
if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
pdsch_pdu_rel15->mcsTable[0] = 1;
else
pdsch_pdu_rel15->mcsTable[0] = 2;
}
pdsch_pdu_rel15->rvIndex[0] = 0;
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = 1;
pdsch_pdu_rel15->transmissionScheme = 0;
pdsch_pdu_rel15->refPoint = 0;
pdsch_pdu_rel15->dmrsConfigType = 0;
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu_rel15->SCID = 0;
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2;
pdsch_pdu_rel15->dmrsPorts = 1;
pdsch_pdu_rel15->resourceAlloc = 1;
pdsch_pdu_rel15->rbStart = 0;
pdsch_pdu_rel15->rbSize = 6;
pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved
for (int i=0; i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp);
if (NrOfSymbols_tmp < NrOfSymbols) {
NrOfSymbols = NrOfSymbols_tmp;
StartSymbolIndex = StartSymbolIndex_tmp;
time_domain_assignment = i; // this is short PDSCH added to the config to fit mixed slot
}
}
AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n");
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols);
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
dci_pdu_rel15[0].frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
pdsch_pdu_rel15->rbStart,dci10_bw);
dci_pdu_rel15[0].time_domain_assignment = time_domain_assignment;
dci_pdu_rel15[0].vrb_to_prb_mapping = 0;
dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0];
dci_pdu_rel15[0].tb_scaling = 0;
LOG_I(MAC, "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n",
dci_pdu_rel15[0].frequency_domain_assignment,
pdsch_pdu_rel15->rbStart,
pdsch_pdu_rel15->rbSize,
dci10_bw,
dci_pdu_rel15[0].time_domain_assignment,
dci_pdu_rel15[0].vrb_to_prb_mapping,
dci_pdu_rel15[0].mcs,
dci_pdu_rel15[0].tb_scaling);
nr_configure_pdcch(pdcch_pdu_rel15, 0, ss, scc, bwp);
LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x CCEIndex %d\n", frameP, slotP, RA_rnti, CCEIndex);
dci_pdu->RNTI[numDlDci] = RA_rnti;
dci_pdu->ScramblingId[numDlDci] = *scc->physCellId;
dci_pdu->ScramblingRNTI[numDlDci] = 0;
dci_pdu->AggregationLevel[numDlDci] = aggregation;
dci_pdu->CceIndex[numDlDci] = CCEIndex;
dci_pdu->beta_PDCCH_1_0[numDlDci] = 0;
dci_pdu->powerControlOffsetSS[numDlDci] = 1;
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
rnti_types[0] = NR_RNTI_RA;
LOG_D(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
pdcch_pdu_rel15->dci_pdu.RNTI[0],
rnti_types[0],
dci_formats[0],
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
pdcch_pdu_rel15->StartSymbolIndex,
pdcch_pdu_rel15->DurationSymbols);
pdcch_pdu_rel15->numDlDci++;
dci_pdu->PayloadSizeBits[0] = nr_dci_size(dci_formats[0], rnti_types[0], dci10_bw);
fill_dci_pdu_rel15(pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw);
dl_req->nPDUs+=2;
// Program UL processing for Msg3
nr_get_Msg3alloc(scc, ubwp, slotP, frameP, ra);
LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
nr_add_msg3(module_idP, CC_id, frameP, slotP);
ra->state = WAIT_Msg3;
LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
x_Overhead = 0;
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, 1, dci_pdu_rel15[0].tb_scaling);
// DL TX request
tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
tx_req->PDU_index = nr_mac->pdu_index[CC_id]++;
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = 8;
nr_mac->TX_req[CC_id].SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP;
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
}
}
void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0];
LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
ra->state = IDLE;
ra->timing_offset = 0;
ra->RRC_timer = 20;
ra->rnti = 0;
ra->msg3_round = 0;
}
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
// TS 38.321 ch 6.2.3 //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//| E | T | R A P I D |//
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |//
//| R | T A |//
//| T A | UL grant |//
//| UL grant |//
//| UL grant |//
//| UL grant |//
//| T C - R N T I |//
//| T C - R N T I |//
/////////////////////////////////////
// UL grant (27 bits) //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//|-------------------|FHF|F_alloc|//
//| Freq allocation |//
//| F_alloc |Time allocation|//
//| MCS | TPC |CSI|//
/////////////////////////////////////
// WIP
// todo:
// - handle MAC RAR BI subheader
// - sending only 1 RAR subPDU
// - UL Grant: hardcoded CSI, TPC, time alloc
// - padding
void nr_fill_rar(uint8_t Mod_idP,
NR_RA_t * ra,
uint8_t * dlsch_buffer,
nfapi_nr_pusch_pdu_t *pusch_pdu){
LOG_D(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d ", ra->Msg2_frame, ra-> Msg2_slot);
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
unsigned char csi_req = 0, tpc_command;
//uint8_t N_UL_Hop;
uint8_t valid_bits;
uint32_t ul_grant;
uint16_t f_alloc, prb_alloc, bwp_size, truncation=0;
tpc_command = 3; // this is 0 dB
/// E/T/RAPID subheader ///
// E = 0, one only RAR, first and last
// T = 1, RAPID
rarh->E = 0;
rarh->T = 1;
rarh->RAPID = ra->preamble_index;
/// RAR MAC payload ///
rar->R = 0;
// TA command
rar->TA1 = (uint8_t) (ra->timing_offset >> 5); // 7 MSBs of timing advance
rar->TA2 = (uint8_t) (ra->timing_offset & 0x1f); // 5 LSBs of timing advance
// TC-RNTI
rar->TCRNTI_1 = (uint8_t) (ra->rnti >> 8); // 8 MSBs of rnti
rar->TCRNTI_2 = (uint8_t) (ra->rnti & 0xff); // 8 LSBs of rnti
// UL grant
ra->msg3_TPC = tpc_command;
bwp_size = pusch_pdu->bwp_size;
prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size);
if (bwp_size>180) {
AssertFatal(1==0,"Initial UBWP larger than 180 currently not supported");
}
else {
valid_bits = (uint8_t)ceil(log2(bwp_size*(bwp_size+1)>>1));
}
if (pusch_pdu->frequency_hopping){
AssertFatal(1==0,"PUSCH with frequency hopping currently not supported");
} else {
for (int i=0; i<valid_bits; i++)
truncation |= (1<<i);
f_alloc = (prb_alloc&truncation);
}
ul_grant = csi_req | (tpc_command << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26);
rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07;
rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff;
rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff;
rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff;
}
@@ -31,9 +31,9 @@
*/
#include "assertions.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
@@ -34,9 +34,9 @@
#include "PHY/defs_nr_common.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
/*MAC*/
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac.h"
/*NFAPI*/
@@ -44,6 +44,9 @@
/*TAG*/
#include "NR_TAG-Id.h"
////////////////////////////////////////////////////////
/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) */////
////////////////////////////////////////////////////////
int nr_generate_dlsch_pdu(module_id_t module_idP,
unsigned char *sdus_payload,
@@ -61,7 +64,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
unsigned char * dlsch_buffer_ptr = sdus_payload;
uint8_t last_size = 0;
int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0;
// MAC CEs
uint8_t mac_header_control_elements[16], *ce_ptr;
ce_ptr = &mac_header_control_elements[0];
@@ -97,6 +99,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
}
LOG_D(MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
mac_ce_size = sizeof(NR_MAC_CE_TA);
// Copying bytes for MAC CEs to the mac pdu pointer
@@ -105,7 +108,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
// Contention resolution fixed subheader and MAC CE
if (ue_cont_res_id) {
mac_pdu_ptr->R = 0;
@@ -130,8 +132,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
// 2) Generation of DLSCH MAC SDU subheaders
// 2) Generation of DLSCH MAC subPDUs including subheaders and MAC SDUs
for (i = 0; i < num_sdus; i++) {
LOG_D(MAC, "[gNB] Generate DLSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]);
@@ -152,14 +153,14 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
mac_pdu_ptr += last_size;
// 3) cycle through SDUs, compute each relevant and place dlsch_buffer in
// 3) cycle through SDUs, compute each relevant and place dlsch_buffer in
memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]);
dlsch_buffer_ptr+= sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
}
// 4) Compute final offset for padding
if (post_padding > 0) {
if (post_padding > 0) {
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING;
mac_pdu_ptr++;
@@ -170,7 +171,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
// compute final offset
offset = ((unsigned char *) mac_pdu_ptr - mac_pdu);
//printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu));
return offset;
@@ -30,8 +30,8 @@
#include "nr_mac_gNB.h"
#include "SCHED_NR/sched_nr.h"
#include "mac_proto.h"
#include "nr_mac_common.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "executables/nr-softmodem.h"
@@ -256,7 +256,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
int configure_fapi_dl_pdu(int Mod_idP,
int *CCEIndex,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex,
uint16_t *rbSize,
uint16_t *rbStart) {
@@ -277,6 +277,13 @@ int configure_fapi_dl_pdu(int Mod_idP,
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
NR_SearchSpace_t *ss;
// TO BE FIXED we are just selecting the first search space here (only one is configured)
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[0];
dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -374,28 +381,34 @@ int configure_fapi_dl_pdu(int Mod_idP,
nr_configure_pdcch(pdcch_pdu_rel15,
1, // ue-specific
ss,
scc,
bwp);
pdcch_pdu_rel15->numDlDci = 1;
pdcch_pdu_rel15->AggregationLevel[0] = 4;
pdcch_pdu_rel15->RNTI[0]=UE_list->rnti[0];
pdcch_pdu_rel15->CceIndex[0] = CCEIndex[0];
pdcch_pdu_rel15->beta_PDCCH_1_0[0]=0;
pdcch_pdu_rel15->powerControlOffsetSS[0]=1;
pdcch_pdu_rel15->dci_pdu.AggregationLevel[0] = 4;
pdcch_pdu_rel15->dci_pdu.RNTI[0]=UE_list->rnti[0];
pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[0]=UE_list->rnti[0];
pdcch_pdu_rel15->dci_pdu.CceIndex[0] = CCEIndex[0];
pdcch_pdu_rel15->dci_pdu.beta_PDCCH_1_0[0]=0;
pdcch_pdu_rel15->dci_pdu.powerControlOffsetSS[0]=1;
int dci_formats[2];
int rnti_types[2];
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
dci_formats[0] = NR_DL_DCI_FORMAT_1_1;
else
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
rnti_types[0] = NR_RNTI_C;
pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types);
pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,pdcch_pdu_rel15->BWPSize);
LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d\n \
LOG_D(MAC, "DCI params: rnti %x, rnti_type %d, dci_format %d\n \
coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
pdcch_pdu_rel15->RNTI[0],
pdcch_pdu_rel15->dci_pdu.RNTI[0],
rnti_types[0],
dci_formats[0],
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
@@ -403,7 +416,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
pdcch_pdu_rel15->DurationSymbols);
int x_Overhead = 0; // should be 0 for initialBWP
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead);
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead,1,0);
// Hardcode it for now
TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0];
@@ -437,7 +450,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr
dci_pdu_rel15->tpc = 2;
LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci],
pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci],
dci_pdu_rel15->frequency_domain_assignment,
dci_pdu_rel15->time_domain_assignment,
dci_pdu_rel15->frequency_hopping_flag,
@@ -484,7 +497,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP,
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = tbs_bytes +2;
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes);;
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes);
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].SFN = frameP;
@@ -533,8 +546,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
UE_id,
0); // m
if (CCEIndex == -1) return;
AssertFatal(CCEIndex>0,"CCEIndex is negative\n");
int CCEIndices[2];
CCEIndices[0] = CCEIndex;
@@ -542,7 +553,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
TBS_bytes = configure_fapi_dl_pdu(module_idP,
CCEIndices,
dl_req,
pucch_sched,
pucch_sched,
dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL,
dlsch_config!=NULL ? &dlsch_config->rbSize : NULL,
dlsch_config!=NULL ? &dlsch_config->rbStart : NULL);
@@ -612,10 +623,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
// fill dlsch_buffer with random data
for (i = 0; i < TBS_bytes; i++){
//mac_sdus[i] = (unsigned char) rand();
((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
//((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
}
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
sdu_lcids[0] = 0x05; // DRB
@@ -652,7 +662,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
offset = nr_generate_dlsch_pdu(module_idP,
(unsigned char *) mac_sdus,
(unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0], //(unsigned char *) mac_pdu,
(unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0],
num_sdus, //num_sdus
sdu_lengths,
sdu_lcids,
@@ -715,6 +725,12 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
NR_SearchSpace_t *ss;
// TO BE FIXED we are just selecting the first search space here (only one is configured)
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[0];
uint16_t rnti = UE_list->rnti[UE_id];
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu;
@@ -809,13 +825,22 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
pusch_pdu->pusch_data.rv_index = 0;
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 0;
uint8_t no_data_in_dmrs = 1; // temp implementation
uint8_t num_dmrs_symb = 0;
for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++)
num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1);
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
pusch_pdu->dmrs_config_type?4:6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI
( no_data_in_dmrs ? 12 : ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1) ? 6 : 4) ) * num_dmrs_symb,
0, //nb_rb_oh
0,
pusch_pdu->nrOfLayers)>>3;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
//pusch_pdu->pusch_uci;
@@ -847,20 +872,21 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
nr_configure_pdcch(pdcch_pdu_rel15,
1, // ue-specific,
ss,
scc,
bwp);
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
AssertFatal(CCEIndex>=0,"CCEIndex is negative \n");
pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex;
pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex;
LOG_D(PHY,"CCEIndex %d\n",pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci]);
LOG_D(PHY,"CCEIndex %d\n",pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci]);
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types);
pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types);
pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,pdcch_pdu_rel15->BWPSize);
}
@@ -33,10 +33,10 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/nr/nr_common.h"
@@ -129,14 +129,33 @@ static inline uint8_t get_max_cces(uint8_t scs) {
return (nr_max_number_of_cces_per_slot[scs]);
}
int find_aggregation_level (NR_SearchSpace_t *ss){
int level = 0;
if( ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0)
level = 1;
if( ss->nrofCandidates->aggregationLevel2 != NR_SearchSpace__nrofCandidates__aggregationLevel2_n0)
level = 2;
if( ss->nrofCandidates->aggregationLevel4 != NR_SearchSpace__nrofCandidates__aggregationLevel4_n0)
level = 4;
if( ss->nrofCandidates->aggregationLevel8 != NR_SearchSpace__nrofCandidates__aggregationLevel8_n0)
level = 8;
if( ss->nrofCandidates->aggregationLevel16 != NR_SearchSpace__nrofCandidates__aggregationLevel16_n0)
level = 16;
AssertFatal(level!=0,"Unable to find aggregation level");
return level;
}
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int bwp_id,
int coreset_id,
int aggregation,
int search_space, // 0 common, 1 ue-specific
int UE_id,
int m
) {
int m) {
// uncomment these when we allocate for common search space
// NR_COMMON_channels_t *cc = nr_mac->common_channels;
// NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -148,14 +167,15 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
NR_ControlResourceSet_t *coreset;
AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id);
secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
if (search_space == 1) {
AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id);
secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[coreset_id];
}
else {
AssertFatal(1==0,"Add code for common search space\n");
coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
}
int *cce_list = nr_mac->cce_list[bwp_id][coreset_id];
@@ -411,63 +431,75 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
int ss_type,
NR_SearchSpace_t *ss,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp){
NR_ControlResourceSet_t *coreset = NULL;
if (bwp) { // This is not the InitialBWP
/// coreset
//ControlResourceSetId
// pdcch_pdu->config_type = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL,
"controlResourceSetToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count>0,
"controlResourceSetToAddModList is empty\n");
NR_ControlResourceSet_t *coreset0 = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0];
NR_ControlResourceSet_t *temp_coreset;
NR_ControlResourceSetId_t coresetid = *ss->controlResourceSetId;
if (ss_type == 0) { // common search space
if (coresetid == 0){
AssertFatal(1==0,"coreset0 currently not supported\n");
}
else {
coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
AssertFatal(coresetid==coreset->controlResourceSetId,"ID of common ss coreset does not correspond to id set in the search space\n");
}
}
else {
int n_list = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
for (int i=0; i<n_list; i++) {
temp_coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
if (coresetid==temp_coreset->controlResourceSetId) {
coreset = temp_coreset;
break;
}
}
if(coreset==NULL)
AssertFatal(1==0,"Couldn't find coreset with id %ld\n",coresetid);
}
pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix;
pdcch_pdu->DurationSymbols = coreset0->duration;
// first symbol
//AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
//frequencyDomainResources
/* uint8_t count=0, start=0, start_set=0;
// find coreset descriptor
// for SPS=14 8 MSBs in positions 13 downto 6
uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
(ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
for (int i=0; i<sps; i++) {
if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
pdcch_pdu->StartSymbolIndex=i;
break;
}
}
pdcch_pdu->DurationSymbols = coreset->duration;
uint64_t bitmap = (((uint64_t)coreset0->frequencyDomainResources.buf[0])<<37)|
(((uint64_t)coreset0->frequencyDomainResources.buf[1])<<29)|
(((uint64_t)coreset0->frequencyDomainResources.buf[2])<<21)|
(((uint64_t)coreset0->frequencyDomainResources.buf[3])<<13)|
(((uint64_t)coreset0->frequencyDomainResources.buf[4])<<5)|
(((uint64_t)coreset0->frequencyDomainResources.buf[5])>>3);
for (int i=0; i<45; i++)
if ((bitmap>>(44-i))&1) {
count++;
if (!start_set) {
start = i;
start_set = 1;
}
}
pdcch_pdu->rb_offset = 6*start;
pdcch_pdu->n_rb = 6*count;
*/
for (int i=0;i<6;i++)
pdcch_pdu->FreqDomainResource[i] = coreset0->frequencyDomainResources.buf[i];
//duration
pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i];
//cce-REG-MappingType
pdcch_pdu->CceRegMappingType = coreset0->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
pdcch_pdu->CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED;
if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
pdcch_pdu->RegBundleSize = (coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
pdcch_pdu->InterleaverSize = (coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize);
pdcch_pdu->RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
pdcch_pdu->InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize);
AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n");
pdcch_pdu->ShiftIndex = coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
pdcch_pdu->ShiftIndex = coreset->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
}
else {
pdcch_pdu->RegBundleSize = 0;
@@ -478,65 +510,16 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
pdcch_pdu->CoreSetType = 1;
//precoderGranularity
pdcch_pdu->precoderGranularity = coreset0->precoderGranularity;
pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
//TCI states
//
/*
//TCI present
if (coreset0->tci_PresentInDCI != NULL) {
AssertFatal(coreset0->tci_StatesPDCCH_ToAddList != NULL,"tci_StatesPDCCH_ToAddList is null\n");
AssertFatal(coreset0->tci_StatesPDCCH_ToAddList->list.count>0,"TCI state list is empty\n");
for (int i=0;i<coreset0->tci_StatesPDCCH_ToAddList->list.count;i++) {
}
*/
for (int i=0;i<pdcch_pdu->numDlDci;i++) {
//pdcch-DMRS-ScramblingID
AssertFatal(coreset0->pdcch_DMRS_ScramblingID != NULL,"coreset0->pdcch_DMRS_ScramblingID is null\n");
pdcch_pdu->ScramblingId[i] = *coreset0->pdcch_DMRS_ScramblingID;
}
/// SearchSpace
// first symbol
//AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
NR_SearchSpace_t *ss=NULL;
int found=0;
int target_ss = NR_SearchSpace__searchSpaceType_PR_common;
if (ss_type == 1) {
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
}
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
if (*ss->controlResourceSetId == coreset0->controlResourceSetId &&
ss->searchSpaceType->present == target_ss) {
found=1;
break;
if (ss_type) {
for (int i=0;i<pdcch_pdu->numDlDci;i++) {
//pdcch-DMRS-ScramblingID
AssertFatal(coreset->pdcch_DMRS_ScramblingID != NULL,"coreset0->pdcch_DMRS_ScramblingID is null\n");
pdcch_pdu->dci_pdu.ScramblingId[i] = *coreset->pdcch_DMRS_ScramblingID;
}
}
AssertFatal(found==1,"Couldn't find a searchspace corresponding to coreset0\n");
AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
// for SPS=14 8 MSBs in positions 13 downto 6,
uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
(ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
for (int i=0; i<sps; i++)
if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
pdcch_pdu->StartSymbolIndex=i;
break;
}
}
else { // this is for InitialBWP
@@ -734,18 +717,21 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
int *rnti_types) {
int *rnti_types,
int N_RB) {
uint16_t N_RB = pdcch_pdu_rel15->BWPSize;
uint8_t fsize=0, pos=0;
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->Payload[d];
AssertFatal(pdcch_pdu_rel15->PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported");
uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->dci_pdu.Payload[d];
AssertFatal(pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported");
int dci_size = pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d];
*dci_pdu=0;
int dci_size = pdcch_pdu_rel15->PayloadSizeBits[d];
/// Payload generation
switch(dci_formats[d]) {
case NR_DL_DCI_FORMAT_1_0:
@@ -754,25 +740,35 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
// Freq domain assignment
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos=fsize;
*dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_size-pos));
LOG_D(MAC,"frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_size-pos,*dci_pdu);
*dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_size-pos));
#ifdef DEBUG_FILL_DCI
LOG_I(MAC,"frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_size-pos,*dci_pdu);
#endif
// Time domain assignment
pos+=4;
*dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment&0xf) << (dci_size-pos));
LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,dci_size-pos,*dci_pdu);
#ifdef DEBUG_FILL_DCI
LOG_I(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,dci_size-pos,*dci_pdu);
#endif
// VRB to PRB mapping
pos++;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_size-pos);
LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu);
#ifdef DEBUG_FILL_DCI
LOG_I(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu);
#endif
// MCS
pos+=5;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos);
LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu);
#ifdef DEBUG_FILL_DCI
LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu);
#endif
// TB scaling
pos+=2;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling&0x3)<<(dci_size-pos);
LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu);
#ifdef DEBUG_FILL_DCI
LOG_I(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu);
#endif
break;
case NR_RNTI_C:
@@ -1089,7 +1085,6 @@ int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot) {
}
int extract_startSymbol(int startSymbolAndLength) {
int tmp = startSymbolAndLength/14;
int tmp2 = startSymbolAndLength%14;
@@ -28,10 +28,12 @@
* @ingroup _mac
*/
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "executables/softmodem-common.h"
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
void nr_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
@@ -87,7 +89,13 @@ void nr_process_mac_pdu(
/*#ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len);
#endif*/
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
// 38.321 Ch6.1.3.20
mac_ce_len = 2;
break;
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
// 38.321 Ch6.1.3.7
break;
case UL_SCH_LCID_S_BSR:
//38.321 section 6.1.3.1
//fixed length
@@ -170,6 +178,24 @@ void nr_process_mac_pdu(
// end of MAC PDU, can ignore the rest.
break;
// MAC SDUs
case UL_SCH_LCID_SRB1:
// todo
break;
case UL_SCH_LCID_SRB2:
// todo
break;
case UL_SCH_LCID_SRB3:
// todo
break;
case UL_SCH_LCID_CCCH_MSG3:
// todo
break;
case UL_SCH_LCID_CCCH:
// todo
mac_subheader_len = 2;
break;
case UL_SCH_LCID_DTCH:
// check if LCID is valid at current time.
if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){
@@ -183,7 +209,7 @@ void nr_process_mac_pdu(
mac_subheader_len = 2;
}
LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
@@ -223,13 +249,12 @@ void nr_process_mac_pdu(
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
if (pdu_len < 0) {
LOG_E(MAC, "%s() residual mac pdu length < 0!\n", __func__);
LOG_E(MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len);
return;
}
}
}
/*
* When data are received on PHY and transmitted to MAC
*/
@@ -282,3 +307,4 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
}
}
+61 -19
View File
@@ -31,8 +31,9 @@
#ifndef __LAYER2_NR_MAC_PROTO_H__
#define __LAYER2_NR_MAC_PROTO_H__
#include "nr_mac_gNB.h"
#include "PHY/defs_gNB.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_TAG-Id.h"
#define MAX_ACK_BITS 2 //only format 0 is available for now
@@ -78,6 +79,48 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
/////// Random Access MAC-PHY interface functions and primitives ///////
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param module_idP Instance ID of gNB
@param preamble_index index of the received RA request
@param slotP Slot number on which to act
@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
@param rnti RA rnti corresponding to this PRACH preamble
@param rach_resource type (0=non BL/CE,1 CE level 0,2 CE level 1, 3 CE level 2,4 CE level 3)
*/
void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP,
uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, int16_t timing_offset);
void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
NR_BWP_Uplink_t *ubwp,
sub_frame_t current_subframe,
frame_t current_frame,
NR_RA_t *ra);
/* \brief Function in gNB to fill RAR pdu when requested by PHY.
@param ra Instance of RA resources of gNB
@param dlsch_buffer Pointer to RAR input buffer
@param N_RB_UL Number of UL resource blocks
*/
void nr_fill_rar(uint8_t Mod_idP,
NR_RA_t * ra,
uint8_t * dlsch_buffer,
nfapi_nr_pusch_pdu_t *pusch_pdu);
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
/////// Phy test scheduler ///////
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
@@ -149,21 +192,24 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
uint8_t SR_flag);
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
int ss_type,
NR_SearchSpace_t *ss,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp);
void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
int *rnti_types);
int *rnti_types,
int N_RB);
int get_spf(nfapi_nr_config_request_scf_t *cfg);
int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot);
void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
int x_overhead);
int x_overhead,
uint8_t nodata_dmrs,
uint8_t tb_scaling);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
@@ -182,17 +228,6 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
int get_num_dmrs(uint16_t dmrs_mask );
uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
uint16_t nr_dci_size(nr_dci_format_t format,
nr_rnti_type_t rnti_type,
uint16_t N_RB);
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int bwp_id,
int coreset_id,
@@ -202,9 +237,6 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int m
);
int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
int get_dlscs(nfapi_nr_config_request_t *cfg);
int get_ulscs(nfapi_nr_config_request_t *cfg);
@@ -224,6 +256,15 @@ void config_nr_mib(int Mod_idP,
int intraFreqReselection);
void nr_generate_Msg2(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP);
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP);
int find_aggregation_level (NR_SearchSpace_t *ss);
void nr_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
@@ -231,6 +272,7 @@ void nr_process_mac_pdu(
uint8_t *pduP,
uint16_t mac_pdu_len);
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of gNB
@param CC_id Component carrier index
+2 -2
View File
@@ -30,8 +30,8 @@
*/
#include "mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
@@ -39,6 +39,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl)
{
@@ -54,7 +55,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
scale = (R>1024)?11:10;
// Intermediate number of information bits
Ninfo = (nb_re * R * Qm * Nl)>>scale;
Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
+97 -23
View File
@@ -42,30 +42,106 @@
#include <stdlib.h>
#include <string.h>
/* Commmon */
#include "targets/ARCH/COMMON/common_lib.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
/* RRC */
#include "NR_BCCH-BCH-Message.h"
#include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfigCommon.h"
#include "NR_MeasConfig.h"
/* PHY */
#include "PHY/defs_gNB.h"
#include "PHY/TOOLS/time_meas.h"
/* Interface */
#include "nfapi_nr_interface_scf.h"
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
/* MAC */
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "PHY/defs_gNB.h"
#include "PHY/TOOLS/time_meas.h"
#include "targets/ARCH/COMMON/common_lib.h"
#include "nr_mac_common.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "NR_TAG.h"
/* Defs */
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#include "NR_TAG.h"
typedef enum {
RA_IDLE = 0,
Msg2 = 1,
WAIT_Msg3 = 2,
Msg4 = 3,
WAIT_Msg4_ACK = 4
} RA_gNB_state_t;
/*! \brief gNB template for the Random access information */
typedef struct {
/// Flag to indicate this process is active
RA_gNB_state_t state;
/// BWP id of RA process
int bwp_id;
/// CORESET0 configured flag
int coreset0_configured;
/// Slot where preamble was received
uint8_t preamble_slot;
/// Subframe where Msg2 is to be sent
uint8_t Msg2_slot;
/// Frame where Msg2 is to be sent
frame_t Msg2_frame;
/// Subframe where Msg3 is to be sent
sub_frame_t Msg3_slot;
/// Frame where Msg3 is to be sent
frame_t Msg3_frame;
/// Msg3 time domain allocation index
uint8_t Msg3_tda_id;
/// Subframe where Msg4 is to be sent
sub_frame_t Msg4_slot;
/// Frame where Msg4 is to be sent
frame_t Msg4_frame;
/// harq_pid used for Msg4 transmission
uint8_t harq_pid;
/// UE RNTI allocated during RAR
rnti_t rnti;
/// RA RNTI allocated from received PRACH
uint16_t RA_rnti;
/// Received preamble_index
uint8_t preamble_index;
/// Received UE Contention Resolution Identifier
uint8_t cont_res_id[6];
/// Timing offset indicated by PHY
int16_t timing_offset;
/// Timeout for RRC connection
int16_t RRC_timer;
/// Msg3 first RB
uint8_t msg3_first_rb;
/// Msg3 number of RB
uint8_t msg3_nb_rb;
/// Msg3 TPC command
uint8_t msg3_TPC;
/// Msg3 ULdelay command
uint8_t msg3_ULdelay;
/// Msg3 cqireq command
uint8_t msg3_cqireq;
/// Round of Msg3 HARQ
uint8_t msg3_round;
/// Msg3 pusch pdu
nfapi_nr_pusch_pdu_t pusch_pdu;
/// TBS used for Msg4
int msg4_TBsize;
/// MCS used for Msg4
int msg4_mcs;
/// RA search space
NR_SearchSpace_t *ra_ss;
} NR_RA_t;
/*! \brief gNB common channels */
typedef struct {
@@ -73,6 +149,7 @@ typedef struct {
int p_gNB;
int Ncp;
int nr_band;
lte_frame_type_t frame_type;
uint64_t dl_CarrierFreq;
NR_BCCH_BCH_Message_t *mib;
NR_ServingCellConfigCommon_t *ServingCellConfigCommon;
@@ -93,7 +170,7 @@ typedef struct {
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations
RA_t ra[NB_RA_PROC_MAX];
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
uint8_t vrb_map[100];
/// VRB map for common channels and retransmissions by PHICH
@@ -120,9 +197,8 @@ typedef struct {
int16_t ta_update;
} NR_UE_sched_ctrl_t;
/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
typedef struct {
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
/// scheduling control info
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
@@ -208,11 +284,11 @@ typedef struct {
uint16_t frequency_domain_assignment; //up to 16 bits
uint8_t time_domain_assignment; // 4 bits
uint8_t frequency_hopping_flag; //1 bit
uint8_t ra_preamble_index; //6 bits
uint8_t ss_pbch_index; //6 bits
uint8_t prach_mask_index; //4 bits
uint8_t vrb_to_prb_mapping; //0 or 1 bit
uint8_t mcs; //5 bits
uint8_t ndi; //1 bit
@@ -224,11 +300,11 @@ typedef struct {
uint8_t tpc; //2 bits
uint8_t pucch_resource_indicator; //3 bits
uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
uint8_t short_messages_indicator; //2 bits
uint8_t short_messages; //8 bits
uint8_t tb_scaling; //2 bits
uint8_t carrier_indicator; //0 or 3 bits
uint8_t bwp_indicator; //0, 1 or 2 bits
uint8_t prb_bundling_size_indicator; //0 or 1 bits
@@ -239,30 +315,28 @@ typedef struct {
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
uint8_t dmrs_sequence_initialization; //0 or 1 bit
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t csi_request;
uint8_t ptrs_dmrs_association;
uint8_t beta_offset_indicator; //0 or 2 bits
uint8_t slot_format_indicator_count;
uint8_t *slot_format_indicators;
uint8_t pre_emption_indication_count;
uint16_t *pre_emption_indications; //14 bit
uint8_t block_number_count;
uint8_t *block_numbers;
uint8_t ul_sul_indicator; //0 or 1 bit
uint8_t antenna_ports;
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
uint16_t padding;
} dci_pdu_rel15_t;
#endif /*__LAYER2_NR_MAC_GNB_H__ */
+23 -30
View File
@@ -503,8 +503,6 @@ pdcp_data_ind(
//-----------------------------------------------------------------------------
{
pdcp_t *pdcp_p = NULL;
list_t *sdu_list_p = NULL;
mem_block_t *new_sdu_p = NULL;
uint8_t pdcp_header_len = 0;
uint8_t pdcp_tailer_len = 0;
pdcp_sn_t sequence_number = 0;
@@ -576,7 +574,6 @@ pdcp_data_ind(
}
}
sdu_list_p = &pdcp_sdu_list;
if (sdu_buffer_sizeP == 0) {
LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!\n");
@@ -974,9 +971,8 @@ pdcp_data_ind(
#endif
if (FALSE == packet_forwarded) {
new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), __func__);
notifiedFIFO_elt_t * new_sdu_p = newNotifiedFIFO_elt(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), 0, NULL, NULL);
if (new_sdu_p) {
if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) {
pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
}
@@ -984,14 +980,15 @@ pdcp_data_ind(
/*
* Prepend PDCP indication header which is going to be removed at pdcp_fifo_flush_sdus()
*/
memset(new_sdu_p->data, 0, sizeof (pdcp_data_ind_header_t));
((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size = sdu_buffer_sizeP - payload_offset;
pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(new_sdu_p);
memset(pdcpHead, 0, sizeof (pdcp_data_ind_header_t));
pdcpHead->data_size = sdu_buffer_sizeP - payload_offset;
AssertFatal((sdu_buffer_sizeP - payload_offset >= 0), "invalid PDCP SDU size!");
// Here there is no virtualization possible
// set ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst for IP layer here
if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id;
pdcpHead->rb_id = rb_id;
if (EPC_MODE_ENABLED) {
/* for the UE compiled in S1 mode, we need 1 here
@@ -1002,45 +999,40 @@ pdcp_data_ind(
#ifdef UESIM_EXPANSION
if (UE_NAS_USE_TUN) {
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
pdcpHead->inst = ctxt_pP->module_id;
} else {
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = 0;
pdcpHead->inst = 0;
}
#else
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
pdcpHead->inst = ctxt_pP->module_id;
#endif
} else { // nfapi_mode
if (UE_NAS_USE_TUN) {
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
pdcpHead->inst = ctxt_pP->module_id;
} else {
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = 1;
pdcpHead->inst = 1;
}
} // nfapi_mode
}
} else {
((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB);
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
pdcpHead->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB);
pdcpHead->inst = ctxt_pP->module_id;
}
if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
static uint32_t pdcp_inst = 0;
((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = pdcp_inst++;
LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size);
pdcpHead->inst = pdcp_inst++;
LOG_D(PDCP, "inst=%d size=%d\n", pdcpHead->inst, pdcpHead->data_size);
}
memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)],
memcpy(pdcpHead+1,
&sdu_buffer_pP->data[payload_offset],
sdu_buffer_sizeP - payload_offset);
#if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
LOG_I(PDCP, "Printing first bytes of PDCP SDU before adding it to the list: \n");
for (int i=0; i<30; i++){
LOG_I(PDCP, "%x", sdu_buffer_pP->data[i]);
}
#endif
list_add_tail_eurecom (new_sdu_p, sdu_list_p);
}
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
log_dump(PDCP, pdcpHead+1, min(sdu_buffer_sizeP - payload_offset,30) , LOG_DUMP_CHAR,
"Printing first bytes of PDCP SDU before adding it to the list: \n");
pushNotifiedFIFO(&pdcp_sdu_list, new_sdu_p);
/* Print octets of incoming data in hexadecimal form */
LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n",
@@ -2390,7 +2382,7 @@ void nr_ip_over_LTE_DRB_preconfiguration(void){
// 1 + drb_identiy_index;
DRB_config->drb_Identity = 1;
DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
*(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
*(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 3; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
DRB_config->rlc_Config = DRB_rlc_config;
@@ -2467,7 +2459,7 @@ void pdcp_layer_init(void)
/*
* Initialize SDU list
*/
list_init(&pdcp_sdu_list, NULL);
initNotifiedFIFO(&pdcp_sdu_list);
pdcp_coll_p = hashtable_create ((LTE_maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, pdcp_free);
AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed");
@@ -2540,7 +2532,8 @@ void pdcp_layer_init(void)
void pdcp_layer_cleanup (void)
//-----------------------------------------------------------------------------
{
list_free (&pdcp_sdu_list);
//list_free (&pdcp_sdu_list);
while(pollNotifiedFIFO(&pdcp_sdu_list)) {};
hashtable_destroy(&pdcp_coll_p);
#ifdef MBMS_MULTICAST_OUT
+1 -1
View File
@@ -522,7 +522,7 @@ pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceC
sdu_size_t pdcp_output_sdu_bytes_to_write;
sdu_size_t pdcp_output_header_bytes_to_write;
list_t pdcp_sdu_list;
notifiedFIFO_t pdcp_sdu_list;
int pdcp_sent_a_sdu;
pdcp_data_req_header_t pdcp_input_header;
unsigned char pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];
+32 -41
View File
@@ -111,69 +111,59 @@ void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) {
}
//-----------------------------------------------------------------------------
int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
mem_block_t *sdu_p;
notifiedFIFO_elt_t *sdu_p;
int pdcp_nb_sdu_sent = 0;
int ret=0;
while ((sdu_p = pollNotifiedFIFO(&pdcp_sdu_list)) != NULL ) {
pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(sdu_p);
AssertFatal(pdcpHead->inst==ctxt_pP->module_id, "To implement correctly multi module id\n");
while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
int rb_id = pdcpHead->rb_id;
int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
pdcpHead->data_size;
void * pdcpData=(void*)(pdcpHead+1);
if (rb_id == 10) { //hardcoded for PC5-Signaling
if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)pdcpData,
"pdcp_fifo_flush_sdus sends a aPC5S message");
}
ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
ret = sendto(pdcp_pc5_sockfd, pdcpData,
sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
} else if (UE_NAS_USE_TUN) {
//ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
if(rb_id == mbms_rab_id){
ret = write(nas_sock_mbms_fd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
ret = write(nas_sock_mbms_fd, pdcpData,sizeToWrite );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",
ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
else
{
#if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
LOG_I(PHY, "PDCP output to be sent to TUN interface: \n");
for (int i = sizeof(pdcp_data_ind_header_t); i < sizeToWrite; i++) {
printf("%02x ",(unsigned char)sdu_p->data[i]);
}
printf("\n");
#endif
ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
//LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
ret = write(nas_sock_fd[ctxt_pP->module_id], pdcpData,sizeToWrite );
LOG_T(PDCP,"[UE PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",
ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
} else if (ENB_NAS_USE_TUN) {
#if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
LOG_I(PHY, "PDCP output to be sent to TUN interface: \n");
for (int i = sizeof(pdcp_data_ind_header_t); i < sizeToWrite; i++) {
printf("%02x ",(unsigned char)sdu_p->data[i]);
}
printf("\n");
#endif
ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), sizeToWrite);
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
ret = write(nas_sock_fd[0], pdcpData, sizeToWrite);
LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],sizeToWrite);
} else if (PDCP_USE_NETLINK) {
memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite);
memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) pdcpHead, sizeToWrite);
nas_nlh_tx->nlmsg_len = sizeToWrite;
ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
} // PDCP_USE_NETLINK
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
#if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
LOG_I(PDCP, "Printing first bytes of PDCP SDU before removing it from the list: \n");
for (int i=0; i<30; i++){
LOG_I(PDCP, "%x", sdu_p->data[i]);
}
#endif
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu_p, __func__);
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR,
"Printing first bytes of PDCP SDU before removing it from the list: \n");
delNotifiedFIFO_elt (sdu_p);
pdcp_nb_sdu_sent ++;
}
@@ -181,12 +171,13 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
}
int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
mem_block_t *sdu_p;
notifiedFIFO_elt_t *sdu_p;
int pdcp_nb_sdu_sent = 0;
//int ret=0;
while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
while ((sdu_p = pollNotifiedFIFO(&pdcp_sdu_list)) != NULL ) {
pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(sdu_p);
AssertFatal(pdcpHead->inst==ctxt_pP->module_id, "To implement correctly multi module id\n");
//int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
//int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
//((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
@@ -212,8 +203,8 @@ int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
//} // PDCP_USE_NETLINK
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu_p, __func__);
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
delNotifiedFIFO_elt (sdu_p);
pdcp_nb_sdu_sent ++;
}
+11 -11
View File
@@ -72,8 +72,8 @@ void mac_rlc_data_ind (
LOG_I(RLC, "RLC instance for the given UE was not found \n");
switch (channel_idP) {
case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -113,8 +113,8 @@ tbs_size_t mac_rlc_data_req(
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
switch (channel_idP) {
case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -123,7 +123,7 @@ tbs_size_t mac_rlc_data_req(
maxsize = tb_sizeP;
ret = rb->generate_pdu(rb, buffer_pP, maxsize);
} else {
LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB\n", __FILE__, __LINE__, __FUNCTION__);
LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB, channel_idP: %d\n", __FILE__, __LINE__, __FUNCTION__, channel_idP);
exit(1);
ret = 0;
}
@@ -166,8 +166,8 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
switch (channel_idP) {
case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -227,8 +227,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
switch (channel_idP) {
case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -654,7 +654,7 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
exit(1);
}
if (channel_id != drb_id + 2) {
if (channel_id != drb_id + 3) {
LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
@@ -737,7 +737,7 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
exit(1);
}
if (channel_id != drb_id + 2) {
if (channel_id != drb_id + 3) {
LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
+1 -1
View File
@@ -28,7 +28,7 @@ typedef void nr_rlc_ue_manager_t;
typedef struct nr_rlc_ue_t {
int rnti;
nr_rlc_entity_t *srb[2];
nr_rlc_entity_t *srb[3];
nr_rlc_entity_t *drb[5];
} nr_rlc_ue_t;
+6 -5
View File
@@ -62,15 +62,15 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.pdu_list[0].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1,
"More than 1 preamble not supported\n");
/*nr_initiate_ra_proc(UL_info->module_id,
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[0].freq_index,
UL_info->rach_ind.pdu_list[0].symbol_index,
UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);*/
UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);
}
}
@@ -224,9 +224,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id];
NR_IF_Module_t *ifi = if_inst[module_id];
gNB_MAC_INST *mac = RC.nrmac[module_id];
LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d crcs:%d]\n",
LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n",
UL_info->frame,UL_info->slot,
module_id,CC_id,
module_id,CC_id, UL_info->rach_ind.number_of_pdus,
UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
if (nfapi_mode != 1) {
+116 -134
View File
@@ -32,9 +32,9 @@
#include "PHY/defs_nr_UE.h"
#include "NR_IF_Module.h"
#include "mac_proto.h"
#include "NR_MAC_UE/mac_proto.h"
#include "assertions.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "NR_MAC_UE/mac_extern.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
#include "executables/softmodem-common.h"
@@ -93,6 +93,14 @@ int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_n
*/
}
int8_t handle_rar (nr_downlink_indication_t *dl_info){
LOG_D(MAC, "handling RAR at MAC layer \n");
nr_process_rar (dl_info);
return 0;
}
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
NR_UE_L2_STATE_t ret;
@@ -105,14 +113,18 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
mac->dl_config_request.number_pdus = 0;
// clean previous FAPI messages
ret = nr_ue_scheduler(
ul_info->module_id,
ul_info->gNB_index,
ul_info->cc_id,
ul_info->frame,
ul_info->slot,
ul_info->ssb_index,
0, 0); // TODO check tx/rx frame/slot is need for NR version
ret = nr_ue_scheduler(NULL, ul_info);
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra){
nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx);
if (mac->generate_nr_prach){
//uint16_t monitoring_slot_period, monitoring_offset;
uint16_t rach_frame = mac->scheduled_response.ul_config->sfn;
uint16_t rx_rach_frame = (rach_frame + mac->RA_offset) % MAX_FRAME_NUMBER; // compensate 2 frames offset delay at gNB side
uint16_t rach_slot = mac->scheduled_response.ul_config->slot;
nr_ue_msg2_scheduler(module_id, rx_rach_frame, rach_slot, &mac->msg2_rx_frame, &mac->msg2_rx_slot);
}
}
switch(ret){
case UE_CONNECTION_OK:
@@ -127,14 +139,13 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
break;
}
mac->if_module->scheduled_response(&mac->scheduled_response);
return 0;
}
int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
int32_t i;
uint32_t ret_mask = 0x0;
module_id_t module_id = dl_info->module_id;
@@ -142,132 +153,98 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
dl_config->number_pdus = 0;
ul_config->number_pdus = 0;
//hook up pointers
mac->scheduled_response.dl_config = dl_config;
mac->scheduled_response.ul_config = ul_config;
mac->scheduled_response.tx_request = &mac->tx_request;
mac->scheduled_response.module_id = dl_info->module_id;
mac->scheduled_response.CC_id = dl_info->cc_id;
mac->scheduled_response.frame = dl_info->frame;
mac->scheduled_response.slot = dl_info->slot;
if (!dl_info->dci_ind && !dl_info->rx_ind) {
// UL indication to schedule reception DCI reception
nr_ue_scheduler(dl_info, NULL);
} else {
// UL indication after reception of DCI or DL PDU
dl_config->number_pdus = 0;
ul_config->number_pdus = 0;
//hook up pointers
mac->scheduled_response.dl_config = dl_config;
mac->scheduled_response.ul_config = ul_config;
mac->scheduled_response.tx_request = &mac->tx_request;
mac->scheduled_response.module_id = dl_info->module_id;
mac->scheduled_response.CC_id = dl_info->cc_id;
mac->scheduled_response.frame = dl_info->frame;
mac->scheduled_response.slot = dl_info->slot;
if(dl_info->dci_ind != NULL){
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
for(i=0; i<dl_info->dci_ind->number_of_dcis; ++i){
LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
// fapi_nr_dci_pdu_rel15_t *dci = &dl_info->dci_ind->dci_list[i].dci;
if(dl_info->dci_ind != NULL){
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
for(i=0; i<dl_info->dci_ind->number_of_dcis; ++i){
LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
ret_mask |= (handle_dci(dl_info->module_id,
dl_info->cc_id,
dl_info->gNB_index,
dl_info->dci_ind->dci_list+i)<< FAPI_NR_DCI_IND);
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
/*switch((dl_info->dci_ind->dci_list+i)->dci_type){
case FAPI_NR_DCI_TYPE_0_0:
case FAPI_NR_DCI_TYPE_0_1:
case FAPI_NR_DCI_TYPE_1_1:
case FAPI_NR_DCI_TYPE_2_0:
case FAPI_NR_DCI_TYPE_2_1:
case FAPI_NR_DCI_TYPE_2_2:
case FAPI_NR_DCI_TYPE_2_3:
AssertFatal(1==0, "Not yet support at this moment!\n");
break;
case FAPI_NR_DCI_TYPE_1_0:
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
// mapping into DL_CONFIG_REQ for DL-SCH
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = 0x0000; // TX RNTI: UE-spec
memcpy(dlsch_config_pdu, dci, sizeof(fapi_nr_dci_pdu_rel15_t));
dl_config->number_pdus = dl_config->number_pdus + 1;
ret_mask |= (handle_dci(
dl_info->module_id,
dl_info->cc_id,
dl_info->gNB_index,
dci,
(dl_info->dci_ind->dci_list+i)->rnti,
(dl_info->dci_ind->dci_list+i)->dci_type)) << FAPI_NR_DCI_IND;
break;
default:
break;
}*/
//(dl_info->dci_list+i)->rnti
}
}
if(dl_info->rx_ind != NULL){
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
for(i=0; i<dl_info->rx_ind->number_pdus; ++i){
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
case FAPI_NR_RX_PDU_TYPE_MIB:
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.additional_bits,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_index,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], MIB case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
/*ret_mask |= (handle_bcch_bch( dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
dl_info->rx_ind->rx_indication_body[i].mib_pdu.pdu,
dl_info->rx_ind->rx_indication_body[i].mib_pdu.additional_bits,
dl_info->rx_ind->rx_indication_body[i].mib_pdu.ssb_index,
dl_info->rx_ind->rx_indication_body[i].mib_pdu.ssb_length,
dl_info->rx_ind->rx_indication_body[i].mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;*/
break;
case FAPI_NR_RX_PDU_TYPE_SIB:
ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length )) << FAPI_NR_RX_PDU_TYPE_SIB;
break;
case FAPI_NR_RX_PDU_TYPE_DLSCH:
// ret_mask |= (0) << FAPI_NR_RX_PDU_TYPE_DLSCH;
ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot, ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
/*
// dl_config structure just stores what was received - not really needed
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
dl_config->number_pdus = dl_config->number_pdus + 1;
*/
/*ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu,
dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
*/
break;
default:
break;
ret_mask |= (handle_dci(dl_info->module_id,
dl_info->cc_id,
dl_info->gNB_index,
dl_info->dci_ind->dci_list+i)<< FAPI_NR_DCI_IND);
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
}
}
if(dl_info->rx_ind != NULL){
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
for(i=0; i<dl_info->rx_ind->number_pdus; ++i){
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
case FAPI_NR_RX_PDU_TYPE_MIB:
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.additional_bits,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_index,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_MIB;
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], MIB case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
break;
case FAPI_NR_RX_PDU_TYPE_SIB:
ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
dl_info->cc_id, dl_info->gNB_index,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
break;
case FAPI_NR_RX_PDU_TYPE_DLSCH:
ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
dl_info->dci_ind,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length,
dl_info->frame,
dl_info->slot,
ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
break;
case FAPI_NR_RX_PDU_TYPE_RAR:
ret_mask |= (handle_rar(dl_info)) << FAPI_NR_RX_PDU_TYPE_RAR;
break;
default:
break;
}
}
}
//clean up nr_downlink_indication_t *dl_info
dl_info->rx_ind = NULL;
dl_info->dci_ind = NULL;
}
//clean up nr_downlink_indication_t *dl_info
dl_info->rx_ind = NULL;
dl_info->dci_ind = NULL;
return 0;
}
@@ -305,7 +282,12 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) {
dl_config->sfn=UE_mac->dl_config_request.sfn;
dl_config->slot=UE_mac->dl_config_request.slot;
dl_config->number_pdus=0;
ue_dci_configuration(UE_mac,dl_config,dcireq->frame,dcireq->slot);
printf(" UE_mac->dl_config_request.slot %d VS dcireq->slot %d \n", UE_mac->dl_config_request.slot, dcireq->slot);
LOG_D(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
ue_dci_configuration(UE_mac, dl_config, dcireq->frame, dcireq->slot);
return 0;
}
+9 -6
View File
@@ -72,7 +72,8 @@ typedef struct {
/// NR UE FAPI-like P7 message, direction: L1 to L2
/// data reception indication structure
fapi_nr_rx_indication_t *rx_ind;
/// ssb_index, if ssb is not present in current TTI, value set to -1
int ssb_index;
/// dci reception indication structure
fapi_nr_dci_indication_t *dci_ind;
@@ -87,11 +88,13 @@ typedef struct {
/// component carrier id
int cc_id;
/// frame
frame_t frame;
/// slot
uint32_t slot;
/// ssb_index, if ssb is not present in current TTI, thie value set to -1
int ssb_index;
frame_t frame_rx;
/// slot rx
uint32_t slot_rx;
/// frame tx
frame_t frame_tx;
/// slot tx
uint32_t slot_tx;
/// dci reception indication structure
fapi_nr_dci_indication_t *dci_ind;
} nr_uplink_indication_t;
+6
View File
@@ -382,6 +382,7 @@ typedef enum e_rab_satus_e {
E_RAB_STATUS_DONE, // from the eNB perspective
E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
E_RAB_STATUS_REESTABLISHED, // after HO
E_RAB_STATUS_TOMODIFY, // ENDC NSA
E_RAB_STATUS_FAILED,
E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE
} e_rab_status_t;
@@ -613,6 +614,7 @@ typedef struct eNB_RRC_UE_s {
/* Number of e_rab to be modified in the list */
uint8_t nb_of_modify_e_rabs;
uint8_t nb_of_failed_e_rabs;
uint8_t nb_of_modify_endc_e_rabs;
e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
@@ -627,6 +629,10 @@ typedef struct eNB_RRC_UE_s {
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB];
rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB];
// LG: For GTPV1 TUNNELS ENDC
uint32_t gnb_gtp_endc_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t gnb_gtp_endc_addrs[S1AP_MAX_E_RAB];
rb_id_t gnb_gtp_endc_ebi[S1AP_MAX_E_RAB];
/* Total number of e_rab already setup in the list */
uint8_t nb_x2u_e_rabs;
// LG: For GTPV1 TUNNELS(X2U)
+67
View File
@@ -4398,6 +4398,17 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
//For the moment we have a single E-RAB which will be the one to be added to the gNB
//Not sure how to select bearers to be added if there are multiple.
X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1;
for (int e_rab=0; e_rab < X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++){
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = 1;
memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr,
&ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr,
sizeof(transport_layer_addr_t));
}
LOG_I(RRC,
"[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n",
ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti);
@@ -7537,6 +7548,41 @@ rrc_eNB_decode_dcch(
}
ue_context_p->ue_context.reestablishment_xid = -1;
//Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete
//including NR specific elements. Not sure if this is the correct one and the correct placement
/*if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->
scg_ConfigResponseNR_r15->buf!=NULL){
//Trigger E-RAB Modification Indication
rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
}*/
if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension!=NULL){
if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension!=NULL){
if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->scg_ConfigResponseNR_r15!=NULL){
/*Trigger E-RAB Modification Indication */
rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
}
}
}
}
}
}
}
} else {
dedicated_DRB = 1;
ue_context_p->ue_context.Status = RRC_RECONFIGURED;
@@ -8708,6 +8754,27 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP,
ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti);
ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded;
int j=0;
while(j < m->nb_e_rabs_admitted_tobeadded){
for (int e_rab_idx=0; e_rab_idx<ue_context->ue_context.setup_e_rabs; e_rab_idx++){
//Update ue_context information with gNB's address and new GTP tunnel ID
if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id){
memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer,
m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer,
m->e_rabs_admitted_tobeadded[j].gnb_addr.length);
ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length;
ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid;
ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY;
break;
}
}
j++;
}
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
0,
ENB_FLAG_YES,
+1
View File
@@ -92,6 +92,7 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
}
}
//------------------------------------------------------------------------------
boolean_t
gtpv_data_req(
+7
View File
@@ -43,6 +43,13 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
uint8_t *inde_list
);
int
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t *const ctxt_pP,
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
uint8_t *inde_list
);
/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP)
*\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels.
*\param module_id Instance ID of eNB.
+72
View File
@@ -2284,3 +2284,75 @@ int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id)
}*/
return 0;
}
int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP) {
MessageDef *msg_p = NULL;
int e_rab = 0;
int e_rab_modify_index = 0;
int e_rab_notmodify_index = 0;
uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs];
memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t));
msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFICATION_IND);
S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
S1AP_E_RAB_MODIFICATION_IND (msg_p).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id;
LOG_I (RRC,"E-RAB modification indication: nb nb_of_e_rabs %u status %u\n",
ue_context_pP->ue_context.nb_of_e_rabs,
ue_context_pP->ue_context.e_rab[e_rab].status);
if (ue_context_pP->ue_context.nb_of_modify_endc_e_rabs > 0){
S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified = ue_context_pP->ue_context.nb_of_modify_endc_e_rabs;
for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) {
//Add E-RAB in the list of E-RABs to be modified
if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_TOMODIFY) {
S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.buffer,
ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer,
ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length);
S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length;
S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab];
e_rab_modify_index++;
}
//Add E-RAB in the list of E-RABs NOT to be modified
else{
S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.buffer,
ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer,
ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length);
S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length;
S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab];
e_rab_notmodify_index++;
}
}
S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_nottobemodified = e_rab_notmodify_index;
}
if (e_rab_modify_index > 0) {
LOG_I(RRC,"S1AP_E_RAB_MODIFICATION_IND: sending the message: nb_of_erabstobemodified %d, total e_rabs %d, index %d\n",
S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified, ue_context_pP->ue_context.setup_e_rabs, e_rab);
MSC_LOG_TX_MESSAGE(
MSC_RRC_ENB,
MSC_S1AP_ENB,
(const char *)&S1AP_E_RAB_MODIFICATION_IND (msg_p),
sizeof(s1ap_e_rab_modification_ind_t),
MSC_AS_TIME_FMT" E RAB MODIFICATION IND UE %X eNB_ue_s1ap_id %u e_rabs:%u succ",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_pP->ue_id_rnti,
S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id,
e_rab_modify_index);
itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
} else {
itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
}
return 0;
}
+2
View File
@@ -285,4 +285,6 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r
int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id);
int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP);
#endif /* RRC_ENB_S1AP_H_ */
+30 -6
View File
@@ -51,9 +51,8 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
uint8_t *const buffer_pP ){
asn_enc_rval_t enc_rval;
//SRB_INFO *Srb_info;
//uint8_t Sdu_size = 0;
uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
uint8_t Sdu_size = 0;
uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
#ifdef DEBUG_RRC
LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
@@ -62,11 +61,15 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
gNB_RRC_INST *rrc;
rrc_gNB_carrier_data_t *carrier;
NR_BCCH_BCH_Message_t *mib;
NR_SRB_INFO * srb_info;
char payload_size, *payload_pP;
rrc = RC.nrrrc[Mod_idP];
carrier = &rrc->carrier;
mib = &carrier->mib;
srb_info = &carrier->Srb0;
/* MIBCH */
if( (Srb_id & RAB_OFFSET ) == MIBCH) {
mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2;
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message,
@@ -84,10 +87,31 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return(3);
}
//BCCH SIB1 SIBs
/* TODO BCCH SIB1 SIBs */
//CCCH
/* CCCH */
if( (Srb_id & RAB_OFFSET ) == CCCH) {
//struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
//if (ue_context_p == NULL) return(0);
//eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
// srb_info=&ue_p->Srb0;
payload_size = srb_info->Tx_buffer.payload_size;
// check if data is there for MAC
if (payload_size > 0) {
payload_pP = srb_info->Tx_buffer.Payload;
LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP);
// Fill buffer
memcpy((void *)buffer_pP, (void*)payload_pP, payload_size);
Sdu_size = payload_size;
srb_info->Tx_buffer.payload_size = 0;
}
return Sdu_size;
}
return(0);
}
}
+4 -3
View File
@@ -319,9 +319,10 @@ typedef struct gNB_RRC_UE_s {
uint8_t nb_release_of_e_rabs;
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
// LG: For GTPV1 TUNNELS
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB];
rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB];
uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB];
rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB];
uint32_t ul_failure_timer;
uint32_t ue_release_timer;
uint32_t ue_release_timer_thres;
+3 -3
View File
@@ -65,9 +65,9 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP);
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList);
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m);
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p);
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
NR_CellGroupConfig_t *secondaryCellGroup,
@@ -89,7 +89,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
NR_RRCReconfiguration_t *reconfig,
NR_RadioBearerConfig_t *rbconfig);
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo);
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
+5 -11
View File
@@ -200,12 +200,12 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
rrc->carrier.pdsch_AntennaPorts,
(NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
0,
0,
0, // WIP hardcoded rnti
(NR_CellGroupConfig_t *)NULL
);
if (get_softmodem_params()->phy_test > 0) {
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
// This is for phytest only, emulate first X2 message if uecap.raw file is present
FILE *fd;
@@ -246,13 +246,13 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo,
(const char *)buffer,
(enc_rval.encoded+7)>>3);
parse_CG_ConfigInfo(rrc,CG_ConfigInfo);
parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL);
}
else {
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
rrc_add_nsa_user(rrc,ue_context_p);
rrc_add_nsa_user(rrc,ue_context_p,NULL);
}
}
}
@@ -304,12 +304,6 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x
(uint8_t *)m->rrc_buffer,
(int) m->rrc_buffer_size);//m->rrc_buffer_size);
/* asn_dec_rval_t dec_rval = uper_decode( NULL,
&asn_DEF_LTE_UL_DCCH_Message,
(void **)&LTE_UL_DCCH_Message,
(uint8_t *)m->rrc_buffer,
(int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size);
*/
gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP];
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
@@ -335,7 +329,7 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x
OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo,
(const char *)m->rrc_buffer,
(enc_rval.encoded+7)>>3);
parse_CG_ConfigInfo(rrc,CG_ConfigInfo);
parse_CG_ConfigInfo(rrc,CG_ConfigInfo,m);
}
+94
View File
@@ -0,0 +1,94 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file rrc_gNB_GTPV1U.c
* \brief rrc GTPV1U procedures for gNB
* \author Lionel GAUTHIER, Panos MATZAKOS
* \version 1.0
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr, panagiotis.matzakos@eurecom.fr
*/
# include "rrc_defs.h"
# include "rrc_extern.h"
# include "RRC/LTE/MESSAGES/asn1_msg.h"
# include "rrc_eNB_GTPV1U.h"
# include "rrc_eNB_UE_context.h"
# include "msc.h"
# include "openair2/RRC/NR/rrc_gNB_UE_context.h"
//# if defined(ENABLE_ITTI)
# include "asn1_conversions.h"
# include "intertask_interface.h"
//#endif
# include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
int
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t *const ctxt_pP,
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
uint8_t *inde_list
) {
rnti_t rnti;
int i;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
if (create_tunnel_resp_pP) {
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
create_tunnel_resp_pP->num_tunnels);
rnti = create_tunnel_resp_pP->rnti;
ue_context_p = rrc_gNB_get_ue_context(
RC.nrrrc[ctxt_pP->module_id],
ctxt_pP->rnti);
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
create_tunnel_resp_pP->enb_S1u_teid[i],
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
inde_list[i],
i,
create_tunnel_resp_pP->eps_bearer_id[i],
create_tunnel_resp_pP->enb_addr.length);
}
MSC_LOG_RX_MESSAGE(
MSC_RRC_ENB,
MSC_GTPU_ENB,
NULL,0,
MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u ebid %u enb-s1u teid %u",
0,0,rnti,
create_tunnel_resp_pP->num_tunnels,
ue_context_p->ue_context.gnb_gtp_ebi[0],
ue_context_p->ue_context.gnb_gtp_teid[0]);
(void)rnti; /* avoid gcc warning "set but not used" */
return 0;
} else {
return -1;
}
}
+39
View File
@@ -0,0 +1,39 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file rrc_gNB_GTPV1U.h
* \brief rrc GTPV1U procedures for gNB
* \author Lionel GAUTHIER, Panos MATZAKOS
* \version 1.0
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr, panagiotis.matzakos@eurecom.fr
*/
#ifndef RRC_GNB_GTPV1U_H_
#define RRC_GNB_GTPV1U_H_
int
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t *const ctxt_pP,
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
uint8_t *inde_list
);
+2 -2
View File
@@ -38,7 +38,7 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) {
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m) {
if (CG_ConfigInfo->criticalExtensions.present == NR_CG_ConfigInfo__criticalExtensions_PR_c1) {
if (CG_ConfigInfo->criticalExtensions.choice.c1) {
@@ -56,7 +56,7 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) {
AssertFatal(1==0,"[InterNode] Failed to decode NR_UE_CapabilityRAT_ContainerList (%zu bits), size of OCTET_STRING %lu\n",
dec_rval.consumed, cg_ConfigInfo->ue_CapabilityInfo->size);
}
rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList);
rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList, m);
}
if (cg_ConfigInfo->candidateCellInfoListMN) AssertFatal(1==0,"Can't handle candidateCellInfoListMN yet\n");
}
+111 -33
View File
@@ -37,13 +37,15 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList) {
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL;
OCTET_STRING_t *ueCapabilityRAT_Container_MRDC=NULL;
int list_size=0;
OCTET_STRING_t *ueCapabilityRAT_Container_nr = NULL;
OCTET_STRING_t *ueCapabilityRAT_Container_MRDC = NULL;
int list_size;
asn_dec_rval_t dec_rval;
AssertFatal(UE_CapabilityRAT_ContainerList!=NULL,"UE_CapabilityRAT_ContainerList is null\n");
AssertFatal((list_size=UE_CapabilityRAT_ContainerList->list.count) >= 2, "UE_CapabilityRAT_ContainerList->list.size %d < 2\n",UE_CapabilityRAT_ContainerList->list.count);
for (int i=0;i<list_size;i++) {
@@ -51,53 +53,55 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerL
else if (UE_CapabilityRAT_ContainerList->list.array[i]->rat_Type == LTE_RAT_Type_eutra_nr) ueCapabilityRAT_Container_MRDC = &UE_CapabilityRAT_ContainerList->list.array[i]->ueCapabilityRAT_Container;
}
AssertFatal(ueCapabilityRAT_Container_nr!=NULL,"ueCapabilityRAT_Container_nr is NULL\n");
AssertFatal(ueCapabilityRAT_Container_MRDC!=NULL,"ueCapabilityRAT_Container_MRDC is NULL\n");
// decode and store capabilities
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_NR_Capability,
(void **)&ue_context_p->ue_context.UE_Capability_nr,
ueCapabilityRAT_Container_nr->buf,
ueCapabilityRAT_Container_nr->size, 0, 0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,
ue_context_p->ue_context.UE_Capability_nr);
ue_context_p->ue_context.UE_Capability_nr = 0;
AssertFatal(1==0,"exiting\n");
if (ueCapabilityRAT_Container_nr != NULL) {
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_NR_Capability,
(void **)&ue_context_p->ue_context.UE_Capability_nr,
ueCapabilityRAT_Container_nr->buf,
ueCapabilityRAT_Container_nr->size, 0, 0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,
ue_context_p->ue_context.UE_Capability_nr);
ue_context_p->ue_context.UE_Capability_nr = 0;
AssertFatal(1==0,"exiting\n");
}
}
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_MRDC_Capability,
(void **)&ue_context_p->ue_context.UE_Capability_MRDC,
ueCapabilityRAT_Container_MRDC->buf,
ueCapabilityRAT_Container_MRDC->size, 0, 0);
if (ueCapabilityRAT_Container_MRDC != NULL) {
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_MRDC_Capability,
(void **)&ue_context_p->ue_context.UE_Capability_MRDC,
ueCapabilityRAT_Container_MRDC->buf,
ueCapabilityRAT_Container_MRDC->size, 0, 0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed);
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,
ue_context_p->ue_context.UE_Capability_MRDC);
ue_context_p->ue_context.UE_Capability_MRDC = 0;
AssertFatal(1==0,"exiting\n");
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed);
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,
ue_context_p->ue_context.UE_Capability_MRDC);
ue_context_p->ue_context.UE_Capability_MRDC = 0;
AssertFatal(1==0,"exiting\n");
}
}
// dump ue_capabilities
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
}
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
}
rrc_add_nsa_user(rrc,ue_context_p);
rrc_add_nsa_user(rrc,ue_context_p, m);
}
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p) {
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) {
// generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331)
@@ -105,6 +109,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
MessageDef *msg;
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
protocol_ctxt_t ctxt;
// NR RRCReconfiguration
@@ -132,6 +139,77 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
memset((void*)CG_Config,0,sizeof(*CG_Config));
__attribute__((unused))int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
if(m!=NULL){
uint8_t inde_list[m->nb_e_rabs_tobeadded];
memset(inde_list, 0, m->nb_e_rabs_tobeadded*sizeof(uint8_t));
if (m->nb_e_rabs_tobeadded>0){
for (int i=0; i<m->nb_e_rabs_tobeadded; i++){
// Add the new E-RABs at the corresponding rrc ue context of the gNB
ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
ue_context_p->ue_context.nb_of_e_rabs++;
//Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW
create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid;
memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
inde_list[i] = i;
LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
i,
create_tunnel_req.sgw_addr[i].buffer[0],
create_tunnel_req.sgw_addr[i].buffer[1],
create_tunnel_req.sgw_addr[i].buffer[2],
create_tunnel_req.sgw_addr[i].buffer[3],
create_tunnel_req.sgw_addr[i].length,
create_tunnel_req.sgw_S1u_teid[i]);
}
//PM: Is this where we should extract the rnti from?
create_tunnel_req.rnti = ue_context_p->ue_id_rnti;
create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded;
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id);
gtpv1u_create_s1u_tunnel(
ctxt.instance,
&create_tunnel_req,
&create_tunnel_resp);
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
&ctxt,
&create_tunnel_resp,
&inde_list[0]);
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
for(int i=0; i<ue_context_p->ue_context.nb_of_e_rabs; i++){
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i];
memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t));
//The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length = create_tunnel_resp.enb_addr.length*8;
LOG_I(RRC,"S1-U create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n",
i,
create_tunnel_resp.enb_addr.buffer[0],
create_tunnel_resp.enb_addr.buffer[1],
create_tunnel_resp.enb_addr.buffer[2],
create_tunnel_resp.enb_addr.buffer[3],
create_tunnel_resp.enb_addr.length,
create_tunnel_resp.enb_S1u_teid[i]);
LOG_I(RRC,"X2AP sGNB Addition Request: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n",
i,
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[0],
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[1],
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[2],
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[3],
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length,
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid);
}
}
else
LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n");
}
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
// Send to X2 entity to transport to MeNB
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
+57 -62
View File
@@ -155,6 +155,26 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = NULL;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->ext1 = NULL;
/* contention free ra */
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric, &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
//secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
//*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= NULL;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
struct NR_CFRA_SSB_Resource *ssbElem = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem->ssb = 0;
ssbElem->ra_PreambleIndex= 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem);
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup));
@@ -354,7 +374,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType0;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
@@ -407,17 +427,45 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Common->pdcch_ConfigCommon->present = NR_SetupRelease_PDCCH_ConfigCommon_PR_setup;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup = calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup));
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet));
NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset));
coreset->controlResourceSetId=1;
// frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B,
coreset->frequencyDomainResources.buf = calloc(1,6);
coreset->frequencyDomainResources.buf[0] = 0xff;
coreset->frequencyDomainResources.buf[1] = 0xff;
coreset->frequencyDomainResources.buf[2] = 0;
coreset->frequencyDomainResources.buf[3] = 0;
coreset->frequencyDomainResources.buf[4] = 0;
coreset->frequencyDomainResources.buf[5] = 0;
coreset->frequencyDomainResources.size = 6;
coreset->frequencyDomainResources.bits_unused = 3;
coreset->duration=1;
coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved;
coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList));
NR_TCI_StateId_t *tci[8];
for (int i=0;i<8;i++) {
tci[i]=calloc(1,sizeof(*tci[i]));
*tci[i] = i;
ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]);
}
coreset->tci_StatesPDCCH_ToReleaseList = NULL;
coreset->tci_PresentInDCI = NULL;
coreset->pdcch_DMRS_ScramblingID = NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList));
NR_SearchSpace_t *ss=calloc(1,sizeof(*ss));
ss->searchSpaceId = 1;
ss->controlResourceSetId=calloc(1,sizeof(*ss->controlResourceSetId));
*ss->controlResourceSetId=0;
*ss->controlResourceSetId=1;
ss->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss->monitoringSlotPeriodicityAndOffset));
ss->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
ss->duration=NULL;
@@ -474,64 +522,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup;
bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup));
bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList));
NR_ControlResourceSet_t *coreset0 = calloc(1,sizeof(*coreset0));
coreset0->controlResourceSetId=1;
// frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B,
coreset0->frequencyDomainResources.buf = calloc(1,6);
coreset0->frequencyDomainResources.buf[0] = 0xff;
coreset0->frequencyDomainResources.buf[1] = 0xff;
coreset0->frequencyDomainResources.buf[2] = 0;
coreset0->frequencyDomainResources.buf[3] = 0;
coreset0->frequencyDomainResources.buf[4] = 0;
coreset0->frequencyDomainResources.buf[5] = 0;
coreset0->frequencyDomainResources.size = 6;
coreset0->frequencyDomainResources.bits_unused = 3;
coreset0->duration=1;
coreset0->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved;
coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
coreset0->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList));
NR_TCI_StateId_t *tci[8];
for (int i=0;i<8;i++) {
tci[i]=calloc(1,sizeof(*tci[i]));
*tci[i] = i;
ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
}
coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
coreset0->tci_PresentInDCI = NULL;
coreset0->pdcch_DMRS_ScramblingID = NULL;
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list,
coreset0);
coreset);
bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList));
NR_SearchSpace_t *ss3 = calloc(1,sizeof(*ss3));
NR_SearchSpace_t *ss2 = calloc(1,sizeof(*ss2));
ss3->searchSpaceId=3;
ss3->controlResourceSetId=calloc(1,sizeof(*ss3->controlResourceSetId));
*ss3->controlResourceSetId=1;
ss3->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss3->monitoringSlotPeriodicityAndOffset));
ss3->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
ss3->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0;
ss3->duration=NULL;
ss3->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss3->monitoringSymbolsWithinSlot));
ss3->monitoringSymbolsWithinSlot->buf = calloc(1,2);
ss3->monitoringSymbolsWithinSlot->size = 2;
ss3->monitoringSymbolsWithinSlot->bits_unused = 2;
ss3->monitoringSymbolsWithinSlot->buf[0]=0xc0;
ss3->monitoringSymbolsWithinSlot->buf[1]=0x0;
ss3->nrofCandidates=calloc(1,sizeof(*ss3->nrofCandidates));
ss3->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
ss3->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
ss3->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
ss3->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
ss3->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
ss3->searchSpaceType=calloc(1,sizeof(*ss3->searchSpaceType));
ss3->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
ss3->searchSpaceType->choice.common = calloc(1,sizeof(*ss3->searchSpaceType->choice.common));
ss3->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0=calloc(1,sizeof(*ss3->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
ss3->searchSpaceType->choice.common->dci_Format2_0=NULL;
ss3->searchSpaceType->choice.common->dci_Format2_2=NULL;
ss3->searchSpaceType->choice.common->dci_Format2_3=NULL;
ss2->searchSpaceId=2;
ss2->controlResourceSetId=calloc(1,sizeof(*ss2->controlResourceSetId));
@@ -557,8 +554,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ss2->searchSpaceType->choice.ue_Specific = calloc(1,sizeof(*ss2->searchSpaceType->choice.ue_Specific));
ss2->searchSpaceType->choice.ue_Specific->dci_Formats=NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0;
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list,
ss3);
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list,
ss2);
@@ -747,7 +742,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType0;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
@@ -773,7 +768,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType0;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
+11
View File
@@ -56,4 +56,15 @@ nr_mac_rrc_data_ind_ue(
return(0);
}
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP ){
// todo
return 0;
}
+2 -2
View File
@@ -42,7 +42,7 @@
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "rrc_vars.h"
#include "mac_proto.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "executables/softmodem-common.h"
@@ -319,7 +319,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
if (get_softmodem_params()->phy_test==1) {
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
// read in files for RRCReconfiguration and RBconfig
FILE *fd;
char filename[1024];
+2 -2
View File
@@ -39,8 +39,8 @@
#include "platform_types.h"
#include "LAYER2/NR_MAC_UE/mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_UE/mac.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "rrc_list.h"
#include "NR_asn_constant.h"
#include "NR_MeasConfig.h"
+12
View File
@@ -102,6 +102,18 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui
\param pdu_len data length of pdu*/
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len);
/**\brief
\param module_id module id
\param CC_id component carrier id
\param frame_t frameP
\param rb_id_t SRB id
\param buffer_pP pointer to buffer*/
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP);
/** @}*/
#endif
+2 -2
View File
@@ -359,7 +359,7 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf(
* Failure means multi_sd < 0.
*/
if (instance->multi_sd < 0) {
X2AP_ERROR("Error: be sure to properly configure X2 in your configuration file.\n");
X2AP_ERROR("Error: be sure to properly configure X22 in your configuration file.\n");
DevAssert(instance->multi_sd >= 0);
}
@@ -474,7 +474,7 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance,
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE);
x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id);
x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data, ue_id);
}
static
+15 -17
View File
@@ -1496,7 +1496,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
}
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id)
x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBAdditionRequest_t *out;
@@ -1516,8 +1516,6 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
int uEaggregateMaximumBitRateDownlink = 100000000;
int uEaggregateMaximumBitRateUplink = 100000000;
int e_rabs_tobeadded = 1;
int e_RAB_ID = 1;
int drb_ID = 2;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
@@ -1527,9 +1525,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY;
e_rab_tobe_added_t e_MCG_rabs_tobeadded;
e_MCG_rabs_tobeadded.gtp_teid = 0;
e_MCG_rabs_tobeadded.eNB_addr.length = 24;
e_MCG_rabs_tobeadded.sgw_addr.length = 24;
uint8_t buf[20] = { 0 };
memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t));
memcpy(e_MCG_rabs_tobeadded.sgw_addr.buffer, buf, 20*sizeof(uint8_t));
FILE *fd;
fd = fopen("../../../executables/uecap.raw","r");
@@ -1614,8 +1612,8 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item;
e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item;
{
e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID;
e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].drb_ID;
e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].e_rab_id;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
@@ -1628,14 +1626,14 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level;
//Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case
INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID);
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8;
INT32_TO_OCTET_STRING(x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID);
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length/8;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length%8;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf =
calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_MCG_rabs_tobeadded.eNB_addr.buffer,
x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.buffer,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
}
@@ -1696,8 +1694,8 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
//uint8_t SgNBSecurityKey[32] = { 0 };
//int uEaggregateMaximumBitRateDownlink = 100000000;
//int uEaggregateMaximumBitRateUplink = 100000000;
int e_rabs_admitted_tobeadded = 1;
int e_RAB_ID = 1;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
@@ -1748,21 +1746,21 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
{
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].e_rab_id;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent;
INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID);
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8;
INT32_TO_OCTET_STRING(x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID);
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length/8;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length%8;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf =
calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_SCG_rabs_tobeadded.eNB_addr.buffer,
x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.buffer,
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
}
+1 -1
View File
@@ -70,7 +70,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2a
int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id);
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id);
int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id);
+19 -11
View File
@@ -1749,13 +1749,22 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer,
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length =
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length =
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
LOG_I(RRC,"x2u tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
i,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[0],
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[1],
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[2],
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[3],
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid);
OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid);
}
@@ -1771,13 +1780,12 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true);
X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
//X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
if (container->size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size;
if (ie->value.choice.MeNBtoSgNBContainer.size > 8192 )
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size;
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
@@ -1891,10 +1899,10 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ;
if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer,
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer,
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length =
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length =
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID,
@@ -1963,7 +1971,7 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
//Allocate an ITTI X2AP_sGNB_reconfiguration_complete message
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE);
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */