From faa111ecc0815354979e075d5b83c5af107d404e Mon Sep 17 00:00:00 2001 From: Raymond Knopp <raymond.knopp@eurecom.fr> Date: Sun, 13 Aug 2017 05:13:27 -0700 Subject: [PATCH] complete programming of Msg2/Msg4 procedures for eMTC. Addition of skeleton for PUCCH UCI (NFAPI) in L1. Some cleanup of eNB_scheduler.c --- cmake_targets/CMakeLists.txt | 2 +- openair1/PHY/LTE_TRANSPORT/defs.h | 76 +- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 2 - openair1/PHY/LTE_TRANSPORT/mdci.h | 18 +- openair1/PHY/LTE_TRANSPORT/proto.h | 2 + openair1/PHY/LTE_TRANSPORT/uci_tools.c | 17 + openair1/PHY/defs.h | 7 +- openair1/SCHED/phy_procedures_lte_eNb.c | 148 +- openair2/LAYER2/MAC/defs.h | 14 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 1513 +++++++++-------- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 12 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 24 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/MAC/proto.h | 47 +- openair2/LAYER2/MAC/rar_tools.c | 48 +- .../GENERIC-LTE-EPC/CONF/rru.oaisim.conf | 6 +- 16 files changed, 1068 insertions(+), 870 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f7bf468b08..a48590ad55 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1566,7 +1566,7 @@ ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c -${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/emu_transport.c +#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/emu_transport.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/pgm_link.c ) diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index 24602c277e..9d3d9c2b40 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -493,6 +493,73 @@ typedef struct { int32_t delta_TF; } LTE_UL_eNB_HARQ_t; + +typedef enum { + pucch_format1=0, + pucch_format1a, + pucch_format1b, + pucch_format2, + pucch_format2a, + pucch_format2b, + pucch_format3 // PUCCH format3 +} PUCCH_FMT_t; + +typedef enum { + SR, + HARQ, + CQI, + HARQ_SR, + HARQ_CQI, + SR_CQI, + HARQ_SR_CQI +} UCI_type_t; + +#ifdef Rel14 +typedef enum { + NOCE, + CEMODEA, + CEMODEB +} UE_type_t; +#endif + +typedef struct { + uint8_t active; + /// Absolute frame for this UCI + uint16_t frame; + /// Absolute subframe for this UCI + uint8_t subframe; + /// corresponding UE RNTI + uint16_t rnti; + /// Type (SR,HARQ,CQI,HARQ_SR,HARQ_CQI,SR_CQI,HARQ_SR_CQI) + UCI_type_t type; + /// PUCCH format to use + PUCCH_FMT_t pucch_fmt; + /// antenna indicator + uint8_t num_pucch_resources; + /// two antenna n1_pucch + uint16_t n_pucch_1[2]; + /// two antenna n2_pucch + uint16_t n_pucch_2[2]; +#ifdef Rel14 + /// non BL/CE, CEmodeA, CEmodeB + UE_type_t ue_type; + /// Indicates the symbols that are left empty due to eMTC retuning. + uint8_t empty_symbols; + /// number of repetitions for BL/CE + uint16_t total_repetitions; + /// The size of the DL CQI/PMI in bits. + uint16_t dl_cqi_pmi_size2; + /// The starting PRB for the PUCCH + uint8_t starting_prb; + /// The number of PRB in PUCCH + uint8_t n_PRB; + /// Selected CDM option + uint8_t cdm_Index; + // Indicates if the resource blocks allocated for this grant overlap with the SRS configuration. + uint8_t Nsrs; +#endif +} LTE_eNB_UCI_t; + typedef struct { /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; @@ -764,15 +831,6 @@ typedef enum { rx_SIC_dual_stream } RX_type_t; -typedef enum { - pucch_format1=0, - pucch_format1a, - pucch_format1b, - pucch_format2, - pucch_format2a, - pucch_format2b, - pucch_format3 // PUCCH format3 -} PUCCH_FMT_t; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index bdf687a711..18df5c3b44 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -120,8 +120,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ unsigned char exit_flag = 0,i,j,r,aa,layer; int re; unsigned char bw_scaling =1; - RU_t *ru; - int ru_id; switch (N_RB_DL) { case 6: diff --git a/openair1/PHY/LTE_TRANSPORT/mdci.h b/openair1/PHY/LTE_TRANSPORT/mdci.h index 17c88ef0b0..1e278f8011 100644 --- a/openair1/PHY/LTE_TRANSPORT/mdci.h +++ b/openair1/PHY/LTE_TRANSPORT/mdci.h @@ -233,6 +233,8 @@ typedef struct DCI6_1A_20MHz DCI6_1A_20MHz_t; /// basic DCI Format Type 6-0B (5 MHz) struct DCI6_0B_5MHz { + /// padding to fill 32-bit word + uint32_t padding:15; /// DCI subframe repetition uint32_t dci_rep:2; /// new data indicator @@ -240,7 +242,7 @@ struct DCI6_0B_5MHz { /// harq id uint32_t harq_pid:1; /// Repetition number - uint32_t rep:2; + uint32_t rep:3; /// Modulation and Coding Scheme and Redundancy Version uint32_t mcs:4; /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits) @@ -250,10 +252,12 @@ struct DCI6_0B_5MHz { } __attribute__ ((__packed__)); typedef struct DCI6_0B_5MHz DCI6_0B_5MHz_t; -#define sizeof_DCI6_0B_5MHz_t 16 +#define sizeof_DCI6_0B_5MHz_t 17 /// basic DCI Format Type 6-1B (5 MHz) struct DCI6_1B_5MHz { + /// padding to fill 32-bit word + uint32_t padding:15; /// DCI subframe repetition number uint32_t dci_rep:2; /// HARQ-ACK resource offset @@ -263,7 +267,7 @@ struct DCI6_1B_5MHz { /// HARQ Process uint32_t harq_pid:1; /// Repetition number - uint32_t rep:2; + uint32_t rep:3; /// Resource block assignment (assignment flag = 0 for 5 MHz, ceil(log2(floor(N_RB_DL/6)))+1) uint32_t rballoc:3; /// Modulation and Coding Scheme and Redundancy Version @@ -273,12 +277,12 @@ struct DCI6_1B_5MHz { } __attribute__ ((__packed__)); typedef struct DCI6_1B_5MHz DCI6_1B_5MHz_t; -#define sizeof_DCI6_1B_5MHz_t 16 +#define sizeof_DCI6_1B_5MHz_t 17 /// basic DCI Format Type 6-0B (10 MHz) struct DCI6_0B_10MHz { /// padding to fill 32-bit word - uint32_t padding:15; + uint32_t padding:14; /// DCI subframe repetition uint32_t dci_rep:2; /// new data indicator @@ -286,7 +290,7 @@ struct DCI6_0B_10MHz { /// harq id uint32_t harq_pid:1; /// Repetition number - uint32_t rep:2; + uint32_t rep:3; /// Modulation and Coding Scheme and Redundancy Version uint32_t mcs:4; /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 3 bits) @@ -296,7 +300,7 @@ struct DCI6_0B_10MHz { } __attribute__ ((__packed__)); typedef struct DCI6_0B_10MHz DCI6_0B_10MHz_t; -#define sizeof_DCI6_0B_10MHz_t 17 +#define sizeof_DCI6_0B_10MHz_t 18 /// basic DCI Format Type 6-1B (10 MHz) struct DCI6_1B_10MHz { diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 024da7a810..87b736e1b4 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -2188,5 +2188,7 @@ int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); +int8_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type); + /**@}*/ #endif diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index fba5b0c0e3..8b72b4e733 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -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); +} + + diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index cea49525c1..bf09cfcaa6 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -888,15 +888,9 @@ typedef struct PHY_VARS_eNB_s { /// Ethernet parameters for fronthaul interface eth_params_t eth_params; int rx_total_gain_dB; - // void (*do_prach)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame, int subframe); int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); - // void (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type); - // void (*proc_tx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *rn); - // void (*tx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc); - // void (*rx_fh)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe); int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); - // void (*fh_asynch)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe); uint8_t local_flag; LTE_DL_FRAME_PARMS frame_parms; PHY_MEASUREMENTS_eNB measurements; @@ -921,6 +915,7 @@ typedef struct PHY_VARS_eNB_s { LTE_eNB_PRACH prach_vars_br; #endif LTE_eNB_COMMON common_vars; + LTE_eNB_UCI_t uci_vars[NUMBER_OF_UE_MAX]; LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PBCH pbch; LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 546e6b7abf..f44e4309d8 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1065,17 +1065,43 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, #endif } +handle_uci_harq_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_ul_config_request_pdu_t *ul_config_pdu) { + +} + handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu) { nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8; int8_t UE_id; // check if we have received a dci for this ue and ulsch descriptor is configured - - AssertFatal((UE_id = find_ulsch(rel8->rnti,eNB,SEARCH_EXIST))>=0, - "No existing UE ULSCH for rnti %x\n",rel8->rnti); - AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, - "ulsch for UE_id %d is not active\n",UE_id); + + if (ul_config_pdu == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { + AssertFatal((UE_id = find_ulsch(rel8->rnti,eNB,SEARCH_EXIST))>=0, + "No existing UE ULSCH for rnti %x\n",rel8->rnti); + AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, + "ulsch for UE_id %d is not active\n",UE_id); + } + else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { + AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST))>=0, + "No existing UE UCI for rnti %x\n",rel8->rnti); + handle_uci_harq_pdu(eNB,proc,ul_config_pdu); + } + else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { + + } + else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { + + } + else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { + + } + else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { + + } + else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { + + } } @@ -1227,7 +1253,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { for (i=0;i<number_ul_pdu;i++) { ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i]; LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type); - AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE, + AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE, "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type); handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu); } @@ -1524,6 +1551,8 @@ void process_HARQ_feedback(uint8_t UE_id, int subframe = proc->subframe_rx; int harq_pid = subframe2harq_pid( fp,frame,subframe); + nfapi_harq_indication_pdu_t *pdu; + if (fp->frame_type == FDD) { //FDD subframe_m4 = (subframe<4) ? subframe+6 : subframe-4; @@ -1546,6 +1575,9 @@ void process_HARQ_feedback(uint8_t UE_id, */ } + // fill ACK/NAK Indication + pdu = &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs]; + eNB->UL_INFO.harq_ind.number_of_harqs++; #if defined(MESSAGE_CHART_GENERATOR_PHY) MSC_LOG_RX_MESSAGE( @@ -1578,6 +1610,7 @@ void process_HARQ_feedback(uint8_t UE_id, ?eNB->ulsch[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]:eNB->ulsch[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[1]; } + else { // PUCCH ACK/NAK if ((SR_payload == 1)&&(pucch_sel!=2)) { // decode Table 7.3 if multiplexing and SR=1 nb_ACK = 0; @@ -2752,8 +2785,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const frame,subframe, i, ulsch_harq->round-1); - dump_ulsch(eNB,proc,i); - exit(-1); LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", eNB->Mod_id,harq_pid, @@ -2768,46 +2799,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1], ret); - /* - if (ulsch_harq->round == - fp->maxHARQ_Msg3Tx) { - LOG_D(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n", - eNB->Mod_id, i); - eNB->UE_stats[i].mode = PRACH; -// if (eNB->mac_enabled==1) { -// mac_xface->cancel_ra_proc(eNB->Mod_id, -// eNB->CC_id, -// frame, -// eNB->UE_stats[i].crnti); -// -// } - - // mac_phy_remove_ue(eNB->Mod_id,eNB->UE_stats[i].crnti); - - eNB->ulsch[(uint32_t)i]->Msg3_active = 0; - //ulsch_harq->phich_active = 0; - - } else { - // activate retransmission for Msg3 (signalled to UE PHY by PHICH (not MAC/DCI) - eNB->ulsch[(uint32_t)i]->Msg3_active = 1; - - get_Msg3_alloc_ret(fp, - subframe, - frame, - &ulsch_harq->frame, - &ulsch_harq->subframe); - - //mac_xface->set_msg3_subframe(eNB->Mod_id, eNB->CC_id, frame, subframe, eNB->ulsch[i]->rnti, - // eNB->ulsch[i]->Msg3_frame, eNB->ulsch[i]->Msg3_subframe); - - - T(T_ENB_PHY_MSG3_ALLOCATION, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), - T_INT(i), T_INT(ulsch->rnti), T_INT(0 - // 0 is for retransmission - ), - T_INT(eNB->ulsch[i]->Msg3_frame), T_INT(eNB->ulsch[i]->Msg3_subframe)); - } -*/ LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i); } // This is Msg3 error @@ -2836,34 +2827,17 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->Mod_id,harq_pid, frame,subframe, i, ulsch->Mlimit); - + ulsch_harq->round=0; ulsch_harq->phich_active=0; eNB->UE_stats[i].ulsch_errors[harq_pid]++; eNB->UE_stats[i].ulsch_consecutive_errors++; - - /*if (ulsch_harq->nb_rb > 20) { - dump_ulsch(eNB,proc,i); - exit(-1); - }*/ - // indicate error to MAC - if (eNB->mac_enabled == 1) { - /* - mac_xface->rx_sdu(eNB->Mod_id, - eNB->CC_id, - frame,subframe, - ulsch->rnti, - NULL, - 0, - harq_pid, - &eNB->ulsch[i]->Msg3_flag); - */ - } - } - } + + } + } } // ulsch in error else { - + fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC @@ -2920,29 +2894,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->Mod_id, frame,harq_pid,i); if (eNB->mac_enabled) { - /* - mac_xface->rx_sdu(eNB->Mod_id, - eNB->CC_id, - frame,subframe, - eNB->ulsch[i]->rnti, - ulsch_harq->b, - ulsch_harq->TBS>>3, - harq_pid, - &ulsch->Msg3_flag); - */ // Fill UL info } // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI) if (ulsch_harq->Msg3_flag == 0 ) { eNB->UE_stats[i].mode = PRACH; - /* - mac_xface->cancel_ra_proc(eNB->Mod_id, - eNB->CC_id, - frame, - eNB->UE_stats[i].crnti); - mac_phy_remove_ue(eNB->Mod_id,eNB->UE_stats[i].crnti); - */ - eNB->ulsch[(uint32_t)i]->Msg3_active = 0; } // Msg3_flag == 0 @@ -2984,26 +2940,12 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const harq_pid,ulsch_harq->TBS>>3); for (j=0; j<ulsch_harq->TBS>>3; j++) - LOG_T(PHY,"%x.",eNB->ulsch[i]->harq_processesyy[harq_pid]->b[j]); + LOG_T(PHY,"%x.",eNB->ulsch[i]->harq_processes[harq_pid]->b[j]); LOG_T(PHY,"\n"); #endif #endif - if (eNB->mac_enabled==1) { - /* - mac_xface->rx_sdu(eNB->Mod_id, - eNB->CC_id, - frame,subframe, - ulsch->rnti, - eNB->ulsch[i]->harq_processes[harq_pid]->b, - eNB->ulsch[i]->harq_processes[harq_pid]->TBS>>3, - harq_pid, - NULL);*/ - - // Fill UL_INFO - - } // mac_enabled==1 } // Msg3_flag == 0 diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 2c8b613b1d..43cb99c286 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -827,15 +827,15 @@ typedef struct { /// Subframe where Msg2 is to be sent uint8_t Msg2_subframe; /// Frame where Msg2 is to be sent - uint8_t Msg2_frame; + frame_t Msg2_frame; /// Subframe where Msg3 is to be sent - uint8_t Msg3_subframe; + sub_frame_t Msg3_subframe; /// Frame where Msg3 is to be sent - uint8_t Msg3_frame; + frame_t Msg3_frame; /// Subframe where Msg4 is to be sent - uint8_t Msg4_subframe; + sub_frame_t Msg4_subframe; /// Frame where Msg4 is to be sent - uint8_t Msg4_frame; + frame_t Msg4_frame; /// Flag to indicate the eNB should generate Msg4 upon reception of SDU from RRC. This is triggered by first ULSCH reception at eNB for new user. uint8_t generate_Msg4; /// Flag to indicate that eNB is waiting for ACK that UE has received Msg3. @@ -854,6 +854,10 @@ typedef struct { int16_t RRC_timer; /// Round of Msg3 HARQ uint8_t msg3_round; + /// TBS used for Msg4 + int Msg4_TBsize; + /// MCS used for Msg4 + int Msg4_mcs; #ifdef Rel14 uint8_t rach_resource_type; uint8_t msg2_mpdcch_repetition_cnt; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 86cb9d2e68..64e8c8380f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -61,12 +61,6 @@ #include "SIMULATION/TOOLS/defs.h" // for taus #include "T.h" -// eMTC notes -// Implements MSG2 and MSG4 -// fill_rar for eMTC -// new RA_templates for eMTC UEs, CCCH_BR instead of CCCH -// resource allocation for format 1A (4->6 PRBs) -// initiate_ra_proc: add detection of BR/CE UEs void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) { @@ -91,7 +85,7 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr if (RA_template->RA_active == TRUE) { - + // program reception 4 subframes prior to transmission msg3_prog_subframe = (RA_template->Msg3_subframe + 6)%10; if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023; @@ -104,7 +98,7 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr (msg3_prog_subframe==subframeP)) { LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n", frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe); - eNB->UL_req[CC_id].sfn_sf = (RA_template->Msg3_frame<<3) + RA_template->Msg3_subframe; + eNB->UL_req[CC_id].sfn_sf = (RA_template->Msg3_frame<<4) + RA_template->Msg3_subframe; if (RA_template->msg3_round == 0) { // program ULSCH ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; @@ -149,44 +143,37 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr } } -void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) -{ +void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) { - int CC_id; eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; - RA_TEMPLATE *RA_template; - uint8_t i; - int16_t rrc_sdu_length; - uint8_t lcid; - uint8_t offset; - int UE_id = -1; - int16_t TBsize = -1; - uint16_t msg4_padding; - uint16_t msg4_post_padding; - uint16_t msg4_header; + uint8_t *vrb_map; int first_rb; int N_RB_DL; nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_pdu_t *TX_req; - UE_list_t *UE_list=&eNB->UE_list; - int round; nfapi_dl_config_request_body_t *dl_req; + vrb_map = cc[CC_idP].vrb_map; + dl_req = &eNB->DL_req[CC_idP].dl_config_request_body; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); + #ifdef Rel14 int rmax = 0; int rep = 0; int reps = 0; int num_nb = 0; + first_rb = 0; struct PRACH_ConfigSIB_v1310 *ext4_prach; PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; - PRACH_ParametersCE_r13_t *p[3]; + PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL}; - if (cc[CC_id].radioResourceConfigCommon_BR) { + if (cc[CC_idP].radioResourceConfigCommon_BR) { - ext4_prach = cc[CC_id].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; switch (prach_ParametersListCE_r13->list.count) { @@ -202,686 +189,856 @@ 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); } } + + if (RA_template->rach_resource_type > 0) { + + // This uses an MPDCCH Type 2 common allocation according to Section 9.1.5 36-213 + // Parameters: + // p=2+4 PRB set (number of PRB pairs 3) + // rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 + // if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates + // if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates + // distributed transmission + + // rmax from SIB2 information + rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; + // choose r3 by default for RAR (Table 9.1.5-5) + rep = 2; + // get actual repetition count from Table 9.1.5-3 + reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep)); + // get narrowband according to higher-layer config + num_nb = p[RA_template->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.count; + RA_template->msg2_narrowband = *p[RA_template->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.array[RA_template->preamble_index%num_nb]; + first_rb = RA_template->msg2_narrowband*6; + + if ((RA_template->msg2_mpdcch_repetition_cnt == 0) && + (mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2)>0)){ + // MPDCCH configuration for RAR + + + + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (RA_template->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = RA_template->msg2_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space + AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, + "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6,0,6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 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.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; + RA_template->msg2_mpdcch_repetition_cnt++; + dl_req->number_pdu++; + + } //repetition_count==0 && SF condition met + else if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions + RA_template->msg2_mpdcch_repetition_cnt++; + if (RA_template->msg2_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition + if (cc[CC_idP].tdd_Config==NULL) { // FDD case + // wait 2 subframes for PDSCH transmission + if (subframeP>7) RA_template->Msg2_frame = (frameP+1)&1023; + else RA_template->Msg2_frame = frameP; + RA_template->Msg2_subframe = (subframeP+2)%10; // +2 is the "n+x" from Section 7.1.11 in 36.213 + } + else { + AssertFatal(1==0,"TDD case not done yet\n"); + } + } // mpdcch_repetition_count == reps + if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { + // Program PDSCH + RA_template->generate_rar = 0; + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + 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.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 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_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10*frameP)+subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; + dl_req->number_pdu++; + + // Program UL processing for Msg3, same as regular LTE + get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe); + + + fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1); + // DL request + eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; + TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble + TX_req->pdu_index = eNB->pdu_index[CC_idP]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 7; + TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload; + eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; + } + } + + } + else #endif + { + if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d))\n", + module_idP, CC_idP, frameP, subframeP, + RA_template->RA_active, + + RA_template->RA_dci_fmt1, + RA_template->RA_dci_size_bits1); + + first_rb = 0; + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->RA_rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + 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.resource_block_coding = getRIV(N_RB_DL,first_rb,4); + + if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) { + LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", + frameP,subframeP,RA_template->RA_rnti); + dl_req->number_dci++; + 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)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + + // Program UL processing for Msg3 + get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe); + + + fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7); + // DL request + eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; + TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble + TX_req->pdu_index = eNB->pdu_index[CC_idP]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 7; + TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload; + eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; + } // PDCCH CCE allocation is feasible + } // Msg2 frame/subframe condition + } // else BL/CE +} - - start_meas(&eNB->schedule_ra); +void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template){ - - 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; + 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; + - 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++) { +#ifdef Rel14 + int rmax = 0; + int rep = 0; + int reps = 0; - RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i]; - if (RA_template->RA_active == TRUE) { + 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}; - 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 (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); - if (RA_template->generate_rar == 1) { + UE_id = find_UE_id(module_idP,RA_template->rnti); + AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); + + + // Get RRCConnectionSetup for Piggyback + rrc_sdu_length = mac_rrc_data_req(module_idP, + CC_idP, + frameP, + CCCH, + 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], + ENB_FLAG_YES, + module_idP, + 0); // not used in this case + + AssertFatal(rrc_sdu_length>=0, + "[MAC][eNB Scheduler] CCCH not allocated\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_idP, frameP, subframeP,UE_id, rrc_sdu_length); + #ifdef Rel14 - if (RA_template->rach_resource_type > 0) { - - // This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213 - // Parameters: - // p=2+4 PRB set (number of PRB pairs 3) - // rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 - // if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates - // if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates - // distributed transmission - - // rmax from SIB2 information - rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; - // choose r3 by default for RAR - rep = 2; - // get actual repetition count from Table 9.1.5-3 - reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep)); - // get narrowband according to higher-layer config - num_nb = p[RA_template->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.count; - RA_template->msg2_narrowband = *p[RA_template->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.array[RA_template->preamble_index%num_nb]; - first_rb = RA_template->msg2_narrowband*6; - - if ((RA_template->msg2_mpdcch_repetition_cnt == 0) && - (mpdcch_sf_condition(eNB,CC_id,frameP,subframeP,rmax,TYPE2)>0)){ - // MPDCCH configuration for RAR + if (RA_template->rach_resource_type>0) { + + // Generate DCI + repetitions first + // This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213 : Note: Assumption that this is still Type 2 Common Search + // Parameters: + // p=2+4 PRB set (number of PRB pairs 6) + // rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 + // if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates + // if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates + // distributed transmission + + // rmax from SIB2 information + rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; + AssertFatal(rmax>=4,"choose rmax>=4 for enough repeititions, or reduce rep to 1 or 2\n"); + + // choose r3 by default for Msg4 (this is ok from table 9.1.5-3 for rmax = >=4, if we choose rmax <4 it has to be less + rep = 2; + // get actual repetition count from Table 9.1.5-3 + reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep)); + // get first narrowband + first_rb = RA_template->msg34_narrowband*6; + + if ((RA_template->msg4_mpdcch_repetition_cnt == 0) && + (mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2)>0)){ + // MPDCCH configuration for RAR + + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (RA_template->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = RA_template->msg34_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; + AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, + "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-C-RNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; /// Check this is still N_id_cell for type2 common + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6,0,6);// check if not getRIV(N_RB_DL,first_rb,6); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of Msg4, 208 bits with N1A_PRB=3 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 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.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3; => 208 bits + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; + RA_template->msg4_mpdcch_repetition_cnt++; + dl_req->number_pdu++; + + } //repetition_count==0 && SF condition met + else if (RA_template->msg4_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions + RA_template->msg4_mpdcch_repetition_cnt++; + if (RA_template->msg4_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition + if (cc[CC_idP].tdd_Config==NULL) { // FDD case + // wait 2 subframes for PDSCH transmission + if (subframeP>7) RA_template->Msg4_frame = (frameP+1)&1023; + else RA_template->Msg4_frame = frameP; + RA_template->Msg4_subframe = (subframeP+2)%10; + } + else { + AssertFatal(1==0,"TDD case not done yet\n"); + } + } // mpdcch_repetition_count == reps + if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { + + // Program PDSCH + + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n", + module_idP, CC_idP, frameP, subframeP,RA_template->rach_resource_type-1,RA_template->rnti); + AssertFatal(1==0,"Msg4 generation not finished for BL/CE UE\n"); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); // check that this isn't getRIV(6,0,6) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 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_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10*frameP)+subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; + dl_req->number_pdu++; + + RA_template->generate_Msg4=0; + RA_template->wait_ack_Msg4=1; + RA_template->RA_active = FALSE; + lcid=0; + + // set HARQ process 0 round to 0 for this UE + UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0; + msg4_header = 1+6+1; // CR header, CR CE, SDU header + + if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { + msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_post_padding = 0; + } else { + msg4_padding = 0; + msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1; + } + + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", + module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); + DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return + // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] + offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + 1, //num_sdus + (unsigned short*)&rrc_sdu_length, // + &lcid, // sdu_lcid + 255, // no drx + 0, // no timing advance + RA_template->cont_res_id, // contention res id + msg4_padding, // no padding + msg4_post_padding); + + memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], + &cc[CC_idP].CCCH_pdu.payload[0], + rrc_sdu_length); + + // DL request + eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; + TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; + TX_req->pdu_length = rrc_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_idP]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = rrc_sdu_length; + TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]; + eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; - - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (RA_template->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = RA_template->msg2_narrowband; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; - AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, - "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.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].physCellId; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(N_RB_DL,first_rb,6); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 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.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.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; - RA_template->msg2_mpdcch_repetition_cnt++; - dl_req->number_pdu++; - - } //repetition_count==0 && SF condition met - if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions - RA_template->msg2_mpdcch_repetition_cnt++; - if (RA_template->msg2_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition - if (cc[CC_id].tdd_Config==NULL) { // FDD case - // wait 2 subframes for PDSCH transmission - if (subframeP>7) RA_template->Msg2_frame = (frameP+1)&1023; - else RA_template->Msg2_frame = frameP; - RA_template->Msg2_subframe = (subframeP+2)%10; - } - else { - AssertFatal(1==0,"TDD case not done yet\n"); - } - } // mpdcch_repetition_count == reps - if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { - // Program PDSCH - RA_template->generate_rar = 0; - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - 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.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 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_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10*frameP)+subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; - dl_req->number_pdu++; - - // Program UL processing for Msg3, same as regular LTE - get_Msg3alloc(&cc[CC_id],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe); - - - fill_rar_br(eNB,CC_id,i,frameP,subframeP,cc[CC_id].RAR_pdu.payload,RA_template->rach_resource_type-1); - // DL request - eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - 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->num_segments = 1; - TX_req->segments[0].segment_length = 7; - TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - } - } - - } - else + // Program ACK/NAK for Msg4 PDSCH + int absSF = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe; + // see Section 10.2 from 36.213 + int ackNAK_absSF = absSF + reps + 4; + + eNB->UL_req[CC_idP].sfn_sf = ((ackNAK_absSF/10)<<4) + (ackNAK_absSF%10); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = RA_template->rnti; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[RA_template->rach_resource_type-1]; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0; + // Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that + if (cc[CC_idP].tdd_Config==NULL) { // FDD case + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = n1pucchan[RA_template->rach_resource_type-1]; + // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case + // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] + // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => + // Delta_ARO = 0 from Table 10.1.2.1-1 + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size = 1; // 1-bit ACK/NAK + } + else { + AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); + } + ul_req->number_of_pdus++; + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP), + T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize)); + + if (opt_enabled==1) { + trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), + eNB->frame, eNB->subframe,0,0); + LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", + module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); + } + } // Msg4 frame/subframe + } // msg4_mpdcch_repetition_count + } // rach_resource_type > 0 + else #endif - { - if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI (proc %d), RA_active %d format 1A (%d,%d))\n", - module_idP, CC_id, frameP, subframeP,i, - RA_template->RA_active, - - RA_template->RA_dci_fmt1, - RA_template->RA_dci_size_bits1); - - first_rb = 0; - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->RA_rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - 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.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)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", - frameP,subframeP,RA_template->RA_rnti); - dl_req->number_dci++; - 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)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - - // Program UL processing for Msg3 - get_Msg3alloc(&cc[CC_id],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); - // DL request - eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - 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->num_segments = 1; - TX_req->segments[0].segment_length = 7; - TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - } // PDCCH CCE allocation is feasible - } // Msg2 frame/subframe condition - } // else BL/CE - } // state generate_rar == 1 - else if (RA_template->generate_Msg4 == 1) { - - // check for Msg4 Message + { // This is normal LTE case + if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", + module_idP, CC_idP, frameP, subframeP,RA_template->rnti); + + first_rb=0; + + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + + + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // C-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.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; + RA_template->Msg4_TBsize = 22; + } else if ((rrc_sdu_length+msg4_header) <= 28) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5; + RA_template->Msg4_TBsize = 28; + } else if ((rrc_sdu_length+msg4_header) <= 32) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6; + RA_template->Msg4_TBsize = 32; + } else if ((rrc_sdu_length+msg4_header) <= 41) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7; + RA_template->Msg4_TBsize = 41; + } else if ((rrc_sdu_length+msg4_header) <= 49) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8; + RA_template->Msg4_TBsize = 49; + } else if ((rrc_sdu_length+msg4_header) <= 57) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9; + RA_template->Msg4_TBsize = 57; + } + + RA_template->Msg4_mcs = dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4); + + if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; - UE_id = find_UE_id(module_idP,RA_template->rnti); - AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); + RA_template->generate_Msg4=0; + RA_template->wait_ack_Msg4=1; + RA_template->RA_active = FALSE; + lcid=0; + // set HARQ process 0 round to 0 for this UE + UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0; - // Get RRCConnectionSetup for Piggyback - rrc_sdu_length = mac_rrc_data_req(module_idP, - CC_id, - frameP, - CCCH, - 1, // 1 transport block - &cc[CC_id].CCCH_pdu.payload[0], - ENB_FLAG_YES, - module_idP, - 0); // not used in this case + if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { + msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_post_padding = 0; + } else { + msg4_padding = 0; + msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1; + } - AssertFatal(rrc_sdu_length>=0, - "[MAC][eNB Scheduler] CCCH not allocated\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_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); + DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return + // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] + offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + 1, //num_sdus + (unsigned short*)&rrc_sdu_length, // + &lcid, // sdu_lcid + 255, // no drx + 0, // no timing advance + RA_template->cont_res_id, // contention res id + msg4_padding, // no padding + msg4_post_padding); + memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], + &cc[CC_idP].CCCH_pdu.payload[0], + rrc_sdu_length); - 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); + // DL request + eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; + TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; + TX_req->pdu_length = rrc_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_idP]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = rrc_sdu_length; + TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]; + eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; + // Program PUCCH1a for ACK/NAK + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = RA_template->rnti; + if (cc[CC_idP].tdd_Config==NULL) { // FDD case + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = cc[CC_idP].radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx; + // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size = 1; // 1-bit ACK/NAK + } + else { + AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD case yet\n"); + } -#ifdef Rel14 - if (RA_template->rach_resource_type>0) { - - // Generate DCI + repetitions first - // This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213 - // Parameters: - // p=2+4 PRB set (number of PRB pairs 6) - // rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 - // if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates - // if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates - // distributed transmission - - // rmax from SIB2 information - rmax = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; - // choose r3 by default for Msg4 - rep = 2; - // get actual repetition count from Table 9.1.5-3 - reps = (rmax<=8)?(1<<rep):(rmax>>(3-rep)); - // get first narrowband - first_rb = RA_template->msg34_narrowband*6; - - if ((RA_template->msg4_mpdcch_repetition_cnt == 0) && - (mpdcch_sf_condition(eNB,CC_id,frameP,subframeP,rmax,TYPE2)>0)){ - // MPDCCH configuration for RAR - - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (RA_template->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = RA_template->msg34_narrowband; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; - AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, - "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.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].physCellId; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(N_RB_DL,first_rb,6); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 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.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.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; - RA_template->msg4_mpdcch_repetition_cnt++; - dl_req->number_pdu++; - - } //repetition_count==0 && SF condition met - if (RA_template->msg4_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions - RA_template->msg4_mpdcch_repetition_cnt++; - if (RA_template->msg4_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition - if (cc[CC_id].tdd_Config==NULL) { // FDD case - // wait 2 subframes for PDSCH transmission - if (subframeP>7) RA_template->Msg4_frame = (frameP+1)&1023; - else RA_template->Msg4_frame = frameP; - RA_template->Msg4_subframe = (subframeP+2)%10; - } - else { - AssertFatal(1==0,"TDD case not done yet\n"); - } - } // mpdcch_repetition_count == reps - if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { - - // Program PDSCH - - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (RA proc %d, RNTI %x)\n", - module_idP, CC_id, frameP, subframeP,i,RA_template->rnti); - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 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_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10*frameP)+subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; - dl_req->number_pdu++; - - RA_template->generate_Msg4=0; - RA_template->wait_ack_Msg4=1; - RA_template->RA_active = FALSE; - lcid=0; - - // set HARQ process 0 round to 0 for this UE - UE_list->UE_sched_ctrl[UE_id].round[CC_id] = 0; - - if ((TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = TBsize - rrc_sdu_length - msg4_header; - msg4_post_padding = 0; - } else { - msg4_padding = 0; - msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1; - } - - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP,CC_id,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); - DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return - // CHECK THIS: &cc[CC_id].CCCH_pdu.payload[0] - offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], - 1, //num_sdus - (unsigned short*)&rrc_sdu_length, // - &lcid, // sdu_lcid - 255, // no drx - 0, // no timing advance - RA_template->cont_res_id, // contention res id - msg4_padding, // no padding - msg4_post_padding); - - memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], - &cc[CC_id].CCCH_pdu.payload[0], - rrc_sdu_length); - - // DL request - eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = rrc_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = rrc_sdu_length; - TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP), - T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TBsize)); - - if (opt_enabled==1) { - trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], - rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), - eNB->frame, eNB->subframe,0,0); - LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); - } - } // Msg4 frame/subframe - } // msg4_mpdcch_repetition_count - } // rach_resource_type > 0 - else -#endif - { - if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n", - module_idP, CC_id, frameP, subframeP,i,RA_template->rnti); - - first_rb=0; - - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - - - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // C-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - - // Compute MCS for 3 PRB - msg4_header = 1+6+1; // CR header, CR CE, SDU header - - - if ((rrc_sdu_length+msg4_header) <= 22) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 4; - TBsize = 22; - } else if ((rrc_sdu_length+msg4_header) <= 28) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5; - TBsize = 28; - } else if ((rrc_sdu_length+msg4_header) <= 32) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6; - TBsize = 32; - } else if ((rrc_sdu_length+msg4_header) <= 41) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7; - TBsize = 41; - } else if ((rrc_sdu_length+msg4_header) <= 49) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8; - TBsize = 49; - } else if ((rrc_sdu_length+msg4_header) <= 57) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9; - TBsize = 57; - } - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4); - - if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - - RA_template->generate_Msg4=0; - RA_template->wait_ack_Msg4=1; - RA_template->RA_active = FALSE; - lcid=0; - - // set HARQ process 0 round to 0 for this UE - UE_list->UE_sched_ctrl[UE_id].round[CC_id] = 0; - - if ((TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = TBsize - rrc_sdu_length - msg4_header; - msg4_post_padding = 0; - } else { - msg4_padding = 0; - msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1; - } - - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP,CC_id,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); - DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return - // CHECK THIS: &cc[CC_id].CCCH_pdu.payload[0] - offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], - 1, //num_sdus - (unsigned short*)&rrc_sdu_length, // - &lcid, // sdu_lcid - 255, // no drx - 0, // no timing advance - RA_template->cont_res_id, // contention res id - msg4_padding, // no padding - msg4_post_padding); - - memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], - &cc[CC_id].CCCH_pdu.payload[0], - rrc_sdu_length); - - // DL request - eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = rrc_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = rrc_sdu_length; - TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP), - T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TBsize)); - - if (opt_enabled==1) { - trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], - rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), - eNB->frame, eNB->subframe,0,0); - LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); - } - - } // CCE Allocation feasible - } // msg4 frame/subframe - } // else rach_resource_type - } else if (RA_template->wait_ack_Msg4==1) { - // check HARQ status and retransmit if necessary - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \tn", - module_idP,CC_id,frameP,subframeP); - // Get candidate harq_pid from PHY + 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)); - UE_id = find_UE_id(module_idP,RA_template->rnti); - AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); - round = UE_list->UE_sched_ctrl[UE_id].round[CC_id]; + if (opt_enabled==1) { + trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), + eNB->frame, eNB->subframe,0,0); + LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", + module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); + } - if (round>0) { + } // CCE Allocation feasible + } // msg4 frame/subframe + } // else rach_resource_type +} + +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 - AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n"); + COMMON_channels_t *cc = eNB->common_channels; + + int rmax = 0; + int rep = 0; + int reps = 0; + + first_rb = 0; + struct PRACH_ConfigSIB_v1310 *ext4_prach; + PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; + PRACH_ParametersCE_r13_t *p[4]; + + if (cc[CC_idP].radioResourceConfigCommon_BR) { + + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + + switch (prach_ParametersListCE_r13->list.count) { + case 4: + p[3]=prach_ParametersListCE_r13->list.array[3]; + case 3: + p[2]=prach_ParametersListCE_r13->list.array[2]; + case 2: + p[1]=prach_ParametersListCE_r13->list.array[1]; + case 1: + p[0]=prach_ParametersListCE_r13->list.array[0]; + default: + AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count); + } + } +#endif + */ + + // check HARQ status and retransmit if necessary + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \tn", + module_idP,CC_idP,frameP,subframeP); + // Get candidate harq_pid from PHY + + UE_id = find_UE_id(module_idP,RA_template->rnti); + AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); + round = UE_list->UE_sched_ctrl[UE_id].round[CC_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) { + +#ifdef Rel14 + AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n"); #endif - { - if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { - - //RA_template->wait_ack_Msg4++; - // we have to schedule a retransmission - - first_rb=0; - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // C-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - - // Compute MCS for 3 PRB - msg4_header = 1+6+1; // CR header, CR CE, SDU header - - - if ((rrc_sdu_length+msg4_header) <= 22) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 4; - TBsize = 22; - } else if ((rrc_sdu_length+msg4_header) <= 28) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5; - TBsize = 28; - } else if ((rrc_sdu_length+msg4_header) <= 32) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6; - TBsize = 32; - } else if ((rrc_sdu_length+msg4_header) <= 41) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7; - TBsize = 41; - } else if ((rrc_sdu_length+msg4_header) <= 49) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8; - TBsize = 49; - } else if ((rrc_sdu_length+msg4_header) <= 57) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9; - TBsize = 57; - } - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4); - - if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - - LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP); - } - else - LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP); - LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n", - module_idP,CC_id,frameP,subframeP,RA_template->rnti); - } - } + { + if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { + + //RA_template->wait_ack_Msg4++; + // we have to schedule a retransmission + + first_rb=0; + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // C-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 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.resource_block_coding= getRIV(N_RB_DL,first_rb,4); + + if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + + LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP); + } + else + LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP); + LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n", + module_idP,CC_idP,frameP,subframeP,RA_template->rnti); + } + } + + } else { + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP); + RA_template->wait_ack_Msg4=0; + RA_template->RA_active=FALSE; + UE_id = find_UE_id(module_idP,RA_template->rnti); + DevAssert( UE_id != -1 ); + eNB->UE_list.UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured=TRUE; + } +} + +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); + - } else { - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_id,frameP,subframeP); - RA_template->wait_ack_Msg4=0; - RA_template->RA_active=FALSE; - UE_id = find_UE_id(module_idP,RA_template->rnti); - DevAssert( UE_id != -1 ); - eNB->UE_list.UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured=TRUE; - } - } //wait_ack_Msg4 == 1 + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + // skip UL component carriers + if (is_UL_sf(&cc[CC_id],subframeP)==1) continue; + + + for (i=0; i<NB_RA_PROC_MAX; i++) { + + RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i]; + + if (RA_template->RA_active == TRUE) { + + LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n", + module_idP,CC_id,i,RA_template->generate_rar,RA_template->generate_Msg4,RA_template->wait_ack_Msg4, RA_template->rnti); + + if (RA_template->generate_rar == 1) generate_Msg2(module_idP,CC_id,frameP,subframeP,RA_template); + else if (RA_template->generate_Msg4 == 1) generate_Msg4(module_idP,CC_id,frameP,subframeP,RA_template); + else if (RA_template->wait_ack_Msg4==1) check_Msg4_retransmission(module_idP,CC_id,frameP,subframeP,RA_template); + + } // RA_active == TRUE } // for i=0 .. N_RA_PROC-1 } // CC_id @@ -910,7 +1067,7 @@ void initiate_ra_proc(module_id_t module_idP, LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,preamble_index); #ifdef Rel14 - LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d PRACH resource type %d\n",module_idP,CC_id,frameP,preamble_index,rach_resource_type); + LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d PRACH resource type %d\n",module_idP,CC_id,frameP,rach_resource_type); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,1); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index a400bb3ccd..208a5c8fbb 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -143,7 +143,10 @@ schedule_SIB1_BR( switch (N_RB_DL) { case 6: case 15: + m=1; n_NB=0; + N_S_NB=0; + Sj=NULL; break; case 25: m=2; @@ -305,11 +308,8 @@ schedule_SI_BR( nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; - int m,i,N_S_NB; - int *Sj; - int n_NB = 0; - int TBS; - int k,rvidx; + int i; + int rvidx; @@ -378,7 +378,7 @@ schedule_SI_BR( if (bcch_sdu_length > 0) { AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3), "RRC provided bcch with length %d > %d\n", - bcch_sdu_length,(si_TBS_r13>>3)); + bcch_sdu_length,(int)(si_TBS_r13>>3)); LOG_D(MAC,"[eNB %d] Frame %d : BCCH_BR %d->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,i,CC_id,bcch_sdu_length); // allocate all 6 PRBs in narrowband for SIB1_BR diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 1b835de69c..09e5fe4d2c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -98,10 +98,10 @@ uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) { } void get_Msg3alloc(COMMON_channels_t *cc, - unsigned char current_subframe, - unsigned int current_frame, - unsigned int *frame, - unsigned char *subframe) + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe) { // Fill in other TDD Configuration!!!! @@ -211,10 +211,10 @@ void get_Msg3alloc(COMMON_channels_t *cc, void get_Msg3allocret(COMMON_channels_t *cc, - unsigned char current_subframe, - unsigned int current_frame, - unsigned int *frame, - unsigned char *subframe) + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe) { if (cc->tdd_Config == NULL) { //FDD /* always retransmit in n+8 */ @@ -249,7 +249,7 @@ void get_Msg3allocret(COMMON_channels_t *cc, } } -uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe) +uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe) { uint8_t ret = 255; @@ -317,8 +317,8 @@ uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe) } uint8_t get_Msg3harqpid(COMMON_channels_t *cc, - uint32_t frame, - unsigned char current_subframe) + frame_t frame, + sub_frame_t current_subframe) { uint8_t ul_subframe=0; @@ -403,7 +403,7 @@ uint8_t get_Msg3harqpid(COMMON_channels_t *cc, } -int is_UL_sf(COMMON_channels_t *ccP,uint8_t subframeP) +int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP) { // if FDD return dummy value diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 2851c91db6..3489c8e5e5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -403,7 +403,7 @@ void rx_sdu(const module_id_t enb_mod_idP, RA_template->generate_Msg4 = 1; RA_template->wait_ack_Msg4 = 0; - // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now + // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different RA_template->Msg4_frame = frameP + ((subframeP>5) ? 1 : 0); RA_template->Msg4_subframe = (subframeP+4)%10; diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 66e7226d23..54bb2f8ad9 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -230,6 +230,17 @@ unsigned short fill_rar( const uint8_t input_buffer_length ); +#ifdef Rel14 +unsigned short fill_rar_br(eNB_MAC_INST *eNB, + int CC_id, + RA_TEMPLATE *RA_template, + const frame_t frameP, + const sub_frame_t subframeP, + uint8_t* const dlsch_buffer, + const uint8_t ce_level + ); +#endif + /* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE @param Mod_id Instance ID of eNB @param preamble_index index of the received RA request. @@ -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); -uint8_t subframe2harqpid(COMMON_channels_t *cc,uint32_t frame,uint8_t subframe); void get_Msg3allocret(COMMON_channels_t *cc, - unsigned char current_subframe, - unsigned int current_frame, - unsigned int *frame, - unsigned char *subframe); + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe); void get_Msg3alloc(COMMON_channels_t *cc, - unsigned char current_subframe, - unsigned int current_frame, - unsigned int *frame, - unsigned char *subframe); + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe); uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); @@ -880,8 +890,23 @@ int to_rbg(int dl_Bandwidth); int to_prb(int dl_Bandwidth); uint8_t get_Msg3harqpid(COMMON_channels_t *cc, - uint32_t frame, - unsigned char current_subframe); + frame_t frame, + sub_frame_t current_subframe); +int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP); + +uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe); + + + +#ifdef Rel14 +int get_numnarrowbandbits(long dl_Bandwidth); + +int mpdcch_sf_condition(eNB_MAC_INST *eNB,int CC_id, frame_t frameP,sub_frame_t subframeP,int rmax,MPDCCH_TYPES_t mpdcch_type); + +int get_numnarrowbands(long dl_Bandwidth); +#endif + + #endif /** @}*/ diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index d40c3280ef..f9ccd4f9ed 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -132,8 +132,8 @@ unsigned short fill_rar( #ifdef Rel14 //------------------------------------------------------------------------------ unsigned short fill_rar_br(eNB_MAC_INST *eNB, - const int CC_id, - const int ra_idx, + int CC_id, + RA_TEMPLATE *RA_template, const frame_t frameP, const sub_frame_t subframeP, uint8_t* const dlsch_buffer, @@ -143,44 +143,41 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, { RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; - + COMMON_channels_t *cc = &eNB->common_channels[CC_id]; uint8_t *rar = (uint8_t *)(dlsch_buffer+1); int i; uint8_t nb,rballoc,reps; uint8_t mcs,TPC,ULdelay,cqireq; - COMMON_channels_t *cc = &eNB->common_channels[CC_id]; int input_buffer_length; - AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs); - - AssertFatal(ra_idx >= 0 && ra_idx < 4, "RA index not in [0..3]\n"); + AssertFatal(RA_template != NULL, "RA is null \n"); // subheader fixed rarh->E = 0; // First and last RAR rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader - rarh->RAPID = cc->RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment - cc->RA_template[ra_idx].timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t)(cc->RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t)(cc->RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 + rarh->RAPID = RA_template->preamble_index; // Respond to Preamble 0 only for the moment + RA_template->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps + rar[0] = (uint8_t)(RA_template->timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 + rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 int N_NB_index; AssertFatal(1==0,"RAR for BL/CE Still to be finished ...\n"); // Copy the Msg2 narrowband - cc->RA_template[ra_idx].msg34_narrowband = cc->RA_template[ra_idx].msg2_narrowband; + RA_template->msg34_narrowband = RA_template->msg2_narrowband; if (ce_level<2) { //CE Level 0,1, CEmodeA input_buffer_length =6; N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); - rar[4] = (uint8_t)(cc->RA_template[ra_idx].rnti>>8); - rar[5] = (uint8_t)(cc->RA_template[ra_idx].rnti&0xff); + rar[4] = (uint8_t)(RA_template->rnti>>8); + rar[5] = (uint8_t)(RA_template->rnti&0xff); //cc->RA_template[ra_idx].timing_offset = 0; nb = 0; - rballoc = mac_computeRIV(6,1+ra_idx,1); // one PRB only for UL Grant in position 1+ra_idx within Narrowband + rballoc = mac_computeRIV(6,1+ce_level,1); // one PRB only for UL Grant in position 1+ce_level within Narrowband rar[1] |= (rballoc&15)<<(4-N_NB_index); // Hopping = 0 (bit 3), 3 MSBs of rballoc reps = 4; @@ -195,27 +192,26 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, input_buffer_length =5; - rar[3] = (uint8_t)(cc->RA_template[ra_idx].rnti>>8); - rar[4] = (uint8_t)(cc->RA_template[ra_idx].rnti&0xff); + rar[3] = (uint8_t)(RA_template->rnti>>8); + rar[4] = (uint8_t)(RA_template->rnti&0xff); } - LOG_D(MAC,"[RAPROC] CC_id %d Frame %d Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n", - CC_id, + LOG_D(MAC,"[RAPROC] Frame %d Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n", frameP, *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], - ra_idx, - cc->RA_template[ra_idx].rnti, - rarh->RAPID,cc->RA_template[0].preamble_index, - cc->RA_template[ra_idx].timing_offset); + ce_level, + RA_template->rnti, + rarh->RAPID,RA_template->preamble_index, + RA_template->timing_offset); if (opt_enabled) { trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1, eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT,"[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", - eNB->Mod_id, CC_id, frameP, cc->RA_template[ra_idx].rnti, + LOG_D(OPT,"[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", + frameP, RA_template->rnti, rarh->RAPID, input_buffer_length); } - return(cc->RA_template[ra_idx].rnti); + return(RA_template->rnti); } #endif diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf index 99d128587a..af262223f0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf @@ -1,8 +1,8 @@ RUs = ( { - local_if_name = "enp1s0"; - remote_address = "192.168.117.113"; - local_address = "192.168.117.205"; + local_if_name = "lo"; + remote_address = "127.0.0.1" + local_address = "127.0.0.2"; local_portc = 50000; remote_portc = 50000; local_portd = 50001; -- GitLab