Commit faa111ec authored by Raymond Knopp's avatar Raymond Knopp

complete programming of Msg2/Msg4 procedures for eMTC. Addition of skeleton...

complete programming of Msg2/Msg4 procedures for eMTC. Addition of skeleton for PUCCH UCI (NFAPI) in L1. Some cleanup of eNB_scheduler.c
parent 41f864ef
...@@ -1566,7 +1566,7 @@ ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ...@@ -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/multicast_link.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/bypass_session_layer.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 ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/pgm_link.c
) )
......
...@@ -493,6 +493,73 @@ typedef struct { ...@@ -493,6 +493,73 @@ typedef struct {
int32_t delta_TF; int32_t delta_TF;
} LTE_UL_eNB_HARQ_t; } 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 { typedef struct {
/// HARQ process mask, indicates which processes are currently active /// HARQ process mask, indicates which processes are currently active
uint16_t harq_mask; uint16_t harq_mask;
...@@ -764,15 +831,6 @@ typedef enum { ...@@ -764,15 +831,6 @@ typedef enum {
rx_SIC_dual_stream rx_SIC_dual_stream
} RX_type_t; } 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_ ...@@ -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; unsigned char exit_flag = 0,i,j,r,aa,layer;
int re; int re;
unsigned char bw_scaling =1; unsigned char bw_scaling =1;
RU_t *ru;
int ru_id;
switch (N_RB_DL) { switch (N_RB_DL) {
case 6: case 6:
......
...@@ -233,6 +233,8 @@ typedef struct DCI6_1A_20MHz DCI6_1A_20MHz_t; ...@@ -233,6 +233,8 @@ typedef struct DCI6_1A_20MHz DCI6_1A_20MHz_t;
/// basic DCI Format Type 6-0B (5 MHz) /// basic DCI Format Type 6-0B (5 MHz)
struct DCI6_0B_5MHz { struct DCI6_0B_5MHz {
/// padding to fill 32-bit word
uint32_t padding:15;
/// DCI subframe repetition /// DCI subframe repetition
uint32_t dci_rep:2; uint32_t dci_rep:2;
/// new data indicator /// new data indicator
...@@ -240,7 +242,7 @@ struct DCI6_0B_5MHz { ...@@ -240,7 +242,7 @@ struct DCI6_0B_5MHz {
/// harq id /// harq id
uint32_t harq_pid:1; uint32_t harq_pid:1;
/// Repetition number /// Repetition number
uint32_t rep:2; uint32_t rep:3;
/// Modulation and Coding Scheme and Redundancy Version /// Modulation and Coding Scheme and Redundancy Version
uint32_t mcs:4; uint32_t mcs:4;
/// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits) /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits)
...@@ -250,10 +252,12 @@ struct DCI6_0B_5MHz { ...@@ -250,10 +252,12 @@ struct DCI6_0B_5MHz {
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
typedef struct DCI6_0B_5MHz DCI6_0B_5MHz_t; 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) /// basic DCI Format Type 6-1B (5 MHz)
struct DCI6_1B_5MHz { struct DCI6_1B_5MHz {
/// padding to fill 32-bit word
uint32_t padding:15;
/// DCI subframe repetition number /// DCI subframe repetition number
uint32_t dci_rep:2; uint32_t dci_rep:2;
/// HARQ-ACK resource offset /// HARQ-ACK resource offset
...@@ -263,7 +267,7 @@ struct DCI6_1B_5MHz { ...@@ -263,7 +267,7 @@ struct DCI6_1B_5MHz {
/// HARQ Process /// HARQ Process
uint32_t harq_pid:1; uint32_t harq_pid:1;
/// Repetition number /// 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) /// Resource block assignment (assignment flag = 0 for 5 MHz, ceil(log2(floor(N_RB_DL/6)))+1)
uint32_t rballoc:3; uint32_t rballoc:3;
/// Modulation and Coding Scheme and Redundancy Version /// Modulation and Coding Scheme and Redundancy Version
...@@ -273,12 +277,12 @@ struct DCI6_1B_5MHz { ...@@ -273,12 +277,12 @@ struct DCI6_1B_5MHz {
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
typedef struct DCI6_1B_5MHz DCI6_1B_5MHz_t; 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) /// basic DCI Format Type 6-0B (10 MHz)
struct DCI6_0B_10MHz { struct DCI6_0B_10MHz {
/// padding to fill 32-bit word /// padding to fill 32-bit word
uint32_t padding:15; uint32_t padding:14;
/// DCI subframe repetition /// DCI subframe repetition
uint32_t dci_rep:2; uint32_t dci_rep:2;
/// new data indicator /// new data indicator
...@@ -286,7 +290,7 @@ struct DCI6_0B_10MHz { ...@@ -286,7 +290,7 @@ struct DCI6_0B_10MHz {
/// harq id /// harq id
uint32_t harq_pid:1; uint32_t harq_pid:1;
/// Repetition number /// Repetition number
uint32_t rep:2; uint32_t rep:3;
/// Modulation and Coding Scheme and Redundancy Version /// Modulation and Coding Scheme and Redundancy Version
uint32_t mcs:4; uint32_t mcs:4;
/// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits) /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits)
...@@ -296,7 +300,7 @@ struct DCI6_0B_10MHz { ...@@ -296,7 +300,7 @@ struct DCI6_0B_10MHz {
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
typedef struct DCI6_0B_10MHz DCI6_0B_10MHz_t; 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) /// basic DCI Format Type 6-1B (10 MHz)
struct DCI6_1B_10MHz { struct DCI6_1B_10MHz {
......
...@@ -2188,5 +2188,7 @@ int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); ...@@ -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_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 #endif
...@@ -844,4 +844,21 @@ void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL) ...@@ -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);
}
...@@ -888,15 +888,9 @@ typedef struct PHY_VARS_eNB_s { ...@@ -888,15 +888,9 @@ typedef struct PHY_VARS_eNB_s {
/// Ethernet parameters for fronthaul interface /// Ethernet parameters for fronthaul interface
eth_params_t eth_params; eth_params_t eth_params;
int rx_total_gain_dB; 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 (*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 *); 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); 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; uint8_t local_flag;
LTE_DL_FRAME_PARMS frame_parms; LTE_DL_FRAME_PARMS frame_parms;
PHY_MEASUREMENTS_eNB measurements; PHY_MEASUREMENTS_eNB measurements;
...@@ -921,6 +915,7 @@ typedef struct PHY_VARS_eNB_s { ...@@ -921,6 +915,7 @@ typedef struct PHY_VARS_eNB_s {
LTE_eNB_PRACH prach_vars_br; LTE_eNB_PRACH prach_vars_br;
#endif #endif
LTE_eNB_COMMON common_vars; 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_SRS srs_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PBCH pbch; LTE_eNB_PBCH pbch;
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
......
...@@ -1065,6 +1065,10 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, ...@@ -1065,6 +1065,10 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
#endif #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, handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
nfapi_ul_config_request_pdu_t *ul_config_pdu) { 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, ...@@ -1072,10 +1076,32 @@ handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
int8_t UE_id; int8_t UE_id;
// check if we have received a dci for this ue and ulsch descriptor is configured // 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, AssertFatal((UE_id = find_ulsch(rel8->rnti,eNB,SEARCH_EXIST))>=0,
"No existing UE ULSCH for rnti %x\n",rel8->rnti); "No existing UE ULSCH for rnti %x\n",rel8->rnti);
AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0,
"ulsch for UE_id %d is not active\n",UE_id); "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) { ...@@ -1227,7 +1253,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
for (i=0;i<number_ul_pdu;i++) { for (i=0;i<number_ul_pdu;i++) {
ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[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); 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); "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type);
handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu); handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu);
} }
...@@ -1524,6 +1551,8 @@ void process_HARQ_feedback(uint8_t UE_id, ...@@ -1524,6 +1551,8 @@ void process_HARQ_feedback(uint8_t UE_id,
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
int harq_pid = subframe2harq_pid( fp,frame,subframe); int harq_pid = subframe2harq_pid( fp,frame,subframe);
nfapi_harq_indication_pdu_t *pdu;
if (fp->frame_type == FDD) { //FDD if (fp->frame_type == FDD) { //FDD
subframe_m4 = (subframe<4) ? subframe+6 : subframe-4; subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
...@@ -1546,6 +1575,9 @@ void process_HARQ_feedback(uint8_t UE_id, ...@@ -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) #if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE( MSC_LOG_RX_MESSAGE(
...@@ -1578,6 +1610,7 @@ void process_HARQ_feedback(uint8_t UE_id, ...@@ -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]; ?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 else { // PUCCH ACK/NAK
if ((SR_payload == 1)&&(pucch_sel!=2)) { // decode Table 7.3 if multiplexing and SR=1 if ((SR_payload == 1)&&(pucch_sel!=2)) { // decode Table 7.3 if multiplexing and SR=1
nb_ACK = 0; nb_ACK = 0;
...@@ -2752,8 +2785,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const ...@@ -2752,8 +2785,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
frame,subframe, i, frame,subframe, i,
ulsch_harq->round-1); 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", 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, 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 ...@@ -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[0],
ulsch_harq->o_ACK[1], ulsch_harq->o_ACK[1],
ret); 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); LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i);
} // This is Msg3 error } // This is Msg3 error
...@@ -2842,23 +2833,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const ...@@ -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_errors[harq_pid]++;
eNB->UE_stats[i].ulsch_consecutive_errors++; 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 } // ulsch in error
...@@ -2920,29 +2894,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const ...@@ -2920,29 +2894,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
eNB->Mod_id, eNB->Mod_id,
frame,harq_pid,i); frame,harq_pid,i);
if (eNB->mac_enabled) { 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 // Fill UL info
} }
// one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI) // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
if (ulsch_harq->Msg3_flag == 0 ) { if (ulsch_harq->Msg3_flag == 0 ) {
eNB->UE_stats[i].mode = PRACH; 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; eNB->ulsch[(uint32_t)i]->Msg3_active = 0;
} // Msg3_flag == 0 } // Msg3_flag == 0
...@@ -2984,26 +2940,12 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const ...@@ -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); harq_pid,ulsch_harq->TBS>>3);
for (j=0; j<ulsch_harq->TBS>>3; j++) 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"); LOG_T(PHY,"\n");
#endif #endif
#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 } // Msg3_flag == 0
......
...@@ -827,15 +827,15 @@ typedef struct { ...@@ -827,15 +827,15 @@ typedef struct {
/// Subframe where Msg2 is to be sent /// Subframe where Msg2 is to be sent
uint8_t Msg2_subframe; uint8_t Msg2_subframe;
/// Frame where Msg2 is to be sent /// Frame where Msg2 is to be sent
uint8_t Msg2_frame; frame_t Msg2_frame;
/// Subframe where Msg3 is to be sent /// Subframe where Msg3 is to be sent
uint8_t Msg3_subframe; sub_frame_t Msg3_subframe;
/// Frame where Msg3 is to be sent /// Frame where Msg3 is to be sent
uint8_t Msg3_frame; frame_t Msg3_frame;
/// Subframe where Msg4 is to be sent /// Subframe where Msg4 is to be sent
uint8_t Msg4_subframe; sub_frame_t Msg4_subframe;
/// Frame where Msg4 is to be sent /// 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. /// 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; uint8_t generate_Msg4;
/// Flag to indicate that eNB is waiting for ACK that UE has received Msg3. /// Flag to indicate that eNB is waiting for ACK that UE has received Msg3.
...@@ -854,6 +854,10 @@ typedef struct { ...@@ -854,6 +854,10 @@ typedef struct {
int16_t RRC_timer; int16_t RRC_timer;
/// Round of Msg3 HARQ /// Round of Msg3 HARQ
uint8_t msg3_round; uint8_t msg3_round;
/// TBS used for Msg4
int Msg4_TBsize;
/// MCS used for Msg4
int Msg4_mcs;
#ifdef Rel14 #ifdef Rel14
uint8_t rach_resource_type; uint8_t rach_resource_type;
uint8_t msg2_mpdcch_repetition_cnt; uint8_t msg2_mpdcch_repetition_cnt;
......
...@@ -61,12 +61,6 @@ ...@@ -61,12 +61,6 @@
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
#include "T.h" #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) { 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 ...@@ -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) { if (RA_template->RA_active == TRUE) {
// program reception 4 subframes prior to transmission
msg3_prog_subframe = (RA_template->Msg3_subframe + 6)%10; msg3_prog_subframe = (RA_template->Msg3_subframe + 6)%10;
if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023; 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 ...@@ -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)) { (msg3_prog_subframe==subframeP)) {
LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n", 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); 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 if (RA_template->msg3_round == 0) { // program ULSCH
ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 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 ...@@ -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]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels; 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; uint8_t *vrb_map;
int first_rb; int first_rb;
int N_RB_DL; int N_RB_DL;
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req; 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; 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 #ifdef Rel14
int rmax = 0; int rmax = 0;
int rep = 0; int rep = 0;
int reps = 0; int reps = 0;
int num_nb = 0; int num_nb = 0;
first_rb = 0; first_rb = 0;
struct PRACH_ConfigSIB_v1310 *ext4_prach; struct PRACH_ConfigSIB_v1310 *ext4_prach;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; 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; prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
switch (prach_ParametersListCE_r13->list.count) { 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) ...@@ -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); 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) { 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: // Parameters:
// p=2+4 PRB set (number of PRB pairs 3) // p=2+4 PRB set (number of PRB pairs 3)
// rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-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) ...@@ -242,7 +202,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// rmax from SIB2 information // rmax from SIB2 information
rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; 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; rep = 2;
// get actual repetition count from Table 9.1.5-3 // get actual repetition count from Table 9.1.5-3
reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep)); 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) ...@@ -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; first_rb = RA_template->msg2_narrowband*6;
if ((RA_template->msg2_mpdcch_repetition_cnt == 0) && 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 // MPDCCH configuration for RAR
...@@ -264,19 +224,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -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.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.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.resource_block_assignment = 0; // Note: this can be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; 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_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
"cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); "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.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.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 = 2; // RA-RNTI
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->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.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.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.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.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.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.redundancy_version = 0;
...@@ -288,7 +248,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -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.pmi = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 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.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_length = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 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; 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) ...@@ -307,14 +267,14 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++; dl_req->number_pdu++;
} //repetition_count==0 && SF condition met } //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++; RA_template->msg2_mpdcch_repetition_cnt++;
if (RA_template->msg2_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition 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 // wait 2 subframes for PDSCH transmission
if (subframeP>7) RA_template->Msg2_frame = (frameP+1)&1023; if (subframeP>7) RA_template->Msg2_frame = (frameP+1)&1023;
else RA_template->Msg2_frame = frameP; 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 { else {
AssertFatal(1==0,"TDD case not done yet\n"); 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) ...@@ -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)); 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_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); 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.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.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.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) ...@@ -358,19 +318,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++; dl_req->number_pdu++;
// Program UL processing for Msg3, same as regular LTE // 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 // DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; eNB->TX_req[CC_idP].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]; 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_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->num_segments = 1;
TX_req->segments[0].segment_length = 7; TX_req->segments[0].segment_length = 7;
TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload; TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; 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) ...@@ -379,8 +339,8 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
#endif #endif
{ {
if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { 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", 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_id, frameP, subframeP,i, module_idP, CC_idP, frameP, subframeP,
RA_template->RA_active, RA_template->RA_active,
RA_template->RA_dci_fmt1, RA_template->RA_dci_fmt1,
...@@ -410,7 +370,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -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); 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", LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
frameP,subframeP,RA_template->RA_rnti); frameP,subframeP,RA_template->RA_rnti);
dl_req->number_dci++; dl_req->number_dci++;
...@@ -420,7 +380,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -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)); 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_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); 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.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.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.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) ...@@ -445,26 +405,111 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++; dl_req->number_pdu++;
// Program UL processing for Msg3 // 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 // DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; eNB->TX_req[CC_idP].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]; 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_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->num_segments = 1;
TX_req->segments[0].segment_length = 7; TX_req->segments[0].segment_length = 7;
TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload; TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
} // PDCCH CCE allocation is feasible } // PDCCH CCE allocation is feasible
} // Msg2 frame/subframe condition } // Msg2 frame/subframe condition
} // else BL/CE } // 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); UE_id = find_UE_id(module_idP,RA_template->rnti);
AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); 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) ...@@ -472,11 +517,11 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// Get RRCConnectionSetup for Piggyback // Get RRCConnectionSetup for Piggyback
rrc_sdu_length = mac_rrc_data_req(module_idP, rrc_sdu_length = mac_rrc_data_req(module_idP,
CC_id, CC_idP,
frameP, frameP,
CCCH, CCCH,
1, // 1 transport block 1, // 1 transport block
&cc[CC_id].CCCH_pdu.payload[0], &cc[CC_idP].CCCH_pdu.payload[0],
ENB_FLAG_YES, ENB_FLAG_YES,
module_idP, module_idP,
0); // not used in this case 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) ...@@ -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", 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 #ifdef Rel14
if (RA_template->rach_resource_type>0) { if (RA_template->rach_resource_type>0) {
// Generate DCI + repetitions first // 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: // Parameters:
// p=2+4 PRB set (number of PRB pairs 6) // p=2+4 PRB set (number of PRB pairs 6)
// rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 // 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) ...@@ -503,7 +548,9 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// rmax from SIB2 information // rmax from SIB2 information
rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; 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; rep = 2;
// get actual repetition count from Table 9.1.5-3 // get actual repetition count from Table 9.1.5-3
reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep)); 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) ...@@ -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; first_rb = RA_template->msg34_narrowband*6;
if ((RA_template->msg4_mpdcch_repetition_cnt == 0) && 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 // MPDCCH configuration for RAR
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); 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) ...@@ -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.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.resource_block_assignment = 0; // Note: this can be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;
AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
"cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); "cc[CC_idP].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.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.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.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.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.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.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);// 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 RAR, 208 bits with N1A_PRB=3 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.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.redundancy_version = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 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) ...@@ -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.pmi = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 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.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_length = 0;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 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; 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) ...@@ -564,10 +611,10 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
dl_req->number_pdu++; dl_req->number_pdu++;
} //repetition_count==0 && SF condition met } //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++; RA_template->msg4_mpdcch_repetition_cnt++;
if (RA_template->msg4_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition 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 // wait 2 subframes for PDSCH transmission
if (subframeP>7) RA_template->Msg4_frame = (frameP+1)&1023; if (subframeP>7) RA_template->Msg4_frame = (frameP+1)&1023;
else RA_template->Msg4_frame = frameP; 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) ...@@ -581,18 +628,19 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
// Program PDSCH // 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", 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_id, frameP, subframeP,i,RA_template->rnti); 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]; 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)); 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_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); 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.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.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.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.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block 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) ...@@ -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.num_bf_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // 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.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.initial_transmission_sf_io = (10*frameP)+subframeP;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; 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) ...@@ -623,21 +671,22 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
lcid=0; lcid=0;
// set HARQ process 0 round to 0 for this UE // 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) { if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header; msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0; msg4_post_padding = 0;
} else { } else {
msg4_padding = 0; 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", 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 DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
// CHECK THIS: &cc[CC_id].CCCH_pdu.payload[0] // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].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 1, //num_sdus
(unsigned short*)&rrc_sdu_length, // (unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid &lcid, // sdu_lcid
...@@ -647,39 +696,66 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -647,39 +696,66 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
msg4_padding, // no padding msg4_padding, // no padding
msg4_post_padding); msg4_post_padding);
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&cc[CC_id].CCCH_pdu.payload[0], &cc[CC_idP].CCCH_pdu.payload[0],
rrc_sdu_length); rrc_sdu_length);
// DL request // DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; eNB->TX_req[CC_idP].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]; 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_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->num_segments = 1;
TX_req->segments[0].segment_length = rrc_sdu_length; 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]; TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0];
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_idP].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), // Program ACK/NAK for Msg4 PDSCH
T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TBsize)); 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) { 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), rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
eNB->frame, eNB->subframe,0,0); 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", 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 frame/subframe
} // msg4_mpdcch_repetition_count } // msg4_mpdcch_repetition_count
} // rach_resource_type > 0 } // rach_resource_type > 0
else else
#endif #endif
{ { // This is normal LTE case
if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { 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", LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
module_idP, CC_id, frameP, subframeP,i,RA_template->rnti); module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
first_rb=0; first_rb=0;
...@@ -710,27 +786,29 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -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) { if ((rrc_sdu_length+msg4_header) <= 22) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 4; 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) { } else if ((rrc_sdu_length+msg4_header) <= 28) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5; 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) { } else if ((rrc_sdu_length+msg4_header) <= 32) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6; 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) { } else if ((rrc_sdu_length+msg4_header) <= 41) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7; 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) { } else if ((rrc_sdu_length+msg4_header) <= 49) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8; 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) { } else if ((rrc_sdu_length+msg4_header) <= 57) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9; 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); 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_dci++;
dl_req->number_pdu++; dl_req->number_pdu++;
...@@ -740,21 +818,21 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -740,21 +818,21 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
lcid=0; lcid=0;
// set HARQ process 0 round to 0 for this UE // 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) { if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header; msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0; msg4_post_padding = 0;
} else { } else {
msg4_padding = 0; 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", 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_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 DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
// CHECK THIS: &cc[CC_id].CCCH_pdu.payload[0] // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].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 1, //num_sdus
(unsigned short*)&rrc_sdu_length, // (unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid &lcid, // sdu_lcid
...@@ -764,43 +842,113 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -764,43 +842,113 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
msg4_padding, // no padding msg4_padding, // no padding
msg4_post_padding); msg4_post_padding);
memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
&cc[CC_id].CCCH_pdu.payload[0], &cc[CC_idP].CCCH_pdu.payload[0],
rrc_sdu_length); rrc_sdu_length);
// DL request // DL request
eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; eNB->TX_req[CC_idP].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]; 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_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->num_segments = 1;
TX_req->segments[0].segment_length = rrc_sdu_length; 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]; TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0];
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; 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(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_id][0][UE_id].payload[0], TBsize)); 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) { 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), rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
eNB->frame, eNB->subframe,0,0); 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", 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 } // CCE Allocation feasible
} // msg4 frame/subframe } // msg4 frame/subframe
} // else rach_resource_type } // 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 // 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", 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 // Get candidate harq_pid from PHY
UE_id = find_UE_id(module_idP,RA_template->rnti); UE_id = find_UE_id(module_idP,RA_template->rnti);
AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); 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) { if (round>0) {
...@@ -831,36 +979,13 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -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.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.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.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; 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); 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_dci++;
dl_req->number_pdu++; dl_req->number_pdu++;
...@@ -869,19 +994,51 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -869,19 +994,51 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
else 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_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", 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 { } 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->wait_ack_Msg4=0;
RA_template->RA_active=FALSE; RA_template->RA_active=FALSE;
UE_id = find_UE_id(module_idP,RA_template->rnti); UE_id = find_UE_id(module_idP,RA_template->rnti);
DevAssert( UE_id != -1 ); DevAssert( UE_id != -1 );
eNB->UE_list.UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured=TRUE; 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 } // RA_active == TRUE
} // for i=0 .. N_RA_PROC-1 } // for i=0 .. N_RA_PROC-1
} // CC_id } // CC_id
...@@ -910,7 +1067,7 @@ void initiate_ra_proc(module_id_t module_idP, ...@@ -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); 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 #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 #endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,1);
......
...@@ -143,7 +143,10 @@ schedule_SIB1_BR( ...@@ -143,7 +143,10 @@ schedule_SIB1_BR(
switch (N_RB_DL) { switch (N_RB_DL) {
case 6: case 6:
case 15: case 15:
m=1;
n_NB=0; n_NB=0;
N_S_NB=0;
Sj=NULL;
break; break;
case 25: case 25:
m=2; m=2;
...@@ -305,11 +308,8 @@ schedule_SI_BR( ...@@ -305,11 +308,8 @@ schedule_SI_BR(
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req; nfapi_tx_request_pdu_t *TX_req;
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
int m,i,N_S_NB; int i;
int *Sj; int rvidx;
int n_NB = 0;
int TBS;
int k,rvidx;
...@@ -378,7 +378,7 @@ schedule_SI_BR( ...@@ -378,7 +378,7 @@ schedule_SI_BR(
if (bcch_sdu_length > 0) { if (bcch_sdu_length > 0) {
AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3), AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3),
"RRC provided bcch with length %d > %d\n", "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); 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 // 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) { ...@@ -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, void get_Msg3alloc(COMMON_channels_t *cc,
unsigned char current_subframe, sub_frame_t current_subframe,
unsigned int current_frame, frame_t current_frame,
unsigned int *frame, frame_t *frame,
unsigned char *subframe) sub_frame_t *subframe)
{ {
// Fill in other TDD Configuration!!!! // Fill in other TDD Configuration!!!!
...@@ -211,10 +211,10 @@ void get_Msg3alloc(COMMON_channels_t *cc, ...@@ -211,10 +211,10 @@ void get_Msg3alloc(COMMON_channels_t *cc,
void get_Msg3allocret(COMMON_channels_t *cc, void get_Msg3allocret(COMMON_channels_t *cc,
unsigned char current_subframe, sub_frame_t current_subframe,
unsigned int current_frame, frame_t current_frame,
unsigned int *frame, frame_t *frame,
unsigned char *subframe) sub_frame_t *subframe)
{ {
if (cc->tdd_Config == NULL) { //FDD if (cc->tdd_Config == NULL) { //FDD
/* always retransmit in n+8 */ /* always retransmit in n+8 */
...@@ -249,7 +249,7 @@ void get_Msg3allocret(COMMON_channels_t *cc, ...@@ -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; uint8_t ret = 255;
...@@ -317,8 +317,8 @@ uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe) ...@@ -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, uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
uint32_t frame, frame_t frame,
unsigned char current_subframe) sub_frame_t current_subframe)
{ {
uint8_t ul_subframe=0; uint8_t ul_subframe=0;
...@@ -403,7 +403,7 @@ uint8_t get_Msg3harqpid(COMMON_channels_t *cc, ...@@ -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 // if FDD return dummy value
......
...@@ -403,7 +403,7 @@ void rx_sdu(const module_id_t enb_mod_idP, ...@@ -403,7 +403,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
RA_template->generate_Msg4 = 1; RA_template->generate_Msg4 = 1;
RA_template->wait_ack_Msg4 = 0; 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_frame = frameP + ((subframeP>5) ? 1 : 0);
RA_template->Msg4_subframe = (subframeP+4)%10; RA_template->Msg4_subframe = (subframeP+4)%10;
......
...@@ -230,6 +230,17 @@ unsigned short fill_rar( ...@@ -230,6 +230,17 @@ unsigned short fill_rar(
const uint8_t input_buffer_length 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 /* \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 Mod_id Instance ID of eNB
@param preamble_index index of the received RA request. @param preamble_index index of the received RA request.
...@@ -857,19 +868,18 @@ uint16_t getRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); ...@@ -857,19 +868,18 @@ uint16_t getRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
int get_subbandsize(uint8_t dl_bandwidth); 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, void get_Msg3allocret(COMMON_channels_t *cc,
unsigned char current_subframe, sub_frame_t current_subframe,
unsigned int current_frame, frame_t current_frame,
unsigned int *frame, frame_t *frame,
unsigned char *subframe); sub_frame_t *subframe);
void get_Msg3alloc(COMMON_channels_t *cc, void get_Msg3alloc(COMMON_channels_t *cc,
unsigned char current_subframe, sub_frame_t current_subframe,
unsigned int current_frame, frame_t current_frame,
unsigned int *frame, frame_t *frame,
unsigned char *subframe); sub_frame_t *subframe);
uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
...@@ -880,8 +890,23 @@ int to_rbg(int dl_Bandwidth); ...@@ -880,8 +890,23 @@ int to_rbg(int dl_Bandwidth);
int to_prb(int dl_Bandwidth); int to_prb(int dl_Bandwidth);
uint8_t get_Msg3harqpid(COMMON_channels_t *cc, uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
uint32_t frame, frame_t frame,
unsigned char current_subframe); 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 #endif
/** @}*/ /** @}*/
...@@ -132,8 +132,8 @@ unsigned short fill_rar( ...@@ -132,8 +132,8 @@ unsigned short fill_rar(
#ifdef Rel14 #ifdef Rel14
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned short fill_rar_br(eNB_MAC_INST *eNB, unsigned short fill_rar_br(eNB_MAC_INST *eNB,
const int CC_id, int CC_id,
const int ra_idx, RA_TEMPLATE *RA_template,
const frame_t frameP, const frame_t frameP,
const sub_frame_t subframeP, const sub_frame_t subframeP,
uint8_t* const dlsch_buffer, uint8_t* const dlsch_buffer,
...@@ -143,44 +143,41 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, ...@@ -143,44 +143,41 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
{ {
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; 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); uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
int i; int i;
uint8_t nb,rballoc,reps; uint8_t nb,rballoc,reps;
uint8_t mcs,TPC,ULdelay,cqireq; uint8_t mcs,TPC,ULdelay,cqireq;
COMMON_channels_t *cc = &eNB->common_channels[CC_id];
int input_buffer_length; int input_buffer_length;
AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs); AssertFatal(RA_template != NULL, "RA is null \n");
AssertFatal(ra_idx >= 0 && ra_idx < 4, "RA index not in [0..3]\n");
// subheader fixed // subheader fixed
rarh->E = 0; // First and last RAR 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->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 rarh->RAPID = RA_template->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 RA_template->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[0] = (uint8_t)(RA_template->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 rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
int N_NB_index; int N_NB_index;
AssertFatal(1==0,"RAR for BL/CE Still to be finished ...\n"); AssertFatal(1==0,"RAR for BL/CE Still to be finished ...\n");
// Copy the Msg2 narrowband // 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 if (ce_level<2) { //CE Level 0,1, CEmodeA
input_buffer_length =6; input_buffer_length =6;
N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth);
rar[4] = (uint8_t)(cc->RA_template[ra_idx].rnti>>8); rar[4] = (uint8_t)(RA_template->rnti>>8);
rar[5] = (uint8_t)(cc->RA_template[ra_idx].rnti&0xff); rar[5] = (uint8_t)(RA_template->rnti&0xff);
//cc->RA_template[ra_idx].timing_offset = 0; //cc->RA_template[ra_idx].timing_offset = 0;
nb = 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 rar[1] |= (rballoc&15)<<(4-N_NB_index); // Hopping = 0 (bit 3), 3 MSBs of rballoc
reps = 4; reps = 4;
...@@ -195,27 +192,26 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, ...@@ -195,27 +192,26 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
input_buffer_length =5; input_buffer_length =5;
rar[3] = (uint8_t)(cc->RA_template[ra_idx].rnti>>8); rar[3] = (uint8_t)(RA_template->rnti>>8);
rar[4] = (uint8_t)(cc->RA_template[ra_idx].rnti&0xff); 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", 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",
CC_id,
frameP, frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx, ce_level,
cc->RA_template[ra_idx].rnti, RA_template->rnti,
rarh->RAPID,cc->RA_template[0].preamble_index, rarh->RAPID,RA_template->preamble_index,
cc->RA_template[ra_idx].timing_offset); RA_template->timing_offset);
if (opt_enabled) { if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1, trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1,
eNB->frame, eNB->subframe, 0, 0); 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", LOG_D(OPT,"[RAPROC] 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, frameP, RA_template->rnti,
rarh->RAPID, input_buffer_length); rarh->RAPID, input_buffer_length);
} }
return(cc->RA_template[ra_idx].rnti); return(RA_template->rnti);
} }
#endif #endif
......
RUs = ( RUs = (
{ {
local_if_name = "enp1s0"; local_if_name = "lo";
remote_address = "192.168.117.113"; remote_address = "127.0.0.1"
local_address = "192.168.117.205"; local_address = "127.0.0.2";
local_portc = 50000; local_portc = 50000;
remote_portc = 50000; remote_portc = 50000;
local_portd = 50001; local_portd = 50001;
......
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