Commit 310efee7 authored by Guido Casati's avatar Guido Casati Committed by cig

Implementation of TA procedures at MAC layer for gNB and UE

- Initial gNB DLSCH and UE spec scheduling implentation
- MAC PDU generation (including header as per TS 38.321)
- MAC PDU processing at UE side with extracion of TA updates
- General code cleanup
- Introduced NR MAC COMMON folder, moved common files here
parent f0b7debe
Branches unavailable
2024.w43 2024.w42 2024.w41 2024.w40 2024.w39 2024.w38 2024.w36 2024.w35 2024.w34 2024.w33 2024.w32 2024.w31 2024.w30 2024.w29 2024.w28 2024.w27 2024.w26 2024.w25 2024.w24 2024.w23 2024.w22 2024.w21 2024.w18 2024.w17 2024.w16 2024.w15 2024.w14 2024.w13 2024.w12 2024.w11 2024.w10 2024.w09 2024.w08 2024.w06 2024.w05 2024.w04 2024.w03 2024.w02 2024.w01 2023.w51 2023.w50 2023.w49 2023.w48 2023.w47 2023.w45 2023.w43 2023.w42 2023.w41 2023.w40 2023.w39 2023.w38 2023.w37 2023.w36 2023.w34 2023.w33 2023.w32 2023.w31 2023.w30 2023.w29 2023.w28 2023.w27 2023.w26 2023.w25 2023.w24 2023.w23 2023.w22 2023.w21 2023.w20 2023.w19 2023.w18 2023.w18b 2023.w16 2023.w15 2023.w14 2023.w13 2023.w12 2023.w11 2023.w11b 2023.w10 2023.w10b 2023.w09 2023.w08 2023.w08b 2023.w07 2023.w06 2023.w05 2023.w03 2023.w02 2022.42 2022.41 2022.w51 2022.w50 2022.w49 2022.w48 2022.w47 2022.w46 2022.w45 2022.w43 2022.w42 2022.w42b 2022.w41 2022.w40 2022.w39 2022.w38 2022.w37 2022.w37b 2022.w36 2022.w35 2022.w33 2022.w32 2022.w31 2022.w31b 2022.w30 2022.w29 2022.w26 2022.w25 2022.w24 2022.w24b 2022.w23 2022.w22 2022.w21 2022.w20 2022.w19 2022.w18 2022.w17 2022.w15 2022.w15b 2022.w14a 2022.w13 2022.w13b 2022.w13a 2022.w12 2022.w10 2022.w09 2022.w09b 2022.w08 2022.w08b 2022.w07 2022.w07b 2022.w06 2022.w06a 2022.w05 2022.w05b 2022.w03_hotfix 2022.w03_b 2022.w02 2022.w01 2021.wk46 2021.wk14_a 2021.wk13_d 2021.wk13_c 2021.w51_c 2021.w51_a 2021.w50_a 2021.w49_b 2021.w49_a 2021.w48 2021.w47 2021.w46 2021.w46-powder 2021.w45 2021.w45_b 2021.w44 2021.w43 2021.w42 2021.w37 2021.w36 2021.w35 2021.w34 2021.w33 2021.w32 2021.w31 2021.w30 2021.w29 2021.w28 2021.w27 2021.w26 2021.w25 2021.w24 2021.w23 2021.w22 2021.w20 2021.w19 2021.w18_b 2021.w18_a 2021.w17_b 2021.w16 2021.w15 2021.w14 2021.w13_a 2021.w12 2021.w11 2021.w10 2021.w09 2021.w08 2021.w06 2021.w05 2021.w04 2021.w02 2020.w51_2 2020.w51 2020.w50 2020.w49 2020.w48_2 2020.w48 2020.w47 2020.w46_2 2020.w46 2020.w45_2 2020.w45 2020.w44 2020.w42_2 2020.w42 2020.w41 2020.w39 2020.w38 2020.w37 2020.w36 2020.w34 2020.w33 2020.w31 2020.w30 2020.w29 2020.w28 2020.w26 2020.w25 2020.w24 2020.w23 2020.w22 2020.w19 2020.w17 2020.w16 2020.w15 2020.w11 2020.w09 2020.w06 2020.w05 v2.1.0 v2.0.0 setparam flexran-eol benetel_phase_rotation benetel_gnb_rel_2.0 benetel_gnb_rel_1.0 benetel_enb_rel_2.0 benetel_enb_rel_1.0 ARC_1.3
No related merge requests found
...@@ -1641,6 +1641,7 @@ set (MAC_NR_SRC ...@@ -1641,6 +1641,7 @@ set (MAC_NR_SRC
${NR_MAC_DIR}/config.c ${NR_MAC_DIR}/config.c
${NR_MAC_DIR}/gNB_scheduler.c ${NR_MAC_DIR}/gNB_scheduler.c
${NR_MAC_DIR}/gNB_scheduler_bch.c ${NR_MAC_DIR}/gNB_scheduler_bch.c
${NR_MAC_DIR}/gNB_scheduler_dlsch.c
${NR_MAC_DIR}/gNB_scheduler_primitives.c ${NR_MAC_DIR}/gNB_scheduler_primitives.c
${NR_MAC_DIR}/gNB_scheduler_phytest.c ${NR_MAC_DIR}/gNB_scheduler_phytest.c
) )
...@@ -1713,7 +1714,7 @@ add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag) ...@@ -1713,7 +1714,7 @@ add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ) add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c )
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE") include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE") include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
......
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h" #include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h" #include "PHY_INTERFACE/phy_interface.h"
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
#include "SCHED_NR/sched_nr.h" #include "SCHED_NR/sched_nr.h"
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h" #include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h" #include "PHY_INTERFACE/phy_interface.h"
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "common/utils/system.h" #include "common/utils/system.h"
......
...@@ -289,7 +289,13 @@ uint16_t nr_get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1); ...@@ -289,7 +289,13 @@ uint16_t nr_get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1);
int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance); /*! \brief Compute the timing adjustment at UE side from the old TA offset and the new received TA command
@param Mod_id Local UE index on which to act
@param CC_id Component Carrier Index
@param timing_advance TA command
@param mu numerology index (0,1,2..)
*/
void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t timing_advance, uint8_t mu);
void nr_process_timing_advance_rar(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance); void nr_process_timing_advance_rar(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance);
unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
......
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
/*! \file phy_procedures_nr_ue.c /*! \file phy_procedures_nr_ue.c
* \brief Implementation of UE procedures from 36.213 LTE specifications * \brief Implementation of UE procedures from 36.213 LTE specifications
* \author R. Knopp, F. Kaltenberger, N. Nikaein, A. Mico Pereperez * \author R. Knopp, F. Kaltenberger, N. Nikaein, A. Mico Pereperez, G. Casati
* \date 2018 * \date 2018
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note * \note
* \warning * \warning
*/ */
...@@ -421,22 +421,6 @@ void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,ui ...@@ -421,22 +421,6 @@ void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,ui
LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance); LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
#endif #endif
}
void nr_process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
{
// uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
// timing advance has Q1.5 format
timing_advance = timing_advance - 31;
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!!
LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
} }
uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id) uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
...@@ -1560,6 +1544,19 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR ...@@ -1560,6 +1544,19 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR
#endif #endif
void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing_advance, uint8_t mu){
// 3GPP TS 38.213 p4.2
int factor_mu = 1 << mu;
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * 1024 / factor_mu ;
LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value is %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
}
void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
uint8_t eNB_id, uint8_t eNB_id,
...@@ -3361,7 +3358,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB ...@@ -3361,7 +3358,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol; uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols; uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); LOG_I(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1);
for (m = s0; m < (s1 + s0); m++) { for (m = s0; m < (s1 + s0); m++) {
...@@ -3528,7 +3525,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ...@@ -3528,7 +3525,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
int frame_rx = proc->frame_rx; int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx; int nr_tti_rx = proc->nr_tti_rx;
int ret=0, ret1=0; int ret=0, ret1=0;
//int CC_id = ue->CC_id; uint8_t CC_id = ue->CC_id;
NR_UE_PDSCH *pdsch_vars; NR_UE_PDSCH *pdsch_vars;
uint8_t is_cw0_active = 0; uint8_t is_cw0_active = 0;
uint8_t is_cw1_active = 0; uint8_t is_cw1_active = 0;
...@@ -3800,11 +3797,89 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ...@@ -3800,11 +3797,89 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (ue->if_inst && ue->if_inst->dl_indication) if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication); ue->if_inst->dl_indication(&dl_indication);
} }
}
// TODO CRC check for CW0
// Check CRC for CW 0
/*if (ret == (1+dlsch0->max_turbo_iterations)) {
*dlsch_errors=*dlsch_errors+1;
if(dlsch0->rnti != 0xffff){
LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
ue->Mod_id,dlsch0->rnti,
harq_pid,frame_rx,subframe_rx,
dlsch0->harq_processes[harq_pid]->rvidx,
dlsch0->harq_processes[harq_pid]->round,
dlsch0->harq_processes[harq_pid]->mcs,
dlsch0->harq_processes[harq_pid]->TBS);
}
} else {
if(dlsch0->rnti != 0xffff){
LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
ue->Mod_id,dlsch0->rnti,
harq_pid,frame_rx,subframe_rx,
dlsch0->harq_processes[harq_pid]->rvidx,
dlsch0->harq_processes[harq_pid]->round,
dlsch0->harq_processes[harq_pid]->mcs,
dlsch0->harq_processes[harq_pid]->TBS);
}
if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){
int j;
LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
LOG_T(PHY,"\n");
}*/
if (ue->mac_enabled == 1) {
switch (pdsch) {
case PDSCH:
printf("PDSCH procedures\n");
nr_ue_send_sdu(ue->Mod_id,
CC_id,
frame_rx,
nr_tti_rx,
dlsch0->harq_processes[harq_pid]->b,
dlsch0->harq_processes[harq_pid]->TBS>>3,
eNB_id);
break;
case SI_PDSCH:
/*ue_decode_si(ue->Mod_id,
CC_id,
frame_rx,
eNB_id,
ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);*/
break;
case P_PDSCH:
/*ue_decode_p(ue->Mod_id,
CC_id,
frame_rx,
eNB_id,
ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);*/
break;
case RA_PDSCH:
/*process_rar(ue,proc,eNB_id,mode,abstraction_flag);*/
break;
case PDSCH1:
/*LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
AssertFatal(1==0,"exiting");*/
break;
case PMCH:
/*LOG_E(PHY,"Shouldn't have PMCH here\n");
AssertFatal(1==0,"exiting");*/
break;
}
}
/*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
}*/
// TODO CRC check for CW1
}
} }
...@@ -4132,6 +4207,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, ...@@ -4132,6 +4207,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
uint8_t do_pdcch_flag, uint8_t do_pdcch_flag,
runmode_t mode) runmode_t mode)
{ {
int l,l2;
int pilot1;
int frame_rx = proc->frame_rx; int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx; int nr_tti_rx = proc->nr_tti_rx;
int slot_pbch; int slot_pbch;
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
//#include "PHY/defs_common.h" //#include "PHY/defs_common.h"
#include "mac.h" #include "mac.h"
#include "RRC/LTE/rrc_defs.h" #include "RRC/LTE/rrc_defs.h"
extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
...@@ -51,13 +50,9 @@ extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; ...@@ -51,13 +50,9 @@ extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern UE_RRC_INST *UE_rrc_inst; extern UE_RRC_INST *UE_rrc_inst;
extern UE_MAC_INST *UE_mac_inst; extern UE_MAC_INST *UE_mac_inst;
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 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 eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern unsigned char NB_INST; extern unsigned char NB_INST;
extern unsigned char NB_eNB_INST; extern unsigned char NB_eNB_INST;
extern uint16_t NB_UE_INST; extern uint16_t NB_UE_INST;
...@@ -65,7 +60,6 @@ extern uint16_t NB_THREAD_INST; ...@@ -65,7 +60,6 @@ extern uint16_t NB_THREAD_INST;
extern unsigned char NB_RN_INST; extern unsigned char NB_RN_INST;
extern unsigned short NODE_ID[1]; extern unsigned short NODE_ID[1];
extern int cqi_to_mcs[16]; extern int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG; extern uint32_t RRC_CONNECTION_FLAG;
......
...@@ -41,6 +41,31 @@ ...@@ -41,6 +41,31 @@
#define NR_BCCH_BCH 5 // MIB #define NR_BCCH_BCH 5 // MIB
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
// - UL/DL-SCH: padding
// - UL-SCH: MSG3 48-bits
// |0|1|2|3|4|5|6|7| bit-wise
// |R|F| LCID |
// | L |
// |0|1|2|3|4|5|6|7| bit-wise
// |R|F| LCID |
// | L |
// | L |
// For both DL/UL-SCH
// For:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
// - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s)
// - UL-SCH: MSG3 48-bits
// |0|1|2|3|4|5|6|7| bit-wise
// |R|R| LCID |
// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits;
// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field;
// F: lenght of L is 0:8 or 1:16 bits wide
// R: Reserved bit, set to zero.
typedef struct { typedef struct {
uint8_t LCID:6; // octet 1 [5:0] uint8_t LCID:6; // octet 1 [5:0]
uint8_t F:1; // octet 1 [6] uint8_t F:1; // octet 1 [6]
......
/*
* 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 extern.h
* \brief NR mac externs
* \author G. Casati
* \date 2019
* \version 1.0
* \email guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
#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"
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
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 int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
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;
extern unsigned short NODE_ID[1];
/* Scheduler */
extern RAN_CONTEXT_t RC;
extern int phy_test;
extern uint8_t nfapi_mode;
/*#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;
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
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
* \warning * \warning
*/ */
#include "mac_defs.h"
//extern NR_UE_MAC_INST_t *UE_mac_inst;
// Type0-PDCCH search space // Type0-PDCCH search space
extern const int32_t table_38213_13_1_c2[16]; extern const int32_t table_38213_13_1_c2[16];
extern const int32_t table_38213_13_1_c3[16]; extern const int32_t table_38213_13_1_c3[16];
......
...@@ -125,16 +125,28 @@ uint32_t get_ssb_slot(uint32_t ssb_index); ...@@ -125,16 +125,28 @@ 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); 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
@param frameP Current Rx frame
@param ttiP Current Rx tti subframe
@param pdu Pointer to the MAC PDU
@param pdu_len Length of the MAC PDU
@param eNB_id Index of eNB that UE is attached to
@returns void
*/
void nr_ue_send_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP, uint8_t ttiP,
uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index);
void nr_ue_process_mac_pdu( void nr_ue_process_mac_pdu(
module_id_t module_idP, module_id_t module_idP,
uint8_t CC_id, uint8_t CC_id,
uint8_t *pduP, uint8_t *pduP,
uint16_t mac_pdu_len, uint16_t mac_pdu_len,
uint8_t eNB_index); uint8_t eNB_index);
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); 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 nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP, uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index);
#endif #endif
/** @}*/ /** @}*/
...@@ -21,23 +21,41 @@ ...@@ -21,23 +21,41 @@
/* \file ue_procedures.c /* \file ue_procedures.c
* \brief procedures related to UE * \brief procedures related to UE
* \author R. Knopp, K.H. HSU * \author R. Knopp, K.H. HSU, G. Casati
* \date 2018 * \date 2018
* \version 0.1 * \version 0.1
* \company Eurecom / NTUST * \company Eurecom / NTUST
* \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note * \note
* \warning * \warning
*/ */
/* MAC related headers */
#include "mac_proto.h" #include "mac_proto.h"
#include "LAYER2/NR_MAC/nr_mac.h" #include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "mac_extern.h" #include "mac_extern.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*/
#include "SCHED_NR_UE/defs.h"
#include "RRC/NR_UE/rrc_proto.h" #include "RRC/NR_UE/rrc_proto.h"
#include "assertions.h" #include "assertions.h"
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
/*Openair Packet Tracer */
#include "UTIL/OPT/opt.h"
#include "OCG.h"
/* log utils */
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "openair2/LAYER2/MAC/mac.h" #include "common/utils/LOG/vcd_signal_dumper.h"
/* TODO remove this for debugging purpose
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/MAC/mac.h"
*/
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
...@@ -2025,21 +2043,88 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e ...@@ -2025,21 +2043,88 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e
return 0; return 0;
} }
void nr_ue_send_sdu(module_id_t module_idP,
uint8_t CC_id,
frame_t frameP,
uint8_t ttiP,
uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index){
printf("nr_ue_send_sdu frame %d\n", frameP);
// Changes wrt LTE: replaced subframeP with ttiP
// TODO double check this and eventually create a type for TTI (tti_t)
// Note: pdu_len was previously named sdu and sdu_len
uint8_t * pduP = pdu;
NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP);
/*
#if UE_TIMING_TRACE
start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
#endif
*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
//LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]);
if (opt_enabled) {
trace_pdu(DIRECTION_DOWNLINK, pduP, pdu_len, module_idP, WS_C_RNTI,
UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP
LOG_D(OPT, "[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n",
module_idP, frameP, UE_mac_inst[module_idP].cs_RNTI, pdu_len);
}
/*
#ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",
module_idP, frameP, eNB_index, num_ce, num_sdu);
#endif
*/
/*
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
for (i = 0; i < 32; i++) {
LOG_T(MAC, "%x.", sdu[i]);
}
LOG_T(MAC, "\n");
#endif
*/
// Processing MAC PDU
// it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs
nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
/*
#if UE_TIMING_TRACE
stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
#endif
*/
}
void nr_ue_process_mac_pdu( void nr_ue_process_mac_pdu(
module_id_t module_idP, module_id_t module_idP,
uint8_t CC_id, uint8_t CC_id,
uint8_t *pduP, uint8_t *pduP,
uint16_t mac_pdu_len, uint16_t mac_pdu_len,
uint8_t eNB_index){ uint8_t eNB_index){
// This function is adapting code from the old
// parse_header(...) and ue_send_sdu(...) functions of OAI LTE
uint8_t *pdu_ptr = pduP; uint8_t *pdu_ptr = pduP;
uint16_t pdu_len = mac_pdu_len; int pdu_len = mac_pdu_len;
uint16_t mac_ce_len; uint16_t mac_ce_len;
uint16_t mac_subheader_len; uint16_t mac_subheader_len;
uint16_t mac_sdu_len; uint16_t mac_sdu_len;
NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP);
uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon;
// For both DL/UL-SCH // For both DL/UL-SCH
// Except: // Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID) // - UL/DL-SCH: fixed-size MAC CE(known by LCID)
...@@ -2067,12 +2152,16 @@ void nr_ue_process_mac_pdu( ...@@ -2067,12 +2152,16 @@ void nr_ue_process_mac_pdu(
uint8_t done = 0; uint8_t done = 0;
while (!done || pdu_len <= 0){ while (!done && pdu_len > 0){
mac_ce_len = 0x0000; mac_ce_len = 0;
mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct mac_subheader_len = 1; // default to fixed-length subheader = 1-oct
mac_sdu_len = 0x0000; mac_sdu_len = 0;
switch(((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID){ switch(((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID){
// MAC CE // MAC CE
/*#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 DL_SCH_LCID_CCCH: case DL_SCH_LCID_CCCH:
// MSG4 RRC Connection Setup 38.331 // MSG4 RRC Connection Setup 38.331
// varialbe length // varialbe length
...@@ -2082,8 +2171,29 @@ void nr_ue_process_mac_pdu( ...@@ -2082,8 +2171,29 @@ void nr_ue_process_mac_pdu(
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
mac_subheader_len = 3; mac_subheader_len = 3;
} }
/*LOG_D(MAC, "[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n",
module_idP, UE_mac_inst[module_idP].crnti, frameP, eNB_index, rx_lengths[i]);*/
/*#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
int j;
for (j = 0; j < rx_lengths[i]; j++) {
LOG_T(MAC, "%x.", (uint8_t) payload_ptr[j]);
}
LOG_T(MAC, "\n");
#endif*/
/*mac_rrc_data_ind_ue(module_idP,
CC_id,
frameP, subframeP,
UE_mac_inst[module_idP].crnti,
CCCH,
(uint8_t *) payload_ptr,
rx_lengths[i], eNB_index, 0);*/
break; break;
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH: case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
// 38.321 Ch6.1.3.14 // 38.321 Ch6.1.3.14
// varialbe length // varialbe length
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
...@@ -2169,10 +2279,70 @@ void nr_ue_process_mac_pdu( ...@@ -2169,10 +2279,70 @@ void nr_ue_process_mac_pdu(
case DL_SCH_LCID_TA_COMMAND: case DL_SCH_LCID_TA_COMMAND:
// 38.321 Ch6.1.3.4 // 38.321 Ch6.1.3.4
mac_ce_len = 1; mac_ce_len = 1;
uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND;
uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID;
/*
#ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pdu_ptr[1]);
#endif
*/
LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ta_command, tag_id, CC_id);
//if (nfapi_mode!=3){ // TODO check nfapi_mode
nr_process_timing_advance(module_idP, CC_id, ta_command, scs);
//}
break; break;
case DL_SCH_LCID_CON_RES_ID: case DL_SCH_LCID_CON_RES_ID:
// 38.321 Ch6.1.3.3 // 38.321 Ch6.1.3.3
mac_ce_len = 6; mac_ce_len = 6;
// TODO index should be shifted by 1
// 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, payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5]);
// TODO RACH is missing
/*if (UE_mac_inst[module_idP].RA_active == 1) {
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n",
module_idP, frameP);
UE_mac_inst[module_idP].RA_active = 0;
// check if RA procedure has finished completely (no contention)
tx_sdu = &UE_mac_inst[module_idP].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);
if(nfapi_mode == 3) { // phy_stub mode
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
// PRACH state.
LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n");
UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH;
//ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
}
else{
ra_failed(module_idP, CC_id, eNB_index);
}
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
return;
}
LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n", module_idP, frameP);
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
if(nfapi_mode == 3){
// phy_stub mode
// Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH
UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH;
} else { // Full stack mode
ra_succeeded(module_idP,CC_id,eNB_index);
}
}*/
break; break;
case DL_SCH_LCID_PADDING: case DL_SCH_LCID_PADDING:
done = 1; done = 1;
...@@ -2180,25 +2350,62 @@ void nr_ue_process_mac_pdu( ...@@ -2180,25 +2350,62 @@ void nr_ue_process_mac_pdu(
break; break;
// MAC SDU // MAC SDU
/* TODO double check SRBs 1-3 & DRB 1-3 */
case DL_SCH_LCID_SRB1: case DL_SCH_LCID_SRB1:
// check if LCID is valid at current time. // check if LCID is valid at current time.
/*if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n",
module_idP, frameP, rx_lcids[i], eNB_index, rx_lengths[i]);
mac_rlc_data_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, ENB_FLAG_NO,
MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);
} else if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1)) {
LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n",
module_idP, frameP, rx_lcids[i], eNB_index, rx_lengths[i]);
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
int j;
for (j = 0; j < rx_lengths[i]; j++)
LOG_T(MAC, "%x.", (unsigned char) payload_ptr[j]);
LOG_T(MAC, "\n");
#endif
mac_rlc_data_ind(module_idP,
UE_mac_inst[module_idP].crnti,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO,
rx_lcids[i],
(char *) payload_ptr, rx_lengths[i], 1, NULL);
}*/
case UL_SCH_LCID_SRB2: case UL_SCH_LCID_SRB2:
// check if LCID is valid at current time. // check if LCID is valid at current time.
case UL_SCH_LCID_SRB3: case UL_SCH_LCID_SRB3:
// check if LCID is valid at current time. // check if LCID is valid at current time.
default: default:
// check if LCID is valid at current time. // check if LCID is valid at current time.
mac_sdu_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
mac_subheader_len = 2;
if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){
mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
mac_subheader_len = 3; mac_subheader_len = 3;
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8)
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff);
} else {
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
mac_subheader_len = 2;
} }
// DRB LCID by RRC // DRB LCID by RRC
break; break;
} }
pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n"); AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n");
} }
} }
......
...@@ -33,9 +33,10 @@ ...@@ -33,9 +33,10 @@
#include "assertions.h" #include "assertions.h"
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h" #include "UTIL/OPT/opt.h"
...@@ -64,10 +65,6 @@ ...@@ -64,10 +65,6 @@
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1 #define DEBUG_eNB_SCHEDULER 1
extern RAN_CONTEXT_t RC;
extern int phy_test;
extern uint8_t nfapi_mode;
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
void clear_nr_nfapi_information(gNB_MAC_INST * gNB, void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
...@@ -375,11 +372,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -375,11 +372,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// Phytest scheduling // Phytest scheduling
if (slot_rxP==2){ if (slot_rxP == NR_UPLINK_SLOT){
nr_schedule_uss_ulsch_phytest(&RC.nrmac[module_idP]->UL_tti_req[0], frame_rxP, slot_rxP); nr_schedule_uss_ulsch_phytest(&RC.nrmac[module_idP]->UL_tti_req[0], frame_rxP, slot_rxP);
} }
if (slot_txP==1){ if (slot_txP == NR_DOWNLINK_SLOT){
nr_schedule_ue_spec(module_idP, frame_txP, slot_txP);
nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL);
} }
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "assertions.h" #include "assertions.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h" #include "UTIL/OPT/opt.h"
......
/*
* 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 gNB_scheduler_dlsch.c
* \brief procedures related to gNB for the DLSCH transport channel
* \author Guido Casati
* \date 2019
* \email: guido.casati@iis.fraunhofe.de
* \version 1.0
* @ingroup _mac
*/
/*PHY*/
#include "PHY/CODING/coding_defs.h"
#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 "LAYER2/MAC/mac.h"
/*NFAPI*/
#include "nfapi_nr_interface.h"
/*TAG*/
#include "NR_TAG-Id.h"
int nr_generate_dlsch_pdu(unsigned char *sdus_payload,
unsigned char *mac_pdu,
unsigned char num_sdus,
unsigned short *sdu_lengths,
unsigned char *sdu_lcids,
unsigned char drx_cmd,
unsigned short timing_advance_cmd,
NR_TAG_Id_t tag_id,
unsigned char *ue_cont_res_id,
unsigned short post_padding){
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
unsigned char * dlsch_buffer_ptr = sdus_payload;
uint8_t last_size = 0;
int offset = 0, mac_ce_size, i;
// MAC CEs
uint8_t mac_header_control_elements[16], *ce_ptr;
ce_ptr = &mac_header_control_elements[0];
// 1) Compute MAC CE and related subheaders
// DRX command subheader (MAC CE size 0)
if (drx_cmd != 255) {
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = DL_SCH_LCID_DRX;
//last_size = 1;
mac_pdu_ptr++;
}
// Timing Advance subheader
if (timing_advance_cmd != 31) {
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND;
//last_size = 1;
mac_pdu_ptr++;
// TA MAC CE (1 octet)
AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n", timing_advance_cmd);
((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f;
((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id;
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
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
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;
mac_pdu_ptr->LCID = DL_SCH_LCID_CON_RES_ID;
mac_pdu_ptr++;
//last_size = 1;
// contention resolution identity MAC ce has a fixed 48 bit size
// this contains the UL CCCH SDU. If UL CCCH SDU is longer than 48 bits,
// it contains the first 48 bits of the UL CCCH SDU
LOG_T(MAC, "[gNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2],
ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
// Copying bytes (6 octects) to CEs pointer
mac_ce_size = 6;
memcpy(ce_ptr, ue_cont_res_id, mac_ce_size);
// Copying bytes for MAC CEs to 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;
}
// 2) Generation of DLSCH MAC SDU subheaders
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]);
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;
}
mac_pdu_ptr += last_size;
// 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) {
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING;
mac_pdu_ptr++;
// compute final offset
offset = ((unsigned char *) mac_pdu_ptr - mac_pdu);
} else {
// no MAC subPDU with padding
}
//printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu));
return offset;
}
/*TODO expand the scheduling functionalities
this function is just generating a dummy MAC PDU and is used to transmit the TA
The structure of the algorithm is taken from the schedule_ue_spec function in LTE
and is preserved for future reference.*/
void
nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
UE_list_t *UE_list = &gNB->UE_list;
nfapi_nr_dl_config_request_body_t *dl_req;
// TODO size corretly the arrays
// at present, preserved the array length from lte code
// however not sure why NR_MAX_NB_RB was used here
unsigned char sdu_lcids[NR_MAX_NB_RB] = {0};
uint16_t sdu_lengths[NR_MAX_NB_RB] = {0};
int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0;
int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0;
// hardcoded parameters
// for DMRS configuration type 1
// sdus should come from RLC
static unsigned char dlsch_buffer[MAX_NR_DLSCH_PAYLOAD_BYTES];
uint8_t Qm = 2;
uint16_t R = 697;
uint16_t nb_rb = 50 ;
uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs
int ta_update = 17;
NR_TAG_Id_t tag_id = 0;
int UE_id = 0; // UE_list->head is -1 !
UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP] + 1; CC_id++) {
LOG_D(MAC, "doing nr_schedule_ue_spec for CC_id %d\n", CC_id);
dl_req = &gNB->DL_req[CC_id].dl_config_request_body;
//for (UE_id = UE_list->head; UE_id >= -1; UE_id = UE_list->next[UE_id]) {
/*
//process retransmission
if (round != 8) {
} else { // This is a potentially new SDU opportunity */
if (gNB->tag->timeAlignmentTimer != NULL) {
if (gNB->tag->timeAlignmentTimer == 0) {
ta_update = ue_sched_ctl->ta_update;
/* if we send TA then set timer to not send it for a while */
if (ta_update != 31)
ue_sched_ctl->ta_timer = 20;
/* reset ta_update */
ue_sched_ctl->ta_update = 31;
} else {
ta_update = 31;
}
}
ta_len = (ta_update != 31) ? 2 : 0;
// retrieve TAG ID
if(gNB->tag->tag_Id != NULL ){
tag_id = gNB->tag->tag_Id;
}
// fill dlsch_buffer with random data
for (i = 0; i < MAX_NR_DLSCH_PAYLOAD_BYTES; i++){
dlsch_buffer[i] = (unsigned char) rand();
}
/*
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
//TODO this will be eventually be removed
for (j = 0; j < NB_RB_MAX; j++){
sdu_lcids[j] = 0x05; // DRB
}
for (k = 0; k < NB_RB_MAX; k++){
sdu_lengths[k] = 1;
header_length_total += 2;
sdu_length_total += 1;
}*/
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
//TODO this will be eventually be removed
while (TBS - header_length_total - sdu_length_total - ta_len >= 3){
if (k < NR_MAX_NB_RB && j < NR_MAX_NB_RB){
sdu_lcids[j] = 0x05; // DRB
sdu_lengths[k] = 1;
header_length_total += 2;
sdu_length_total += 1;
num_sdus +=1;
k++, j++;
}
else {
break;
}
}
/*
// RLC data on DCCH
if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
}
// RLC data on DCCH1
if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
}
// looping over lcid
for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
// here sdu_lcids[num_sdus] is populated
}*/
// there is at least one SDU or TA command
// if (num_sdus > 0 ){
if (ta_len + sdu_length_total + header_length_total > 0) {
// Check if there is data from RLC or CE
if (TBS - header_length_total - sdu_length_total - ta_len >= 2) {
// we have to consider padding
// padding param currently not in use
padding = TBS - header_length_total - sdu_length_total - ta_len - 1;
post_padding = 1;
} else {
post_padding = 0;
}
offset = nr_generate_dlsch_pdu((unsigned char *) dlsch_buffer,
(unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
num_sdus, //num_sdus
sdu_lengths,
sdu_lcids,
255, // no drx
ta_update, // timing advance
tag_id,
NULL, // contention res id
post_padding);
// Padding: fill remainder of DLSCH with 0
if (post_padding > 0){
for (int j = 0; j < (TBS - offset); j++)
UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + j] = 0;
}
// Printing bit by bit for debugging purpose
/*for (int k = 0; k < TBS; k++){
printf("MAC PDU %u\n",((( UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][k/8]) & (1 << (k & 7))) >> (k & 7)));
if ((k+1)%8 == 0)
printf("\n");
}*/
}
else { // There is no data from RLC or MAC header, so don't schedule
}
//}
//} // UE_id loop
} // CC_id loop
}
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "nr_mac_gNB.h" #include "nr_mac_gNB.h"
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "NR_TAG-Id.h"
void set_cset_offset(uint16_t); void set_cset_offset(uint16_t);
...@@ -70,6 +71,19 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -70,6 +71,19 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
frame_t frame_txP, sub_frame_t slot_txP, frame_t frame_txP, sub_frame_t slot_txP,
frame_t frame_rxP, sub_frame_t slot_rxP); frame_t frame_rxP, sub_frame_t slot_rxP);
int nr_generate_dlsch_pdu(unsigned char *sdus_payload,
unsigned char *mac_pdu,
unsigned char num_sdus,
unsigned short *sdu_lengths,
unsigned char *sdu_lcids,
unsigned char drx_cmd,
unsigned short timing_advance_cmd,
NR_TAG_Id_t tag_id,
unsigned char *ue_cont_res_id,
unsigned short post_padding);
void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
void nr_schedule_css_dlsch_phytest(module_id_t module_idP, void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
*/ */
#include "mac_proto.h" #include "mac_proto.h"
#include "LAYER2/MAC/mac_extern.h" //temporary #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "assertions.h" #include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h"
...@@ -106,6 +106,9 @@ void mac_top_init_gNB(void) ...@@ -106,6 +106,9 @@ void mac_top_init_gNB(void)
RC.nrmac[i]->Mod_id = i; RC.nrmac[i]->Mod_id = i;
RC.nrmac[i]->tag = (NR_TAG_t*)malloc(sizeof(NR_TAG_t));
memset((void*)RC.nrmac[i]->tag,0,sizeof(NR_TAG_t));
for (j = 0; j < MAX_NUM_CCs; j++) { for (j = 0; j < MAX_NUM_CCs; j++) {
RC.nrmac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j]; RC.nrmac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j];
......
...@@ -55,12 +55,14 @@ ...@@ -55,12 +55,14 @@
#include "common/ran_context.h" #include "common/ran_context.h"
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "PHY/TOOLS/time_meas.h" #include "PHY/TOOLS/time_meas.h"
#include "targets/ARCH/COMMON/common_lib.h" #include "targets/ARCH/COMMON/common_lib.h"
#include "NR_TAG.h"
/*! \brief gNB common channels */ /*! \brief gNB common channels */
typedef struct { typedef struct {
int physCellId; int physCellId;
...@@ -107,7 +109,9 @@ typedef struct gNB_MAC_INST_s { ...@@ -107,7 +109,9 @@ typedef struct gNB_MAC_INST_s {
/// frame counter /// frame counter
frame_t frame; frame_t frame;
/// slot counter /// slot counter
int slot; int slot;
/// timing advance group
NR_TAG_t *tag;
/// Pointer to IF module instance for PHY /// Pointer to IF module instance for PHY
NR_IF_Module_t *if_inst; NR_IF_Module_t *if_inst;
/// Common cell resources /// Common cell resources
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "openair1/PHY/phy_extern.h" #include "openair1/PHY/phy_extern.h"
#include "openair1/SCHED_NR/fapi_nr_l1.h" #include "openair1/SCHED_NR/fapi_nr_l1.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h" #include "common/ran_context.h"
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
*/ */
#include "nr_rrc_extern.h" #include "nr_rrc_extern.h"
#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "COMMON/openair_defs.h" #include "COMMON/openair_defs.h"
#include "COMMON/platform_types.h" #include "COMMON/platform_types.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include "platform_types.h" #include "platform_types.h"
#include "LAYER2/NR_MAC_UE/mac.h" #include "LAYER2/NR_MAC_UE/mac.h"
#include "LAYER2/NR_MAC/nr_mac.h" #include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "rrc_list.h" #include "rrc_list.h"
#include "NR_asn_constant.h" #include "NR_asn_constant.h"
#include "NR_MeasConfig.h" #include "NR_MeasConfig.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment