From 2e7c28a591bc69649de9be11905349fe0d9f2421 Mon Sep 17 00:00:00 2001 From: "Wilson W.K. Thong" <wilsonthong@astri.org> Date: Fri, 6 Jan 2017 11:55:22 +0800 Subject: [PATCH] fix incorrect PUCCH format causing no SR received by eNB in TDD fix incorrect fss_pusch calculation fix the incorrrect HARQ-PID checking remove incorrect checking on downlink DCI HARQ PID value fix incorrect downlink ACK/NACK feedback procedures in TDD fix no activating PDSCH decoding when DL-DCI is indicating a downlink retransmission see issue #176 --- openair1/PHY/CODING/TESTBENCH/ltetest.c | 1 + openair1/PHY/LTE_TRANSPORT/dci_tools.c | 228 ++++++++++++------- openair1/PHY/LTE_TRANSPORT/defs.h | 6 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 19 ++ openair1/PHY/LTE_TRANSPORT/group_hopping.c | 3 +- openair1/PHY/LTE_TRANSPORT/phich.c | 10 + openair1/PHY/LTE_TRANSPORT/proto.h | 5 +- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 10 + openair1/PHY/impl_defs_lte.h | 2 + openair1/SCHED/defs.h | 14 ++ openair1/SCHED/phy_procedures_lte_common.c | 174 +++++++++++---- openair1/SCHED/phy_procedures_lte_ue.c | 231 +++++++++++++++----- openair1/SIMULATION/LTE_PHY/mbmssim.c | 1 + openair1/SIMULATION/LTE_PHY/syncsim.c | 1 + openair2/LAYER2/MAC/proto.h | 2 +- openair2/LAYER2/MAC/ue_procedures.c | 3 +- openair2/PHY_INTERFACE/defs.h | 2 +- 17 files changed, 516 insertions(+), 196 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/ltetest.c b/openair1/PHY/CODING/TESTBENCH/ltetest.c index bb4c136af..6bc5e2526 100644 --- a/openair1/PHY/CODING/TESTBENCH/ltetest.c +++ b/openair1/PHY/CODING/TESTBENCH/ltetest.c @@ -256,6 +256,7 @@ int test_logmap8(LTE_eNB_DLSCH_t *dlsch_eNB, &PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][0], PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid], + frame, subframe, PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid, num_pdcch_symbols,1); diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1dfbc9d7d..d4fc7bdf3 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1061,8 +1061,8 @@ int generate_eNB_dlsch_params_from_dci(int frame, // 36-213 sec.7.1.7.2 p.26 I_mcs = mcs; } else { - if (harq_pid>1) { - LOG_E(PHY,"ERROR: Format 1A: harq_pid > 1\n"); + if (harq_pid>=8) { + LOG_E(PHY,"ERROR: Format 1A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -1206,7 +1206,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, } if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 1: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 1: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -1496,7 +1496,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -1848,7 +1848,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -2117,7 +2117,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -2279,7 +2279,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -2450,7 +2450,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -2528,7 +2528,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 1E_2A_M10PRB: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -3818,7 +3818,8 @@ int generate_ue_dlsch_params_from_dci(int frame, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, - uint8_t beamforming_mode) + uint8_t beamforming_mode, + uint16_t tc_rnti) { uint8_t harq_pid=0; @@ -3832,11 +3833,29 @@ int generate_ue_dlsch_params_from_dci(int frame, uint8_t TPC=0; uint8_t NPRB=0,tbswap=0,tpmi=0; uint8_t Ngap; + uint8_t dai=0; LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq; #ifdef DEBUG_DCI - LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, dci_format %d\n",rnti,dci_format); + LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n", + rnti, + frame%1024, + subframe, + (dci_format==format0? "Format 0":( + dci_format==format1? "format 1":( + dci_format==format1A? "format 1A":( + dci_format==format1B? "format 1B":( + dci_format==format1C? "format 1C":( + dci_format==format1D? "format 1D":( + dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":( + dci_format==format2? "format 2":( + dci_format==format2A? "format 2A":( + dci_format==format2B? "format 2B":( + dci_format==format2C? "format 2C":( + dci_format==format2D? "format 2D":( + dci_format==format3? "format 3": "UNKNOWN" + )))))))))))))); #endif switch (dci_format) { @@ -3858,6 +3877,7 @@ int generate_ue_dlsch_params_from_dci(int frame, ndi = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type; @@ -3877,8 +3897,8 @@ int generate_ue_dlsch_params_from_dci(int frame, NPRB = (TPC&1) + 2; } else { - if (harq_pid>1) { - LOG_E(PHY,"Format 1A: harq_pid > 1\n"); + if (harq_pid>=8) { + LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -3914,6 +3934,7 @@ int generate_ue_dlsch_params_from_dci(int frame, ndi = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai; //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type; @@ -3933,10 +3954,10 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; } else { - //if (harq_pid>1) { - // LOG_E(PHY,"Format 1A: harq_pid > 1\n"); - // return(-1); - //} + if (harq_pid>=8) { + LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); + return(-1); + } dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT25[rballoc]; @@ -3967,6 +3988,7 @@ int generate_ue_dlsch_params_from_dci(int frame, ndi = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type; @@ -3986,8 +4008,8 @@ int generate_ue_dlsch_params_from_dci(int frame, NPRB = (TPC&1) + 2; } else { - if (harq_pid>1) { - LOG_E(PHY,"Format 1A: harq_pid > 1\n"); + if (harq_pid>=8) { + LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -4034,6 +4056,7 @@ int generate_ue_dlsch_params_from_dci(int frame, ndi = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type; @@ -4053,8 +4076,8 @@ int generate_ue_dlsch_params_from_dci(int frame, NPRB = (TPC&1) + 2; } else { - if (harq_pid>1) { - LOG_E(PHY,"Format 1A: harq_pid > 1\n"); + if (harq_pid>=8) { + LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -4139,16 +4162,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; dlsch0_harq->dl_power_off = 1; //no power offset - LOG_D(PHY,"UE (%x/%d): Subframe %d Format1A DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d, round %d\n", - dlsch[0]->rnti, - harq_pid, - subframe, - ndi, - dlsch0_harq->DCINdi, - dlsch0_harq->first_tx, - dlsch0_harq->status, - dlsch0_harq->round); - if ((ndi!=dlsch0_harq->DCINdi)|| // DCI has been toggled or this is the first transmission + dlsch[0]->active = 1; // fix no DLSCH decoding for downlink retransmission + + if ((ndi!=dlsch0_harq->DCINdi) || // DCI has been toggled or this is the first transmission (dlsch0_harq->first_tx==1)) { dlsch0_harq->round = 0; @@ -4156,10 +4172,41 @@ int generate_ue_dlsch_params_from_dci(int frame, //LOG_I(PHY,"[PDSCH %x/%d] Format 1A DCI First TX: Clearing flag\n"); dlsch0_harq->first_tx = 0; } - } + } else if (dlsch0_harq->round == 0) { // duplicated PDSCH received. possibly eNB missed the previous DL ACK/NACK feedback - dlsch0_harq->DCINdi = ndi; + // skip PDSCH decoding + dlsch[0]->active = 0; + // report ACK back to eNB for this duplicated PDSCH + dlsch0_harq->status = SCH_IDLE; + dlsch0_harq->round = 0; + dlsch[0]->harq_ack[subframe].ack = 1; + dlsch[0]->harq_ack[subframe].harq_id = harq_pid; + dlsch[0]->harq_ack[subframe].send_harq_status = 1; + LOG_D(PHY,"UE (%x/%d): Format1A DCI: Duplicated PDSCH. Setting ACK for subframe %d (pid %d, round 0)\n", + dlsch[0]->rnti,harq_pid, subframe,harq_pid); + } + + LOG_D(PHY,"UE (%x/%d): SFN/SF %4d/%1d Format1A DCI: dai %d, ndi %d, old_ndi %d (first tx %d), harq_status %d, round %d\n", + rnti, + harq_pid, + frame % 1024, + subframe, + dai, + ndi, + dlsch0_harq->DCINdi, + dlsch0_harq->first_tx, + dlsch0_harq->status, + dlsch0_harq->round); + + if (rnti == tc_rnti) { + dlsch0_harq->DCINdi = (uint8_t)-1; + LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n", + rnti,harq_pid,dlsch0_harq->DCINdi); + } else { + dlsch0_harq->DCINdi = ndi; + } + dlsch[0]->harq_ack[subframe].vDAI_DL = dai+1; // this a retransmission if(dlsch0_harq->round) { @@ -4184,7 +4231,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->Qm = get_Qm(mcs); } dlsch[0]->rnti = rnti; - dlsch[0]->active = 1; dlsch0 = dlsch[0]; //printf("Format 1A: harq_pid %d, nb_rb %d, round %d\n",harq_pid,dlsch0_harq->nb_rb,dlsch0_harq->round); break; @@ -4411,7 +4457,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } if (harq_pid>=8) { - LOG_E(PHY,"Format 1: harq_pid >= 8\n"); + LOG_E(PHY,"Format 1: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -4729,7 +4775,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } if (harq_pid>=8) { - LOG_E(PHY,"Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -5143,7 +5189,7 @@ int generate_ue_dlsch_params_from_dci(int frame, if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n"); + LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -5407,7 +5453,7 @@ int generate_ue_dlsch_params_from_dci(int frame, harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; if (harq_pid>=8) { - LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid >= 8\n"); + LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); return(-1); } @@ -5585,7 +5631,6 @@ int generate_ue_dlsch_params_from_dci(int frame, } #endif - dlsch[0]->active=1; // compute DL power control parameters computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off); @@ -6249,7 +6294,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, uint8_t transmission_mode = ue->transmission_mode[eNB_id]; ANFBmode_t AckNackFBMode; LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - // LTE_UE_DLSCH_t **dlsch = ue->dlsch[0]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[0]; PHY_MEASUREMENTS *meas = &ue->measurements; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; @@ -6264,12 +6309,15 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } uint32_t cqi_req; - uint32_t dai=0; + uint32_t dai=3; uint32_t cshift; uint32_t TPC; uint32_t ndi; uint32_t mcs; uint32_t rballoc,RIV_max; + uint16_t* RIV2first_rb_LUT; + uint16_t* RIV2nb_rb_LUT; + // uint32_t hopping; // uint32_t type; @@ -6315,8 +6363,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } RIV_max = RIV_max6; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT6[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT6[rballoc]; + RIV2first_rb_LUT = RIV2first_rb_LUT6; + RIV2nb_rb_LUT = RIV2nb_rb_LUT6; break; @@ -6343,8 +6391,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } RIV_max = RIV_max25; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT25[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT25[rballoc]; + RIV2first_rb_LUT = RIV2first_rb_LUT25; + RIV2nb_rb_LUT = RIV2nb_rb_LUT25; // printf("***********rballoc %d, first_rb %d, nb_rb %d (dci %p)\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb,dci_pdu); break; @@ -6371,8 +6419,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } RIV_max = RIV_max50; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT50[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT50[rballoc]; + RIV2first_rb_LUT = RIV2first_rb_LUT50; + RIV2nb_rb_LUT = RIV2nb_rb_LUT50; break; @@ -6399,8 +6447,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } RIV_max = RIV_max100; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT100[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT100[rballoc]; + RIV2first_rb_LUT = RIV2first_rb_LUT100; + RIV2nb_rb_LUT = RIV2nb_rb_LUT100; // printf("rb_alloc (20 MHz dci) %d\n",rballoc); break; @@ -6432,6 +6480,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } ulsch->harq_processes[harq_pid]->TPC = TPC; + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n", @@ -7063,6 +7113,13 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, // ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; } + dlsch[0]->harq_ack[subframe].vDAI_UL = dai+1; + + LOG_D(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d\n", + harq_pid, + (frame_parms->frame_type == TDD? "TDD" : "FDD"), + cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc, ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag); + ulsch->beta_offset_cqi_times8 = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18; ulsch->beta_offset_ri_times8 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10; ulsch->beta_offset_harqack_times8 = beta_ack[ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index];//16; @@ -7071,47 +7128,48 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, ulsch->srs_active = use_srs; ulsch->bundling = 1-AckNackFBMode; - if (ulsch->harq_processes[harq_pid]->round == 0) { - if ((rnti >= cba_rnti) && (rnti < p_rnti)) - ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; - else - ulsch->harq_processes[harq_pid]->status = ACTIVE; - - ulsch->harq_processes[harq_pid]->rvidx = 0; - ulsch->harq_processes[harq_pid]->mcs = mcs; - - // ulsch->harq_processes[harq_pid]->calibration_flag =0; - if (ulsch->harq_processes[harq_pid]->mcs < 29) - ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - else - LOG_E(PHY,"Fatal: mcs > 28!!! and round == 0\n"); + if ((rnti >= cba_rnti) && (rnti < p_rnti)) + ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; + else + ulsch->harq_processes[harq_pid]->status = ACTIVE; - /* - else if (ulsch->harq_processes[harq_pid]->mcs == 29) { - ulsch->harq_processes[harq_pid]->mcs = 4; - ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - // ulsch->harq_processes[harq_pid]->calibration_flag =1; - // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb); - }*/ - ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; - ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch; - ulsch->harq_processes[harq_pid]->round = 0; + ulsch->harq_processes[harq_pid]->rvidx = 0; - // a Ndi=1 automatically acknowledges previous PUSCH transmission - if (ue->ulsch_Msg3_active[eNB_id] == 1) - ue->ulsch_Msg3_active[eNB_id] = 0; + // ulsch->harq_processes[harq_pid]->calibration_flag =0; + if (mcs < 29) { + ulsch->harq_processes[harq_pid]->mcs = mcs; + // ulsch->harq_processes[harq_pid]->round = 0; } else { - // printf("Ndi = 0 : Setting RVidx from mcs %d\n",((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs); - if (mcs>28) ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; - - // ulsch->harq_processes[harq_pid]->round++; + ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; + if (ulsch->harq_processes[harq_pid]->round == 0) { + LOG_W(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); + } else { + LOG_D(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); + } + //LOG_E(PHY,"Fatal: mcs(%d) > 28!!! and round == 0\n", mcs); } + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d\n", - ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb, - ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx); - - // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; + /* + else if (ulsch->harq_processes[harq_pid]->mcs == 29) { + ulsch->harq_processes[harq_pid]->mcs = 4; + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; + // ulsch->harq_processes[harq_pid]->calibration_flag =1; + // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb); + }*/ + ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; + ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch; + + // a Ndi=1 automatically acknowledges previous PUSCH transmission + if (ue->ulsch_Msg3_active[eNB_id] == 1) + ue->ulsch_Msg3_active[eNB_id] = 0; + + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d\n", + ue->Mod_id,harq_pid, + proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb, + ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id]); + + // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; #ifdef DEBUG_DCI printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx,subframe); diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index b6bbe09b3..8e17697ff 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -675,12 +675,16 @@ typedef struct { typedef struct { /// HARQ process id uint8_t harq_id; - /// ACK bits (after decoding) + /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX uint8_t ack; /// send status (for PUCCH) uint8_t send_harq_status; /// nCCE (for PUCCH) uint8_t nCCE; + /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched + uint8_t vDAI_DL; + /// DAI value detected from DCI0/4. 0xff indicates not touched + uint8_t vDAI_UL; } harq_status_t; typedef struct { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 4a80110b2..01512fde8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -159,6 +159,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_DLSCH_t *dlsch, LTE_DL_UE_HARQ_t *harq_process, + uint8_t frame, uint8_t subframe, uint8_t harq_pid, uint8_t is_crnti, @@ -241,6 +242,11 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, return(dlsch->max_turbo_iterations); } + if (dlsch->harq_ack[subframe].ack != 2) { + LOG_W(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", + phy_vars_ue->Mod_id, subframe, dlsch->harq_ack[subframe].ack); + } + if (llr8_flag == 0) { //#ifdef __AVX2__ #if 0 @@ -609,10 +615,20 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, //printf("CRC failed, segment %d\n",r); err_flag = 1; } + } + int32_t frame_rx_prev = frame; + int32_t subframe_rx_prev = subframe - 1; + if (subframe_rx_prev < 0) { + frame_rx_prev--; + subframe_rx_prev += 10; } + frame_rx_prev = frame_rx_prev%1024; if (err_flag == 1) { + LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, round %d, subframe %d)\n", + phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->round, subframe); + dlsch->harq_ack[subframe].ack = 0; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; @@ -631,6 +647,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, return((1+dlsch->max_turbo_iterations)); } else { + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, round %d, subframe %d)\n", + phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->round, subframe); + harq_process->status = SCH_IDLE; harq_process->round = 0; dlsch->harq_ack[subframe].ack = 1; diff --git a/openair1/PHY/LTE_TRANSPORT/group_hopping.c b/openair1/PHY/LTE_TRANSPORT/group_hopping.c index bbd908b34..9cbdfad39 100644 --- a/openair1/PHY/LTE_TRANSPORT/group_hopping.c +++ b/openair1/PHY/LTE_TRANSPORT/group_hopping.c @@ -118,7 +118,8 @@ void generate_nPRS(LTE_DL_FRAME_PARMS *frame_parms) uint16_t next = 0; uint8_t ns=0; - uint32_t fss_pusch = frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + uint32_t fss_pucch = (frame_parms->Nid_cell) % 30; + uint32_t fss_pusch = (fss_pucch + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH) % 30; x2 = (32*(uint32_t)(frame_parms->Nid_cell/30)) + fss_pusch; #ifdef DEBUG_GROUPHOP diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index 989567ca3..36c4f6c55 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1110,6 +1110,16 @@ void rx_phich(PHY_VARS_UE *ue, nseq_PHICH = ((ulsch->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) + ulsch->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH); } else { + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX %s\n", + ue->Mod_id, + harq_pid, + proc->frame_rx, + subframe, + (ulsch->harq_processes[harq_pid]->status==SCH_IDLE? "SCH_IDLE" : + (ulsch->harq_processes[harq_pid]->status==ACTIVE? "ACTIVE" : + (ulsch->harq_processes[harq_pid]->status==CBA_ACTIVE? "CBA_ACTIVE": + (ulsch->harq_processes[harq_pid]->status==DISABLED? "DISABLED" : "UNKNOWN"))))); + return; } diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 94aa21c71..4e8a5e62f 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1138,6 +1138,7 @@ void dlsch_scale_channel(int32_t **dl_ch_estimates_ext, @param dlsch_llr Pointer to LLR values computed by dlsch_demodulation @param lte_frame_parms Pointer to frame descriptor @param dlsch Pointer to DLSCH descriptor + @param frame Frame number @param subframe Subframe number @param num_pdcch_symbols Number of PDCCH symbols @param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads) @@ -1149,6 +1150,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *lte_frame_parms, LTE_UE_DLSCH_t *dlsch, LTE_DL_UE_HARQ_t *harq_process, + uint8_t frame, uint8_t subframe, uint8_t harq_pid, uint8_t is_crnti, @@ -1499,7 +1501,8 @@ int generate_ue_dlsch_params_from_dci(int frame, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, - uint8_t beamforming_mode); + uint8_t beamforming_mode, + uint16_t tc_rnti); int32_t generate_eNB_dlsch_params_from_dci(int frame, uint8_t subframe, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 4559aaa32..329fd90ea 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -469,6 +469,16 @@ uint32_t ulsch_encoding(uint8_t *a, Q_ACK = Qprime * Q_m; Qprime_ACK = Qprime; + LOG_D(PHY,"UE (%x/%d) O_ACK %d, Mcs_initial %d, Nsymb_initial %d, beta_offset_harqack*8 %d, sum Kr %d, Qprime_ACK %d, Q_ACK %d\n", + rnti, harq_pid, + ulsch->harq_processes[harq_pid]->O_ACK, + ulsch->harq_processes[harq_pid]->Msc_initial, + ulsch->harq_processes[harq_pid]->Nsymb_initial, + ulsch->beta_offset_harqack_times8, + sumKr, + Qprime_ACK, + Q_ACK); + // Compute Q_cqi, assume O>11, p. 26 36-212 if (control_only_flag == 0) { diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index 7a30bff6a..751de8b64 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -994,6 +994,8 @@ typedef struct { uint8_t num_pdcch_symbols; /// Allocated CRNTI for UE uint16_t crnti; + /// 1: the allocated crnti is Temporary C-RNTI / 0: otherwise + uint8_t crnti_is_temporary; /// Total number of PDU errors (diagnostic mode) uint32_t dci_errors; /// Total number of PDU received diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 2490a4035..ad6791035 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -300,6 +300,18 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); */ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK); +/*! \brief Reset ACK/NACK information + @param frame_parms Pointer to DL frame parameter descriptor + @param harq_ack Pointer to dlsch_ue harq_ack status descriptor + @param subframe Subframe for UE transmission (n in 36.213) + @param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH + @returns status indicator for PUCCH/PUSCH transmission +*/ +uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, + harq_status_t *harq_ack, + unsigned char subframe, + unsigned char *o_ACK); + /*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6) @param frame_parms Pointer to DL frame parameter descriptor @param subframe Subframe for UE transmission (n in 36.213) @@ -366,6 +378,7 @@ subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch TDD, this routine computes the complex procedure described in Section 10.1 of 36.213 (through tables 10.1-1,10.1-2) @param phy_vars_ue Pointer to UE variables @param proc Pointer to RXn-TXnp4 proc information +@param harq_ack Pointer to dlsch_ue harq_ack status descriptor @param eNB_id Index of eNB @param b Pointer to PUCCH payload (b[0],b[1]) @param SR 1 means there's a positive SR in parallel to ACK/NAK @@ -373,6 +386,7 @@ TDD, this routine computes the complex procedure described in Section 10.1 of 36 */ uint16_t get_n1_pucch(PHY_VARS_UE *phy_vars_ue, UE_rxtx_proc_t *proc, + harq_status_t *harq_ack, uint8_t eNB_id, uint8_t *b, uint8_t SR); diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 239a5e2f8..2aaab3013 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -320,85 +320,128 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s } // This function implements table 10.1-1 of 36-213, p. 69 -uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, +// return the number 'Nbundled' +uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, unsigned char subframe, - unsigned char *o_ACK) + unsigned char *o_ACK, + uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise { - - uint8_t status=0; - uint8_t subframe_dl; + uint8_t subframe_ul=0xff, subframe_dl0=0xff, subframe_dl1=0xff; // printf("get_ack: SF %d\n",subframe); if (frame_parms->frame_type == FDD) { if (subframe < 4) - subframe_dl = subframe + 6; + subframe_dl0 = subframe + 6; else - subframe_dl = subframe - 4; + subframe_dl0 = subframe - 4; - o_ACK[0] = harq_ack[subframe_dl].ack; - status = harq_ack[subframe_dl].send_harq_status; + o_ACK[0] = harq_ack[subframe_dl0].ack; + status = harq_ack[subframe_dl0].send_harq_status; //printf("get_ack: Getting ACK/NAK for PDSCH (subframe %d) => %d\n",subframe_dl,o_ACK[0]); } else { switch (frame_parms->tdd_config) { case 1: - if (subframe == 2) { // ACK subframes 5 (forget 6) - o_ACK[0] = harq_ack[5].ack; - status = harq_ack[5].send_harq_status; + if (subframe == 2) { // ACK subframes 5,6 + subframe_ul = 6; + subframe_dl0 = 5; + subframe_dl1 = 6; } else if (subframe == 3) { // ACK subframe 9 - o_ACK[0] = harq_ack[9].ack; - status = harq_ack[9].send_harq_status; + subframe_ul = 9; + subframe_dl0 = 9; + subframe_dl1 = 0xff; } else if (subframe == 4) { // nothing - status = 0; - } else if (subframe == 7) { // ACK subframes 0 (forget 1) - o_ACK[0] = harq_ack[0].ack; - status = harq_ack[0].send_harq_status; + subframe_ul = 0xff; + subframe_dl0 = 0xff; // invalid subframe number indicates ACK/NACK is not needed + subframe_dl1 = 0xff; + } else if (subframe == 7) { // ACK subframes 0,1 + subframe_ul = 1; + subframe_dl0 = 0; + subframe_dl1 = 1; } else if (subframe == 8) { // ACK subframes 4 - o_ACK[0] = harq_ack[4].ack; - status = harq_ack[4].send_harq_status; + subframe_ul = 4; + subframe_dl0 = 4; + subframe_dl1 = 0xff; } else { LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n", subframe,frame_parms->tdd_config); return(0); } + // report ACK/NACK status + o_ACK[0] = 1; + status = 0; + if ((subframe_dl0 < 10) && (harq_ack[subframe_dl0].send_harq_status)) { + o_ACK[0] &= harq_ack[subframe_dl0].ack; + status = harq_ack[subframe_dl0].send_harq_status; + } + if ((subframe_dl1 < 10) && (harq_ack[subframe_dl1].send_harq_status)) { + o_ACK[0] &= harq_ack[subframe_dl1].ack; + status = harq_ack[subframe_dl1].send_harq_status; + } + // report status = Nbundled + if (!status) { + o_ACK[0] = 0; + } else { + if (harq_ack[subframe_ul].vDAI_UL < 0xff) { + status = harq_ack[subframe_ul].vDAI_UL; + } + } + + if (!do_reset && (subframe_ul < 10)) { + if ((subframe_dl0 < 10) && (subframe_dl1 < 10)) { + LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d harq_status=%d vDAI_DL=%d, dlsf#%d ACK=%d harq_status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", + subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, + subframe_dl0, harq_ack[subframe_dl0].ack, harq_ack[subframe_dl0].send_harq_status, harq_ack[subframe_dl0].vDAI_DL, + subframe_dl1, harq_ack[subframe_dl1].ack, harq_ack[subframe_dl1].send_harq_status, harq_ack[subframe_dl1].vDAI_DL, + o_ACK[0], status); + } else if (subframe_dl0 < 10) { + LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", + subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, + subframe_dl0, harq_ack[subframe_dl0].ack, harq_ack[subframe_dl0].send_harq_status, harq_ack[subframe_dl0].vDAI_DL, + o_ACK[0], status); + }else if (subframe_dl1 < 10) { + LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", + subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, + subframe_dl1, harq_ack[subframe_dl1].ack, harq_ack[subframe_dl1].send_harq_status, harq_ack[subframe_dl1].vDAI_DL, + o_ACK[0], status); + } + } + + // reset ACK/NACK status + if (do_reset) { + LOG_D(PHY,"ul-sf#%d ACK/NACK status resetting @ dci0-sf#%d, dci1x/2x-sf#%d, dci1x/2x-sf#%d\n", subframe, subframe_ul, subframe_dl0, subframe_dl1); + if (subframe_ul < 10) { + harq_ack[subframe_ul].vDAI_UL = 0xff; + } + if (subframe_dl0 < 10) { + harq_ack[subframe_dl0].vDAI_DL = 0xff; + harq_ack[subframe_dl0].ack = 2; + harq_ack[subframe_dl0].send_harq_status = 0; + } + if (subframe_dl1 < 10) { + harq_ack[subframe_dl1].vDAI_DL = 0xff; + harq_ack[subframe_dl1].ack = 2; + harq_ack[subframe_dl1].send_harq_status = 0; + } + } + break; case 3: if (subframe == 2) { // ACK subframes 5 and 6 - if (harq_ack[5].send_harq_status == 1) { - o_ACK[0] = harq_ack[5].ack; - - if (harq_ack[6].send_harq_status == 1) - o_ACK[1] = harq_ack[6].ack; - } else if (harq_ack[6].send_harq_status == 1) - o_ACK[0] = harq_ack[6].ack; - - status = harq_ack[5].send_harq_status + (harq_ack[6].send_harq_status<<1); + subframe_dl0 = 5; + subframe_dl1 = 6; //printf("Subframe 2, TDD config 3: harq_ack[5] = %d (%d),harq_ack[6] = %d (%d)\n",harq_ack[5].ack,harq_ack[5].send_harq_status,harq_ack[6].ack,harq_ack[6].send_harq_status); } else if (subframe == 3) { // ACK subframes 7 and 8 - if (harq_ack[7].send_harq_status == 1) { - o_ACK[0] = harq_ack[7].ack; - - if (harq_ack[8].send_harq_status == 1) - o_ACK[1] = harq_ack[8].ack; - } else if (harq_ack[8].send_harq_status == 1) - o_ACK[0] = harq_ack[8].ack; - - status = harq_ack[7].send_harq_status + (harq_ack[8].send_harq_status<<1); + subframe_dl0 = 7; + subframe_dl1 = 8; //printf("Subframe 3, TDD config 3: harq_ack[7] = %d,harq_ack[8] = %d\n",harq_ack[7].ack,harq_ack[8].ack); //printf("status %d : o_ACK (%d,%d)\n", status,o_ACK[0],o_ACK[1]); } else if (subframe == 4) { // ACK subframes 9 and 0 - if (harq_ack[9].send_harq_status == 1) { - o_ACK[0] = harq_ack[9].ack; - - if (harq_ack[0].send_harq_status == 1) - o_ACK[1] = harq_ack[0].ack; - } else if (harq_ack[0].send_harq_status == 1) - o_ACK[0] = harq_ack[0].ack; - - status = harq_ack[9].send_harq_status + (harq_ack[0].send_harq_status<<1); + subframe_dl0 = 9; + subframe_dl1 = 0; //printf("Subframe 4, TDD config 3: harq_ack[9] = %d,harq_ack[0] = %d\n",harq_ack[9].ack,harq_ack[0].ack); } else { LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n", @@ -406,6 +449,25 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, return(0); } + // report ACK/NACK status + if (harq_ack[subframe_dl0].send_harq_status == 1) { + o_ACK[0] = harq_ack[subframe_dl0].ack; + + if (harq_ack[subframe_dl1].send_harq_status == 1) + o_ACK[1] = harq_ack[subframe_dl1].ack; + } else if (harq_ack[subframe_dl1].send_harq_status == 1) + o_ACK[0] = harq_ack[subframe_dl1].ack; + + status = harq_ack[subframe_dl0].send_harq_status + (harq_ack[subframe_dl1].send_harq_status<<1); + + if (do_reset) { + // reset ACK/NACK status + harq_ack[subframe_dl0].ack = 2; + harq_ack[subframe_dl1].ack = 2; + harq_ack[subframe_dl0].send_harq_status = 0; + harq_ack[subframe_dl1].send_harq_status = 0; + } + break; } @@ -416,6 +478,24 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, return(status); } +uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, + harq_status_t *harq_ack, + unsigned char subframe, + unsigned char *o_ACK) +{ + return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 0); +} + +uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, + harq_status_t *harq_ack, + unsigned char subframe, + unsigned char *o_ACK) +{ + return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 1); +} + + + uint8_t Np6[4]= {0,1,3,5}; uint8_t Np15[4]= {0,3,8,13}; uint8_t Np25[4]= {0,5,13,22}; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 1c6aa6b20..27ef6119e 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -266,7 +266,7 @@ void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later // for more flexibility - uint8_t i,j,k; + uint8_t i,j,k,s; PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; //[NUMBER_OF_CONNECTED_eNB_MAX][2]; @@ -276,6 +276,13 @@ void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) if(ue->dlsch[i][j]) { for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->dlsch[i][j]->harq_processes[k]; k++) { ue->dlsch[i][j]->harq_processes[k]->status = SCH_IDLE; + for (s=0; s<10; s++) { + // reset ACK/NACK bit to DTX for all subframes s = 0..9 + ue->dlsch[i][j]->harq_ack[s].ack = 2; + ue->dlsch[i][j]->harq_ack[s].send_harq_status = 0; + ue->dlsch[i][j]->harq_ack[s].vDAI_UL = 0xff; + ue->dlsch[i][j]->harq_ack[s].vDAI_DL = 0xff; + } } } } @@ -301,7 +308,9 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) // if contention resolution fails, go back to PRACH PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH; - LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0 and State RRC_IDLE\n",Mod_id); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti_is_temporary = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti = 0; + LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id); //mac_xface->macphy_exit(""); } @@ -310,8 +319,9 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) int i; - LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded\n",Mod_id); + LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti_is_temporary = 0; PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0; PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH; @@ -728,6 +738,7 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id) uint16_t get_n1_pucch(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, + harq_status_t *harq_ack, uint8_t eNB_id, uint8_t *b, uint8_t SR) @@ -737,7 +748,8 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, uint8_t nCCE0,nCCE1,harq_ack1,harq_ack0; ANFBmode_t bundling_flag; uint16_t n1_pucch0=0,n1_pucch1=0; - int subframe_offset; + static uint8_t candidate_dl[9]; // which downlink(s) the current ACK/NACK is associating to + uint8_t last_dl=0xff; // the last downlink with valid DL-DCI. for calculating the PUCCH resource index int sf; int M; // clear this, important for case where n1_pucch selection is not used @@ -775,41 +787,71 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, M=1; // This is the offset for a particular subframe (2,3,4) => (0,2,4) - if (subframe == 2) { // ACK subframes 5 (forget 6) - subframe_offset = 5; + if (subframe == 2) { // ACK subframes 5,6 + candidate_dl[0] = 6; + candidate_dl[1] = 5; M=2; } else if (subframe == 3) { // ACK subframe 9 - subframe_offset = 9; - } else if (subframe == 7) { // ACK subframes 0 (forget 1) - subframe_offset = 0; + candidate_dl[0] = 9; + } else if (subframe == 7) { // ACK subframes 0,1 + candidate_dl[0] = 1; + candidate_dl[1] = 0; M=2; } else if (subframe == 8) { // ACK subframes 4 - subframe_offset = 4; + candidate_dl[0] = 4; } else { LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config); return(0); } + // checking which downlink candidate is the last downlink with valid DL-DCI + int k; + for (k=0;k<M;k++) { + if (harq_ack[candidate_dl[k]].send_harq_status>0) { + last_dl = candidate_dl[k]; + break; + } + } + if (last_dl >= 10) { + LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", + ue->Mod_id,proc->frame_tx,last_dl,frame_parms->tdd_config); + return (0); + } + + LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch0 from last_dl=%d\n", + proc->frame_tx%1024, + proc->subframe_tx, + last_dl); // i=0 - nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[subframe_offset]; + nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[last_dl]; n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; - // set ACK/NAK to values if not DTX - if (ue->dlsch[eNB_id][0]->harq_ack[subframe_offset].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[subframe_offset].ack; - + harq_ack0 = b[0]; if (harq_ack0!=2) { // DTX - if (SR == 0) { // last paragraph pg 68 from 36.213 (v8.6), m=0 - b[0]=(M==2) ? 1-harq_ack0 : harq_ack0; - b[1]=harq_ack0; // in case we use pucch format 1b (subframes 2,7) + if (frame_parms->frame_type == FDD ) { + if (SR == 0) { // last paragraph pg 68 from 36.213 (v8.6), m=0 + b[0]=(M==2) ? 1-harq_ack0 : harq_ack0; + b[1]=harq_ack0; // in case we use pucch format 1b (subframes 2,7) ue->pucch_sel[subframe] = 0; - return(n1_pucch0); - } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213) - b[0]=harq_ack0; + return(n1_pucch0); + } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213) + b[0]=harq_ack0; return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } + } else { + if (SR == 0) { + b[0] = harq_ack0; + b[1] = harq_ack0; + ue->pucch_sel[subframe] = 0; + return(n1_pucch0); + } else { + b[0] = harq_ack0; + b[1] = harq_ack0; + return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } } } @@ -823,20 +865,20 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, harq_ack1 = 2; // DTX harq_ack0 = 2; // DTX // This is the offset for a particular subframe (2,3,4) => (0,2,4) - subframe_offset = (subframe-2)<<1; + last_dl = (subframe-2)<<1; // i=0 - nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[5+subframe_offset]; + nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[5+last_dl]; n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; // i=1 - nCCE1 = ue->pdcch_vars[eNB_id]->nCCE[(6+subframe_offset)%10]; + nCCE1 = ue->pdcch_vars[eNB_id]->nCCE[(6+last_dl)%10]; n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; // set ACK/NAK to values if not DTX - if (ue->dlsch[eNB_id][0]->harq_ack[(6+subframe_offset)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack1 = ue->dlsch[eNB_id][0]->harq_ack[(6+subframe_offset)%10].ack; + if (ue->dlsch[eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack1 = ue->dlsch[eNB_id][0]->harq_ack[(6+last_dl)%10].ack; - if (ue->dlsch[eNB_id][0]->harq_ack[5+subframe_offset].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[5+subframe_offset].ack; + if (ue->dlsch[eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[5+last_dl].ack; if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed @@ -1194,7 +1236,6 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB int Mod_id = ue->Mod_id; int CC_id = ue->CC_id; uint8_t Msg3_flag=0; - uint8_t ack_status=0; uint16_t first_rb, nb_rb; unsigned int input_buffer_length; int i; @@ -1202,6 +1243,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB int tx_amp; uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32))); uint8_t access_mode; + uint8_t Nbundled=0; + uint8_t ack_status=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN); @@ -1245,6 +1288,49 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } } + if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) { + + uint8_t isBad = 0; + if (ue->frame_parms.N_RB_UL <= ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) { + LOG_D(PHY,"Invalid PUSCH first_RB=%d for N_RB_UL=%d\n", + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, + ue->frame_parms.N_RB_UL); + isBad = 1; + } + if (ue->frame_parms.N_RB_UL < ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) { + LOG_D(PHY,"Invalid PUSCH num_RB=%d for N_RB_UL=%d\n", + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, + ue->frame_parms.N_RB_UL); + isBad = 1; + } + if (0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) { + LOG_D(PHY,"Invalid PUSCH first_RB=%d\n", + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb); + isBad = 1; + } + if (0 >= ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) { + LOG_D(PHY,"Invalid PUSCH num_RB=%d\n", + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb); + isBad = 1; + } + if (ue->frame_parms.N_RB_UL < (ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb)) { + LOG_D(PHY,"Invalid PUSCH num_RB=%d + first_RB=%d for N_RB_UL=%d\n", + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, + ue->frame_parms.N_RB_UL); + isBad = 1; + } + if ((0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx) || + (3 < ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx)) { + LOG_D(PHY,"Invalid PUSCH RV index=%d\n", ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx); + isBad = 1; + } + + if (isBad) { + LOG_D(PHY,"Skip PUSCH generation!\n"); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; + } + } if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) { ue->generate_ul_signal[eNB_id] = 1; @@ -1263,7 +1349,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->dlsch[eNB_id][0]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK); - + Nbundled = ack_status; first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb; nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; @@ -1292,8 +1378,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } #ifdef DEBUG_PHY_PROC - LOG_D(PHY, - "[UE %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d\n", + LOG_D(PHY, + "[UE %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", Mod_id,harq_pid,frame_tx,subframe_tx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, @@ -1306,7 +1392,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2, ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1], ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, + ue->ulsch[eNB_id]->bundling); #endif @@ -1408,8 +1495,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue, harq_pid, eNB_id, - ue->transmission_mode[eNB_id],0, - 0)!=0) { // Nbundled, to be updated!!!! + ue->transmission_mode[eNB_id],0, + Nbundled)!=0) { LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_tx); @@ -1570,6 +1657,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin int CC_id = ue->CC_id; int tx_amp; int8_t Po_PUCCH; + uint8_t ack_status=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN); @@ -1633,18 +1721,24 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin SR_payload=0; } - if (get_ack(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_ack, - subframe_tx,pucch_ack_payload) > 0) { + ack_status = get_ack(&ue->frame_parms, + ue->dlsch[eNB_id][0]->harq_ack, + subframe_tx,pucch_ack_payload); + if (ack_status > 0) { // we need to transmit ACK/NAK in this subframe ue->generate_ul_signal[eNB_id] = 1; + if ((frame_parms->frame_type == TDD) && (SR_payload>0)) { + format = pucch_format1b; + } + n1_pucch = get_n1_pucch(ue, - proc, - eNB_id, - pucch_ack_payload, - SR_payload); + proc, + ue->dlsch[eNB_id][0]->harq_ack, + eNB_id, + pucch_ack_payload, + SR_payload); if (ue->mac_enabled == 1) { Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); @@ -1665,21 +1759,25 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif if (SR_payload>0) { - LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH, amp %d\n", + LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH, amp %d\n", Mod_id, ue->dlsch[eNB_id][0]->rnti, - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - frame_tx, subframe_tx, + frame_tx % 1024, subframe_tx, + (format == pucch_format1a? "1a": ( + format == pucch_format1b? "1b" : "??")), pucch_ack_payload[0],pucch_ack_payload[1], + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, Po_PUCCH, tx_amp); } else { - LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[eNB_id][0]->rnti, - frame_tx, subframe_tx, + frame_tx, subframe_tx, + (format == pucch_format1a? "1a": ( + format == pucch_format1b? "1b" : "??")), frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, isShortenPucch, n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload, @@ -1879,7 +1977,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; unsigned int aa; - + @@ -2014,6 +2112,17 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui ue->generate_prach=0; } + // reset DL ACK/NACK status + reset_ack(&ue->frame_parms, + ue->dlsch[eNB_id][0]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK); + + reset_ack(&ue->frame_parms, + ue->dlsch_SI[eNB_id]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_tx); @@ -2600,7 +2709,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint SI_RNTI, 0, P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0)) { + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + ue->pdcch_vars[eNB_id]->crnti_is_temporary? ue->pdcch_vars[eNB_id]->crnti: 0)==0)) { ue->dlsch_received[eNB_id]++; @@ -2644,7 +2754,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint SI_RNTI, 0, P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0) { + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + 0)==0) { ue->dlsch_SI_received[eNB_id]++; @@ -2674,7 +2785,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint SI_RNTI, 0, P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0) { + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + 0)==0) { ue->dlsch_p_received[eNB_id]++; @@ -2709,7 +2821,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint SI_RNTI, ue->prach_resources[eNB_id]->ra_RNTI, P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0) { + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + 0)==0) { ue->dlsch_ra_received[eNB_id]++; @@ -2871,6 +2984,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs &ue->frame_parms, ue->dlsch_MCH[0], ue->dlsch_MCH[0]->harq_processes[0], + frame_rx, subframe_rx, 0, 0,1); @@ -3046,6 +3160,9 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo ue->pdcch_vars[eNB_id]->crnti, timing_advance); + // remember this c-rnti is still a tc-rnti + ue->pdcch_vars[eNB_id]->crnti_is_temporary = 1; + //timing_advance = 0; process_timing_advance_rar(ue,proc,timing_advance); @@ -3174,6 +3291,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, &ue->frame_parms, dlsch0, dlsch0->harq_processes[harq_pid], + frame_rx, subframe_rx, harq_pid, pdsch==PDSCH?1:0, @@ -3233,6 +3351,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, mac_xface->ue_send_sdu(ue->Mod_id, CC_id, frame_rx, + subframe_rx, dlsch0->harq_processes[dlsch0->current_harq_pid]->b, dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3, eNB_id); @@ -3308,7 +3427,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); @@ -3528,10 +3647,6 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } - else { - // printf("PDSCH inactive in subframe %d\n",subframe_rx-1); - ue->dlsch[eNB_id][0]->harq_ack[subframe_rx].send_harq_status = 0; - } // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index 7849dec1a..2f8fda770 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -492,6 +492,7 @@ int main(int argc, char **argv) &UE->frame_parms, UE->dlsch_MCH[0], UE->dlsch_MCH[0]->harq_processes[0], + frame, subframe, 0,0,0); diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 7e94122e6..b18cd7886 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -1651,6 +1651,7 @@ int main(int argc, char **argv) PHY_vars_UE[UE_idx]->lte_ue_pdsch_vars[0]->llr[0], &PHY_vars_UE[UE_idx]->lte_frame_parms, PHY_vars_UE[UE_idx]->dlsch_ue[0][0], + frame, subframe, 0, PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols); diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 9454f3da8..5da2367ce 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -402,7 +402,7 @@ void ue_decode_si(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_in void ue_decode_p(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_index, void *pdu, uint16_t len); -void ue_send_sdu(module_id_t module_idP, uint8_t CC_id,frame_t frame, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); +void ue_send_sdu(module_id_t module_idP, uint8_t CC_id,frame_t frame, sub_frame_t subframe, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); #ifdef Rel10 diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index cdac22c48..85100d14a 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -333,6 +333,7 @@ ue_send_sdu( module_id_t module_idP, uint8_t CC_id, frame_t frameP, + sub_frame_t subframeP, uint8_t* sdu, uint16_t sdu_len, uint8_t eNB_index @@ -451,7 +452,7 @@ ue_send_sdu( #endif mac_rrc_data_ind(module_idP, CC_id, - frameP,0, // unknown subframe + frameP,subframeP, UE_mac_inst[module_idP].crnti, CCCH, (uint8_t*)payload_ptr, diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h index 156b9091b..497325205 100644 --- a/openair2/PHY_INTERFACE/defs.h +++ b/openair2/PHY_INTERFACE/defs.h @@ -152,7 +152,7 @@ typedef struct { void (*ue_decode_p)(module_id_t Mod_id,int CC_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len); /// Send a received DLSCH sdu to MAC - void (*ue_send_sdu)(module_id_t Mod_id,uint8_t CC_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); + void (*ue_send_sdu)(module_id_t Mod_id,uint8_t CC_id,frame_t frameP,sub_frame_t subframe,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); #ifdef Rel10 /// Send a received MCH sdu to MAC -- GitLab