add prach
This commit is contained in:
+291
-133
@@ -1,4 +1,17 @@
|
||||
#include <stdint.h>
|
||||
#include <common/utils/LOG/log.h>
|
||||
#include <common/utils/system.h>
|
||||
#include <common/config/config_userapi.h>
|
||||
#include <targets/RT/USER/lte-softmodem.h>
|
||||
#include <openair1/PHY/defs_eNB.h>
|
||||
#include <openair1/PHY/phy_extern.h>
|
||||
#include <nfapi/oai_integration/vendor_ext.h>
|
||||
#include <openair1/SCHED/fapi_l1.h>
|
||||
#include <openair1/PHY/INIT/phy_init.h>
|
||||
#include <openair2/LAYER2/MAC/mac_extern.h>
|
||||
#include <openair1/PHY/LTE_REFSIG/lte_refsig.h>
|
||||
#include <nfapi/oai_integration/nfapi_pnf.h>
|
||||
#include <executables/split_headers.h>
|
||||
#include <nfapi/oai_integration/vendor_ext.h>
|
||||
#include <openair1/PHY/INIT/lte_init.c>
|
||||
#include <executables/split_headers.h>
|
||||
@@ -6,125 +19,214 @@
|
||||
#define FS6_BUF_SIZE 100*1000
|
||||
static UDPsock_t sockFS6;
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
int subframe;
|
||||
} fs6_ul_t;
|
||||
void prach_eNB_extract(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, int frame,int subframe) {
|
||||
commonUDP_t *UDPheader=(commonUDP_t *) bufferZone;
|
||||
fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone);
|
||||
|
||||
if (is_prach_subframe(&eNB->frame_parms, frame,subframe)<=0)
|
||||
return;
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
int subframe;
|
||||
int num_pdcch_symbols;
|
||||
int num_dci;
|
||||
int amp;
|
||||
bool UE_active[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PHICH phich_vars;
|
||||
} fs6_dl_t;
|
||||
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;
|
||||
|
||||
for (int i=0; i<eNB->num_RU; i++) {
|
||||
ru=eNB->RU_list[i];
|
||||
|
||||
#if 0
|
||||
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
|
||||
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
|
||||
int ce_level;
|
||||
|
||||
void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int harq_pid,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
LTE_eNB_DLSCH_t *dlsch1,
|
||||
LTE_eNB_UE_stats *ue_stats,
|
||||
int ra_flag) {
|
||||
int frame=proc->frame_tx;
|
||||
int subframe=proc->subframe_tx;
|
||||
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
|
||||
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
||||
|
||||
// 36-212
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
|
||||
// Replace dlsch_encoding
|
||||
// data is in
|
||||
// dlsch->harq_processes[harq_pid]->e
|
||||
feedDlschBuffers(eNB,
|
||||
dlsch_harq->pdu,
|
||||
dlsch_harq->pdsch_start,
|
||||
dlsch,
|
||||
frame,
|
||||
subframe,
|
||||
&eNB->dlsch_rate_matching_stats,
|
||||
&eNB->dlsch_turbo_encoding_stats,
|
||||
&eNB->dlsch_turbo_encoding_waiting_stats,
|
||||
&eNB->dlsch_turbo_encoding_main_stats,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats0,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats1,
|
||||
&eNB->dlsch_interleaving_stats);
|
||||
// 36-211
|
||||
dlsch_scrambling(fp,
|
||||
0,
|
||||
dlsch,
|
||||
harq_pid,
|
||||
get_G(fp,
|
||||
dlsch_harq->nb_rb,
|
||||
dlsch_harq->rb_alloc,
|
||||
dlsch_harq->Qm,
|
||||
dlsch_harq->Nl,
|
||||
dlsch_harq->pdsch_start,
|
||||
frame,subframe,
|
||||
0),
|
||||
0,
|
||||
frame,
|
||||
subframe<<1);
|
||||
dlsch_modulation(eNB,
|
||||
eNB->common_vars.txdataF,
|
||||
AMP,
|
||||
frame,
|
||||
subframe,
|
||||
dlsch_harq->pdsch_start,
|
||||
dlsch,
|
||||
dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
|
||||
for (ce_level=0; ce_level<4; ce_level++)
|
||||
eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa];
|
||||
}
|
||||
}
|
||||
|
||||
dlsch->active = 0;
|
||||
dlsch_harq->round++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void prach_eNB_extract(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe, uint8_t *buf, int bufSize) {
|
||||
commonUDP_t *header=(commonUDP_t *) buf;
|
||||
header->contentBytes=1000;
|
||||
header->nbBlocks=1;
|
||||
/* 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
|
||||
);
|
||||
*/
|
||||
// run PRACH detection for CE-level 0 only for now when br_flag is set
|
||||
rx_prach(eNB,
|
||||
eNB->RU_list[0],
|
||||
header->max_preamble,
|
||||
header->max_preamble_energy,
|
||||
header->max_preamble_delay,
|
||||
header->avg_preamble_energy,
|
||||
frame,
|
||||
0,
|
||||
true
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
void prach_eNB_process(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
|
||||
void prach_eNB_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
|
||||
commonUDP_t *UDPheader=(commonUDP_t *) bufferZone;
|
||||
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;
|
||||
// Fixme: not clear why we call twice with "br" and without
|
||||
int br_flag=1;
|
||||
|
||||
if (br_flag==1) {
|
||||
int prach_mask;
|
||||
prach_mask = is_prach_subframe (&eNB->frame_parms, eNB->proc.frame_prach_br, eNB->proc.subframe_prach_br);
|
||||
eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br;
|
||||
int ind = 0;
|
||||
int ce_level = 0;
|
||||
/* Save for later, it doesn't work
|
||||
for (int ind=0,ce_level=0;ce_level<4;ce_level++) {
|
||||
|
||||
if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1)&&
|
||||
(prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions
|
||||
(eNB->prach_vars_br.repetition_number[ce_level]==
|
||||
eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) {
|
||||
|
||||
*/
|
||||
|
||||
if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) {
|
||||
if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + eNB->prach_DTX_threshold_emtc[0])) {
|
||||
eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++;
|
||||
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].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",
|
||||
ind,
|
||||
ce_level,
|
||||
prach_mask,
|
||||
eNB->preamble_list_br[ind].preamble_rel8.timing_advance,
|
||||
eNB->preamble_list_br[ind].preamble_rel8.preamble, eNB->preamble_list_br[ind].preamble_rel8.rnti, eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ind++;
|
||||
}
|
||||
} */// ce_level
|
||||
} else if ((eNB->prach_energy_counter == 100) &&
|
||||
(max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) {
|
||||
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,
|
||||
max_preamble[0],
|
||||
max_preamble_energy[0]/10,
|
||||
max_preamble_energy[0]%10,
|
||||
max_preamble_delay[0]);
|
||||
pthread_mutex_lock(&eNB->UL_INFO_mutex);
|
||||
eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1;
|
||||
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->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_rel13.rach_resource_type = 0;
|
||||
eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MODE_PNF) { // If NFAPI PNF then we need to send the message to the VNF
|
||||
LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
|
||||
NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf),
|
||||
eNB->preamble_list[0].preamble_rel8.timing_advance,
|
||||
eNB->preamble_list[0].preamble_rel8.preamble,
|
||||
eNB->preamble_list[0].preamble_rel8.rnti,
|
||||
eNB->preamble_list[0].preamble_rel13.rach_resource_type);
|
||||
oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind);
|
||||
eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
|
||||
} // max_preamble_energy > prach_I0 + 100
|
||||
else {
|
||||
eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((avg_preamble_energy[0]*124)>>10);
|
||||
|
||||
if (eNB->prach_energy_counter < 100)
|
||||
eNB->prach_energy_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
void phy_procedures_eNB_uespec_RX_extract(uint8_t *buf, int bufSize, PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc) {
|
||||
//RX processing for ue-specific resources (i
|
||||
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
|
||||
const int subframe = proc->subframe_rx;
|
||||
const int frame = proc->frame_rx;
|
||||
/* TODO: use correct rxdata */
|
||||
T (T_ENB_PHY_INPUT_SIGNAL, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (0),
|
||||
T_BUFFER (&eNB->RU_list[0]->common.rxdata[0][subframe * eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti * 4));
|
||||
|
||||
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return;
|
||||
|
||||
T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 );
|
||||
LOG_D (PHY, "[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n", eNB->Mod_id, frame, subframe);
|
||||
eNB->rb_mask_ul[0] = 0;
|
||||
eNB->rb_mask_ul[1] = 0;
|
||||
eNB->rb_mask_ul[2] = 0;
|
||||
eNB->rb_mask_ul[3] = 0;
|
||||
// Fix me here, these should be locked
|
||||
eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0;
|
||||
eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0;
|
||||
// Call SRS first since all others depend on presence of SRS or lack thereof
|
||||
srs_procedures (eNB, proc);
|
||||
eNB->first_run_I0_measurements = 0;
|
||||
uci_procedures (eNB, proc);
|
||||
lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements);
|
||||
int min_I0=1000,max_I0=0;
|
||||
|
||||
if ((frame==0) && (subframe==4)) {
|
||||
for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) {
|
||||
if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
|
||||
|
||||
if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0)
|
||||
min_I0 = eNB->measurements.n0_subband_power_tot_dB[i];
|
||||
|
||||
if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0)
|
||||
max_I0 = eNB->measurements.n0_subband_power_tot_dB[i];
|
||||
}
|
||||
|
||||
LOG_I (PHY, "max_I0 %d, min_I0 %d\n", max_I0, min_I0);
|
||||
}
|
||||
|
||||
void phy_procedures_eNB_uespec_RX_extract(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc, uint8_t *buf, int bufSize) {
|
||||
commonUDP_t *header=(commonUDP_t *) buf;
|
||||
header->contentBytes=1000;
|
||||
header->nbBlocks=1;
|
||||
return;
|
||||
}
|
||||
|
||||
void phy_procedures_eNB_uespec_RX_process(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc) {
|
||||
void phy_procedures_eNB_uespec_RX_process(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc) {
|
||||
}
|
||||
|
||||
void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas ) {
|
||||
void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int do_meas ) {
|
||||
commonUDP_t *UDPheader=(commonUDP_t *) bufferZone;
|
||||
UDPheader->contentBytes=1000;
|
||||
UDPheader->nbBlocks=1;
|
||||
fs6_dl_t *header=(fs6_dl_t *) commonUDPdata(bufferZone);
|
||||
// TBD: read frame&subframe from received data
|
||||
int frame=proc->frame_tx;
|
||||
int subframe=proc->subframe_tx;
|
||||
uint32_t i,aa;
|
||||
uint8_t harq_pid;
|
||||
uint8_t num_pdcch_symbols=0;
|
||||
uint8_t num_dci=0;
|
||||
uint8_t num_mdci = 0;
|
||||
uint8_t ul_subframe;
|
||||
uint32_t ul_frame;
|
||||
int frame=proc->frame_tx=header->frame;
|
||||
int subframe=proc->subframe_tx=header->subframe;
|
||||
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
||||
LTE_UL_eNB_HARQ_t *ulsch_harq;
|
||||
|
||||
eNB->pdcch_vars[subframe&1].num_pdcch_symbols=header->num_pdcch_symbols;
|
||||
eNB->pdcch_vars[subframe&1].num_dci=header->num_dci;
|
||||
uint8_t num_mdci = eNB->mpdcch_vars[subframe&1].num_dci = header->num_mdci;
|
||||
|
||||
if (do_meas==1) {
|
||||
start_meas(&eNB->phy_proc_tx);
|
||||
@@ -132,7 +234,7 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eN
|
||||
}
|
||||
|
||||
// clear the transmit data array for the current subframe
|
||||
for (aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) {
|
||||
for (int aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) {
|
||||
memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)],
|
||||
0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
|
||||
}
|
||||
@@ -142,21 +244,20 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eN
|
||||
pmch_procedures(eNB,proc);
|
||||
} else {
|
||||
// this is not a pmch subframe, so generate PSS/SSS/PBCH
|
||||
common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx);
|
||||
common_signal_procedures(eNB,frame, subframe);
|
||||
}
|
||||
}
|
||||
|
||||
// clear existing ulsch dci allocations before applying info from MAC (this is table
|
||||
ul_subframe = pdcch_alloc2ul_subframe (fp, subframe);
|
||||
ul_frame = pdcch_alloc2ul_frame (fp, frame, subframe);
|
||||
|
||||
// clear previous allocation information for all UEs
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
if (eNB->dlsch[i][0])
|
||||
eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
|
||||
}
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
for (int i=0; i< header->num_dci; i++)
|
||||
eNB->pdcch_vars[subframe&1].dci_alloc[i]=header->dci_alloc[i];
|
||||
|
||||
generate_dci_top(header->num_pdcch_symbols,
|
||||
header->num_dci,
|
||||
&eNB->pdcch_vars[subframe&1].dci_alloc[0],
|
||||
@@ -165,7 +266,6 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eN
|
||||
fp,
|
||||
eNB->common_vars.txdataF,
|
||||
header->subframe);
|
||||
num_mdci = eNB->mpdcch_vars[subframe &1].num_dci;
|
||||
|
||||
if (num_mdci > 0) {
|
||||
LOG_D (PHY, "[eNB %" PRIu8 "] Frame %d, subframe %d: Calling generate_mdci_top (mpdcch) (num_dci %" PRIu8 ")\n", eNB->Mod_id, frame, subframe, num_mdci);
|
||||
@@ -177,6 +277,7 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eN
|
||||
if (header->UE_active[UE_id]) { // if we generate dlsch, we must generate pdsch
|
||||
LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0];
|
||||
LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[UE_id][1];
|
||||
int harq_pid=dlsch0->harq_ids[frame%2][subframe]=header->UE_active[UE_id];
|
||||
pdsch_procedures(eNB,
|
||||
proc,
|
||||
harq_pid,
|
||||
@@ -191,15 +292,32 @@ void phy_procedures_eNB_TX_process(uint8_t *bufferZone, int bufSize, PHY_VARS_eN
|
||||
AMP);
|
||||
}
|
||||
|
||||
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) {
|
||||
void appendFs6DLUE(uint8_t *bufferZone, uint8_t *UEdata, int UEdataLen) {
|
||||
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++;
|
||||
}
|
||||
|
||||
AssertFatal(firstFreeByte+UEdataLen+sizeof(fs6_dl_t) <= bufferZone+FS6_BUF_SIZE, "");
|
||||
commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte;
|
||||
FirstUDPheader->nbBlocks++;
|
||||
newUDPheader->blockID=curBlock;
|
||||
newUDPheader->contentBytes=sizeof(fs6_dl_t)+UEdataLen;
|
||||
// We skip the fs6 DL header, that is populated by caller
|
||||
// This header will be duplicated during sending
|
||||
memcpy(commonUDPdata(firstFreeByte+sizeof(fs6_dl_t)), UEdata, UEdataLen);
|
||||
}
|
||||
|
||||
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) {
|
||||
fs6_dl_t *header=(fs6_dl_t *) commonUDPdata(bufferZone);
|
||||
int frame=proc->frame_tx;
|
||||
int subframe=proc->subframe_tx;
|
||||
uint32_t i,aa;
|
||||
uint8_t harq_pid;
|
||||
uint8_t num_pdcch_symbols=0;
|
||||
uint8_t num_dci=0;
|
||||
uint8_t num_mdci = 0;
|
||||
uint8_t ul_subframe;
|
||||
uint32_t ul_frame;
|
||||
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
||||
@@ -215,7 +333,7 @@ void phy_procedures_eNB_TX_extract(uint8_t bufferZone, PHY_VARS_eNB *eNB, L1_rxt
|
||||
ul_frame = pdcch_alloc2ul_frame (fp, frame, subframe);
|
||||
|
||||
// clear previous allocation information for all UEs
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
if (eNB->dlsch[i][0])
|
||||
eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
|
||||
}
|
||||
@@ -224,8 +342,11 @@ void phy_procedures_eNB_TX_extract(uint8_t bufferZone, PHY_VARS_eNB *eNB, L1_rxt
|
||||
//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 scheduled here
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
|
||||
for (int i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
int harq_pid;
|
||||
|
||||
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0)
|
||||
harq_pid = 0;
|
||||
else
|
||||
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
|
||||
|
||||
@@ -255,13 +376,15 @@ void phy_procedures_eNB_TX_extract(uint8_t bufferZone, PHY_VARS_eNB *eNB, L1_rxt
|
||||
}
|
||||
}
|
||||
|
||||
num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols;
|
||||
num_dci = eNB->pdcch_vars[subframe&1].num_dci;
|
||||
uint8_t num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols;
|
||||
uint8_t num_dci = eNB->pdcch_vars[subframe&1].num_dci;
|
||||
uint8_t num_mdci = eNB->mpdcch_vars[subframe&1].num_dci;
|
||||
LOG_D(PHY,"num_pdcch_symbols %"PRIu8",number dci %"PRIu8"\n",num_pdcch_symbols, num_dci);
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
header->num_pdcch_symbols=num_pdcch_symbols;
|
||||
header->num_dci=num_dci;
|
||||
header->num_mdci=num_mdci;
|
||||
header->amp=AMP;
|
||||
}
|
||||
|
||||
@@ -270,11 +393,11 @@ void phy_procedures_eNB_TX_extract(uint8_t bufferZone, PHY_VARS_eNB *eNB, L1_rxt
|
||||
if (do_meas==1) start_meas(&eNB->dlsch_ue_specific);
|
||||
|
||||
// Now scan UE specific DLSCH
|
||||
LTE_eNB_DLSCH_t *dlsch0,*dlsch1;
|
||||
LTE_eNB_DLSCH_t *dlsch0;
|
||||
|
||||
for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
|
||||
dlsch0 = eNB->dlsch[UE_id][0];
|
||||
dlsch1 = eNB->dlsch[UE_id][1];
|
||||
header->UE_active[UE_id]=-1;
|
||||
|
||||
if ((dlsch0)&&(dlsch0->rnti>0)&&
|
||||
#ifdef PHY_TX_THREAD
|
||||
@@ -284,7 +407,7 @@ void phy_procedures_eNB_TX_extract(uint8_t bufferZone, PHY_VARS_eNB *eNB, L1_rxt
|
||||
#endif
|
||||
) {
|
||||
// get harq_pid
|
||||
harq_pid = dlsch0->harq_ids[frame%2][subframe];
|
||||
int harq_pid = dlsch0->harq_ids[frame%2][subframe];
|
||||
AssertFatal(harq_pid>=0,"harq_pid is negative\n");
|
||||
|
||||
if (harq_pid>=8) {
|
||||
@@ -299,14 +422,37 @@ void phy_procedures_eNB_TX_extract(uint8_t bufferZone, PHY_VARS_eNB *eNB, L1_rxt
|
||||
dlsch0->harq_ids[frame%2][6],
|
||||
dlsch0->harq_ids[frame%2][7]);
|
||||
} else {
|
||||
header->UE_active[UE_id]=true;
|
||||
header->UE_active[UE_id]=harq_pid;
|
||||
|
||||
if (dlsch_procedures(eNB,
|
||||
proc,
|
||||
harq_pid,
|
||||
dlsch0,
|
||||
&eNB->UE_stats[(uint32_t)UE_id])) {
|
||||
append(UEdata);
|
||||
// data in: dlsch0 harq_processes[harq_pid]->e
|
||||
/* length
|
||||
get_G(fp,
|
||||
dlsch_harq->nb_rb,
|
||||
dlsch_harq->rb_alloc,
|
||||
dlsch_harq->Qm,
|
||||
dlsch_harq->Nl,
|
||||
dlsch_harq->pdsch_start,
|
||||
frame,subframe,
|
||||
0)
|
||||
need harq_pid
|
||||
*/
|
||||
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch0->harq_processes[harq_pid];
|
||||
appendFs6DLUE(bufferZone,
|
||||
dlsch0->harq_processes[harq_pid]->e,
|
||||
get_G(fp,
|
||||
dlsch_harq->nb_rb,
|
||||
dlsch_harq->rb_alloc,
|
||||
dlsch_harq->Qm,
|
||||
dlsch_harq->Nl,
|
||||
dlsch_harq->pdsch_start,
|
||||
frame,subframe,
|
||||
0)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
|
||||
@@ -334,9 +480,13 @@ void DL_du_fs6(RU_t *ru, int frame, int subframe, uint64_t TS) {
|
||||
RU_proc_t *ru_proc=&ru->proc;
|
||||
|
||||
for (int i=0; i<ru->num_eNB; i++) {
|
||||
uint8_t bufferZone[FS6_BUF_SIZE];
|
||||
receiveSubFrame(&sockFS6, TS, bufferZone, sizeof(bufferZone) );
|
||||
phy_procedures_eNB_TX_process( bufferZone, sizeof(bufferZone), ru->eNB_list[i], &ru->eNB_list[i]->proc.L1_proc, 1);
|
||||
initBufferZone(bufferZone);
|
||||
int nb_blocks=receiveSubFrame(&sockFS6, TS, bufferZone, sizeof(bufferZone) );
|
||||
|
||||
if (nb_blocks>0)
|
||||
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: %d\n", subframe);
|
||||
}
|
||||
|
||||
/* Fixme: datamodel issue: a ru is supposed to be connected to several eNB
|
||||
@@ -371,15 +521,15 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) {
|
||||
oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
|
||||
}
|
||||
|
||||
uint8_t bufferZone[FS6_BUF_SIZE];
|
||||
prach_eNB_extract(eNB,NULL,proc->frame_rx,proc->subframe_rx, bufferZone, FS6_BUF_SIZE);
|
||||
initBufferZone(bufferZone);
|
||||
prach_eNB_extract(bufferZone, FS6_BUF_SIZE, eNB, proc->frame_rx,proc->subframe_rx );
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
phy_procedures_eNB_uespec_RX_extract(eNB, &proc->L1_proc, bufferZone, FS6_BUF_SIZE);
|
||||
phy_procedures_eNB_uespec_RX_extract(bufferZone, FS6_BUF_SIZE, eNB, &proc->L1_proc );
|
||||
}
|
||||
|
||||
for (int i=0; i<ru->num_eNB; i++) {
|
||||
sendSubFrame(&sockFS6,bufferZone);
|
||||
sendSubFrame(&sockFS6,bufferZone, sizeof(fs6_ul_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,28 +544,36 @@ void DL_cu_fs6(RU_t *ru,int frame, int subframe) {
|
||||
eNB->UL_INFO.CC_id = eNB->CC_id;
|
||||
eNB->if_inst->UL_indication(&eNB->UL_INFO);
|
||||
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
|
||||
uint8_t bufferZone[FS6_BUF_SIZE];
|
||||
initBufferZone(bufferZone);
|
||||
phy_procedures_eNB_TX_extract(bufferZone, eNB, &proc->L1_proc, 1, bufferZone, FS6_BUF_SIZE);
|
||||
sendSubFrame(&sockFS6, bufferZone );
|
||||
commonUDP_t *firstHeader=(commonUDP_t *) bufferZone;
|
||||
|
||||
if (firstHeader->nbBlocks==0) {
|
||||
firstHeader->nbBlocks=1; // We have to send the signaling, even is there is no user plan data (no UE)
|
||||
firstHeader->blockID=0;
|
||||
firstHeader->contentBytes=sizeof(fs6_dl_t);
|
||||
}
|
||||
|
||||
sendSubFrame(&sockFS6, bufferZone, sizeof(fs6_dl_t) );
|
||||
}
|
||||
|
||||
void UL_cu_fs6(RU_t *ru,int frame, int subframe, uint64_t TS) {
|
||||
uint8_t bufferZone[FS6_BUF_SIZE];
|
||||
receiveSubFrame(&sockFS6, TS, bufferZone, sizeof(bufferZone) );
|
||||
initBufferZone(bufferZone);
|
||||
int nb_blocks=receiveSubFrame(&sockFS6, TS, bufferZone, sizeof(bufferZone) );
|
||||
// Fixme: datamodel issue
|
||||
PHY_VARS_eNB *eNB = RC.eNB[0][0];
|
||||
L1_proc_t *proc = &eNB->proc;
|
||||
prach_eNB_process(eNB,NULL,proc->frame_rx,proc->subframe_rx);
|
||||
prach_eNB_process(bufferZone, sizeof(bufferZone), eNB,NULL,proc->frame_rx,proc->subframe_rx);
|
||||
release_UE_in_freeList(eNB->Mod_id);
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
phy_procedures_eNB_uespec_RX_process(eNB, &proc->L1_proc);
|
||||
phy_procedures_eNB_uespec_RX_process(bufferZone, sizeof(bufferZone), eNB, &proc->L1_proc);
|
||||
}
|
||||
}
|
||||
|
||||
void *cu_fs6(void *arg) {
|
||||
RU_t *ru = (RU_t *)arg;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
//RU_proc_t *proc = &ru->proc;
|
||||
int64_t AbsoluteSubframe=-1;
|
||||
fill_rf_config(ru,ru->rf_config_file);
|
||||
init_frame_parms(&ru->frame_parms,1);
|
||||
@@ -436,7 +594,7 @@ void *cu_fs6(void *arg) {
|
||||
|
||||
void *du_fs6(void *arg) {
|
||||
RU_t *ru = (RU_t *)arg;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
//RU_proc_t *proc = &ru->proc;
|
||||
int64_t AbsoluteSubframe=-1;
|
||||
fill_rf_config(ru,ru->rf_config_file);
|
||||
init_frame_parms(&ru->frame_parms,1);
|
||||
|
||||
@@ -34,17 +34,44 @@ typedef struct frequency_s {
|
||||
int nbSamples;
|
||||
} frequency_t;
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
int subframe;
|
||||
uint16_t max_preamble[4];
|
||||
uint16_t max_preamble_energy[4];
|
||||
uint16_t max_preamble_delay[4];
|
||||
uint16_t avg_preamble_energy[4];
|
||||
} fs6_ul_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
int subframe;
|
||||
int num_pdcch_symbols;
|
||||
int num_dci;
|
||||
DCI_ALLOC_t dci_alloc[32];
|
||||
int num_mdci;
|
||||
int amp;
|
||||
bool UE_active[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PHICH phich_vars;
|
||||
} fs6_dl_t;
|
||||
|
||||
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result);
|
||||
int receiveSubFrame(UDPsock_t *sock, uint64_t expectedTS, void *bufferZone, int bufferSize);
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone);
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize);
|
||||
|
||||
inline size_t alignedSize(void *ptr) {
|
||||
#define initBufferZone(xBuf) \
|
||||
uint8_t xBuf[FS6_BUF_SIZE];\
|
||||
((commonUDP_t *)xBuf)->nbBlocks=0;
|
||||
|
||||
|
||||
inline size_t alignedSize(uint8_t *ptr) {
|
||||
commonUDP_t *header=(commonUDP_t *) ptr;
|
||||
return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign;
|
||||
}
|
||||
|
||||
inline void * commonUDPdata(void* ptr) {
|
||||
return (void*) (((commonUDP_t*)ptr)+1);
|
||||
inline void *commonUDPdata(uint8_t *ptr) {
|
||||
return (void *) (((commonUDP_t *)ptr)+1);
|
||||
}
|
||||
|
||||
void *cu_fs6(void *arg);
|
||||
@@ -54,7 +81,16 @@ void rx_rf(RU_t *ru,int *frame,int *subframe);
|
||||
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);
|
||||
|
||||
bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int harq_pid,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
LTE_eNB_UE_stats *ue_stats) ;
|
||||
void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int harq_pid,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
LTE_eNB_DLSCH_t *dlsch1);
|
||||
// mistakes in main OAI
|
||||
void phy_init_RU(RU_t *);
|
||||
void feptx_prec(RU_t *);
|
||||
|
||||
@@ -99,11 +99,20 @@ int receiveSubFrame(UDPsock_t *sock, uint64_t expectedTS, void *bufferZone, int
|
||||
return rcved;
|
||||
}
|
||||
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone) {
|
||||
commonUDP_t *header=(commonUDP_t *)bufferZone ;
|
||||
int nbBlocks=header->nbBlocks;
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize) {
|
||||
commonUDP_t *UDPheader=(commonUDP_t *)bufferZone ;
|
||||
int nbBlocks=UDPheader->nbBlocks;
|
||||
int blockId=0;
|
||||
|
||||
do {
|
||||
if (blockId > 0 ) {
|
||||
commonUDP_t *currentHeader=(commonUDP_t *)bufferZone;
|
||||
*currentHeader=*UDPheader;
|
||||
currentHeader->blockID=blockId;
|
||||
memcpy(commonUDPdata((void *)currentHeader), commonUDPdata(bufferZone), secondHeaderSize);
|
||||
blockId++;
|
||||
}
|
||||
|
||||
int sz=alignedSize(bufferZone);
|
||||
// Let's use the first address returned by getaddrinfo()
|
||||
int ret=sendto(sock->sockHandler, bufferZone, sz, 0,
|
||||
|
||||
Reference in New Issue
Block a user