Merge remote-tracking branch 'origin/fix-lte-ue-bad-dci' into integration_2025_w39 (!3582)

replace bad DCI by specific message for each case and add checks for bad...

Replace bad DCI by specific message for each case and add checks for bad
pointers, or sanitize detected warnings. Then fix several issues in DCI
decoding. With this MR, LTE UE has less bad DCI, and each bad DCI has a
reason better diagnosis.
This commit is contained in:
Jaroslava Fiedlerova
2025-09-23 09:55:31 +02:00
2 changed files with 121 additions and 154 deletions
+95 -94
View File
@@ -941,17 +941,17 @@ void extract_dci2A_info(uint8_t N_RB_DL, frame_type_t frame_type, uint8_t nb_ant
pdci_info_extarcted->tpmi = tpmi;
}
int check_dci_format1_1a_coherency(DCI_format_t dci_format,
uint8_t N_RB_DL,
uint16_t rnti,
uint16_t tc_rnti,
uint16_t si_rnti,
uint16_t ra_rnti,
uint16_t p_rnti,
uint32_t frame,
uint8_t subframe,
DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
LTE_DL_UE_HARQ_t *pdlsch0_harq)
static int check_dci_format1_1a_coherency(DCI_format_t dci_format,
uint8_t N_RB_DL,
uint16_t rnti,
uint16_t tc_rnti,
uint16_t si_rnti,
uint16_t ra_rnti,
uint16_t p_rnti,
uint32_t frame,
uint8_t subframe,
DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
LTE_DL_UE_HARQ_t *pdlsch0_harq)
{
uint8_t harq_pid = pdci_info_extarcted->harq_pid;
uint32_t rballoc = pdci_info_extarcted->rballoc;
@@ -982,34 +982,39 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
// I- check dci content minimum coherency
if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0)
{
return(0);
LOG_I(PHY, "bad system or random access rnti %x id, harq %d \n", rnti, harq_pid);
return (0);
}
if(harq_pid>=8)
{
// LOG_I(PHY,"bad harq id \n");
return(0);
LOG_I(PHY, "bad harq id %d\n", harq_pid);
return (0);
}
if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) )
{
// LOG_I(PHY,"bad dci format \n");
return(0);
LOG_I(PHY, "bad dci format 1 with system rnti %x\n", rnti);
return (0);
}
if( mcs1 > 28)
{
if (!pdlsch0_harq) {
LOG_E(PHY, "pointer to pdlsch0_harq is NULL\n");
return 0;
}
if(pdlsch0_harq->round == 0)
{
// LOG_I(PHY,"bad dci mcs + round \n");
return(0);
LOG_I(PHY, "bad dci mcs %d + round %d\n", mcs1, pdlsch0_harq->round);
return (0);
}
if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
{
// LOG_I(PHY,"bad dci mcs + rnti \n");
return(0);
LOG_I(PHY, "bad dci mcs %d + rnti %x\n", mcs1, rnti);
return (0);
}
}
@@ -1065,47 +1070,47 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
}
}
else if (dci_format == format1)
{
NPRB = conv_nprb(rah, rballoc, N_RB_DL);
else if (dci_format == format1) {
NPRB = conv_nprb(rah, rballoc, N_RB_DL);
}
if(dci_format == format1A && rballoc > RIV_max)
{
// LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max);
// DCI false detection
return(0);
LOG_I(PHY, "bad dci rballoc rballoc %d RIV_max %lld \n", rballoc, RIV_max);
// DCI false detection
return (0);
}
if(NPRB == 0)
{
// DCI false detection
// LOG_I(PHY,"bad NPRB = 0 \n");
LOG_I(PHY, "bad dci NPRB = 0 \n");
return(0);
}
// this a retransmission
if (!pdlsch0_harq) {
LOG_E(PHY, "pointer to pdlsch0_harq is NULL\n");
return 0;
}
if(pdlsch0_harq->round>0)
{
// compare old TBS to new TBS
if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1]))
{
// this is an eNB issue
// retransmisison but old and new TBS are different !!!
// work around, consider it as a new transmission
LOG_E(PHY,
"Format1A Retransmission but TBS are different: consider it as new transmission !!!, round %d, mcs 1 %d, NPRB %d \n",
pdlsch0_harq->round,
mcs1,
NPRB);
pdlsch0_harq->round = 0;
//return(0); // ?? to cross check
return(0); // ?? to cross check
// this is an eNB issue
// retransmisison but old and new TBS are different !!!
// we have missed DCIs, consider it as a new transmission
LOG_W(PHY,
"dci format1A Retransmission but TBS are different: consider it as new transmission !!!, round %d, mcs 1 %d, NPRB "
"%d \n",
pdlsch0_harq->round,
mcs1,
NPRB);
pdlsch0_harq->round = 0;
return (0);
}
}
return(1);
}
@@ -1148,14 +1153,15 @@ int check_dci_format1c_coherency(uint8_t N_RB_DL,
if(rballoc > RIV_max)
{
// DCI false detection
return(0);
LOG_I(PHY, "bad dci format 1c rballoc rballoc %d RIV_max %u \n", rballoc, RIV_max); // DCI false detection
return (0);
}
if(NPRB == 0)
{
// DCI false detection
return(0);
LOG_I(PHY, "bad dci format 1c NPRB = 0 \n");
// DCI false detection
return (0);
}
return(1);
@@ -1204,53 +1210,44 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
#endif
// I- check dci content minimum coherency
if(harq_pid>=8)
{
// LOG_I(PHY,"bad harq pid\n");
if (harq_pid >= 8) {
LOG_I(PHY, "bad dci foramt2 harq pid %d\n", harq_pid);
return(0);
}
if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) )
{
// LOG_I(PHY,"bad rnti\n");
return(0);
if ((rnti == si_rnti) || (rnti == p_rnti) || (rnti == ra_rnti)) {
LOG_I(PHY, "bad dci format 2 rnti %x\n", rnti);
return (0);
}
if( mcs1 > 28)
{
if(pdlsch0_harq->round == 0)
{
// LOG_I(PHY,"bad mcs1\n");
return(0);
}
if (!pdlsch0_harq) {
LOG_E(PHY, "pointer to pdlsch0_harq is NULL\n");
return 0;
}
if ((mcs1 > 28) && !pdlsch0_harq->round) {
LOG_I(PHY, "bad mcs1 %d while round is %d\n", mcs1, pdlsch0_harq->round);
return (0);
}
if( mcs2 > 28)
{
if(pdlsch1_harq->round == 0)
{
// LOG_I(PHY,"bad mcs2\n");
return(0);
}
if (!pdlsch1_harq) {
LOG_E(PHY, "pointer to pdlsch0_harq is NULL\n");
return 0;
}
if ((mcs2 > 28) && !pdlsch1_harq->round) {
LOG_I(PHY, "bad mcs2 %d while round is %d\n", mcs2, pdlsch0_harq->round);
return (0);
}
if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0))
{
// DCI false detection
// LOG_I(PHY,"bad rv1\n");
if ((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0)) {
LOG_I(PHY, "bad mcs2 %d while round is %d and rv1 %d and mcs1 %d\n", mcs2, pdlsch0_harq->round, rv1, mcs1);
return(0);
}
if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0))
{
// DCI false detection
// LOG_I(PHY,"bad rv2\n");
if ((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0)) {
LOG_I(PHY, "bad mcs2 %d while round is %d and rv2 %d \n", mcs2, pdlsch0_harq->round, rv2);
return(0);
}
switch (N_RB_DL) {
case 6:
if (rah == 0)
@@ -1307,14 +1304,14 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
if( (rballoc > RIV_max) && (rah == 1) )
{
// DCI false detection
// LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max);
LOG_I(PHY, "bad rballoc %d RIV_max %lld\n", rballoc, RIV_max);
return(0);
}
if(NPRB == 0)
{
// DCI false detection
// LOG_I(PHY,"bad NPRB\n");
LOG_I(PHY, "dci format 2 bad NPRB %d\n", NPRB);
return(0);
}
@@ -1627,8 +1624,13 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
{
if(mcs1 < 29)
{
pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB4TBS-1];
pdlsch0_harq->Qm = get_Qm(mcs1);
int tbs = get_I_TBS(mcs1);
if (NPRB4TBS > 110 || tbs >= TBStable_rowCnt) {
LOG_E(PHY, "NPRB4TBS %d out of array\n", NPRB4TBS);
pdlsch0_harq->TBS = 0;
} else
pdlsch0_harq->TBS = TBStable[tbs][NPRB4TBS - 1];
pdlsch0_harq->Qm = get_Qm(mcs1);
}
}
@@ -2304,11 +2306,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
p_rnti,frame,subframe,
&dci_info_extarcted,
dlsch0_harq);
if(status == 0)
{
printf("bad DCI 1A !!! \n");
return(-1);
}
if (status == 0) // log of error is done
return (-1);
// dci is correct ==> update internal structure and prepare dl decoding
#ifdef DEBUG_DCI
@@ -2412,12 +2411,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
p_rnti,frame,subframe,
&dci_info_extarcted,
dlsch0_harq);
if(status == 0)
{
printf("bad DCI 1 !!! \n");
return(-1);
}
if (status == 0) // log of error is done
return (-1);
// dci is correct ==> update internal structure and prepare dl decoding
#ifdef DEBUG_DCI
@@ -3528,8 +3523,14 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
if (rballoc > RIV_max) {
LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n",
proc->frame_rx, subframe, rnti, dci_format,rballoc,RIV_max);
LOG_W(PHY,
"frame %d, subframe %d, rnti %x, format %d, generate_ue_ulsch_params_from_dci impossible rb_alloc[%d] > RIV_max[%d]\n",
proc->frame_rx,
subframe,
rnti,
dci_format,
rballoc,
RIV_max);
LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid);
ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
return(-1);
+26 -60
View File
@@ -1381,12 +1381,6 @@ void dci_decoding(uint8_t DCI_LENGTH,
//debug_printf("Done DCI Viterbi \n");
}
static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8];
int get_nCCE_offset_l1(int *CCE_table,
const unsigned char L,
const int nCCE,
@@ -1593,19 +1587,19 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
switch (L2) {
case 1:
CCEmap_mask = (1<<(CCEind&0x1f));
CCEmap_mask = (1U << (CCEind & 0x1f));
break;
case 2:
CCEmap_mask = (3<<(CCEind&0x1f));
CCEmap_mask = (3U << (CCEind & 0x1f));
break;
case 4:
CCEmap_mask = (0xf<<(CCEind&0x1f));
CCEmap_mask = (0xfU << (CCEind & 0x1f));
break;
case 8:
CCEmap_mask = (0xff<<(CCEind&0x1f));
CCEmap_mask = (0xffU << (CCEind & 0x1f));
break;
default:
@@ -1625,25 +1619,14 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
else
LOG_D(PHY,"[DCI search nPdcch %d - ue spec %x] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
pdcch_vars[eNB_id]->num_pdcch_symbols,pdcch_vars[eNB_id]->crnti,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c);
dci_decoding(sizeof_bits,
L,
&pdcch_vars[eNB_id]->e_rx[CCEind*72],
&dci_decoded_output[current_thread_id][0]);
/*
for (i=0;i<3+(sizeof_bits>>3);i++)
printf("dci_decoded_output[%d][%d] => %x\n",current_thread_id,i,dci_decoded_output[current_thread_id][i]);
*/
crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits);
uint8_t dci_decoded_output[(MAX_DCI_SIZE_BITS + 64) / 8] = {};
dci_decoding(sizeof_bits, L, &pdcch_vars[eNB_id]->e_rx[CCEind * 72], dci_decoded_output);
crc = (crc16(dci_decoded_output, sizeof_bits) >> 16) ^ extract_crc(dci_decoded_output, sizeof_bits);
#ifdef DEBUG_DCI_DECODING
printf("crc =>%x\n",crc);
#endif
if (((L>1) && ((crc == si_rnti)||
(crc == p_rnti)||
(crc == ra_rnti)/*||(crc == 0xfff9)*/))||
(crc == pdcch_vars[eNB_id]->crnti)) {
uint8_t *ptr = dci_decoded_output;
if ((do_common && (L > 1) && (crc == si_rnti || crc == p_rnti || crc == ra_rnti)) || (crc == pdcch_vars[eNB_id]->crnti)) {
dci_alloc[*dci_cnt].dci_length = sizeof_bits;
dci_alloc[*dci_cnt].rnti = crc;
dci_alloc[*dci_cnt].L = L;
@@ -1651,30 +1634,19 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
//printf("DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes);
if (sizeof_bytes<=4) {
dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0];
dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1];
dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2];
dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3];
#ifdef DEBUG_DCI_DECODING
printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0],
dci_decoded_output[current_thread_id][1],
dci_decoded_output[current_thread_id][2],
dci_decoded_output[current_thread_id][3]);
#endif
dci_alloc[*dci_cnt].dci_pdu[3] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[2] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[1] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[0] = *ptr++;
} else {
dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0];
dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1];
dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2];
dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3];
dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4];
dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5];
dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6];
dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7];
#ifdef DEBUG_DCI_DECODING
printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3],
dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]);
#endif
dci_alloc[*dci_cnt].dci_pdu[7] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[6] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[5] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[4] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[3] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[2] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[1] = *ptr++;
dci_alloc[*dci_cnt].dci_pdu[0] = *ptr++;
}
if (crc==si_rnti /*|| crc==0xfff9*/) {
@@ -1689,8 +1661,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
*dci_cnt = *dci_cnt+1;
} else if (crc==pdcch_vars[eNB_id]->crnti) {
if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A
if ((mode & UL_DCI) && (format_c == format0) && ((dci_decoded_output[0] & 0x80) == 0)) { // check if pdu is format 0 or 1A
if (*format0_found == 0) {
dci_alloc[*dci_cnt].format = format0;
*format0_found = 1;
@@ -1772,8 +1743,7 @@ uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
int16_t eNB_id,
uint8_t subframe)
{
uint8_t dci_cnt=0,old_dci_cnt=0;
uint8_t dci_cnt = 0;
uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
@@ -1879,8 +1849,7 @@ uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
&CCEmap1,
&CCEmap2);
if ((CCEmap0==0xffff)||
((format0_found==1)&&(format_c_found==1)))
if ((CCEmap0 == 0xffff) || ((format0_found == 1) && (format_c_found == 1)))
return(dci_cnt);
if (DCIFormat == format1)
@@ -1892,7 +1861,7 @@ uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
//printf("[DCI search] Format 1/1A aggregation 1\n");
old_dci_cnt=dci_cnt;
int old_dci_cnt = dci_cnt;
dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
dci_alloc,
eNB_id,
@@ -1916,15 +1885,12 @@ uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
&CCEmap1,
&CCEmap2);
if ((CCEmap0==0xffff) ||
(format_c_found==1))
if ((CCEmap0 == 0xffff) || (format_c_found == 1))
return(dci_cnt);
if (dci_cnt>old_dci_cnt)
return(dci_cnt);
//printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
}
else if (DCIFormat == format1A)
{