Commit d28419cf authored by laurent's avatar laurent

usage of setAllfromTS in also monolitic version, RACH detected to the cu,...

usage of setAllfromTS in also monolitic version, RACH detected to the cu, several bugs fixed, still no attach complete
parent b9079220
......@@ -16,62 +16,18 @@
#include <openair1/PHY/INIT/lte_init.c>
#include <openair1/PHY/LTE_ESTIMATION/lte_estimation.h>
#include <executables/split_headers.h>
#include <openair1/PHY/CODING/coding_extern.h>
#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 <RC.nb_RU; i++) {
LTE_DL_FRAME_PARMS *fp=&RC.ru[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; j<RC.nb_CC[i]; j++) {
LTE_DL_FRAME_PARMS *fp=&RC.eNB[i][j]->frame_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; r<ulsch_harq->C; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
int Kr;
if (r<ulsch_harq->Cminus)
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 (r<ulsch_harq->Cminus)
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; i<NUMBER_OF_UE_MAX; i++)
}
void phy_procedures_eNB_uespec_RX_process(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc) {
void recvFs6Ul(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB) {
void *bufPtr=bufferZone;
for (int i=0; i < nbBlocks; i++) { //nbBlocks is the actual received blocks
if ( ((commonUDP_t *)bufPtr)->contentBytes >= 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];
if ( ((commonUDP_t *)bufPtr)->contentBytes > sizeof(fs6_dl_t) ) {
int type=hDLUE(bufPtr)->type;
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;
dlsch0->active[subframe] = 1;
#else
dlsch0->active = 1;
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;
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;
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;
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);
}
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);
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; i<NUMBER_OF_UE_MAX; i++) {
int harq_pid;
// Send to DU the UL scheduled for future UL subframe
for (int i=0; i<NUMBER_OF_UE_MAX; i++) {
int harq_pid;
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[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 (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;
if (ulsch->ue_type > NOCE)
harq_pid = 0;
else
harq_pid= subframe2harq_pid(&eNB->frame_parms,frame,subframe);
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_id<NUMBER_OF_UE_MAX; UE_id++) {
LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[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; i<ru->num_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;
......
......@@ -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 <RC.nb_RU; i++) {
LTE_DL_FRAME_PARMS *fp=&RC.ru[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; j<RC.nb_CC[i]; j++) {
LTE_DL_FRAME_PARMS *fp=&RC.eNB[i][j]->frame_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; i<ru->nb_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;
......
......@@ -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
......@@ -649,7 +649,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
for (i=0; i<NCS2; i++) {
lev = (int32_t)prach_ifft[(preamble_shift2+i)];
lev = (int32_t)prach_ifft[(preamble_shift2+i)];
avg_en += lev;
levdB = dB_fixed_times10(lev);
......
......@@ -36,6 +36,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#define PRACH_DEBUG
uint16_t NCS_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419};
uint16_t NCS_restricted[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case
uint16_t NCS_4[7] = {2,4,6,8,10,12,15};
......
......@@ -266,15 +266,15 @@ typedef struct {
/// coded RI bits
int16_t q_RI[MAX_RI_PAYLOAD];
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
int16_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
int16_t eE[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
uint8_t h[MAX_NUM_CHANNEL_BITS];
/// Pointer to the payload
uint8_t *b;
uint8_t *bb;
/// Pointers to transport block segments
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
uint32_t RTCC[MAX_NUM_ULSCH_SEGMENTS];
/// Current Number of Symbols
uint8_t Nsymb_pusch;
/// SRS active flag
......
......@@ -53,9 +53,9 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) {
if (ulsch) {
for (i=0; i<8; i++) {
if (ulsch->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; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
......@@ -114,10 +114,10 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
if (ulsch->harq_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];
iprime<G;
iprime+=8,j2+=8,ep+=8,yp+=8) {
ep[0] = yp[0];
......
......@@ -1253,6 +1253,7 @@ typedef struct PHY_VARS_eNB_s {
int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240];
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
uint8_t *FS6bufferZone;
} PHY_VARS_eNB;
......
......@@ -1417,7 +1417,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
pdu->rx_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
......
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