From 36195ec31aadf09ceead2f9eaf942710eabb6377 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 6 Feb 2020 20:09:30 +0100 Subject: [PATCH] RA fixes and additions: - RA resource selection and transmission - MAC header structs for RA - RA procedure msg1 fixes - code cleanup --- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 10 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 133 +++--- openair1/SIMULATION/NR_PHY/prachsim.c | 3 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 42 ++ openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 13 + openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c | 26 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 428 ++++++------------ .../NR_MAC_UE/nr_ue_dci_configuration.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 170 ++++++- openair2/RRC/NR_UE/L2_interface_ue.c | 11 + openair2/RRC/NR_UE/rrc_proto.h | 12 + 13 files changed, 471 insertions(+), 385 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 1e46cde82e..c144a37a06 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -56,7 +56,7 @@ extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10]; extern uint16_t nr_du[838]; extern int16_t nr_ru[2*839]; -int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ) +int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) { //lte_frame_type_t frame_type = ue->frame_parms.frame_type; @@ -66,13 +66,13 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint8_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; uint8_t restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag; - uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex; - //uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index; - int16_t *prachF = ue->prach_vars[eNB_id]->prachF; + uint8_t preamble_index = ue->prach_resources[gNB_id]->ra_PreambleIndex; + //uint8_t tdd_mapindex = ue->prach_resources[gNB_id]->ra_TDD_map_index; + int16_t *prachF = ue->prach_vars[gNB_id]->prachF; int16_t prach_tmp[98304*2*4] __attribute__((aligned(32))); int16_t *prach = prach_tmp; int16_t *prach2; - int16_t amp = ue->prach_vars[eNB_id]->amp; + int16_t amp = ue->prach_vars[gNB_id]->amp; int16_t Ncp; uint16_t NCS=0; uint16_t *prach_root_sequence_map; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index e6b43c26ac..2bf268051c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1755,9 +1755,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); - - -int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ); +int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe); void *dlsch_thread(void *arg); /**@}*/ diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index eedd2ad581..9a3168a33e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -210,9 +210,12 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, exit(-1); } +#endif + #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) -//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162}; -/* +unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162}; +#endif + unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL) { @@ -250,9 +253,10 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, else return(amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6) } -*/ -unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) +#if 0 + +unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) // TbD { int gain_dB = power_dBm - power_max_dBm; @@ -269,8 +273,6 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb return(0); } -#endif - void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx) { unsigned int coded_bits_per_codeword; @@ -4480,11 +4482,11 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, return(0); } -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode) { +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) { /* TBR // here params are hardcoded */ int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power; - uint16_t preamble_tx=ue->prach_resources[0]->ra_PreambleIndex; //uint16_t preamble_tx=50; // TBR + uint16_t preamble_tx = 50, pathloss; NR_PRACH_RESOURCES_t prach_resources; uint8_t mod_id = ue->Mod_id; NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); @@ -4493,76 +4495,56 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); ue->generate_nr_prach = 0; - if (ue->mac_enabled == 0){ - ue->prach_resources[gNB_id] = &prach_resources; // TBR double check pointer - ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx; - ue->prach_resources[gNB_id]->ra_TDD_map_index = 0; - // ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; // TBR - // ue->prach_resources[gNB_id]->ra_RNTI = 93; // TBR - } else { + if (ue->mac_enabled == 0){ + ue->prach_resources[gNB_id] = &prach_resources; // TBR double check pointer + ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx; + ue->prach_resources[gNB_id]->ra_TDD_map_index = 0; + ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; // TBR + ue->prach_resources[gNB_id]->ra_RNTI = 93; // TBR NR_UE_MAC_INST_t + } else { // ask L2 for RACH transport - /* TBR - // check if these modes are active */ - if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { - LOG_D(PHY,"Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx); + if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) { + LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx); ue->prach_resources[gNB_id] = nr_ue_get_rach(mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx); - // LOG_D(PHY,"Got prach_resources for gNB %d address %p, RRCCommon %p\n", gNB_id, ue->prach_resources[gNB_id], UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); // TBR update this } } - if (ue->prach_resources[gNB_id]!=NULL) { + if (ue->prach_resources[gNB_id] != NULL) { ue->generate_nr_prach = 1; ue->prach_cnt = 0; + pathloss = get_nr_PL(ue, gNB_id); + LOG_I(PHY,"runmode %d\n",runmode); - #ifdef SMBV // TBR + if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) { + // todo power control as per 38.213 ch 7.4 + ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss; + ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm; ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx; - #endif + } - #ifdef OAI_EMU // TBR - ue->prach_PreambleIndex=ue->prach_resources[gNB_id]->ra_PreambleIndex; - #endif + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %d\n", + ue->Mod_id, + frame_tx, + nr_tti_tx, + ue->prach_resources[gNB_id]->ra_PreambleIndex, + pathloss, + ue->tx_power_dBm[nr_tti_tx], + ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, + ue->prach_resources[gNB_id]->ra_RNTI); - // if (abstraction_flag == 0) { // TBR - - LOG_I(PHY,"mode %d\n",mode); - - if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) { - /* TODO TBR - // check if ra_PREAMBLE_RECEIVED_TARGET_POWER is filled id */ - ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER + get_nr_PL(ue,gNB_id); - /* TODO TBR - DEBUG ONLY */ - printf("ue->tx_power_dBm[nr_tti_tx] %d ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER %d get_nr_PL(ue,gNB_id) %d\n", ue->tx_power_dBm[nr_tti_tx], ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, get_nr_PL(ue,gNB_id)); - } else { - ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm; - ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx; /* TODO TBR this is hardcoded */ - } - - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", ue->Mod_id, - frame_tx, - nr_tti_tx, - ue->prach_resources[gNB_id]->ra_PreambleIndex, - get_nr_PL(ue,gNB_id), - ue->tx_power_dBm[nr_tti_tx], - ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, - ue->prach_resources[gNB_id]->ra_TDD_map_index, - ue->prach_resources[gNB_id]->ra_RNTI); - - ue->tx_total_RE[nr_tti_tx] = 96; /* TODO TBR this is hardcoded */ + ue->tx_total_RE[nr_tti_tx] = 96; /* todo TBR double check */ #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - ue->prach_vars[gNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], /* TODO TBR get_tx_amp is still valid for NR ? */ - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 6); /* TODO TBR why 6 ? */ + ue->prach_vars[gNB_id]->amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx], + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL); #else - ue->prach_vars[gNB_id]->amp = AMP; /* TODO TBR where does this come from ? */ + ue->prach_vars[gNB_id]->amp = AMP; #endif - if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) /* TODO TBR double check where calibration prach tx is handled */ - LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n", - ue->Mod_id, + if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id, proc->frame_rx, proc->nr_tti_tx, ue->tx_power_dBm[nr_tti_tx], @@ -4571,38 +4553,35 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t // start_meas(&ue->tx_prach); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); - // prach_power = generate_nr_prach(ue,gNB_id,nr_tti_tx,frame_tx); - prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator /* TODO TBR this is hardcoded */ + prach_power = generate_nr_prach(ue, gNB_id, nr_tti_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); - // stop_meas(&ue->tx_prach); - LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", + + LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", ue->Mod_id, get_nr_PL(ue,gNB_id), ue->tx_power_dBm[nr_tti_tx], dB_fixed(prach_power), ue->prach_vars[gNB_id]->amp); - // } else { - // UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1; - // UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex; - // } // commented for compiling as abstraction flag is 0 if (ue->mac_enabled == 1) - // nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); TBR + nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); - - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", - ue->Mod_id,frame_tx,nr_tti_tx,gNB_id, + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n", + ue->Mod_id, + frame_tx, + nr_tti_tx, + gNB_id, ue->prach_resources[gNB_id]->ra_PreambleIndex, - ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,gNB_id), - get_nr_PL(ue,gNB_id)); + ue->tx_power_dBm[nr_tti_tx], + pathloss); } // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue - if (mode == calib_prach_tx) + if (runmode == calib_prach_tx) ue->prach_resources[gNB_id]=NULL; - LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt); + LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id,frame_tx,nr_tti_tx, ue->generate_nr_prach, ue->prach_cnt); ue->prach_cnt++; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index fac5d599c8..33ee14424c 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -514,8 +514,7 @@ int main(int argc, char **argv) /*tx_lev = generate_nr_prach(UE, 0, //gNB_id, - subframe, - 0); //Nf */ //commented for testing purpose + subframe); */ //commented for testing purpose UE_nr_rxtx_proc_t proc={0}; nr_ue_prach_procedures(UE,&proc,0,0); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index bbccb9f707..3c7cc4ac81 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -96,12 +96,53 @@ 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; + // /*! \brief CCCH payload */ // TBR // typedef struct { // uint8_t payload[CCCH_PAYLOAD_SIZE_MAX]; @@ -154,6 +195,7 @@ typedef struct { #define UL_SCH_LCID_SRB1 0x01 #define UL_SCH_LCID_SRB2 0x02 #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 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index ef733020e0..8309afbb69 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -100,10 +100,12 @@ 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 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 061b1fa399..3e3704da6c 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -152,6 +152,19 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, uint8_t gNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); + +unsigned char 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); + 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); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c index 85c8cf8935..a3a00a84b8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c @@ -35,7 +35,7 @@ #include "mac_defs.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" -/* 38.321 subclause 7.3 - return values are in dB */ +/* 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){ NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id); @@ -43,13 +43,15 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - NR_SubcarrierSpacing_t scs = nr_rach_ConfigCommon->msg1_SubcarrierSpacing; uint8_t preambleFormat, prachConfigIndex; lte_frame_type_t frame_type = TDD; // TODO TBR retrieve frame type. Currently hardcoded to TDD. - // was nr_UE_mac_inst[mod_id].tdd_Config nr_frequency_range_e fr = nr_FR1; // TODO TBR retrieve frame type. Currently hardcoded to FR1. int mu; + // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211 + + NR_SubcarrierSpacing_t scs = nr_rach_ConfigCommon->msg1_SubcarrierSpacing; + switch (scs){ case NR_SubcarrierSpacing_kHz15: mu = 0; @@ -87,6 +89,8 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){ AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %d\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; preambleFormat = get_nr_prach_fmt(prachConfigIndex,frame_type,fr); @@ -128,28 +132,16 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){ return; } +/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */ int8_t nr_get_Po_NOMINAL_PUSCH(module_id_t mod_id, uint8_t CC_id){ NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon; NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources; - //AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id); int8_t receivedTargerPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower + nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; return receivedTargerPower; - //return (-120 + (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower << 1) + nr_get_DELTA_PREAMBLE(mod_id, CC_id) ); -} - -/*int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id){ // TBR - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - - LOG_D(MAC, "[PUSCH]%d dB\n", - nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1); - return ((int8_t) - (nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1)); -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 501f96b771..b4708a6c81 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -67,7 +67,7 @@ extern UE_MODE_t get_nrUE_mode(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id); 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 uint8_t nfapi_mode; // TBR +//extern uint8_t nfapi_mode; // 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 @@ -80,45 +80,29 @@ void nr_get_prach_resources(module_id_t mod_id, NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources; - NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon; + // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig; // todo int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, frequencyStart, i, deltaPreamble_Msg3; uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size; - NR_RSRP_Range_t rsrp_ThresholdSSB; - /* TBR retrieve following params - // currently hardcoded */ - prach_resources->ra_PreambleIndex = 51; - - /*uint8_t Msg3_size = nr_UE_mac_inst->RA_Msg3_size; - uint8_t f_id = 0, num_prach = 0;*/ - - /*AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL, - "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", - mod_id);*/ + // NR_RSRP_Range_t rsrp_ThresholdSSB; // TBR todo /////////////////////////////////////////////////////////// //////////* UE Random Access Resource Selection *////////// /////////////////////////////////////////////////////////// - //numberOfRA_Preambles = (1 + nr_rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2; - numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles; - rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; - nr_UE_mac_inst->nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + // 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 + // -- TBR coming from dci_pdu_rel15[0].ra_preamble_index + // -- 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 - /* TBR 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_PreambleIndex provided by PDCCH && ra_PreambleIndex != 0b000000 - - set REAMBLE_INDEX to ra_PreambleIndex - - select the SSB signalled by PDCCH - - RA initiated for SI request: - - SSB selection, set prach_resources->ra_PreambleIndex */ - - // if (rach_ConfigDedicated) { // This is for network controlled Mobility + // if (rach_ConfigDedicated) { // This is for network controlled Mobility // // TBR operation for contention-free RA resources when: // // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection // // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection @@ -126,14 +110,19 @@ void nr_get_prach_resources(module_id_t mod_id, // return; // } - /* Contention-based RA preamble selection: - - TBR selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB */ + //////////* Contention-based RA preamble selection *////////// + + // todo: selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB + // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; // TBR + + Msg3_size = nr_UE_mac_inst->RA_Msg3_size; + numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles; + if (!nr_rach_ConfigCommon->groupBconfigured) { noGroupB = 1; } else { - /* RA preambles group B is configured + // 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->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2; sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA; switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){ /* - Threshold to determine the groups of RA preambles */ @@ -169,11 +158,11 @@ void nr_get_prach_resources(module_id_t mod_id, break; default: AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %d\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA); - /* TBR cases 10 -15*/ + /* todo cases 10 -15*/ } - /* - Power offset for preamble selection */ - /* TBR: what value to use as default? */ + /* Power offset for preamble selection in dB */ + /* TBR: what value to use as default? Shall it be converted ? */ messagePowerOffsetGroupB = -9999; switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){ case 0: @@ -204,84 +193,58 @@ void nr_get_prach_resources(module_id_t mod_id, AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %d\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); } - // TBR Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 + // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 nr_UE_mac_inst->deltaPreamble_Msg3 = 0; deltaPreamble_Msg3 = nr_UE_mac_inst->deltaPreamble_Msg3; } PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; - // PLThreshold = prach_resources->RA_PCMAX - nr_get_DELTA_PREAMBLE(mod_id, CC_id) - nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id) - messagePowerOffsetGroupB; - // TBR Note Pcmax is set to 0 here, we have to fix this /* Msg3 has not been transmitted yet */ if (first_Msg3 == 1) { if (noGroupB == 1) { // use Group A preamble prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; - prach_resources->ra_RACH_MaskIndex = 0; nr_UE_mac_inst->RA_usedGroupA = 1; } else if ((Msg3_size < messageSizeGroupA) && (get_PL(mod_id, 0, gNB_id) > PLThreshold)) { - // TBR update get_PL to NR - // TBR add condition for initiation by CCCH // Group B is configured and RA preamble Group A is used + // - todo TBR update get_PL to NR get_nr_PL (needs PHY_VARS_NR_UE) + // - todo add condition on CCCH_sdu_size for initiation by CCCH prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - prach_resources->ra_RACH_MaskIndex = 0; nr_UE_mac_inst->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); - prach_resources->ra_RACH_MaskIndex = 0; + prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); nr_UE_mac_inst->RA_usedGroupA = 0; } - - //TBR check why this is here - // prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); - } else { - // Msg3 is being retransmitted + } else { // Msg3 is being retransmitted if (nr_UE_mac_inst->RA_usedGroupA == 1) { if (nr_rach_ConfigCommon->groupBconfigured){ prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; } else { prach_resources->ra_PreambleIndex = (taus()) & 0x3f; // TBR check this - prach_resources->ra_RACH_MaskIndex = 0; } } else { - // TBR FIXME nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero - prach_resources->ra_PreambleIndex = - sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - prach_resources->ra_RACH_MaskIndex = 0; + prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); } } - // TBR 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 - - /* // choose random PRACH resource in TDD - if (nr_UE_mac_inst->tdd_Config) { - num_prach = get_num_prach_tdd(mod_id); - - if ((num_prach > 0) && (num_prach < 6)) - prach_resources->ra_TDD_map_index = (taus() % num_prach); - - f_id = get_fid_prach_tdd(mod_id, nr_UE_mac_inst [mod_id].RA_prach_resources->ra_TDD_map_index); - }*/ + // 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) *////////// ///////////////////////////////////////////////////////////////////////////// - // TBR condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) - // TBR check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission - if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER >1) + // todo condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) // TBR + // todo check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission + if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++; - //prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower + - // nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; // TBR prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); /* RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) @@ -289,11 +252,7 @@ void nr_get_prach_resources(module_id_t mod_id, // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario) // 3) TBR extend this (e.g. f_id selection, ul_carrier_id are hardcoded) */ - ul_carrier_id = 0; // UL carrier used for RA preamble transmission, hardcoded for NUL carrier - f_id = 0; - //frequencyStart = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; - - switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ + switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used case 0: msg1_FDM = 1; break; @@ -312,36 +271,41 @@ void nr_get_prach_resources(module_id_t mod_id, prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; - // TBR this is for TDD FR1 only - 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]; // starting symbol of the PRACH occasion + // 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] - // pick the first slot of the PRACH occasion in a system frame (0 <= t_id <= 80) + ul_carrier_id = 0; // todo SUL + f_id = nr_rach_ConfigCommon->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; + + LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI); } void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ - #if 0 //TBR + + NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - - // start contention resolution timer - nr_UE_mac_inst->RA_attempt_number++; - if (opt_enabled) { - trace_pdu(DIRECTION_UPLINK, NULL, 0, mod_id, WS_NO_RNTI, nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, nr_UE_mac_inst->RA_attempt_number); - LOG_D(OPT, "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", mod_id, frameP, 1, nr_UE_mac_inst->RA_Msg3_size); - } - #endif + // Start contention resolution timer + nr_UE_mac_inst->RA_attempt_number++; // todo this is not used + } - void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ #if 0 // TBR AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); @@ -352,10 +316,6 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint nr_UE_mac_inst->RA_contention_resolution_cnt = 0; nr_UE_mac_inst->RA_contention_resolution_timer_active = 1; - if (opt_enabled) { - trace_pdu(DIRECTION_UPLINK, &nr_UE_mac_inst->CCCH_pdu.payload[0], nr_UE_mac_inst->RA_Msg3_size, mod_id, WS_C_RNTI, nr_UE_mac_inst->crnti, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, 0); - LOG_D(OPT, "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", mod_id, frameP, nr_UE_mac_inst->crnti /*nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex */, nr_UE_mac_inst->RA_Msg3_size); - } #endif } @@ -374,44 +334,35 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, int nr_tti_tx){ NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); - uint8_t size_sdu = 0, Nb_tb = 1, lcid = CCCH, dcch_header_len = 0, ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; - // UE_MODE_t UE_mode; - uint16_t Size16, sdu_lengths; + uint8_t lcid = CCCH, dcch_header_len = 0, mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES], * payload; + uint16_t size_sdu = 0; + unsigned short post_padding; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (struct NR_RACH_ConfigCommon_t *) NULL; NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources; int32_t frame_diff = 0; - // Modification for phy_stub_ue operation // TBR - // if(nfapi_mode == 3) { // phy_stub_ue mode - // UE_mode = nr_UE_mac_inst->UE_mode[CC_id]; - // LOG_D(MAC, "ue_get_rach, UE_mode: %d", UE_mode); - // } - // else // Full stack mode - // UE_mode = get_nrUE_mode(mod_id, CC_id, gNB_id); // TBR + uint8_t sdu_lcids[NB_RB_MAX] = {0}; // TBR + uint16_t sdu_lengths[NB_RB_MAX] = {0}; // TBR + int TBS_bytes = 848, header_length_total, num_sdus, offset; // TBR AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); if (UE_mode == PRACH) { - LOG_D(MAC, "ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active); - if (nr_UE_mac_inst->nr_rach_ConfigCommon) { - nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon; - printf("nr_rach_ConfigCommon from MAC nr_UE_mac_inst\n"); /* TBR DEBUG only */ - } else return NULL; - /* TBR moved below - size_sdu = mac_rrc_nr_data_req(mod_id, - CC_id, - frame, - CCCH, - 1, - &nr_UE_mac_inst->CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT) + 1], gNB_id, 0);*/ + LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active); + + AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); + + if (nr_UE_mac_inst->nr_rach_ConfigCommon) { // TBR check the condition + nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon; + } else return NULL; if (nr_UE_mac_inst->RA_active == 0) { /* RA not active - checking if RRC is ready to initiate the RA procedure */ - LOG_I(MAC, "RA not active\n"); + LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n"); - /* TBR flush Msg3 Buffer + /* TBR flush Msg3 Buffer this was done like this but at PHY level for(i=0; iRA_PREAMBLE_TRANSMISSION_COUNTER = 1; - nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; - prach_resources->RA_PREAMBLE_BACKOFF = 0; - - /* TBR: if carrier to use is explicitly signalled do RA CARRIER SELECTION (SUL, NUL) this will set PCMAX */ - prach_resources->RA_PCMAX = 0; - - /* TBR: BWP operation (subclause 5.15 TS 38.321) */ + nr_UE_mac_inst->RA_RAPID_found = 0; /* Set RA_PREAMBLE_POWER_RAMPING_STEP */ switch (nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep){ // in dB @@ -445,187 +389,113 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, break; } + prach_resources->RA_PREAMBLE_BACKOFF = 0; prach_resources->RA_SCALING_FACTOR_BI = 1; + prach_resources->RA_PCMAX = 0; // currently hardcoded to 0 - /* TBR: initialization by beam failure recovery */ + // todo: + // - 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 - /* TBR: initialization by handover */ + if (!IS_SOFTMODEM_NOS1){ + // todo mac_rrc_nr_data_req_ue + payload = &nr_UE_mac_inst->CCCH_pdu.payload; + size_sdu = (uint16_t) mac_rrc_nr_data_req_ue(mod_id, + CC_id, + frame, + CCCH, + payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]); - /* size_sdu = mac_rrc_nr_data_req(mod_id, - CC_id, - frame, - CCCH, - Nb_tb, - &nr_UE_mac_inst->CCCH_pdu.payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]); */ - // TBR mac_rrc_nr_data_req is a GNB func - // use nr_mac_rrc_data_ind_ue instead + LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id,frame, size_sdu); - // TBR fix CCCH PDU payload - Size16 = (uint16_t) size_sdu; + // todo: else triggers a transmission on DCCH using PRACH (during handover, or sending SR for example) - /* TBR FIX THIS + } else { + // fill ulsch_buffer with random data + payload = (uint8_t *)nr_UE_mac_inst->ulsch_pdu.payload[0]; + 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] = UL_SCH_LCID_DTCH; + sdu_lengths[0] = TBS_bytes - 3; + header_length_total += 2 + (sdu_lengths[0] >= 128); + size_sdu += sdu_lengths[0]; + num_sdus +=1; + } - // LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",mod_id,frame,size_sdu); - LOG_I(RRC, - "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest gNB %d) --->][MAC_UE][MOD %02d][]\n", - frame, mod_id, gNB_id, mod_id); - LOG_I(MAC, - "[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", - mod_id, frame, size_sdu); - - nr_UE_mac_inst->RA_RAPID_found = 0; - // TBR which frame and slot ? + // TBR which frame and slot ? nr_UE_mac_inst->RA_tx_frame = frame; nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx; nr_UE_mac_inst->RA_backoff_frame = frame; - nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;*/ + nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx; - /*if (size_sdu > 0) { */ + if (size_sdu > 0) { // TBR size_sdu + MAC_Header_len + mac_ce_len /* TBR initialisation by RRC // PDU from CCCH */ LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame); - // TBR - /*nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(SCH_SUBHEADER_SHORT) + sizeof(SCH_SUBHEADER_SHORT); + nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; + nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // TBR size_sdu + MAC_Header_len + mac_ce_len nr_UE_mac_inst->RA_prachMaskIndex = 0; - prach_resources->Msg3 = nr_UE_mac_inst->CCCH_pdu.payload; - nr_UE_mac_inst->RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + // TBR todo: add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + nr_UE_mac_inst->RA_backoff_cnt = 0; + nr_UE_mac_inst->RA_active = 1; + prach_resources->Msg3 = payload; - AssertFatal(nr_rach_ConfigCommon != NULL, - "[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n", - mod_id, frame); - nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; - - if (nr_UE_mac_inst->RA_window_cnt == 9) { - nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! - }*/ + // TBR todo double check window count + // nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; + // if (nr_UE_mac_inst->RA_window_cnt == 9) { + // nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! + // } // Fill in preamble and PRACH resources nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, NULL); - /*generate_ulsch_header((uint8_t *) & nr_UE_mac_inst->CCCH_pdu.payload[0], // mac header - 1, // num sdus - 0, // short pading - &Size16, // sdu length - &lcid, // sdu lcid - NULL, // power headroom - NULL, // crnti - NULL, // truncated bsr - NULL, // short bsr - NULL, // long_bsr - 1); //post_padding*/ - return (&nr_UE_mac_inst->RA_prach_resources); + offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer + (uint8_t *) payload, // logical channel payload + 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 + 1); // post_padding - /*} else if (nr_UE_mac_inst->scheduling_info. - BSR_bytes[nr_UE_mac_inst->scheduling_info.LCGID[DCCH]] > 0) { - // This is for triggering a transmission on DCCH using PRACH (during handover, - // or sending SR for example) + // Padding: fill remainder of DLSCH with 0 + if (post_padding > 0){ + for (int j = 0; j < (TBS_bytes - offset); j++) + payload[offset + j] = 0; // mac_pdu[offset + j] = 0; + } - dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element - LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(mod_id, - nr_UE_mac_inst->crnti, - gNB_id, frame, nr_tti_tx, - ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6 - #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 - #endif - ); - - if (nr_UE_mac_inst->crnti_before_ho) - LOG_D(MAC, - "[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n", - mod_id, frame, - nr_UE_mac_inst->crnti, - nr_UE_mac_inst->crnti_before_ho, - rlc_status.bytes_in_buffer, dcch_header_len); - else - LOG_D(MAC, - "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n", - mod_id, frame, rlc_status.bytes_in_buffer, - dcch_header_len); - - sdu_lengths = mac_rlc_data_req(mod_id, nr_UE_mac_inst->crnti, - gNB_id, frame, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used - (char *) &ulsch_buff[0] - #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0,0 - #endif - ); - - if(sdu_lengths > 0) - LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", mod_id, sdu_lengths); - else - LOG_E(MAC, "[UE %d] TX DCCH error\n", mod_id ); - - update_bsr(mod_id, frame, nr_tti_tx, gNB_id); - nr_UE_mac_inst->scheduling_info.BSR[nr_UE_mac_inst-> - scheduling_info.LCGID[DCCH]] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, - nr_UE_mac_inst - [mod_id].scheduling_info.BSR_bytes - [nr_UE_mac_inst - [mod_id].scheduling_info.LCGID - [DCCH]]); - - //TBR: fill BSR infos in UL TBS - - //header_len +=2; - nr_UE_mac_inst->RA_active = 1; - nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = - 1; - nr_UE_mac_inst->RA_Msg3_size = - size_sdu + dcch_header_len; - nr_UE_mac_inst->RA_prachMaskIndex = 0; - prach_resources->Msg3 = - ulsch_buff; - nr_UE_mac_inst->RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) - - AssertFatal(nr_rach_ConfigCommon != NULL, - "[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n", - mod_id, frame); - nr_UE_mac_inst->RA_window_cnt = - 2 + - nr_rach_ConfigCommon->ra_SupervisionInfo. - ra_ResponseWindowSize; - - if (nr_UE_mac_inst->RA_window_cnt == 9) { - nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! - } - - - nr_UE_mac_inst->RA_tx_frame = frame; - nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx; - nr_UE_mac_inst->RA_backoff_frame = frame; - nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx; - // Fill in preamble and PRACH resource - nr_get_prach_resources(mod_id, CC_id, gNB_id, - nr_tti_tx, 1, NULL); - generate_ulsch_header((uint8_t *) ulsch_buff, // mac header - 1, // num sdus - 0, // short pading - &Size16, // sdu length - &lcid, // sdu lcid - NULL, // power headroom - &nr_UE_mac_inst->crnti, // crnti - NULL, // truncated bsr - NULL, // short bsr - NULL, // long_bsr - 0); //post_padding - - return (&nr_UE_mac_inst->RA_prach_resources); - }*/ + return (prach_resources); + } } 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 + // 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 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, nr_UE_mac_inst->RA_window_cnt, nr_UE_mac_inst->RA_tx_frame, nr_UE_mac_inst->RA_tx_subframe); - // - TBR check + if (nr_UE_mac_inst->rnti_type = NR_RNTI_RA){ // add condition on BI + // TBR todo + } else { + prach_resources->RA_PREAMBLE_BACKOFF = 0; + } // compute backoff parameters if (nr_UE_mac_inst->RA_backoff_cnt > 0){ frame_diff = (sframe_t) frame - nr_UE_mac_inst->RA_backoff_frame; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 677a27fb3d..d595116979 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -114,7 +114,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_ 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); + rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot); // TBR dl_config->number_pdus = dl_config->number_pdus + 1; } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index e192bfb232..7c99ed36a6 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2752,7 +2752,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 @@ -3280,3 +3282,169 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n"); } } + +//////////////////////////////////////////////////////// +/////* ULSCH MAC PDU generation (6.1.2 TS 38.321) *///// +//////////////////////////////////////////////////////// + +unsigned char 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) { + + NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu; + unsigned char first_element = 0, last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0; + int mac_ce_size, offset; + + LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus); + + #ifdef DEBUG_HEADER_PARSING + + 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]); + + #endif + + // Generating UL MAC subPDUs including MAC SDU and subheader + + 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); + + 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]; + } + + 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 final offset for padding + if (post_padding > 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 - mac_pdu)); + + return offset; +} \ No newline at end of file diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index cb8ded1971..08976522b0 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -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; } \ No newline at end of file diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 6e0d0a10de..7bc7e4b90c 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -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