Commit 2e7c28a5 authored by Wilson W.K. Thong's avatar Wilson W.K. Thong

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
parent 3bf8768d
...@@ -256,6 +256,7 @@ int test_logmap8(LTE_eNB_DLSCH_t *dlsch_eNB, ...@@ -256,6 +256,7 @@ int test_logmap8(LTE_eNB_DLSCH_t *dlsch_eNB,
&PHY_vars_UE->lte_frame_parms, &PHY_vars_UE->lte_frame_parms,
PHY_vars_UE->dlsch_ue[0][0], 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], PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid],
frame,
subframe, subframe,
PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid, PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid,
num_pdcch_symbols,1); num_pdcch_symbols,1);
......
This diff is collapsed.
...@@ -675,12 +675,16 @@ typedef struct { ...@@ -675,12 +675,16 @@ typedef struct {
typedef struct { typedef struct {
/// HARQ process id /// HARQ process id
uint8_t harq_id; uint8_t harq_id;
/// ACK bits (after decoding) /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX
uint8_t ack; uint8_t ack;
/// send status (for PUCCH) /// send status (for PUCCH)
uint8_t send_harq_status; uint8_t send_harq_status;
/// nCCE (for PUCCH) /// nCCE (for PUCCH)
uint8_t nCCE; 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; } harq_status_t;
typedef struct { typedef struct {
......
...@@ -159,6 +159,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, ...@@ -159,6 +159,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_DLSCH_t *dlsch, LTE_UE_DLSCH_t *dlsch,
LTE_DL_UE_HARQ_t *harq_process, LTE_DL_UE_HARQ_t *harq_process,
uint8_t frame,
uint8_t subframe, uint8_t subframe,
uint8_t harq_pid, uint8_t harq_pid,
uint8_t is_crnti, uint8_t is_crnti,
...@@ -241,6 +242,11 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, ...@@ -241,6 +242,11 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
return(dlsch->max_turbo_iterations); 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) { if (llr8_flag == 0) {
//#ifdef __AVX2__ //#ifdef __AVX2__
#if 0 #if 0
...@@ -609,10 +615,20 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, ...@@ -609,10 +615,20 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
//printf("CRC failed, segment %d\n",r); //printf("CRC failed, segment %d\n",r);
err_flag = 1; 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) { 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].ack = 0;
dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].harq_id = harq_pid;
dlsch->harq_ack[subframe].send_harq_status = 1; dlsch->harq_ack[subframe].send_harq_status = 1;
...@@ -631,6 +647,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, ...@@ -631,6 +647,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
return((1+dlsch->max_turbo_iterations)); return((1+dlsch->max_turbo_iterations));
} else { } 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->status = SCH_IDLE;
harq_process->round = 0; harq_process->round = 0;
dlsch->harq_ack[subframe].ack = 1; dlsch->harq_ack[subframe].ack = 1;
......
...@@ -118,7 +118,8 @@ void generate_nPRS(LTE_DL_FRAME_PARMS *frame_parms) ...@@ -118,7 +118,8 @@ void generate_nPRS(LTE_DL_FRAME_PARMS *frame_parms)
uint16_t next = 0; uint16_t next = 0;
uint8_t ns=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; x2 = (32*(uint32_t)(frame_parms->Nid_cell/30)) + fss_pusch;
#ifdef DEBUG_GROUPHOP #ifdef DEBUG_GROUPHOP
......
...@@ -1110,6 +1110,16 @@ void rx_phich(PHY_VARS_UE *ue, ...@@ -1110,6 +1110,16 @@ void rx_phich(PHY_VARS_UE *ue,
nseq_PHICH = ((ulsch->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) + nseq_PHICH = ((ulsch->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) +
ulsch->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH); ulsch->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH);
} else { } 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; return;
} }
......
...@@ -1138,6 +1138,7 @@ void dlsch_scale_channel(int32_t **dl_ch_estimates_ext, ...@@ -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 dlsch_llr Pointer to LLR values computed by dlsch_demodulation
@param lte_frame_parms Pointer to frame descriptor @param lte_frame_parms Pointer to frame descriptor
@param dlsch Pointer to DLSCH descriptor @param dlsch Pointer to DLSCH descriptor
@param frame Frame number
@param subframe Subframe number @param subframe Subframe number
@param num_pdcch_symbols Number of PDCCH symbols @param num_pdcch_symbols Number of PDCCH symbols
@param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads) @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, ...@@ -1149,6 +1150,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
LTE_DL_FRAME_PARMS *lte_frame_parms, LTE_DL_FRAME_PARMS *lte_frame_parms,
LTE_UE_DLSCH_t *dlsch, LTE_UE_DLSCH_t *dlsch,
LTE_DL_UE_HARQ_t *harq_process, LTE_DL_UE_HARQ_t *harq_process,
uint8_t frame,
uint8_t subframe, uint8_t subframe,
uint8_t harq_pid, uint8_t harq_pid,
uint8_t is_crnti, uint8_t is_crnti,
...@@ -1499,7 +1501,8 @@ int generate_ue_dlsch_params_from_dci(int frame, ...@@ -1499,7 +1501,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
uint16_t si_rnti, uint16_t si_rnti,
uint16_t ra_rnti, uint16_t ra_rnti,
uint16_t p_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, int32_t generate_eNB_dlsch_params_from_dci(int frame,
uint8_t subframe, uint8_t subframe,
......
...@@ -469,6 +469,16 @@ uint32_t ulsch_encoding(uint8_t *a, ...@@ -469,6 +469,16 @@ uint32_t ulsch_encoding(uint8_t *a,
Q_ACK = Qprime * Q_m; Q_ACK = Qprime * Q_m;
Qprime_ACK = Qprime; 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 // Compute Q_cqi, assume O>11, p. 26 36-212
if (control_only_flag == 0) { if (control_only_flag == 0) {
......
...@@ -994,6 +994,8 @@ typedef struct { ...@@ -994,6 +994,8 @@ typedef struct {
uint8_t num_pdcch_symbols; uint8_t num_pdcch_symbols;
/// Allocated CRNTI for UE /// Allocated CRNTI for UE
uint16_t crnti; 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) /// Total number of PDU errors (diagnostic mode)
uint32_t dci_errors; uint32_t dci_errors;
/// Total number of PDU received /// Total number of PDU received
......
...@@ -300,6 +300,18 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); ...@@ -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); 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) /*! \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 frame_parms Pointer to DL frame parameter descriptor
@param subframe Subframe for UE transmission (n in 36.213) @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 ...@@ -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) 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 phy_vars_ue Pointer to UE variables
@param proc Pointer to RXn-TXnp4 proc information @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 eNB_id Index of eNB
@param b Pointer to PUCCH payload (b[0],b[1]) @param b Pointer to PUCCH payload (b[0],b[1])
@param SR 1 means there's a positive SR in parallel to ACK/NAK @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 ...@@ -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, uint16_t get_n1_pucch(PHY_VARS_UE *phy_vars_ue,
UE_rxtx_proc_t *proc, UE_rxtx_proc_t *proc,
harq_status_t *harq_ack,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t *b, uint8_t *b,
uint8_t SR); uint8_t SR);
......
...@@ -320,85 +320,128 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s ...@@ -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 // 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, harq_status_t *harq_ack,
unsigned char subframe, 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 status=0;
uint8_t subframe_dl; uint8_t subframe_ul=0xff, subframe_dl0=0xff, subframe_dl1=0xff;
// printf("get_ack: SF %d\n",subframe); // printf("get_ack: SF %d\n",subframe);
if (frame_parms->frame_type == FDD) { if (frame_parms->frame_type == FDD) {
if (subframe < 4) if (subframe < 4)
subframe_dl = subframe + 6; subframe_dl0 = subframe + 6;
else else
subframe_dl = subframe - 4; subframe_dl0 = subframe - 4;
o_ACK[0] = harq_ack[subframe_dl].ack; o_ACK[0] = harq_ack[subframe_dl0].ack;
status = harq_ack[subframe_dl].send_harq_status; 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]); //printf("get_ack: Getting ACK/NAK for PDSCH (subframe %d) => %d\n",subframe_dl,o_ACK[0]);
} else { } else {
switch (frame_parms->tdd_config) { switch (frame_parms->tdd_config) {
case 1: case 1:
if (subframe == 2) { // ACK subframes 5 (forget 6) if (subframe == 2) { // ACK subframes 5,6
o_ACK[0] = harq_ack[5].ack; subframe_ul = 6;
status = harq_ack[5].send_harq_status; subframe_dl0 = 5;
subframe_dl1 = 6;
} else if (subframe == 3) { // ACK subframe 9 } else if (subframe == 3) { // ACK subframe 9
o_ACK[0] = harq_ack[9].ack; subframe_ul = 9;
status = harq_ack[9].send_harq_status; subframe_dl0 = 9;
subframe_dl1 = 0xff;
} else if (subframe == 4) { // nothing } else if (subframe == 4) { // nothing
status = 0; subframe_ul = 0xff;
} else if (subframe == 7) { // ACK subframes 0 (forget 1) subframe_dl0 = 0xff; // invalid subframe number indicates ACK/NACK is not needed
o_ACK[0] = harq_ack[0].ack; subframe_dl1 = 0xff;
status = harq_ack[0].send_harq_status; } else if (subframe == 7) { // ACK subframes 0,1
subframe_ul = 1;
subframe_dl0 = 0;
subframe_dl1 = 1;
} else if (subframe == 8) { // ACK subframes 4 } else if (subframe == 8) { // ACK subframes 4
o_ACK[0] = harq_ack[4].ack; subframe_ul = 4;
status = harq_ack[4].send_harq_status; subframe_dl0 = 4;
subframe_dl1 = 0xff;
} else { } else {
LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n", LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n",
subframe,frame_parms->tdd_config); subframe,frame_parms->tdd_config);
return(0); 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; break;
case 3: case 3:
if (subframe == 2) { // ACK subframes 5 and 6 if (subframe == 2) { // ACK subframes 5 and 6
if (harq_ack[5].send_harq_status == 1) { subframe_dl0 = 5;
o_ACK[0] = harq_ack[5].ack; subframe_dl1 = 6;
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);
//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); //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 } else if (subframe == 3) { // ACK subframes 7 and 8
if (harq_ack[7].send_harq_status == 1) { subframe_dl0 = 7;
o_ACK[0] = harq_ack[7].ack; subframe_dl1 = 8;
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);
//printf("Subframe 3, TDD config 3: harq_ack[7] = %d,harq_ack[8] = %d\n",harq_ack[7].ack,harq_ack[8].ack); //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]); //printf("status %d : o_ACK (%d,%d)\n", status,o_ACK[0],o_ACK[1]);
} else if (subframe == 4) { // ACK subframes 9 and 0 } else if (subframe == 4) { // ACK subframes 9 and 0
if (harq_ack[9].send_harq_status == 1) { subframe_dl0 = 9;
o_ACK[0] = harq_ack[9].ack; subframe_dl1 = 0;
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);
//printf("Subframe 4, TDD config 3: harq_ack[9] = %d,harq_ack[0] = %d\n",harq_ack[9].ack,harq_ack[0].ack); //printf("Subframe 4, TDD config 3: harq_ack[9] = %d,harq_ack[0] = %d\n",harq_ack[9].ack,harq_ack[0].ack);
} else { } else {
LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n", 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, ...@@ -406,6 +449,25 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,
return(0); 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; break;
} }
...@@ -416,6 +478,24 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, ...@@ -416,6 +478,24 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,
return(status); 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 Np6[4]= {0,1,3,5};
uint8_t Np15[4]= {0,3,8,13}; uint8_t Np15[4]= {0,3,8,13};
uint8_t Np25[4]= {0,5,13,22}; uint8_t Np25[4]= {0,5,13,22};
......
This diff is collapsed.
...@@ -492,6 +492,7 @@ int main(int argc, char **argv) ...@@ -492,6 +492,7 @@ int main(int argc, char **argv)
&UE->frame_parms, &UE->frame_parms,
UE->dlsch_MCH[0], UE->dlsch_MCH[0],
UE->dlsch_MCH[0]->harq_processes[0], UE->dlsch_MCH[0]->harq_processes[0],
frame,
subframe, subframe,
0,0,0); 0,0,0);
......
...@@ -1651,6 +1651,7 @@ int main(int argc, char **argv) ...@@ -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_ue_pdsch_vars[0]->llr[0],
&PHY_vars_UE[UE_idx]->lte_frame_parms, &PHY_vars_UE[UE_idx]->lte_frame_parms,
PHY_vars_UE[UE_idx]->dlsch_ue[0][0], PHY_vars_UE[UE_idx]->dlsch_ue[0][0],
frame,
subframe, subframe,
0, 0,
PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols); PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols);
......
...@@ -402,7 +402,7 @@ void ue_decode_si(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_in ...@@ -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_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 #ifdef Rel10
......
...@@ -333,6 +333,7 @@ ue_send_sdu( ...@@ -333,6 +333,7 @@ ue_send_sdu(
module_id_t module_idP, module_id_t module_idP,
uint8_t CC_id, uint8_t CC_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP,
uint8_t* sdu, uint8_t* sdu,
uint16_t sdu_len, uint16_t sdu_len,
uint8_t eNB_index uint8_t eNB_index
...@@ -451,7 +452,7 @@ ue_send_sdu( ...@@ -451,7 +452,7 @@ ue_send_sdu(
#endif #endif
mac_rrc_data_ind(module_idP, mac_rrc_data_ind(module_idP,
CC_id, CC_id,
frameP,0, // unknown subframe frameP,subframeP,
UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].crnti,
CCCH, CCCH,
(uint8_t*)payload_ptr, (uint8_t*)payload_ptr,
......
...@@ -152,7 +152,7 @@ typedef struct { ...@@ -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); 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 /// 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 #ifdef Rel10
/// Send a received MCH sdu to MAC /// Send a received MCH sdu to MAC
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment