From d28419cfca26ca6bd6a493b6359c572a02380702 Mon Sep 17 00:00:00 2001 From: laurent Date: Sat, 24 Aug 2019 16:28:55 +0200 Subject: [PATCH] usage of setAllfromTS in also monolitic version, RACH detected to the cu, several bugs fixed, still no attach complete --- executables/main-fs6.c | 508 ++++++++++++++------ executables/main-ocp.c | 151 +++--- executables/split_headers.h | 51 +- openair1/PHY/LTE_TRANSPORT/prach.c | 2 +- openair1/PHY/LTE_TRANSPORT/prach_common.c | 1 + openair1/PHY/LTE_TRANSPORT/transport_eNB.h | 6 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 79 +-- openair1/PHY/defs_eNB.h | 1 + openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- 9 files changed, 522 insertions(+), 279 deletions(-) diff --git a/executables/main-fs6.c b/executables/main-fs6.c index 6aed32d132..1ebce9ef7d 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -16,62 +16,18 @@ #include #include #include +#include #define FS6_BUF_SIZE 100*1000 static UDPsock_t sockFS6; -// Fixme: there are many mistakes in the datamodel and in redondant variables -// TDD is also mode complex -void setAllfromTS(uint64_t TS) { - for (int i=0; i frame_parms; - uint64_t TStx=TS+sf_ahead*fp->samples_per_tti; - RU_proc_t *proc =&RC.ru[i]->proc; - proc->timestamp_rx= TS; - proc->timestamp_tx= TStx; - proc->subframe_rx= (TS / fp->samples_per_tti)%10; - proc->subframe_tx= (TStx / fp->samples_per_tti)%10; - proc->subframe_prach=(TS / fp->samples_per_tti)%10; - proc->subframe_prach_br=(TS / fp->samples_per_tti)%10; - proc->frame_rx= (TS / (fp->samples_per_tti*10))&1023; - proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; - } - for (int i=0; i < RC.nb_inst; i++) { - for (int j=0; jframe_parms; - uint64_t TStx=TS+sf_ahead*fp->samples_per_tti; - L1_proc_t *proc =&RC.eNB[i][j]->proc; - L1_rxtx_proc_t *proc1=&RC.eNB[i][j]->proc.L1_proc; - proc->timestamp_rx= TS; - proc->timestamp_tx= TStx; - proc->subframe_rx= (TS / fp->samples_per_tti)%10; - proc->subframe_prach=(TS / fp->samples_per_tti)%10; - proc->subframe_prach_br=(TS / fp->samples_per_tti)%10; - proc->frame_rx= (TS / (fp->samples_per_tti*10))&1023; - proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; - proc1->timestamp_tx= TStx; - proc1->subframe_rx= (TS / fp->samples_per_tti)%10; - proc1->subframe_tx= (TStx / fp->samples_per_tti)%10; - proc1->frame_rx= (TS / (fp->samples_per_tti*10))&1023; - proc1->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; - } - } - - return; -} - - -void prach_eNB_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, int frame,int subframe) { +void prach_eNB_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) { fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone); - if (is_prach_subframe(&eNB->frame_parms, frame,subframe)<=0) + if (is_prach_subframe(&eNB->frame_parms, eNB->proc.frame_prach,eNB->proc.subframe_prach)<=0) return; - eNB->proc.frame_prach = frame; - eNB->proc.subframe_prach = subframe; - eNB->proc.frame_prach_br = frame; - eNB->proc.subframe_prach_br = subframe; RU_t *ru; int aa=0; int ru_aa; @@ -88,19 +44,19 @@ void prach_eNB_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, int } } - /* Fixme: the orgin code calls the two funtiosn, so one overwrite the second? - rx_prach(eNB, - eNB->RU_list[0], - header->max_preamble, - header->max_preamble_energy, - header->max_preamble_delay, - header->avg_preamble_energy, - frame, - 0, - false - ); - */ + rx_prach(eNB, + eNB->RU_list[0], + header->max_preamble, + header->max_preamble_energy, + header->max_preamble_delay, + header->avg_preamble_energy, + eNB->proc.frame_prach, + 0, + false + ); // run PRACH detection for CE-level 0 only for now when br_flag is set + /* fixme: seems not operational and may overwrite regular LTE prach detection + * OAI code can call is sequence rx_prach(eNB, eNB->RU_list[0], header->max_preamble, @@ -111,17 +67,26 @@ void prach_eNB_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, int 0, true ); + */ + LOG_D(PHY,"RACH detection index 0: max preamble: %u, energy: %u, delay: %u, avg energy: %u\n", + header->max_preamble[0], + header->max_preamble_energy[0], + header->max_preamble_delay[0], + header->avg_preamble_energy[0] + ); return; } -void prach_eNB_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { +void prach_eNB_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) { fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone); uint16_t *max_preamble=header->max_preamble; uint16_t *max_preamble_energy=header->max_preamble_energy; uint16_t *max_preamble_delay=header->max_preamble_delay; uint16_t *avg_preamble_energy=header->avg_preamble_energy; + int subframe=eNB->proc.subframe_prach; + int frame=eNB->proc.frame_prach; // Fixme: not clear why we call twice with "br" and without - int br_flag=1; + int br_flag=0; if (br_flag==1) { int prach_mask; @@ -206,6 +171,29 @@ void prach_eNB_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,RU_t } } +void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen) { + uint8_t *bufferZone=eNB->FS6bufferZone; + commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; + // move to the end + uint8_t *firstFreeByte=bufferZone; + int curBlock=0; + + for (int i=0; i < FirstUDPheader->nbBlocks; i++) { + AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); + firstFreeByte+=alignedSize(firstFreeByte); + curBlock++; + } + + commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; + FirstUDPheader->nbBlocks++; + newUDPheader->blockID=curBlock; + newUDPheader->contentBytes=sizeof(fs6_ul_t)+sizeof(fs6_ul_uespec_t) + dataLen; + hULUE(newUDPheader)->UE_id=UE_id; + hULUE(newUDPheader)->harq_id=harq_pid; + hULUE(newUDPheader)->segment=segmentID; + memcpy(hULUE(newUDPheader)+1, data, dataLen); +} + void pusch_procedures_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { uint32_t harq_pid; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; @@ -223,9 +211,14 @@ void pusch_procedures_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eN LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; if (ulsch->rnti>0) - LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d handled:%d]\n", + LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d active: %d handled:%d]\n", i, harq_pid, frame,subframe,i,ulsch->rnti, - ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); + ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->status, ulsch_harq->handled); + + if ((ulsch) && + (ulsch->rnti>0) && + (ulsch_harq->status == ACTIVE)) + LOG_E(PHY,"active ulsch harq\n"); if ((ulsch) && (ulsch->rnti>0) && @@ -265,7 +258,8 @@ void pusch_procedures_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eN ulsch_harq->O_ACK, ulsch->beta_offset_cqi_times8); start_meas(&eNB->ulsch_demodulation_stats); - rx_ulsch(eNB,proc, i); + eNB->FS6bufferZone=bufferZone; + rx_ulsch(eNB, proc, i); stop_meas(&eNB->ulsch_demodulation_stats); // TBD: add datablock for transmission } @@ -318,13 +312,98 @@ void phy_procedures_eNB_uespec_RX_extract(uint8_t *bufferZone, int bufSize, PHY_ return; } -void pusch_procedures_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { +int ulsch_decoding_process(PHY_VARS_eNB *eNB, int UE_id, int llr8_flag) { + int harq_pid; + LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; + + if (ulsch->ue_type>0) + harq_pid = 0; + else + harq_pid = subframe2harq_pid(&eNB->frame_parms,eNB->proc.frame_rx,eNB->proc.subframe_rx); + + LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; + decoder_if_t *tc; + int offset, ret; + + if (llr8_flag == 0) + tc = *decoder16; + else + tc = *decoder8; + + for (int r=0; rC; r++) { + // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); + // Get Turbo interleaver parameters + int Kr; + + if (rCminus) + Kr = ulsch_harq->Kminus; + else + Kr = ulsch_harq->Kplus; + + int Kr_bytes = Kr>>3; + int crc_type; + + if (ulsch_harq->C == 1) + crc_type = CRC24_A; + else + crc_type = CRC24_B; + + start_meas(&eNB->ulsch_turbo_decoding_stats); + ret = tc(&ulsch_harq->d[r][96], + NULL, + ulsch_harq->c[r], + NULL, + Kr, + ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, + crc_type, + (r==0) ? ulsch_harq->F : 0, + &eNB->ulsch_tc_init_stats, + &eNB->ulsch_tc_alpha_stats, + &eNB->ulsch_tc_beta_stats, + &eNB->ulsch_tc_gamma_stats, + &eNB->ulsch_tc_ext_stats, + &eNB->ulsch_tc_intl1_stats, + &eNB->ulsch_tc_intl2_stats); + stop_meas(&eNB->ulsch_turbo_decoding_stats); + + // Reassembly of Transport block here + + if (ret != (1+ulsch->max_turbo_iterations)) { + if (rCminus) + Kr = ulsch_harq->Kminus; + else + Kr = ulsch_harq->Kplus; + + Kr_bytes = Kr>>3; + + if (r==0) { + memcpy(ulsch_harq->bb, + &ulsch_harq->c[0][(ulsch_harq->F>>3)], + Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); + offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); + } else { + memcpy(ulsch_harq->bb+offset, + ulsch_harq->c[r], + Kr_bytes - ((ulsch_harq->C>1)?3:0)); + offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); + } + } else { + break; + } + } + + return(ret); +} + +void pusch_procedures_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) { //LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; + const int subframe = eNB->proc.subframe_rx; + const int frame = eNB->proc.frame_rx; uint32_t harq_pid; uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe); + // TBD: read UL data + for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[i]; @@ -353,11 +432,16 @@ void pusch_procedures_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eN } start_meas(&eNB->ulsch_decoding_stats); - int ret = ulsch_decoding(eNB,proc, + /* + int ret = ulsch_decoding(eNB,&eNB->proc.L1_proc, i, 0, // control_only_flag ulsch_harq->V_UL_DAI, ulsch_harq->nb_rb>20 ? 1 : 0); + */ + int ret = ulsch_decoding_process(eNB, + i, + ulsch_harq->nb_rb>20 ? 1 : 0); stop_meas(&eNB->ulsch_decoding_stats); LOG_D(PHY, "[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d ulsch_decoding_stats[t:%lld max:%lld]\n", @@ -474,7 +558,26 @@ void pusch_procedures_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eN } // for (i=0; icontentBytes >= sizeof(fs6_ul_t)+sizeof(fs6_ul_uespec_t) ) { + LTE_eNB_ULSCH_t *ulsch =eNB->ulsch[hULUE(bufPtr)->UE_id]; + LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[hULUE(bufPtr)->harq_id]; + memcpy(&ulsch_harq->d[hULUE(bufPtr)->segment][96], + hULUE(bufPtr)+1, + hULUE(bufPtr)->segLen); + bufPtr+=alignedSize(bufPtr); + LOG_W(PHY,"Received ulsch data for: rnti:%d, fsf: %d/%d\n", ulsch->rnti, eNB->proc.frame_rx, eNB->proc.subframe_rx); + } + } +} + +void phy_procedures_eNB_uespec_RX_process(uint8_t *bufferZone, int nbBlocks,PHY_VARS_eNB *eNB) { + // The configuration arrived in Dl, so we can extract the UL data + recvFs6Ul(bufferZone, nbBlocks, eNB); + pusch_procedures_process(bufferZone, nbBlocks, eNB); } void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas ) { @@ -504,36 +607,75 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int nbBlocks, PHY_VARS_e void *bufPtr=bufferZone; for (int i=0; i < nbBlocks; i++) { //nbBlocks is the actual received blocks - if ( ((commonUDP_t *)bufPtr)->contentBytes >= sizeof(fs6_dl_t)+sizeof(fs6_dl_uespec_t) ) { - int curUE=hDLUE(bufPtr)->UE_id; - LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[curUE][0]; - LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch0->harq_processes[hDLUE(bufPtr)->harq_pid]; -#ifdef PHY_TX_THREAD - dlsch0->active[subframe] = 1; -#else - dlsch0->active = 1; -#endif - dlsch0->harq_ids[frame%2][subframe]=hDLUE(bufPtr)->harq_pid; - dlsch0->rnti=hDLUE(bufPtr)->rnti; - dlsch0->sqrt_rho_a=hDLUE(bufPtr)->sqrt_rho_a; - dlsch0->sqrt_rho_b=hDLUE(bufPtr)->sqrt_rho_b; - dlsch_harq->nb_rb=hDLUE(bufPtr)->nb_rb; - memcpy(dlsch_harq->rb_alloc, hDLUE(bufPtr)->rb_alloc, sizeof(hDLUE(bufPtr)->rb_alloc)); - dlsch_harq->Qm=hDLUE(bufPtr)->Qm; - dlsch_harq->Nl=hDLUE(bufPtr)->Nl; - dlsch_harq->pdsch_start=hDLUE(bufPtr)->pdsch_start; -#ifdef PHY_TX_THREAD - dlsch_harq->i0=hDLUE(bufPtr)->i0; - dlsch_harq->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag; -#else - dlsch0->i0=hDLUE(bufPtr)->i0; - dlsch0->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag; -#endif - memcpy(dlsch_harq->e, - hDLUE(bufPtr)+1, hDLUE(bufPtr)->dataLen); - } + if ( ((commonUDP_t *)bufPtr)->contentBytes > sizeof(fs6_dl_t) ) { + int type=hDLUE(bufPtr)->type; - bufPtr+=alignedSize(bufPtr); + if ( type == fs6DlConfig) { + int curUE=hDLUE(bufPtr)->UE_id; + LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[curUE][0]; + LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch0->harq_processes[hDLUE(bufPtr)->harq_pid]; +#ifdef PHY_TX_THREAD + dlsch0->active[subframe] = 1; +#else + dlsch0->active = 1; +#endif + dlsch0->harq_ids[frame%2][subframe]=hDLUE(bufPtr)->harq_pid; + dlsch0->rnti=hDLUE(bufPtr)->rnti; + dlsch0->sqrt_rho_a=hDLUE(bufPtr)->sqrt_rho_a; + dlsch0->sqrt_rho_b=hDLUE(bufPtr)->sqrt_rho_b; + dlsch_harq->nb_rb=hDLUE(bufPtr)->nb_rb; + memcpy(dlsch_harq->rb_alloc, hDLUE(bufPtr)->rb_alloc, sizeof(hDLUE(bufPtr)->rb_alloc)); + dlsch_harq->Qm=hDLUE(bufPtr)->Qm; + dlsch_harq->Nl=hDLUE(bufPtr)->Nl; + dlsch_harq->pdsch_start=hDLUE(bufPtr)->pdsch_start; +#ifdef PHY_TX_THREAD + dlsch_harq->i0=hDLUE(bufPtr)->i0; + dlsch_harq->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag; +#else + dlsch0->i0=hDLUE(bufPtr)->i0; + dlsch0->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag; +#endif + memcpy(dlsch_harq->e, + hDLUE(bufPtr)+1, hDLUE(bufPtr)->dataLen); + } else if (type == fs6UlConfig) { + int nbUE=(((commonUDP_t *)bufPtr)->contentBytes - sizeof(fs6_dl_t)) / sizeof( fs6_dl_ulsched_t ) ; + + for ( int i=0; i < nbUE; i++ ) { + int curUE=hTxULUE(bufPtr)->UE_id; + LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[curUE]; + LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[hTxULUE(bufPtr)->harq_pid]; + ulsch->ue_type=hTxULUE(bufPtr)->ue_type; + ulsch->harq_mask=hTxULUE(bufPtr)->harq_mask; + ulsch->Mlimit=hTxULUE(bufPtr)->Mlimit; + ulsch->max_turbo_iterations=hTxULUE(bufPtr)->max_turbo_iterations; + ulsch->bundling=hTxULUE(bufPtr)->bundling; + ulsch->beta_offset_cqi_times8=hTxULUE(bufPtr)->beta_offset_cqi_times8; + ulsch->beta_offset_ri_times8=hTxULUE(bufPtr)->beta_offset_ri_times8; + ulsch->beta_offset_harqack_times8=hTxULUE(bufPtr)->beta_offset_harqack_times8; + ulsch->Msg3_active=hTxULUE(bufPtr)->Msg3_active; + ulsch->cyclicShift=hTxULUE(bufPtr)->cyclicShift; + ulsch->cooperation_flag=hTxULUE(bufPtr)->cooperation_flag; + ulsch->num_active_cba_groups=hTxULUE(bufPtr)->num_active_cba_groups; + memcpy(ulsch->cba_rnti,hTxULUE(bufPtr)->cba_rnti,sizeof(ulsch->cba_rnti));//NUM_MAX_CBA_GROUP]; + ulsch->rnti=hTxULUE(bufPtr)->rnti; + ulsch_harq->nb_rb=hTxULUE(bufPtr)->nb_rb; + ulsch_harq->handled=0; + ulsch_harq->status = ACTIVE; + ulsch_harq->frame = frame; + ulsch_harq->subframe = subframe; + ulsch_harq->first_rb=hTxULUE(bufPtr)->first_rb; + ulsch_harq->V_UL_DAI=hTxULUE(bufPtr)->V_UL_DAI; + ulsch_harq->Qm=hTxULUE(bufPtr)->Qm; + ulsch_harq->srs_active=hTxULUE(bufPtr)->srs_active; + ulsch_harq->TBS=hTxULUE(bufPtr)->TBS; + ulsch_harq->Nsymb_pusch=hTxULUE(bufPtr)->Nsymb_pusch; + LOG_W(PHY,"Received request to perform ulsch for: rnti:%d, fsf: %d/%d\n", ulsch->rnti, frame, subframe); + } + } else + LOG_E(PHY, "Impossible block in fs6 DL\n"); + + bufPtr+=alignedSize(bufPtr); + } } if (do_meas==1) { @@ -616,6 +758,63 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int nbBlocks, PHY_VARS_e AMP); } +#define cpyToDu(a) hTxULUE(newUDPheader)->a=ulsch->a +#define cpyToDuHarq(a) hTxULUE(newUDPheader)->a=ulsch_harq->a + +void appendFs6TxULUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int curUE, LTE_eNB_ULSCH_t *ulsch, int frame, int subframe) { + commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; + // move to the end + uint8_t *firstFreeByte=bufferZone; + int curBlock=0; + + for (int i=0; i < FirstUDPheader->nbBlocks; i++) { + AssertFatal( ((commonUDP_t *) firstFreeByte)->blockID==curBlock,""); + firstFreeByte+=alignedSize(firstFreeByte); + curBlock++; + } + + commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte; + FirstUDPheader->nbBlocks++; + newUDPheader->blockID=curBlock; + newUDPheader->contentBytes=sizeof(fs6_dl_t)+sizeof(fs6_dl_ulsched_t); + // We skip the fs6 DL header, that is populated by caller + // This header will be duplicated during sending + hTxULUE(newUDPheader)->type=fs6UlConfig; + hTxULUE(newUDPheader)->UE_id=curUE; + int harq_pid; + + if (ulsch->ue_type > NOCE) + // LTE-M case + harq_pid = 0; + else + harq_pid = subframe2harq_pid(fp, frame, subframe); + + LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[harq_pid]; + hTxULUE(newUDPheader)->harq_pid=harq_pid; + cpyToDu(ue_type); + cpyToDu(harq_mask); + cpyToDu(Mlimit); + cpyToDu(max_turbo_iterations); + cpyToDu(bundling); + cpyToDu(beta_offset_cqi_times8); + cpyToDu(beta_offset_ri_times8); + cpyToDu(beta_offset_harqack_times8); + cpyToDu(Msg3_active); + cpyToDu(cyclicShift); + cpyToDu(cooperation_flag); + cpyToDu(num_active_cba_groups); + memcpy(hTxULUE(newUDPheader)->cba_rnti,ulsch->cba_rnti,sizeof(ulsch->cba_rnti));//NUM_MAX_CBA_GROUP]; + cpyToDu(rnti); + cpyToDuHarq(nb_rb); + cpyToDuHarq(first_rb); + cpyToDuHarq(V_UL_DAI); + cpyToDuHarq(Qm); + cpyToDuHarq(srs_active); + cpyToDuHarq(TBS); + cpyToDuHarq(Nsymb_pusch); + LOG_W(PHY,"Added request to perform ulsch for: rnti:%d, fsf: %d/%d\n", ulsch->rnti, frame, subframe); +} + void appendFs6DLUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int UE_id, int8_t harq_pid, LTE_eNB_DLSCH_t *dlsch0, LTE_DL_eNB_HARQ_t *harqData, int frame, int subframe) { commonUDP_t *FirstUDPheader=(commonUDP_t *) bufferZone; // move to the end @@ -643,6 +842,7 @@ void appendFs6DLUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int UE_id, int8_ newUDPheader->contentBytes=sizeof(fs6_dl_t)+sizeof(fs6_dl_uespec_t) + UEdataLen; // We skip the fs6 DL header, that is populated by caller // This header will be duplicated during sending + hDLUE(newUDPheader)->type=fs6DlConfig; hDLUE(newUDPheader)->UE_id=UE_id; hDLUE(newUDPheader)->harq_pid=harq_pid; hDLUE(newUDPheader)->rnti=dlsch0->rnti; @@ -662,9 +862,8 @@ void appendFs6DLUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int UE_id, int8_ #endif hDLUE(newUDPheader)->dataLen=UEdataLen; memcpy(hDLUE(newUDPheader)+1, harqData->e, UEdataLen); - - for (int i=0; i < UEdataLen; i++) - LOG_D(PHY,"buffer e:%hhx\n", ( (uint8_t *)(hDLUE(newUDPheader)+1) )[i]); + //for (int i=0; i < UEdataLen; i++) + //LOG_D(PHY,"buffer e:%hhx\n", ( (uint8_t *)(hDLUE(newUDPheader)+1) )[i]); } void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas, uint8_t *buf, int bufSize) { @@ -677,59 +876,51 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx return; } - // clear existing ulsch dci allocations before applying info from MAC (this is table - // returns -1 (or 255) if there is no ul (tdd cases) - int ul_subframe = pdcch_alloc2ul_subframe (fp, subframe); - int ul_frame = pdcch_alloc2ul_frame (fp, frame, subframe); - // clear previous allocation information for all UEs for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { //if (eNB->dlsch[i][0]) //eNB->dlsch[i][0]->subframe_tx[subframe] = 0; } - /* TODO: check the following test - in the meantime it is put back as it was before */ - //if ((ul_subframe < 10)&& - // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is a potential UL subframe that will be scheduled here - if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be schedulyed here - for (int i=0; iulsch[i]; - if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type > NOCE) - // LTE-M case - harq_pid = 0; - else - hDL(bufferZone)->UE_ul_active[i] = harq_pid = subframe2harq_pid(fp, ul_frame, ul_subframe); + if (ulsch->ue_type > NOCE) + harq_pid = 0; + else + harq_pid= subframe2harq_pid(&eNB->frame_parms,frame,subframe); - if (eNB->ulsch[i]) { - //LTE_UL_eNB_HARQ_t *ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid]; - /* Store first_rb and n_DMRS for correct PHICH generation below. - * For PHICH generation we need "old" values of last scheduling - * for this HARQ process. 'generate_eNB_dlsch_params' below will - * overwrite first_rb and n_DMRS and 'generate_phich_top', done - * after 'generate_eNB_dlsch_params', would use the "new" values - * instead of the "old" ones. - * - * This has been tested for FDD only, may be wrong for TDD. - * - * TODO: maybe we should restructure the code to be sure it - * is done correctly. The main concern is if the code - * changes and first_rb and n_DMRS are modified before - * we reach here, then the PHICH processing will be wrong, - * using wrong first_rb and n_DMRS values to compute - * ngroup_PHICH and nseq_PHICH. - * - * TODO: check if that works with TDD. - */ - /* seems useless: unused variables - header->previous_first_rb= - ulsch_harq->previous_first_rb = ulsch_harq->first_rb; - header->previous_n_DMRS = - ulsch_harq->previous_n_DMRS = ulsch_harq->n_DMRS; - */ - hDL(bufferZone)->UE_ul_active[i] = harq_pid; - } else - hDL(bufferZone)->UE_ul_active[i] = -1; + LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; + + if (ulsch->rnti>0) { + LOG_I(PHY,"check in UL scheduled harq %d: rnti %d, tx frame %d/%d, ulsch: %d, %d/%d (handled: %d)\n", + harq_pid, ulsch->rnti, frame, subframe, ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); + + for (int k=0; k<8; k++) + if ( ulsch->harq_processes[k]->status == ACTIVE) + LOG_I(PHY,"check in UL scheduledi (harq_pid %d): rnti %d, tx frame %d/%d, ulsch: %d, %d/%d (handled: %d)\n", k, + ulsch->rnti, frame, subframe, ulsch->harq_processes[k]->status, ulsch->harq_processes[k]->frame, ulsch->harq_processes[k]->subframe, ulsch->harq_processes[k]->handled); + } + + for (int k=0; k<8; k++) { + ulsch_harq = ulsch->harq_processes[k]; + + if (ulsch && + (ulsch->rnti>0) && + (ulsch_harq->status == ACTIVE) && + (ulsch_harq->frame == frame) && + (ulsch_harq->subframe == subframe) && + (ulsch_harq->handled == 0) + ) + appendFs6TxULUE(bufferZone, + fp, + i, + ulsch, + frame, + subframe + ); } } @@ -755,9 +946,6 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx if (do_meas==1) start_meas(&eNB->dlsch_ue_specific); - // Now scan UE specific DLSCH - LTE_eNB_DLSCH_t *dlsch0; - for (int UE_id=0; UE_iddlsch[UE_id][0]; @@ -838,8 +1026,6 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx } void DL_du_fs6(RU_t *ru) { - RU_proc_t *ru_proc=&ru->proc; - for (int i=0; inum_eNB; i++) { initBufferZone(bufferZone); int nb_blocks=receiveSubFrame(&sockFS6, bufferZone, sizeof(bufferZone), CTsentCUv0 ); @@ -853,8 +1039,7 @@ void DL_du_fs6(RU_t *ru) { hUDP(bufferZone)->timestamp); } - setAllfromTS(hUDP(bufferZone)->timestamp - - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti); + setAllfromTS(hUDP(bufferZone)->timestamp - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti); phy_procedures_eNB_TX_process( bufferZone, nb_blocks, ru->eNB_list[i], &ru->eNB_list[i]->proc.L1_proc, 1); } else LOG_E(PHY,"DL not received for subframe\n"); @@ -868,13 +1053,15 @@ void DL_du_fs6(RU_t *ru) { void UL_du_fs6(RU_t *ru, int frame, int subframe) { RU_proc_t *ru_proc=&ru->proc; int tmpf=frame, tmpsf=subframe; - rx_rf(ru,&tmpf,&tmpsf); + rx_rf(ru); AssertFatal(tmpf==frame && tmpsf==subframe, "lost synchronization\n"); - ru_proc->frame_tx = (ru_proc->frame_tx+ru_proc->frame_offset)&1023; setAllfromTS(ru_proc->timestamp_rx); + // front end processing: convert from time domain to frequency domain + // fills rxdataF buffer + fep_full(ru); // Fixme: datamodel issue PHY_VARS_eNB *eNB = RC.eNB[0][0]; - L1_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; if (NFAPI_MODE==NFAPI_MODE_PNF) { // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick @@ -885,7 +1072,7 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) { initBufferZone(bufferZone); hUDP(bufferZone)->timestamp=ru->proc.timestamp_rx; - prach_eNB_extract(bufferZone, FS6_BUF_SIZE, eNB, proc->frame_rx,proc->subframe_rx ); + prach_eNB_extract(bufferZone, FS6_BUF_SIZE, eNB); if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { phy_procedures_eNB_uespec_RX_extract(bufferZone, FS6_BUF_SIZE, eNB, &proc->L1_proc ); @@ -902,7 +1089,7 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) { } } -void DL_cu_fs6(RU_t *ru, uint64_t TS) { +void DL_cu_fs6(RU_t *ru) { // Fixme: datamodel issue PHY_VARS_eNB *eNB = RC.eNB[0][0]; L1_proc_t *proc = &eNB->proc; @@ -945,10 +1132,11 @@ void UL_cu_fs6(RU_t *ru, uint64_t *TS) { setAllfromTS(hUDP(bufferZone)->timestamp); PHY_VARS_eNB *eNB = RC.eNB[0][0]; + prach_eNB_process(bufferZone, sizeof(bufferZone), eNB); release_UE_in_freeList(eNB->Mod_id); if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { - phy_procedures_eNB_uespec_RX_process(bufferZone, sizeof(bufferZone), eNB, &eNB->proc.L1_proc); + phy_procedures_eNB_uespec_RX_process(bufferZone, nb_blocks, eNB); } } @@ -965,7 +1153,7 @@ void *cu_fs6(void *arg) { while(1) { timeStamp+=ru->frame_parms.samples_per_tti; UL_cu_fs6(ru, &timeStamp); - DL_cu_fs6(ru, timeStamp); + DL_cu_fs6(ru); } return NULL; diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 432ec6025a..b3983463e0 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -46,6 +46,54 @@ void free_transport(PHY_VARS_eNB *eNB) { void reset_opp_meas(void) { } +// Fixme: there are many mistakes in the datamodel and in redondant variables +// TDD is also mode complex +void setAllfromTS(uint64_t TS) { + for (int i=0; i frame_parms; + RU_proc_t *proc =&RC.ru[i]->proc; + uint64_t TStx=TS+(sf_ahead)*fp->samples_per_tti; + uint64_t TSrach=TS;//-fp->samples_per_tti; + proc->timestamp_rx= TS; + proc->timestamp_tx= TStx; + proc->subframe_rx= (TS / fp->samples_per_tti)%10; + proc->subframe_tx= (TStx / fp->samples_per_tti)%10; + proc->subframe_prach=(TSrach / fp->samples_per_tti)%10; + proc->subframe_prach_br=proc->subframe_prach; + proc->frame_rx= (TS / (fp->samples_per_tti*10))&1023; + proc->frame_prach= (TSrach / (fp->samples_per_tti*10))&1023; + proc->frame_prach_br=(TSrach / (fp->samples_per_tti*10))&1023; + proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; + } + + for (int i=0; i < RC.nb_inst; i++) { + for (int j=0; jframe_parms; + L1_proc_t *proc =&RC.eNB[i][j]->proc; + L1_rxtx_proc_t *proc1=&RC.eNB[i][j]->proc.L1_proc; + uint64_t TStx=TS+(sf_ahead)*fp->samples_per_tti; + uint64_t TSrach=TS;//-fp->samples_per_tti; + proc->timestamp_rx= TS; + proc->timestamp_tx= TStx; + proc->subframe_rx= (TS / fp->samples_per_tti)%10; + proc->subframe_prach=(TSrach / fp->samples_per_tti)%10; + proc->subframe_prach_br=(TSrach / fp->samples_per_tti)%10; + proc->frame_rx= (TS / (fp->samples_per_tti*10))&1023; + proc->frame_prach= (TSrach / (fp->samples_per_tti*10))&1023; + proc->frame_prach_br=(TSrach / (fp->samples_per_tti*10))&1023; + proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; + proc1->timestamp_tx= TStx; + proc1->subframe_rx= (TS / fp->samples_per_tti)%10; + proc1->subframe_tx= (TStx / fp->samples_per_tti)%10; + proc1->frame_rx= (TS / (fp->samples_per_tti*10))&1023; + proc1->frame_tx= (TStx / (fp->samples_per_tti*10))&1023; + } + } + + return; +} + + void init_eNB_proc(int inst) { /*int i=0;*/ int CC_id; @@ -98,7 +146,6 @@ void init_RU_proc(RU_t *ru) { proc->instance_cnt_eNBs = -1; proc->first_rx = 1; proc->first_tx = 1; - proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; @@ -112,8 +159,7 @@ void init_RU_proc(RU_t *ru) { threadCreate(&t, cu_fs6, (void *)ru, "MainCu", -1, OAI_PRIORITY_RT_MAX); else if ( strncasecmp(fs6,"du", 2) == 0 ) { threadCreate(&t, du_fs6, (void *)ru, "MainDu", -1, OAI_PRIORITY_RT_MAX); - } - else + } else AssertFatal(false, "environement variable fs6 is not cu or du"); } else threadCreate(&t, ru_thread, (void *)ru, "MainRu", -1, OAI_PRIORITY_RT_MAX); @@ -263,6 +309,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { eNB->prach_energy_counter = 0; } } + + SET_LOG_DEBUG(PRACH); } void stop_eNB(int nb_inst) { @@ -421,17 +469,8 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) { } } -void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag, int frame, int subframe) { +void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) { uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4],avg_preamble_energy[4]; - - if (br_flag==0) { - eNB->proc.frame_prach = frame; - eNB->proc.subframe_prach = subframe; - } else { - eNB->proc.frame_prach_br = frame; - eNB->proc.subframe_prach_br = subframe; - } - RU_t *ru; int aa=0; int ru_aa; @@ -456,10 +495,16 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag, int frame, int subfram &max_preamble_energy[0], &max_preamble_delay[0], &avg_preamble_energy[0], - frame, + eNB->proc.frame_prach, 0 ,br_flag ); + LOG_D(PHY,"RACH detection index 0: max preamble: %u, energy: %u, delay: %u, avg energy: %u\n", + max_preamble[0], + max_preamble_energy[0], + max_preamble_delay[0], + avg_preamble_energy[0] + ); if (br_flag==1) { int prach_mask; @@ -483,7 +528,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag, int frame, int subfram eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind]; // eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; // note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4 - eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + subframe + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40)); + eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + eNB->proc.subframe_prach + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40)); eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1 + ce_level; // CE Level LOG_I (PHY, "Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", @@ -504,8 +549,8 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag, int frame, int subfram LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", eNB->Mod_id, eNB->CC_id, - frame, - subframe, + eNB->proc.frame_prach, + eNB->proc.subframe_prach, max_preamble[0], max_preamble_energy[0]/10, max_preamble_energy[0]%10, @@ -515,11 +560,11 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag, int frame, int subfram eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; - eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; + eNB->UL_INFO.rach_ind.sfn_sf = eNB->proc.frame_prach<<4 | eNB->proc.subframe_prach; eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; - eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here + eNB->preamble_list[0].preamble_rel8.rnti = 1+eNB->proc.subframe_prach; // note: fid is implicitly 0 here eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is @@ -547,8 +592,8 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag, int frame, int subfram void prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { // check if we have to detect PRACH first if (is_prach_subframe(&eNB->frame_parms, frame,subframe)>0) { - prach_procedures_ocp(eNB, 0, frame, subframe); - prach_procedures_ocp(eNB, 1, frame, subframe); + prach_procedures_ocp(eNB, 0); + prach_procedures_ocp(eNB, 1); } } @@ -586,28 +631,14 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name void eNB_top(PHY_VARS_eNB *eNB, int dummy1, int dummy2, char *string,RU_t *ru) { L1_proc_t *proc = &eNB->proc; L1_rxtx_proc_t *L1_proc = &proc->L1_proc; - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; - RU_proc_t *ru_proc=&ru->proc; if (!oai_exit) { - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->subframe_rx = ru_proc->subframe_rx; - L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? - (L1_proc->frame_rx+1)&1023 : - L1_proc->frame_rx; - L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; - if (rxtx(eNB,L1_proc,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); - - ru_proc->timestamp_tx = L1_proc->timestamp_tx; - ru_proc->subframe_tx = L1_proc->subframe_tx; - ru_proc->frame_tx = L1_proc->frame_tx; } } -void rx_rf(RU_t *ru,int *frame,int *subframe) { +void rx_rf(RU_t *ru) { RU_proc_t *proc = &ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; void *rxp[ru->nb_rx]; @@ -616,7 +647,8 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { openair0_timestamp ts=0,old_ts=0; for (i=0; inb_rx; i++) - rxp[i] = (void *)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; + //receive in the next slot + rxp[i] = (void *)&ru->common.rxdata[i][((ru->proc.subframe_rx+1)%10)*fp->samples_per_tti]; old_ts = proc->timestamp_rx; rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, @@ -630,6 +662,12 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { // "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); if(rxs != fp->samples_per_tti) { LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); +#if defined(USRP_REC_PLAY) + exit_fun("Exiting IQ record/playback"); +#else + //exit_fun( "problem receiving samples" ); + LOG_E(PHY, "problem receiving samples"); +#endif } if (proc->first_rx == 1) { @@ -638,27 +676,13 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { proc->first_rx = false; } else { if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { - LOG_E(HW,"impossible shift in RFSIM\n"); + LOG_E(HW,"impossible shift in RFSIM, rx: %ld, previous rx distance: %ld\n", proc->timestamp_rx, proc->timestamp_rx - old_ts); //ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); //proc->timestamp_rx = ts-ru->ts_offset; } } - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - // synchronize first reception to frame 0 subframe 0 - proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); - proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; - proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; - - if (rxs != fp->samples_per_tti) { -#if defined(USRP_REC_PLAY) - exit_fun("Exiting IQ record/playback"); -#else - //exit_fun( "problem receiving samples" ); - LOG_E(PHY, "problem receiving samples"); -#endif - } + setAllfromTS(proc->timestamp_rx); } void tx_rf(RU_t *ru) { @@ -723,9 +747,6 @@ void tx_rf(RU_t *ru) { static void *ru_thread( void *param ) { RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - int subframe =9; - int frame =1023; if (ru->if_south == LOCAL_RF) { // configure RF parameters only fill_rf_config(ru,ru->rf_config_file); @@ -747,23 +768,8 @@ static void *ru_thread( void *param ) { // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. - // They are set on the first rx/tx in the underly FH routines. - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } - // synchronization on input FH interface, acquire signals/data and block - AssertFatal(ru->fh_south_in, "No fronthaul interface at south port"); - ru->fh_south_in(ru,&frame,&subframe); - - // adjust for timing offset between RU - if (ru->idx!=0) - proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; + rx_rf(ru); // do RX front-end processing (frequency-shift, dft) if needed if (ru->feprx) @@ -819,7 +825,6 @@ void set_function_spec_param(RU_t *ru) { ru->feptx_ofdm = feptx_ofdm; ru->feptx_prec = feptx_prec; // this is fep with idft and precoding ru->rfdevice.host_type = RAU_HOST; - ru->fh_south_in = rx_rf; // local synchronous RF RX ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface ru->stop_rf = stop_rf; diff --git a/executables/split_headers.h b/executables/split_headers.h index 2e0df34c54..f3b17e4918 100644 --- a/executables/split_headers.h +++ b/executables/split_headers.h @@ -58,13 +58,43 @@ typedef struct { DCI_ALLOC_t dci_alloc[32]; int num_mdci; int amp; - int8_t UE_ul_active[NUMBER_OF_UE_MAX]; - int8_t UE_ul_first_rb[NUMBER_OF_UE_MAX]; // - int8_t UE_ul_last_rb[NUMBER_OF_UE_MAX]; // LTE_eNB_PHICH phich_vars; } fs6_dl_t; +enum pckType { + fs6UlConfig=25, + fs6DlConfig=26, +}; + typedef struct { + enum pckType type:8; + uint16_t UE_id; + int8_t harq_pid; + UE_type_t ue_type; + uint16_t harq_mask; + uint16_t nb_rb; + uint8_t Qm; + uint16_t first_rb; + uint8_t V_UL_DAI; + uint8_t srs_active; + uint32_t TBS; + uint8_t Nsymb_pusch; + uint8_t Mlimit; + uint8_t max_turbo_iterations; + uint8_t bundling; + uint16_t beta_offset_cqi_times8; + uint16_t beta_offset_ri_times8; + uint16_t beta_offset_harqack_times8; + uint8_t Msg3_active; + uint16_t rnti; + uint8_t cyclicShift; + uint8_t cooperation_flag; + uint8_t num_active_cba_groups; + uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; +} fs6_dl_ulsched_t; + +typedef struct { + enum pckType type:8; int UE_id; int8_t harq_pid; uint16_t rnti; @@ -76,10 +106,17 @@ typedef struct { uint8_t pdsch_start; uint8_t sib1_br_flag; uint16_t i0; - uint32_t rb_alloc[4]; + uint32_t rb_alloc[4];; int dataLen; } fs6_dl_uespec_t; +typedef struct { + short UE_id; + short harq_id; + short segment; + short segLen; +} fs6_ul_uespec_t; + bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result); int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType); int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType); @@ -92,6 +129,8 @@ int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, ui #define hDL(xBuf) ((fs6_dl_t*)(((commonUDP_t *)xBuf)+1)) #define hUL(xBuf) ((fs6_ul_t*)(((commonUDP_t *)xBuf)+1)) #define hDLUE(xBuf) ((fs6_dl_uespec_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) +#define hTxULUE(xBuf) ((fs6_dl_ulsched_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1)) +#define hULUE(xBuf) ((fs6_ul_uespec_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1)) static inline size_t alignedSize(uint8_t *ptr) { commonUDP_t *header=(commonUDP_t *) ptr; @@ -102,10 +141,11 @@ static inline void *commonUDPdata(uint8_t *ptr) { return (void *) (((commonUDP_t *)ptr)+1); } +void setAllfromTS(uint64_t TS); void *cu_fs6(void *arg); void *du_fs6(void *arg); void fill_rf_config(RU_t *ru, char *rf_config_file); -void rx_rf(RU_t *ru,int *frame,int *subframe); +void rx_rf(RU_t *ru); void tx_rf(RU_t *ru); void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe); void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); @@ -128,5 +168,6 @@ void phy_init_RU(RU_t *); void feptx_prec(RU_t *); void feptx_ofdm(RU_t *); void oai_subframe_ind(uint16_t sfn, uint16_t sf); +void fep_full(RU_t *ru); extern uint16_t sf_ahead; #endif diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index f49005b5d7..6aca9ba904 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -649,7 +649,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<harq_processes[i]) { - if (ulsch->harq_processes[i]->b) { - free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES); - ulsch->harq_processes[i]->b = NULL; + if (ulsch->harq_processes[i]->bb) { + free16(ulsch->harq_processes[i]->bb,MAX_ULSCH_PAYLOAD_BYTES); + ulsch->harq_processes[i]->bb = NULL; } for (r=0; rharq_processes[i]) { memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t)); - ulsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->bb = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); - if (ulsch->harq_processes[i]->b) - memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); + if (ulsch->harq_processes[i]->bb) + memset(ulsch->harq_processes[i]->bb,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); else exit_flag=3; @@ -274,7 +274,7 @@ int ulsch_decoding_data_2thread0(td_params *tdp) { Kr_bytes = Kr>>3; memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); - ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), + ulsch_harq->RTCC[r] = generate_dummy_w(4+(Kr_bytes*8), (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); #ifdef DEBUG_ULSCH_DECODING @@ -286,11 +286,11 @@ int ulsch_decoding_data_2thread0(td_params *tdp) { ulsch_harq->Nl); #endif - if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], + if (lte_rate_matching_turbo_rx(ulsch_harq->RTCC[r], G, ulsch_harq->w[r], (uint8_t *) &dummy_w[r][0], - ulsch_harq->e+r_offset, + ulsch_harq->eE+r_offset, ulsch_harq->C, NSOFT, 0, //Uplink @@ -340,7 +340,7 @@ int ulsch_decoding_data_2thread0(td_params *tdp) { Kr = ulsch_harq->Kplus; Kr_bytes = Kr>>3; - memcpy(ulsch_harq->b+offset, + memcpy(ulsch_harq->bb+offset, ulsch_harq->c[r], Kr_bytes - ((ulsch_harq->C>1)?3:0)); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); @@ -448,7 +448,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr Kr_bytes = Kr>>3; memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); - ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), + ulsch_harq->RTCC[r] = generate_dummy_w(4+(Kr_bytes*8), (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); #ifdef DEBUG_ULSCH_DECODING @@ -461,11 +461,11 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr #endif start_meas(&eNB->ulsch_rate_unmatching_stats); - if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], + if (lte_rate_matching_turbo_rx(ulsch_harq->RTCC[r], G, ulsch_harq->w[r], (uint8_t *) &dummy_w[r][0], - ulsch_harq->e+r_offset, + ulsch_harq->eE+r_offset, ulsch_harq->C, NSOFT, 0, //Uplink @@ -521,12 +521,12 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr Kr_bytes = Kr>>3; if (r==0) { - memcpy(ulsch_harq->b, + memcpy(ulsch_harq->bb, &ulsch_harq->c[0][(ulsch_harq->F>>3)], Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); } else { - memcpy(ulsch_harq->b+offset, + memcpy(ulsch_harq->bb+offset, ulsch_harq->c[r], Kr_bytes - ((ulsch_harq->C>1)?3:0)); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); @@ -553,7 +553,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; int G = ulsch_harq->G; - unsigned int E; + unsigned int EE; decoder_if_t *tc; if (llr8_flag == 0) @@ -571,7 +571,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) Kr_bytes = Kr>>3; memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); - ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), + ulsch_harq->RTCC[r] = generate_dummy_w(4+(Kr_bytes*8), (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); #ifdef DEBUG_ULSCH_DECODING @@ -584,11 +584,11 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) #endif start_meas(&eNB->ulsch_rate_unmatching_stats); - if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], + if (lte_rate_matching_turbo_rx(ulsch_harq->RTCC[r], G, ulsch_harq->w[r], (uint8_t *) &dummy_w[r][0], - ulsch_harq->e+r_offset, + ulsch_harq->eE+r_offset, ulsch_harq->C, NSOFT, 0, //Uplink @@ -598,13 +598,13 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) ulsch_harq->Qm, 1, r, - &E)==-1) { + &EE)==-1) { LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n"); return(-1); } stop_meas(&eNB->ulsch_rate_unmatching_stats); - r_offset += E; + r_offset += EE; start_meas(&eNB->ulsch_deinterleaving_stats); sub_block_deinterleaving_turbo(4+Kr, &ulsch_harq->d[r][96], @@ -616,6 +616,13 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) else crc_type = CRC24_B; + if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 ) { + // r is the segment id, + // Kr is the segment length in short + sendFs6Ul(eNB, UE_id, harq_pid, r, &ulsch_harq->d[r][96], Kr*sizeof(int16_t)); + return 0; + } + start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], NULL, @@ -645,12 +652,12 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) Kr_bytes = Kr>>3; if (r==0) { - memcpy(ulsch_harq->b, + memcpy(ulsch_harq->bb, &ulsch_harq->c[0][(ulsch_harq->F>>3)], Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); } else { - memcpy(ulsch_harq->b+offset, + memcpy(ulsch_harq->bb+offset, ulsch_harq->c[r], Kr_bytes - ((ulsch_harq->C>1)?3:0)); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); @@ -1190,8 +1197,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, j2+=2; } - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; } break; @@ -1203,10 +1210,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, j2+=4; } - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; } break; @@ -1218,12 +1225,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, j2+=6; } - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; + ulsch_harq->eE[iprime++] = y[j2++]; } break; @@ -1261,7 +1268,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, */ int16_t *yp,*ep; - for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0]; + for (iprime=0,yp=&y[j2],ep=&ulsch_harq->eE[0]; iprimerx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b; + pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->bb; // estimate timing advance for MAC sync_pos = lte_est_timing_advance_pusch(eNB,UE_id); timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check