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
This commit is contained in:
@@ -1641,6 +1641,7 @@ set (MAC_NR_SRC
|
||||
${NR_MAC_DIR}/config.c
|
||||
${NR_MAC_DIR}/gNB_scheduler.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_phytest.c
|
||||
)
|
||||
@@ -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( 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}/LAYER2/NR_MAC_UE")
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
|
||||
#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 "RRC/LTE/rrc_extern.h"
|
||||
#include "PHY_INTERFACE/phy_interface.h"
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@
|
||||
#include "SCHED_NR/sched_nr.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 "RRC/LTE/rrc_extern.h"
|
||||
#include "PHY_INTERFACE/phy_interface.h"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "PHY/LTE_TRANSPORT/if4_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 "common/utils/LOG/log.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);
|
||||
|
||||
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);
|
||||
|
||||
unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
/*! \file phy_procedures_nr_ue.c
|
||||
* \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
|
||||
* \version 0.1
|
||||
* \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
|
||||
* \warning
|
||||
*/
|
||||
@@ -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);
|
||||
#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)
|
||||
@@ -1560,6 +1544,19 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR
|
||||
|
||||
#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,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
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
|
||||
uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
|
||||
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++) {
|
||||
|
||||
@@ -3528,7 +3525,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_tti_rx = proc->nr_tti_rx;
|
||||
int ret=0, ret1=0;
|
||||
//int CC_id = ue->CC_id;
|
||||
uint8_t CC_id = ue->CC_id;
|
||||
NR_UE_PDSCH *pdsch_vars;
|
||||
uint8_t is_cw0_active = 0;
|
||||
uint8_t is_cw1_active = 0;
|
||||
@@ -3800,11 +3797,89 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
if (ue->if_inst && ue->if_inst->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,
|
||||
uint8_t do_pdcch_flag,
|
||||
runmode_t mode)
|
||||
{
|
||||
int l,l2;
|
||||
int pilot1;
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_tti_rx = proc->nr_tti_rx;
|
||||
int slot_pbch;
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
//#include "PHY/defs_common.h"
|
||||
#include "mac.h"
|
||||
|
||||
#include "RRC/LTE/rrc_defs.h"
|
||||
|
||||
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];
|
||||
extern UE_RRC_INST *UE_rrc_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_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_eNB_INST;
|
||||
extern uint16_t NB_UE_INST;
|
||||
@@ -65,7 +60,6 @@ extern uint16_t NB_THREAD_INST;
|
||||
extern unsigned char NB_RN_INST;
|
||||
extern unsigned short NODE_ID[1];
|
||||
|
||||
|
||||
extern int cqi_to_mcs[16];
|
||||
|
||||
extern uint32_t RRC_CONNECTION_FLAG;
|
||||
|
||||
@@ -41,6 +41,31 @@
|
||||
|
||||
#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 {
|
||||
uint8_t LCID:6; // octet 1 [5:0]
|
||||
uint8_t F:1; // octet 1 [6]
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "mac_defs.h"
|
||||
|
||||
//extern NR_UE_MAC_INST_t *UE_mac_inst;
|
||||
|
||||
// Type0-PDCCH search space
|
||||
extern const int32_t table_38213_13_1_c2[16];
|
||||
extern const int32_t table_38213_13_1_c3[16];
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
/* \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(
|
||||
module_id_t module_idP,
|
||||
uint8_t CC_id,
|
||||
uint8_t *pduP,
|
||||
uint16_t mac_pdu_len,
|
||||
uint16_t mac_pdu_len,
|
||||
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);
|
||||
|
||||
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
|
||||
/** @}*/
|
||||
|
||||
@@ -21,23 +21,41 @@
|
||||
|
||||
/* \file ue_procedures.c
|
||||
* \brief procedures related to UE
|
||||
* \author R. Knopp, K.H. HSU
|
||||
* \author R. Knopp, K.H. HSU, G. Casati
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \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
|
||||
* \warning
|
||||
*/
|
||||
|
||||
/* MAC related headers */
|
||||
#include "mac_proto.h"
|
||||
#include "LAYER2/NR_MAC/nr_mac.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac.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 "assertions.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 "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 <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
|
||||
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(
|
||||
module_id_t module_idP,
|
||||
uint8_t CC_id,
|
||||
uint8_t *pduP,
|
||||
uint16_t mac_pdu_len,
|
||||
uint16_t mac_pdu_len,
|
||||
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;
|
||||
uint16_t pdu_len = mac_pdu_len;
|
||||
int pdu_len = mac_pdu_len;
|
||||
|
||||
uint16_t mac_ce_len;
|
||||
uint16_t mac_subheader_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
|
||||
// Except:
|
||||
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
|
||||
@@ -2067,12 +2152,16 @@ void nr_ue_process_mac_pdu(
|
||||
|
||||
uint8_t done = 0;
|
||||
|
||||
while (!done || pdu_len <= 0){
|
||||
mac_ce_len = 0x0000;
|
||||
mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
|
||||
mac_sdu_len = 0x0000;
|
||||
while (!done && pdu_len > 0){
|
||||
mac_ce_len = 0;
|
||||
mac_subheader_len = 1; // default to fixed-length subheader = 1-oct
|
||||
mac_sdu_len = 0;
|
||||
switch(((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID){
|
||||
// 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:
|
||||
// MSG4 RRC Connection Setup 38.331
|
||||
// varialbe length
|
||||
@@ -2082,8 +2171,29 @@ void nr_ue_process_mac_pdu(
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
|
||||
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;
|
||||
|
||||
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
|
||||
|
||||
// 38.321 Ch6.1.3.14
|
||||
// varialbe length
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
|
||||
@@ -2169,10 +2279,70 @@ void nr_ue_process_mac_pdu(
|
||||
case DL_SCH_LCID_TA_COMMAND:
|
||||
// 38.321 Ch6.1.3.4
|
||||
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;
|
||||
case DL_SCH_LCID_CON_RES_ID:
|
||||
// 38.321 Ch6.1.3.3
|
||||
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;
|
||||
case DL_SCH_LCID_PADDING:
|
||||
done = 1;
|
||||
@@ -2180,25 +2350,62 @@ void nr_ue_process_mac_pdu(
|
||||
break;
|
||||
|
||||
// MAC SDU
|
||||
/* TODO double check SRBs 1-3 & DRB 1-3 */
|
||||
|
||||
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:
|
||||
// check if LCID is valid at current time.
|
||||
case UL_SCH_LCID_SRB3:
|
||||
// check if LCID is valid at current time.
|
||||
default:
|
||||
// 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){
|
||||
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_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
|
||||
break;
|
||||
}
|
||||
pdu_ptr += ( 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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,10 @@
|
||||
#include "assertions.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/NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "UTIL/OPT/opt.h"
|
||||
@@ -64,10 +65,6 @@
|
||||
#define ENABLE_MAC_PAYLOAD_DEBUG
|
||||
#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 };
|
||||
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
@@ -375,11 +372,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "assertions.h"
|
||||
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.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/vcd_signal_dumper.h"
|
||||
#include "UTIL/OPT/opt.h"
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* 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 @@
|
||||
|
||||
#include "LAYER2/MAC/mac.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 "common/utils/LOG/log.h"
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "nr_mac_gNB.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "NR_TAG-Id.h"
|
||||
|
||||
void set_cset_offset(uint16_t);
|
||||
|
||||
@@ -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_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 nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "mac_proto.h"
|
||||
#include "LAYER2/MAC/mac_extern.h" //temporary
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "assertions.h"
|
||||
|
||||
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
@@ -106,6 +106,9 @@ void mac_top_init_gNB(void)
|
||||
|
||||
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++) {
|
||||
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 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "LAYER2/MAC/mac.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/TOOLS/time_meas.h"
|
||||
#include "targets/ARCH/COMMON/common_lib.h"
|
||||
|
||||
|
||||
#include "NR_TAG.h"
|
||||
|
||||
/*! \brief gNB common channels */
|
||||
typedef struct {
|
||||
int physCellId;
|
||||
@@ -107,7 +109,9 @@ typedef struct gNB_MAC_INST_s {
|
||||
/// frame counter
|
||||
frame_t frame;
|
||||
/// slot counter
|
||||
int slot;
|
||||
int slot;
|
||||
/// timing advance group
|
||||
NR_TAG_t *tag;
|
||||
/// Pointer to IF module instance for PHY
|
||||
NR_IF_Module_t *if_inst;
|
||||
/// Common cell resources
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "openair1/PHY/phy_extern.h"
|
||||
#include "openair1/SCHED_NR/fapi_nr_l1.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/NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
#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/platform_types.h"
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "platform_types.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 "NR_asn_constant.h"
|
||||
#include "NR_MeasConfig.h"
|
||||
|
||||
Reference in New Issue
Block a user