Commit db808ddd authored by Raymond Knopp's avatar Raymond Knopp

Merge branch 'RU-RAU-split' of https://gitlab.eurecom.fr/oai/openairinterface5g into RU-RAU-split

Conflicts:
	openair2/ENB_APP/enb_config.c
parents c1fff427 faa111ec
......@@ -1566,7 +1566,7 @@ ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/emu_transport.c
#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/emu_transport.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/pgm_link.c
)
......
......@@ -493,6 +493,73 @@ typedef struct {
int32_t delta_TF;
} LTE_UL_eNB_HARQ_t;
typedef enum {
pucch_format1=0,
pucch_format1a,
pucch_format1b,
pucch_format2,
pucch_format2a,
pucch_format2b,
pucch_format3 // PUCCH format3
} PUCCH_FMT_t;
typedef enum {
SR,
HARQ,
CQI,
HARQ_SR,
HARQ_CQI,
SR_CQI,
HARQ_SR_CQI
} UCI_type_t;
#ifdef Rel14
typedef enum {
NOCE,
CEMODEA,
CEMODEB
} UE_type_t;
#endif
typedef struct {
uint8_t active;
/// Absolute frame for this UCI
uint16_t frame;
/// Absolute subframe for this UCI
uint8_t subframe;
/// corresponding UE RNTI
uint16_t rnti;
/// Type (SR,HARQ,CQI,HARQ_SR,HARQ_CQI,SR_CQI,HARQ_SR_CQI)
UCI_type_t type;
/// PUCCH format to use
PUCCH_FMT_t pucch_fmt;
/// antenna indicator
uint8_t num_pucch_resources;
/// two antenna n1_pucch
uint16_t n_pucch_1[2];
/// two antenna n2_pucch
uint16_t n_pucch_2[2];
#ifdef Rel14
/// non BL/CE, CEmodeA, CEmodeB
UE_type_t ue_type;
/// Indicates the symbols that are left empty due to eMTC retuning.
uint8_t empty_symbols;
/// number of repetitions for BL/CE
uint16_t total_repetitions;
/// The size of the DL CQI/PMI in bits.
uint16_t dl_cqi_pmi_size2;
/// The starting PRB for the PUCCH
uint8_t starting_prb;
/// The number of PRB in PUCCH
uint8_t n_PRB;
/// Selected CDM option
uint8_t cdm_Index;
// Indicates if the resource blocks allocated for this grant overlap with the SRS configuration.
uint8_t Nsrs;
#endif
} LTE_eNB_UCI_t;
typedef struct {
/// HARQ process mask, indicates which processes are currently active
uint16_t harq_mask;
......@@ -764,15 +831,6 @@ typedef enum {
rx_SIC_dual_stream
} RX_type_t;
typedef enum {
pucch_format1=0,
pucch_format1a,
pucch_format1b,
pucch_format2,
pucch_format2a,
pucch_format2b,
pucch_format3 // PUCCH format3
} PUCCH_FMT_t;
......
......@@ -120,8 +120,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
unsigned char exit_flag = 0,i,j,r,aa,layer;
int re;
unsigned char bw_scaling =1;
RU_t *ru;
int ru_id;
switch (N_RB_DL) {
case 6:
......
......@@ -233,6 +233,8 @@ typedef struct DCI6_1A_20MHz DCI6_1A_20MHz_t;
/// basic DCI Format Type 6-0B (5 MHz)
struct DCI6_0B_5MHz {
/// padding to fill 32-bit word
uint32_t padding:15;
/// DCI subframe repetition
uint32_t dci_rep:2;
/// new data indicator
......@@ -240,7 +242,7 @@ struct DCI6_0B_5MHz {
/// harq id
uint32_t harq_pid:1;
/// Repetition number
uint32_t rep:2;
uint32_t rep:3;
/// Modulation and Coding Scheme and Redundancy Version
uint32_t mcs:4;
/// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits)
......@@ -250,10 +252,12 @@ struct DCI6_0B_5MHz {
} __attribute__ ((__packed__));
typedef struct DCI6_0B_5MHz DCI6_0B_5MHz_t;
#define sizeof_DCI6_0B_5MHz_t 16
#define sizeof_DCI6_0B_5MHz_t 17
/// basic DCI Format Type 6-1B (5 MHz)
struct DCI6_1B_5MHz {
/// padding to fill 32-bit word
uint32_t padding:15;
/// DCI subframe repetition number
uint32_t dci_rep:2;
/// HARQ-ACK resource offset
......@@ -263,7 +267,7 @@ struct DCI6_1B_5MHz {
/// HARQ Process
uint32_t harq_pid:1;
/// Repetition number
uint32_t rep:2;
uint32_t rep:3;
/// Resource block assignment (assignment flag = 0 for 5 MHz, ceil(log2(floor(N_RB_DL/6)))+1)
uint32_t rballoc:3;
/// Modulation and Coding Scheme and Redundancy Version
......@@ -273,12 +277,12 @@ struct DCI6_1B_5MHz {
} __attribute__ ((__packed__));
typedef struct DCI6_1B_5MHz DCI6_1B_5MHz_t;
#define sizeof_DCI6_1B_5MHz_t 16
#define sizeof_DCI6_1B_5MHz_t 17
/// basic DCI Format Type 6-0B (10 MHz)
struct DCI6_0B_10MHz {
/// padding to fill 32-bit word
uint32_t padding:15;
uint32_t padding:14;
/// DCI subframe repetition
uint32_t dci_rep:2;
/// new data indicator
......@@ -286,7 +290,7 @@ struct DCI6_0B_10MHz {
/// harq id
uint32_t harq_pid:1;
/// Repetition number
uint32_t rep:2;
uint32_t rep:3;
/// Modulation and Coding Scheme and Redundancy Version
uint32_t mcs:4;
/// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits)
......@@ -296,7 +300,7 @@ struct DCI6_0B_10MHz {
} __attribute__ ((__packed__));
typedef struct DCI6_0B_10MHz DCI6_0B_10MHz_t;
#define sizeof_DCI6_0B_10MHz_t 17
#define sizeof_DCI6_0B_10MHz_t 18
/// basic DCI Format Type 6-1B (10 MHz)
struct DCI6_1B_10MHz {
......
......@@ -2188,5 +2188,7 @@ int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
int8_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type);
/**@}*/
#endif
......@@ -844,4 +844,21 @@ void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL)
}
int8_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type) {
uint8_t i;
int8_t first_free_index=-1;
AssertFatal(eNB!=NULL,"eNB is null\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
if ((eNB->uci_vars[i].active >0) &&
(eNB->uci_vars[i].rnti==rnti) &&
(eNB->uci_vars[i].frame==frame) &&
(eNB->uci_vars[i].subframe==subframe)) return(i);
else if ((eNB->uci_vars[i].active == 0) && (first_free_index==-1)) first_free_index=i;
}
if (type == SEARCH_EXIST) return(-1);
else return(first_free_index);
}
......@@ -619,6 +619,8 @@ typedef enum {
typedef struct RU_t_s{
/// index of this ru
uint32_t idx;
/// Pointer to configuration file
char *rf_config_file;
/// southbound interface
RU_if_south_t if_south;
/// timing
......@@ -886,15 +888,9 @@ typedef struct PHY_VARS_eNB_s {
/// Ethernet parameters for fronthaul interface
eth_params_t eth_params;
int rx_total_gain_dB;
// void (*do_prach)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame, int subframe);
int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *);
// void (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type);
// void (*proc_tx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *rn);
// void (*tx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc);
// void (*rx_fh)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe);
int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB);
// void (*fh_asynch)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe);
uint8_t local_flag;
LTE_DL_FRAME_PARMS frame_parms;
PHY_MEASUREMENTS_eNB measurements;
......@@ -919,6 +915,7 @@ typedef struct PHY_VARS_eNB_s {
LTE_eNB_PRACH prach_vars_br;
#endif
LTE_eNB_COMMON common_vars;
LTE_eNB_UCI_t uci_vars[NUMBER_OF_UE_MAX];
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PBCH pbch;
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
......@@ -1423,6 +1420,7 @@ typedef struct RRU_capabilities_s {
} RRU_capabilities_t;
typedef struct RRU_config_s {
/// Fronthaul format
RU_if_south_t FH_fmt;
/// number of EUTRA bands (<=4) configured in RRU
......
......@@ -1065,6 +1065,10 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
#endif
}
handle_uci_harq_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_ul_config_request_pdu_t *ul_config_pdu) {
}
handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
nfapi_ul_config_request_pdu_t *ul_config_pdu) {
......@@ -1072,10 +1076,32 @@ handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
int8_t UE_id;
// check if we have received a dci for this ue and ulsch descriptor is configured
if (ul_config_pdu == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) {
AssertFatal((UE_id = find_ulsch(rel8->rnti,eNB,SEARCH_EXIST))>=0,
"No existing UE ULSCH for rnti %x\n",rel8->rnti);
AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0,
"ulsch for UE_id %d is not active\n",UE_id);
}
else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST))>=0,
"No existing UE UCI for rnti %x\n",rel8->rnti);
handle_uci_harq_pdu(eNB,proc,ul_config_pdu);
}
else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) {
}
else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) {
}
else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
}
else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
}
else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
}
}
......@@ -1227,7 +1253,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
for (i=0;i<number_ul_pdu;i++) {
ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i];
LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type);
AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE,
AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE,
"Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type);
handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu);
}
......@@ -1524,6 +1551,8 @@ void process_HARQ_feedback(uint8_t UE_id,
int subframe = proc->subframe_rx;
int harq_pid = subframe2harq_pid( fp,frame,subframe);
nfapi_harq_indication_pdu_t *pdu;
if (fp->frame_type == FDD) { //FDD
subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
......@@ -1546,6 +1575,9 @@ void process_HARQ_feedback(uint8_t UE_id,
*/
}
// fill ACK/NAK Indication
pdu = &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs];
eNB->UL_INFO.harq_ind.number_of_harqs++;
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE(
......@@ -1578,6 +1610,7 @@ void process_HARQ_feedback(uint8_t UE_id,
?eNB->ulsch[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]:eNB->ulsch[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[1];
}
else { // PUCCH ACK/NAK
if ((SR_payload == 1)&&(pucch_sel!=2)) { // decode Table 7.3 if multiplexing and SR=1
nb_ACK = 0;
......@@ -2752,8 +2785,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
frame,subframe, i,
ulsch_harq->round-1);
dump_ulsch(eNB,proc,i);
exit(-1);
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
eNB->Mod_id,harq_pid,
......@@ -2768,46 +2799,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
ulsch_harq->o_ACK[0],
ulsch_harq->o_ACK[1],
ret);
/*
if (ulsch_harq->round ==
fp->maxHARQ_Msg3Tx) {
LOG_D(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n",
eNB->Mod_id, i);
eNB->UE_stats[i].mode = PRACH;
// if (eNB->mac_enabled==1) {
// mac_xface->cancel_ra_proc(eNB->Mod_id,
// eNB->CC_id,
// frame,
// eNB->UE_stats[i].crnti);
//
// }
// mac_phy_remove_ue(eNB->Mod_id,eNB->UE_stats[i].crnti);
eNB->ulsch[(uint32_t)i]->Msg3_active = 0;
//ulsch_harq->phich_active = 0;
} else {
// activate retransmission for Msg3 (signalled to UE PHY by PHICH (not MAC/DCI)
eNB->ulsch[(uint32_t)i]->Msg3_active = 1;
get_Msg3_alloc_ret(fp,
subframe,
frame,
&ulsch_harq->frame,
&ulsch_harq->subframe);
//mac_xface->set_msg3_subframe(eNB->Mod_id, eNB->CC_id, frame, subframe, eNB->ulsch[i]->rnti,
// eNB->ulsch[i]->Msg3_frame, eNB->ulsch[i]->Msg3_subframe);
T(T_ENB_PHY_MSG3_ALLOCATION, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
T_INT(i), T_INT(ulsch->rnti), T_INT(0
// 0 is for retransmission
),
T_INT(eNB->ulsch[i]->Msg3_frame), T_INT(eNB->ulsch[i]->Msg3_subframe));
}
*/
LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i);
} // This is Msg3 error
......@@ -2842,23 +2833,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
eNB->UE_stats[i].ulsch_errors[harq_pid]++;
eNB->UE_stats[i].ulsch_consecutive_errors++;
/*if (ulsch_harq->nb_rb > 20) {
dump_ulsch(eNB,proc,i);
exit(-1);
}*/
// indicate error to MAC
if (eNB->mac_enabled == 1) {
/*
mac_xface->rx_sdu(eNB->Mod_id,
eNB->CC_id,
frame,subframe,
ulsch->rnti,
NULL,
0,
harq_pid,
&eNB->ulsch[i]->Msg3_flag);
*/
}
}
}
} // ulsch in error
......@@ -2920,29 +2894,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
eNB->Mod_id,
frame,harq_pid,i);
if (eNB->mac_enabled) {
/*
mac_xface->rx_sdu(eNB->Mod_id,
eNB->CC_id,
frame,subframe,
eNB->ulsch[i]->rnti,
ulsch_harq->b,
ulsch_harq->TBS>>3,
harq_pid,
&ulsch->Msg3_flag);
*/
// Fill UL info
}
// one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
if (ulsch_harq->Msg3_flag == 0 ) {
eNB->UE_stats[i].mode = PRACH;
/*
mac_xface->cancel_ra_proc(eNB->Mod_id,
eNB->CC_id,
frame,
eNB->UE_stats[i].crnti);
mac_phy_remove_ue(eNB->Mod_id,eNB->UE_stats[i].crnti);
*/
eNB->ulsch[(uint32_t)i]->Msg3_active = 0;
} // Msg3_flag == 0
......@@ -2984,26 +2940,12 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
harq_pid,ulsch_harq->TBS>>3);
for (j=0; j<ulsch_harq->TBS>>3; j++)
LOG_T(PHY,"%x.",eNB->ulsch[i]->harq_processesyy[harq_pid]->b[j]);
LOG_T(PHY,"%x.",eNB->ulsch[i]->harq_processes[harq_pid]->b[j]);
LOG_T(PHY,"\n");
#endif
#endif
if (eNB->mac_enabled==1) {
/*
mac_xface->rx_sdu(eNB->Mod_id,
eNB->CC_id,
frame,subframe,
ulsch->rnti,
eNB->ulsch[i]->harq_processes[harq_pid]->b,
eNB->ulsch[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid,
NULL);*/
// Fill UL_INFO
} // mac_enabled==1
} // Msg3_flag == 0
......
......@@ -526,6 +526,8 @@ void RCconfig_RU() {
int num_eNB4RU = 0;
libconfig_int eNB_list[256];
int fronthaul_flag = CONFIG_TRUE;
/// TRUE for eNB or RRU, FALSE for RAU
int local_rf_flag = CONFIG_TRUE;
load_config_file(&cfg);
......@@ -553,7 +555,27 @@ void RCconfig_RU() {
fronthaul_flag = CONFIG_FALSE;
}
if (fronthaul_flag != CONFIG_TRUE) { // no fronthaul
if ( !(
config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf)
)
) {
local_rf_flag = CONFIG_FALSE;
}
if (local_rf_flag == CONFIG_TRUE) { // eNB or RRU
if ( !(
config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_MAX_RS_EPRE, &max_pdschReferenceSignalPower)
)
) {
AssertFatal (0,
"Failed to parse configuration file %s, RU %d config !\n",
RC.config_file_name, j);
continue;
}
>>>>>>> faa111ecc0815354979e075d5b83c5af107d404e
AssertFatal((setting_band = config_setting_get_member(setting_ru, CONFIG_STRING_RU_BAND_LIST))!=NULL,"No allowable LTE bands\n");
......@@ -566,7 +588,8 @@ void RCconfig_RU() {
printf("RU %d: band %d\n",j,band[i]);
}
} // fronthaul_flag == CONFIG_FALSE
else { // fronthaul_flag == CONFIG_TRUE
if (fronthaul_flag == CONFIG_TRUE) { // fronthaul_flag == CONFIG_TRUE
if ( !(
config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_ADDRESS, (const char **)&ipv4)
&& config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_REMOTE_ADDRESS, (const char **)&ipv4_remote)
......@@ -605,7 +628,6 @@ void RCconfig_RU() {
if ( !(
config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_TX, &nb_tx)
&& config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_RX, &nb_rx)
&& config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf)
)) {
AssertFatal (0,
"Failed to parse configuration file %s, RU %d config !\n",
......
......@@ -834,15 +834,15 @@ typedef struct {
/// Subframe where Msg2 is to be sent
uint8_t Msg2_subframe;
/// Frame where Msg2 is to be sent
uint8_t Msg2_frame;
frame_t Msg2_frame;
/// Subframe where Msg3 is to be sent
uint8_t Msg3_subframe;
sub_frame_t Msg3_subframe;
/// Frame where Msg3 is to be sent
uint8_t Msg3_frame;
frame_t Msg3_frame;
/// Subframe where Msg4 is to be sent
uint8_t Msg4_subframe;
sub_frame_t Msg4_subframe;
/// Frame where Msg4 is to be sent
uint8_t Msg4_frame;
frame_t Msg4_frame;
/// Flag to indicate the eNB should generate Msg4 upon reception of SDU from RRC. This is triggered by first ULSCH reception at eNB for new user.
uint8_t generate_Msg4;
/// Flag to indicate that eNB is waiting for ACK that UE has received Msg3.
......@@ -861,6 +861,10 @@ typedef struct {
int16_t RRC_timer;
/// Round of Msg3 HARQ
uint8_t msg3_round;
/// TBS used for Msg4
int Msg4_TBsize;
/// MCS used for Msg4
int Msg4_mcs;
#ifdef Rel14
uint8_t rach_resource_type;
uint8_t msg2_mpdcch_repetition_cnt;
......
......@@ -61,12 +61,6 @@
#include "SIMULATION/TOOLS/defs.h" // for taus
#include "T.h"
// eMTC notes
// Implements MSG2 and MSG4
// fill_rar for eMTC
// new RA_templates for eMTC UEs, CCCH_BR instead of CCCH
// resource allocation for format 1A (4->6 PRBs)
// initiate_ra_proc: add detection of BR/CE UEs
void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) {
......@@ -91,7 +85,7 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr
if (RA_template->RA_active == TRUE) {
// program reception 4 subframes prior to transmission
msg3_prog_subframe = (RA_template->Msg3_subframe + 6)%10;
if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023;
......@@ -104,7 +98,7 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr
(msg3_prog_subframe==subframeP)) {
LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
eNB->UL_req[CC_id].sfn_sf = (RA_template->Msg3_frame<<3) + RA_template->Msg3_subframe;
eNB->UL_req[CC_id].sfn_sf = (RA_template->Msg3_frame<<4) + RA_template->Msg3_subframe;
if (RA_template->msg3_round == 0) { // program ULSCH
ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
......@@ -149,44 +143,37 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr
}
}
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
{
void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) {
int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
RA_TEMPLATE *RA_template;
uint8_t i;
int16_t rrc_sdu_length;
uint8_t lcid;
uint8_t offset;
int UE_id = -1;
int16_t TBsize = -1;
uint16_t msg4_padding;
uint16_t msg4_post_padding;
uint16_t msg4_header;
uint8_t *vrb_map;
int first_rb;
int N_RB_DL;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req;
UE_list_t *UE_list=&eNB->UE_list;
int round;
nfapi_dl_config_request_body_t *dl_req;
vrb_map = cc[CC_idP].vrb_map;
dl_req = &eNB->DL_req[CC_idP].dl_config_request_body;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
#ifdef Rel14
int rmax = 0;
int rep = 0;
int reps = 0;
int num_nb = 0;
first_rb = 0;
struct PRACH_ConfigSIB_v1310 *ext4_prach;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
PRACH_ParametersCE_r13_t *p[3];
PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL};
if (cc[CC_id].radioResourceConfigCommon_BR) {
if (cc[CC_idP].radioResourceConfigCommon_BR) {
ext4_prach = cc[CC_id].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
switch (prach_ParametersListCE_r13->list.count) {
......@@ -202,37 +189,10 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count);
}
}
#endif
start_meas(&eNB->schedule_ra);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
// skip UL component carriers
if (is_UL_sf(&cc[CC_id],subframeP)==1) continue;
vrb_map = cc[CC_id].vrb_map;
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
N_RB_DL = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
for (i=0; i<NB_RA_PROC_MAX; i++) {
RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i];
if (RA_template->RA_active == TRUE) {
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
module_idP,CC_id,i,RA_template->generate_rar,RA_template->generate_Msg4,RA_template->wait_ack_Msg4, RA_template->rnti);
if (RA_template->generate_rar == 1) {
#ifdef Rel14
if (RA_template->rach_resource_type > 0) {
// This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213
// This uses an MPDCCH Type 2 common allocation according to Section 9.1.5 36-213
// Parameters:
// p=2+4 PRB set (number of PRB pairs 3)
// rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3
......@@ -242,7 +202,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// rmax from SIB2 information
rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13;
// choose r3 by default for RAR
// choose r3 by default for RAR (Table 9.1.5-5)
rep = 2;
// get actual repetition count from Table 9.1.5-3
reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep));
......@@ -252,7 +212,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
first_rb = RA_template->msg2_narrowband*6;
if ((RA_template->msg2_mpdcch_repetition_cnt == 0) &&
(mpdcch_sf_condition(eNB,CC_id,frameP,subframeP,rmax,TYPE2)>0)){
(mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2)>0)){
// MPDCCH configuration for RAR
......@@ -264,19 +224,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = RA_template->msg2_narrowband;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;
AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space
AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
"cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].physCellId;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(N_RB_DL,first_rb,6);
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6,0,6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0;
......@@ -288,7 +248,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 2;// N1A_PRB=3; => 208 bits
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0;
......@@ -307,14 +267,14 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++;
} //repetition_count==0 && SF condition met
if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
else if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
RA_template->msg2_mpdcch_repetition_cnt++;
if (RA_template->msg2_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition
if (cc[CC_id].tdd_Config==NULL) { // FDD case
if (cc[CC_idP].tdd_Config==NULL) { // FDD case
// wait 2 subframes for PDSCH transmission
if (subframeP>7) RA_template->Msg2_frame = (frameP+1)&1023;
else RA_template->Msg2_frame = frameP;
RA_template->Msg2_subframe = (subframeP+2)%10;
RA_template->Msg2_subframe = (subframeP+2)%10; // +2 is the "n+x" from Section 7.1.11 in 36.213
}
else {
AssertFatal(1==0,"TDD case not done yet\n");
......@@ -328,7 +288,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
......@@ -358,19 +318,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++;
// Program UL processing for Msg3, same as regular LTE
get_Msg3alloc(&cc[CC_id],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
fill_rar_br(eNB,CC_id,i,frameP,subframeP,cc[CC_id].RAR_pdu.payload,RA_template->rach_resource_type-1);
fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1);
// DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus];
TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->pdu_index = eNB->pdu_index[CC_idP]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = 7;
TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
}
}
......@@ -379,8 +339,8 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
#endif
{
if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI (proc %d), RA_active %d format 1A (%d,%d))\n",
module_idP, CC_id, frameP, subframeP,i,
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d))\n",
module_idP, CC_idP, frameP, subframeP,
RA_template->RA_active,
RA_template->RA_dci_fmt1,
......@@ -410,7 +370,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4);
if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
frameP,subframeP,RA_template->RA_rnti);
dl_req->number_dci++;
......@@ -420,7 +380,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
......@@ -445,26 +405,111 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++;
// Program UL processing for Msg3
get_Msg3alloc(&cc[CC_id],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
fill_rar(module_idP,CC_id,frameP,cc[CC_id].RAR_pdu.payload,N_RB_DL,7);
fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7);
// DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus];
TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->pdu_index = eNB->pdu_index[CC_idP]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = 7;
TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
} // PDCCH CCE allocation is feasible
} // Msg2 frame/subframe condition
} // else BL/CE
} // state generate_rar == 1
else if (RA_template->generate_Msg4 == 1) {
}
void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template){
// check for Msg4 Message
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
int16_t rrc_sdu_length;
int UE_id = -1;
uint16_t msg4_padding;
uint16_t msg4_post_padding;
uint16_t msg4_header;
uint8_t *vrb_map;
int first_rb;
int N_RB_DL;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_ul_config_request_pdu_t *ul_config_pdu;
nfapi_tx_request_pdu_t *TX_req;
UE_list_t *UE_list=&eNB->UE_list;
nfapi_dl_config_request_body_t *dl_req;
nfapi_ul_config_request_body_t *ul_req;
uint8_t lcid;
uint8_t offset;
#ifdef Rel14
int rmax = 0;
int rep = 0;
int reps = 0;
first_rb = 0;
struct PRACH_ConfigSIB_v1310 *ext4_prach;
struct PUCCH_ConfigCommon_v1310 *ext4_pucch;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
struct N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13;
PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL};
int pucchreps[4]={1,1,1,1};
int n1pucchan[4]={0,0,0,0};
if (cc[CC_idP].radioResourceConfigCommon_BR) {
ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
ext4_pucch = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310;
prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13;
AssertFatal(prach_ParametersListCE_r13!=NULL,"prach_ParametersListCE_r13 is null\n");
AssertFatal(pucch_N1PUCCH_AN_InfoList_r13!=NULL,"pucch_N1PUCCH_AN_InfoList_r13 is null\n");
// check to verify CE-Level compatibility in SIB2_BR
AssertFatal(prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count,
"prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n");
switch (prach_ParametersListCE_r13->list.count) {
case 4:
p[3] = prach_ParametersListCE_r13->list.array[3];
n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3];
AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n");
pucchreps[3] = (int)(4<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
case 3:
p[2] = prach_ParametersListCE_r13->list.array[2];
n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2];
AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n");
pucchreps[2] = (int)(4<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
case 2:
p[1] =prach_ParametersListCE_r13->list.array[1];
n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
pucchreps[1] = (int)(1<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
case 1:
p[0] = prach_ParametersListCE_r13->list.array[0];
n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
pucchreps[0] = (int)(1<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
default:
AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count);
}
}
#endif
vrb_map = cc[CC_idP].vrb_map;
dl_req = &eNB->DL_req[CC_idP].dl_config_request_body;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
ul_req = &eNB->UL_req[CC_idP].ul_config_request_body;
ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
UE_id = find_UE_id(module_idP,RA_template->rnti);
AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
......@@ -472,11 +517,11 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// Get RRCConnectionSetup for Piggyback
rrc_sdu_length = mac_rrc_data_req(module_idP,
CC_id,
CC_idP,
frameP,
CCCH,
1, // 1 transport block
&cc[CC_id].CCCH_pdu.payload[0],
&cc[CC_idP].CCCH_pdu.payload[0],
ENB_FLAG_YES,
module_idP,
0); // not used in this case
......@@ -486,14 +531,14 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
module_idP, CC_id, frameP, subframeP,UE_id, rrc_sdu_length);
module_idP, CC_idP, frameP, subframeP,UE_id, rrc_sdu_length);
#ifdef Rel14
if (RA_template->rach_resource_type>0) {
// Generate DCI + repetitions first
// This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213
// This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213 : Note: Assumption that this is still Type 2 Common Search
// Parameters:
// p=2+4 PRB set (number of PRB pairs 6)
// rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3
......@@ -503,7 +548,9 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// rmax from SIB2 information
rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13;
// choose r3 by default for Msg4
AssertFatal(rmax>=4,"choose rmax>=4 for enough repeititions, or reduce rep to 1 or 2\n");
// choose r3 by default for Msg4 (this is ok from table 9.1.5-3 for rmax = >=4, if we choose rmax <4 it has to be less
rep = 2;
// get actual repetition count from Table 9.1.5-3
reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep));
......@@ -511,7 +558,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
first_rb = RA_template->msg34_narrowband*6;
if ((RA_template->msg4_mpdcch_repetition_cnt == 0) &&
(mpdcch_sf_condition(eNB,CC_id,frameP,subframeP,rmax,TYPE2)>0)){
(mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2)>0)){
// MPDCCH configuration for RAR
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
......@@ -522,19 +569,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;
AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
"cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
"cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-C-RNTI
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].physCellId;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; /// Check this is still N_id_cell for type2 common
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(N_RB_DL,first_rb,6);
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6,0,6);// check if not getRIV(N_RB_DL,first_rb,6);
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of Msg4, 208 bits with N1A_PRB=3
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0;
......@@ -545,7 +592,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 2;// N1A_PRB=3; => 208 bits
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3; => 208 bits
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0;
......@@ -564,10 +611,10 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++;
} //repetition_count==0 && SF condition met
if (RA_template->msg4_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
else if (RA_template->msg4_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
RA_template->msg4_mpdcch_repetition_cnt++;
if (RA_template->msg4_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition
if (cc[CC_id].tdd_Config==NULL) { // FDD case
if (cc[CC_idP].tdd_Config==NULL) { // FDD case
// wait 2 subframes for PDSCH transmission
if (subframeP>7) RA_template->Msg4_frame = (frameP+1)&1023;
else RA_template->Msg4_frame = frameP;
......@@ -581,18 +628,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// Program PDSCH
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (RA proc %d, RNTI %x)\n",
module_idP, CC_id, frameP, subframeP,i,RA_template->rnti);
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n",
module_idP, CC_idP, frameP, subframeP,RA_template->rach_resource_type-1,RA_template->rnti);
AssertFatal(1==0,"Msg4 generation not finished for BL/CE UE\n");
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->rnti;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); // check that this isn't getRIV(6,0,6)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block
......@@ -611,7 +659,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10*frameP)+subframeP;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0;
......@@ -623,21 +671,22 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
lcid=0;
// set HARQ process 0 round to 0 for this UE
UE_list->UE_sched_ctrl[UE_id].round[CC_id] = 0;
UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0;
msg4_header = 1+6+1; // CR header, CR CE, SDU header
if ((TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header;
if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0;
} else {
msg4_padding = 0;
msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1;
msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1;
}
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
module_idP,CC_id,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
// CHECK THIS: &cc[CC_id].CCCH_pdu.payload[0]
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
// CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
1, //num_sdus
(unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid
......@@ -647,39 +696,66 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
msg4_padding, // no padding
msg4_post_padding);
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&cc[CC_id].CCCH_pdu.payload[0],
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&cc[CC_idP].CCCH_pdu.payload[0],
rrc_sdu_length);
// DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus];
TX_req->pdu_length = rrc_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->pdu_index = eNB->pdu_index[CC_idP]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = rrc_sdu_length;
TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0];
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TBsize));
TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0];
eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
// Program ACK/NAK for Msg4 PDSCH
int absSF = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe;
// see Section 10.2 from 36.213
int ackNAK_absSF = absSF + reps + 4;
eNB->UL_req[CC_idP].sfn_sf = ((ackNAK_absSF/10)<<4) + (ackNAK_absSF%10);
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu));
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = RA_template->rnti;
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[RA_template->rach_resource_type-1];
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0;
// Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that
if (cc[CC_idP].tdd_Config==NULL) { // FDD case
ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = n1pucchan[RA_template->rach_resource_type-1];
// NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
// = N_ECCE_q + Delta_ARO + n1pucchan[ce_level]
// higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 =>
// Delta_ARO = 0 from Table 10.1.2.1-1
ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size = 1; // 1-bit ACK/NAK
}
else {
AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
}
ul_req->number_of_pdus++;
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize));
if (opt_enabled==1) {
trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
eNB->frame, eNB->subframe,0,0);
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
}
} // Msg4 frame/subframe
} // msg4_mpdcch_repetition_count
} // rach_resource_type > 0
else
#endif
{
{ // This is normal LTE case
if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n",
module_idP, CC_id, frameP, subframeP,i,RA_template->rnti);
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
first_rb=0;
......@@ -710,27 +786,29 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
if ((rrc_sdu_length+msg4_header) <= 22) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 4;
TBsize = 22;
RA_template->Msg4_TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5;
TBsize = 28;
RA_template->Msg4_TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6;
TBsize = 32;
RA_template->Msg4_TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7;
TBsize = 41;
RA_template->Msg4_TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8;
TBsize = 49;
RA_template->Msg4_TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9;
TBsize = 57;
RA_template->Msg4_TBsize = 57;
}
RA_template->Msg4_mcs = dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4);
if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
dl_req->number_dci++;
dl_req->number_pdu++;
......@@ -740,21 +818,21 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
lcid=0;
// set HARQ process 0 round to 0 for this UE
UE_list->UE_sched_ctrl[UE_id].round[CC_id] = 0;
UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0;
if ((TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header;
if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0;
} else {
msg4_padding = 0;
msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1;
msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1;
}
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
module_idP,CC_id,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
LOG_I(MAC,"[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
// CHECK THIS: &cc[CC_id].CCCH_pdu.payload[0]
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
// CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
1, //num_sdus
(unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid
......@@ -764,43 +842,113 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
msg4_padding, // no padding
msg4_post_padding);
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&cc[CC_id].CCCH_pdu.payload[0],
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&cc[CC_idP].CCCH_pdu.payload[0],
rrc_sdu_length);
// DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP;
TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus];
TX_req->pdu_length = rrc_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->pdu_index = eNB->pdu_index[CC_idP]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = rrc_sdu_length;
TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0];
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0];
eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
// Program PUCCH1a for ACK/NAK
memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu));
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = RA_template->rnti;
if (cc[CC_idP].tdd_Config==NULL) { // FDD case
ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = cc[CC_idP].radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx;
// NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size = 1; // 1-bit ACK/NAK
}
else {
AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD case yet\n");
}
ul_req->number_of_pdus++;
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TBsize));
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize));
if (opt_enabled==1) {
trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
eNB->frame, eNB->subframe,0,0);
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
}
} // CCE Allocation feasible
} // msg4 frame/subframe
} // else rach_resource_type
} else if (RA_template->wait_ack_Msg4==1) {
}
void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) {
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
int UE_id = -1;
uint8_t *vrb_map;
int first_rb;
int N_RB_DL;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
UE_list_t *UE_list=&eNB->UE_list;
nfapi_dl_config_request_body_t *dl_req;
int round;
/*
#ifdef Rel14
COMMON_channels_t *cc = eNB->common_channels;
int rmax = 0;
int rep = 0;
int reps = 0;
first_rb = 0;
struct PRACH_ConfigSIB_v1310 *ext4_prach;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
PRACH_ParametersCE_r13_t *p[4];
if (cc[CC_idP].radioResourceConfigCommon_BR) {
ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
switch (prach_ParametersListCE_r13->list.count) {
case 4:
p[3]=prach_ParametersListCE_r13->list.array[3];
case 3:
p[2]=prach_ParametersListCE_r13->list.array[2];
case 2:
p[1]=prach_ParametersListCE_r13->list.array[1];
case 1:
p[0]=prach_ParametersListCE_r13->list.array[0];
default:
AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count);
}
}
#endif
*/
// check HARQ status and retransmit if necessary
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \tn",
module_idP,CC_id,frameP,subframeP);
module_idP,CC_idP,frameP,subframeP);
// Get candidate harq_pid from PHY
UE_id = find_UE_id(module_idP,RA_template->rnti);
AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
round = UE_list->UE_sched_ctrl[UE_id].round[CC_id];
round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP];
vrb_map = cc[CC_idP].vrb_map;
dl_req = &eNB->DL_req[CC_idP].dl_config_request_body;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
if (round>0) {
......@@ -831,36 +979,13 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = RA_template->Msg4_mcs;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
// Compute MCS for 3 PRB
msg4_header = 1+6+1; // CR header, CR CE, SDU header
if ((rrc_sdu_length+msg4_header) <= 22) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 4;
TBsize = 22;
} else if ((rrc_sdu_length+msg4_header) <= 28) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5;
TBsize = 28;
} else if ((rrc_sdu_length+msg4_header) <= 32) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6;
TBsize = 32;
} else if ((rrc_sdu_length+msg4_header) <= 41) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7;
TBsize = 41;
} else if ((rrc_sdu_length+msg4_header) <= 49) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8;
TBsize = 49;
} else if ((rrc_sdu_length+msg4_header) <= 57) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9;
TBsize = 57;
}
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4);
if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
dl_req->number_dci++;
dl_req->number_pdu++;
......@@ -869,19 +994,51 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
else
LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
module_idP,CC_id,frameP,subframeP,RA_template->rnti);
module_idP,CC_idP,frameP,subframeP,RA_template->rnti);
}
}
} else {
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_id,frameP,subframeP);
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP);
RA_template->wait_ack_Msg4=0;
RA_template->RA_active=FALSE;
UE_id = find_UE_id(module_idP,RA_template->rnti);
DevAssert( UE_id != -1 );
eNB->UE_list.UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured=TRUE;
}
} //wait_ack_Msg4 == 1
}
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
{
int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
RA_TEMPLATE *RA_template;
uint8_t i;
start_meas(&eNB->schedule_ra);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
// skip UL component carriers
if (is_UL_sf(&cc[CC_id],subframeP)==1) continue;
for (i=0; i<NB_RA_PROC_MAX; i++) {
RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i];
if (RA_template->RA_active == TRUE) {
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
module_idP,CC_id,i,RA_template->generate_rar,RA_template->generate_Msg4,RA_template->wait_ack_Msg4, RA_template->rnti);
if (RA_template->generate_rar == 1) generate_Msg2(module_idP,CC_id,frameP,subframeP,RA_template);
else if (RA_template->generate_Msg4 == 1) generate_Msg4(module_idP,CC_id,frameP,subframeP,RA_template);
else if (RA_template->wait_ack_Msg4==1) check_Msg4_retransmission(module_idP,CC_id,frameP,subframeP,RA_template);
} // RA_active == TRUE
} // for i=0 .. N_RA_PROC-1
} // CC_id
......@@ -910,7 +1067,7 @@ void initiate_ra_proc(module_id_t module_idP,
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,preamble_index);
#ifdef Rel14
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d PRACH resource type %d\n",module_idP,CC_id,frameP,preamble_index,rach_resource_type);
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d PRACH resource type %d\n",module_idP,CC_id,frameP,rach_resource_type);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,1);
......
......@@ -143,7 +143,10 @@ schedule_SIB1_BR(
switch (N_RB_DL) {
case 6:
case 15:
m=1;
n_NB=0;
N_S_NB=0;
Sj=NULL;
break;
case 25:
m=2;
......@@ -305,11 +308,8 @@ schedule_SI_BR(
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req;
nfapi_dl_config_request_body_t *dl_req;
int m,i,N_S_NB;
int *Sj;
int n_NB = 0;
int TBS;
int k,rvidx;
int i;
int rvidx;
......@@ -378,7 +378,7 @@ schedule_SI_BR(
if (bcch_sdu_length > 0) {
AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3),
"RRC provided bcch with length %d > %d\n",
bcch_sdu_length,(si_TBS_r13>>3));
bcch_sdu_length,(int)(si_TBS_r13>>3));
LOG_D(MAC,"[eNB %d] Frame %d : BCCH_BR %d->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,i,CC_id,bcch_sdu_length);
// allocate all 6 PRBs in narrowband for SIB1_BR
......
......@@ -98,10 +98,10 @@ uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) {
}
void get_Msg3alloc(COMMON_channels_t *cc,
unsigned char current_subframe,
unsigned int current_frame,
unsigned int *frame,
unsigned char *subframe)
sub_frame_t current_subframe,
frame_t current_frame,
frame_t *frame,
sub_frame_t *subframe)
{
// Fill in other TDD Configuration!!!!
......@@ -211,10 +211,10 @@ void get_Msg3alloc(COMMON_channels_t *cc,
void get_Msg3allocret(COMMON_channels_t *cc,
unsigned char current_subframe,
unsigned int current_frame,
unsigned int *frame,
unsigned char *subframe)
sub_frame_t current_subframe,
frame_t current_frame,
frame_t *frame,
sub_frame_t *subframe)
{
if (cc->tdd_Config == NULL) { //FDD
/* always retransmit in n+8 */
......@@ -249,7 +249,7 @@ void get_Msg3allocret(COMMON_channels_t *cc,
}
}
uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe)
uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe)
{
uint8_t ret = 255;
......@@ -317,8 +317,8 @@ uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe)
}
uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
uint32_t frame,
unsigned char current_subframe)
frame_t frame,
sub_frame_t current_subframe)
{
uint8_t ul_subframe=0;
......@@ -403,7 +403,7 @@ uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
}
int is_UL_sf(COMMON_channels_t *ccP,uint8_t subframeP)
int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP)
{
// if FDD return dummy value
......
......@@ -407,7 +407,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
RA_template->generate_Msg4 = 1;
RA_template->wait_ack_Msg4 = 0;
// Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now
// Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
RA_template->Msg4_frame = frameP + ((subframeP>5) ? 1 : 0);
RA_template->Msg4_subframe = (subframeP+4)%10;
......
......@@ -230,6 +230,17 @@ unsigned short fill_rar(
const uint8_t input_buffer_length
);
#ifdef Rel14
unsigned short fill_rar_br(eNB_MAC_INST *eNB,
int CC_id,
RA_TEMPLATE *RA_template,
const frame_t frameP,
const sub_frame_t subframeP,
uint8_t* const dlsch_buffer,
const uint8_t ce_level
);
#endif
/* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE
@param Mod_id Instance ID of eNB
@param preamble_index index of the received RA request.
......@@ -861,19 +872,18 @@ uint16_t getRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
int get_subbandsize(uint8_t dl_bandwidth);
uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe);
void get_Msg3allocret(COMMON_channels_t *cc,
unsigned char current_subframe,
unsigned int current_frame,
unsigned int *frame,
unsigned char *subframe);
sub_frame_t current_subframe,
frame_t current_frame,
frame_t *frame,
sub_frame_t *subframe);
void get_Msg3alloc(COMMON_channels_t *cc,
unsigned char current_subframe,
unsigned int current_frame,
unsigned int *frame,
unsigned char *subframe);
sub_frame_t current_subframe,
frame_t current_frame,
frame_t *frame,
sub_frame_t *subframe);
uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
......@@ -884,8 +894,23 @@ int to_rbg(int dl_Bandwidth);
int to_prb(int dl_Bandwidth);
uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
uint32_t frame,
unsigned char current_subframe);
frame_t frame,
sub_frame_t current_subframe);
int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP);
uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe);
#ifdef Rel14
int get_numnarrowbandbits(long dl_Bandwidth);
int mpdcch_sf_condition(eNB_MAC_INST *eNB,int CC_id, frame_t frameP,sub_frame_t subframeP,int rmax,MPDCCH_TYPES_t mpdcch_type);
int get_numnarrowbands(long dl_Bandwidth);
#endif
#endif
/** @}*/
......@@ -132,8 +132,8 @@ unsigned short fill_rar(
#ifdef Rel14
//------------------------------------------------------------------------------
unsigned short fill_rar_br(eNB_MAC_INST *eNB,
const int CC_id,
const int ra_idx,
int CC_id,
RA_TEMPLATE *RA_template,
const frame_t frameP,
const sub_frame_t subframeP,
uint8_t* const dlsch_buffer,
......@@ -143,44 +143,41 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
{
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
COMMON_channels_t *cc = &eNB->common_channels[CC_id];
uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
int i;
uint8_t nb,rballoc,reps;
uint8_t mcs,TPC,ULdelay,cqireq;
COMMON_channels_t *cc = &eNB->common_channels[CC_id];
int input_buffer_length;
AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs);
AssertFatal(ra_idx >= 0 && ra_idx < 4, "RA index not in [0..3]\n");
AssertFatal(RA_template != NULL, "RA is null \n");
// subheader fixed
rarh->E = 0; // First and last RAR
rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = cc->RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment
cc->RA_template[ra_idx].timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t)(cc->RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(cc->RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
rarh->RAPID = RA_template->preamble_index; // Respond to Preamble 0 only for the moment
RA_template->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t)(RA_template->timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
int N_NB_index;
AssertFatal(1==0,"RAR for BL/CE Still to be finished ...\n");
// Copy the Msg2 narrowband
cc->RA_template[ra_idx].msg34_narrowband = cc->RA_template[ra_idx].msg2_narrowband;
RA_template->msg34_narrowband = RA_template->msg2_narrowband;
if (ce_level<2) { //CE Level 0,1, CEmodeA
input_buffer_length =6;
N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth);
rar[4] = (uint8_t)(cc->RA_template[ra_idx].rnti>>8);
rar[5] = (uint8_t)(cc->RA_template[ra_idx].rnti&0xff);
rar[4] = (uint8_t)(RA_template->rnti>>8);
rar[5] = (uint8_t)(RA_template->rnti&0xff);
//cc->RA_template[ra_idx].timing_offset = 0;
nb = 0;
rballoc = mac_computeRIV(6,1+ra_idx,1); // one PRB only for UL Grant in position 1+ra_idx within Narrowband
rballoc = mac_computeRIV(6,1+ce_level,1); // one PRB only for UL Grant in position 1+ce_level within Narrowband
rar[1] |= (rballoc&15)<<(4-N_NB_index); // Hopping = 0 (bit 3), 3 MSBs of rballoc
reps = 4;
......@@ -195,27 +192,26 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
input_buffer_length =5;
rar[3] = (uint8_t)(cc->RA_template[ra_idx].rnti>>8);
rar[4] = (uint8_t)(cc->RA_template[ra_idx].rnti&0xff);
rar[3] = (uint8_t)(RA_template->rnti>>8);
rar[4] = (uint8_t)(RA_template->rnti&0xff);
}
LOG_D(MAC,"[RAPROC] CC_id %d Frame %d Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",
CC_id,
LOG_D(MAC,"[RAPROC] Frame %d Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",
frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx,
cc->RA_template[ra_idx].rnti,
rarh->RAPID,cc->RA_template[0].preamble_index,
cc->RA_template[ra_idx].timing_offset);
ce_level,
RA_template->rnti,
rarh->RAPID,RA_template->preamble_index,
RA_template->timing_offset);
if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1,
eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,"[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
eNB->Mod_id, CC_id, frameP, cc->RA_template[ra_idx].rnti,
LOG_D(OPT,"[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
frameP, RA_template->rnti,
rarh->RAPID, input_buffer_length);
}
return(cc->RA_template[ra_idx].rnti);
return(RA_template->rnti);
}
#endif
......
RUs = (
{
local_if_name = "lo";
remote_address = "127.0.0.2";
local_address = "127.0.0.1";
remote_address = "127.0.0.1"
local_address = "127.0.0.2";
local_portc = 50000;
remote_portc = 50000;
local_portd = 50001;
......
......@@ -1210,6 +1210,17 @@ static void* ru_thread( void* param ) {
else ret = attach_rru(ru);
AssertFatal(ret==0,"Cannot connect to radio\n");
}
// if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(&ru->frame_parms,1);
phy_init_RU(ru);
// }
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
pthread_mutex_lock(&RC.ru_mutex);
......@@ -1829,6 +1840,7 @@ void init_RU(const char *rf_config_file) {
for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
ru = RC.ru[ru_id];
ru->rf_config_file = rf_config_file;
ru->idx = ru_id;
ru->ts_offset = 0;
// use eNB_list[0] as a reference for RU frame parameters
......@@ -1911,7 +1923,7 @@ void init_RU(const char *rf_config_file) {
ru->fh_south_out = tx_rf; // local synchronous RF TX
ru->start_rf = start_rf; // need to start the local RF interface
printf("configuring ru_id %d (start_rf %p)\n",ru_id,start_rf);
/*
if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
fill_rf_config(ru,rf_config_file);
init_frame_parms(&ru->frame_parms,1);
......@@ -1922,7 +1934,7 @@ void init_RU(const char *rf_config_file) {
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
}*/
break;
case REMOTE_IF5: // the remote unit is IF5 RRU
......
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