Commit 025f56d2 authored by Raymond Knopp's avatar Raymond Knopp

node function interfaces via function pointers. Suggestions from L. Thomas, B. Mongazon, C. Roux.

parent f33e9a70
......@@ -1167,7 +1167,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
frame_parms->phich_config_common.phich_duration);
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_eNB][MOD %02"PRIu8"][]\n", eNB->Mod_id);
if (eNB->node_function != NGFI_RRU_IF4) {
if (eNB->node_function != NGFI_RRU_IF4p5) {
lte_gold(frame_parms,eNB->lte_gold_table,frame_parms->Nid_cell);
generate_pcfich_reg_mapping(frame_parms);
generate_phich_reg_mapping(frame_parms);
......@@ -1191,12 +1191,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
if (abstraction_flag==0) {
// TX vars
if (eNB->node_function != NGFI_RCC_IF4)
if (eNB->node_function != NGFI_RCC_IF4p5)
common_vars->txdata[eNB_id] = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
common_vars->txdataF[eNB_id] = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
if (eNB->node_function != NGFI_RCC_IF4)
if (eNB->node_function != NGFI_RCC_IF4p5)
common_vars->txdata[eNB_id][i] = (int32_t*)malloc16_clear( FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(int32_t) );
common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear( FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t) );
#ifdef DEBUG_PHY
......@@ -1208,14 +1208,14 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
}
// RX vars
if (eNB->node_function != NGFI_RCC_IF4) {
if (eNB->node_function != NGFI_RCC_IF4p5) {
common_vars->rxdata[eNB_id] = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
common_vars->rxdata_7_5kHz[eNB_id] = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
}
common_vars->rxdataF[eNB_id] = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
if (eNB->node_function != NGFI_RCC_IF4) {
if (eNB->node_function != NGFI_RCC_IF4p5) {
common_vars->rxdata[eNB_id][i] = (int32_t*)malloc16_clear( FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(int32_t) );
common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( frame_parms->samples_per_tti*sizeof(int32_t) );
}
......@@ -1227,7 +1227,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
#endif
}
if (eNB->node_function != NGFI_RRU_IF4) {
if (eNB->node_function != NGFI_RRU_IF4p5) {
// Channel estimates for SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
......@@ -1250,7 +1250,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
if (abstraction_flag==0) {
if (eNB->node_function != NGFI_RRU_IF4) {
if (eNB->node_function != NGFI_RRU_IF4p5) {
generate_ul_ref_sigs_rx();
// SRS
......@@ -1264,7 +1264,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
// ULSCH VARS, skip if NFGI_RRU_IF4
if (eNB->node_function!=NGFI_RRU_IF4)
if (eNB->node_function!=NGFI_RRU_IF4p5)
prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) );
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
......@@ -1277,7 +1277,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
#endif
}
if (eNB->node_function != NGFI_RRU_IF4) {
if (eNB->node_function != NGFI_RRU_IF4p5) {
AssertFatal(frame_parms->nb_antennas_rx <= sizeof(prach_vars->prach_ifft) / sizeof(prach_vars->prach_ifft[0]),
"nb_antennas_rx too large");
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
......@@ -1399,7 +1399,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
eNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
init_prach_tables(839);
} // node_function != NGFI_RRU_IF4
} // node_function != NGFI_RRU_IF4p5
return (0);
}
......
......@@ -42,9 +42,9 @@
#include "PHY/TOOLS/alaw_lut.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) {
void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int32_t **txdataF = eNB->common_vars.txdataF[0];
int32_t **rxdataF = eNB->common_vars.rxdataF[0];
......@@ -57,16 +57,18 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
uint16_t *data_block=NULL, *i=NULL;
if (packet_type == IF4_PDLFFT) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
if (packet_type == IF4p5_PDLFFT) {
db_fulllength = 12*fp->N_RB_DL;
db_halflength = (db_fulllength)>>1;
slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
IF4_header_t *dl_header = (IF4_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
IF4p5_header_t *dl_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
gen_IF4_dl_header(dl_header, frame, subframe);
gen_IF4p5_dl_header(dl_header, frame, subframe);
for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
......@@ -86,23 +88,23 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
&tx_buffer,
db_fulllength,
1,
IF4_PDLFFT)) < 0) {
perror("ETHERNET write for IF4_PDLFFT\n");
IF4p5_PDLFFT)) < 0) {
perror("ETHERNET write for IF4p5_PDLFFT\n");
}
slotoffsetF += fp->ofdm_symbol_size;
blockoffsetF += fp->ofdm_symbol_size;
}
} else if (packet_type == IF4_PULFFT) {
} else if (packet_type == IF4p5_PULFFT) {
db_fulllength = 12*fp->N_RB_UL;
db_halflength = (db_fulllength)>>1;
slotoffsetF = 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
IF4_header_t *ul_header = (IF4_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
IF4p5_header_t *ul_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
gen_IF4_ul_header(ul_header, frame, subframe);
gen_IF4p5_ul_header(ul_header, frame, subframe);
for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
......@@ -122,23 +124,23 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
&tx_buffer,
db_fulllength,
1,
IF4_PULFFT)) < 0) {
perror("ETHERNET write for IF4_PULFFT\n");
IF4p5_PULFFT)) < 0) {
perror("ETHERNET write for IF4p5_PULFFT\n");
}
slotoffsetF += fp->ofdm_symbol_size;
blockoffsetF += fp->ofdm_symbol_size;
}
} else if (packet_type == IF4_PRACH) {
} else if (packet_type == IF4p5_PRACH) {
// FIX: hard coded prach samples length
db_fulllength = 839*2;
IF4_header_t *prach_header = (IF4_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
IF4p5_header_t *prach_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
gen_IF4_prach_header(prach_header, frame, subframe);
gen_IF4p5_prach_header(prach_header, frame, subframe);
memcpy((int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t),
memcpy((int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t),
(&rxsigF[0][k]),
db_fulllength*sizeof(int16_t));
......@@ -147,18 +149,19 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
&tx_buffer,
db_fulllength,
1,
IF4_PRACH)) < 0) {
perror("ETHERNET write for IF4_PRACH\n");
IF4p5_PRACH)) < 0) {
perror("ETHERNET write for IF4p5_PRACH\n");
}
} else {
AssertFatal(1==0, "send_IF4 - Unknown packet_type %x", packet_type);
AssertFatal(1==0, "send_IF4p5 - Unknown packet_type %x", packet_type);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
return;
}
void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_type, uint32_t *symbol_number) {
void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_type, uint32_t *symbol_number) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int32_t **txdataF = eNB->common_vars.txdataF[0];
int32_t **rxdataF = eNB->common_vars.rxdataF[0];
......@@ -168,15 +171,17 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
uint16_t element_id;
uint16_t db_fulllength, db_halflength;
int slotoffsetF=0, blockoffsetF=0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
if (eNB->node_function == NGFI_RRU_IF4) {
if (eNB->node_function == NGFI_RRU_IF4p5) {
db_fulllength = (12*fp->N_RB_DL);
} else {
db_fulllength = (12*fp->N_RB_UL);
}
db_halflength = db_fulllength>>1;
IF4_header_t *packet_header=NULL;
IF4p5_header_t *packet_header=NULL;
uint16_t *data_block=NULL, *i=NULL;
if (eNB->ifdevice.trx_read_func(&eNB->ifdevice,
......@@ -187,13 +192,13 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
perror("ETHERNET read");
}
packet_header = (IF4_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4_header_t);
packet_header = (IF4p5_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t);
*frame = ((packet_header->frame_status)>>6)&0xffff;
*subframe = ((packet_header->frame_status)>>22)&0x000f;
if (*packet_type == IF4_PDLFFT) {
if (*packet_type == IF4p5_PDLFFT) {
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
......@@ -209,7 +214,7 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
*(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
}
} else if (*packet_type == IF4_PULFFT) {
} else if (*packet_type == IF4p5_PULFFT) {
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + 1;
......@@ -225,25 +230,26 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
*(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
}
} else if (*packet_type == IF4_PRACH) {
} else if (*packet_type == IF4p5_PRACH) {
// FIX: hard coded prach samples length
db_fulllength = 839*2;
memcpy((&rxsigF[0][0]),
(int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4_header_t),
(int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t),
db_fulllength*sizeof(int16_t));
} else {
AssertFatal(1==0, "recv_IF4 - Unknown packet_type %x", *packet_type);
AssertFatal(1==0, "recv_IF4p5 - Unknown packet_type %x", *packet_type);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
return;
}
void gen_IF4_dl_header(IF4_header_t *dl_packet, int frame, int subframe) {
dl_packet->type = IF4_PACKET_TYPE;
dl_packet->sub_type = IF4_PDLFFT;
void gen_IF4p5_dl_header(IF4p5_header_t *dl_packet, int frame, int subframe) {
dl_packet->type = IF4p5_PACKET_TYPE;
dl_packet->sub_type = IF4p5_PDLFFT;
dl_packet->rsvd = 0;
......@@ -254,9 +260,9 @@ void gen_IF4_dl_header(IF4_header_t *dl_packet, int frame, int subframe) {
}
void gen_IF4_ul_header(IF4_header_t *ul_packet, int frame, int subframe) {
ul_packet->type = IF4_PACKET_TYPE;
ul_packet->sub_type = IF4_PULFFT;
void gen_IF4p5_ul_header(IF4p5_header_t *ul_packet, int frame, int subframe) {
ul_packet->type = IF4p5_PACKET_TYPE;
ul_packet->sub_type = IF4p5_PULFFT;
ul_packet->rsvd = 0;
......@@ -267,9 +273,9 @@ void gen_IF4_ul_header(IF4_header_t *ul_packet, int frame, int subframe) {
}
void gen_IF4_prach_header(IF4_header_t *prach_packet, int frame, int subframe) {
prach_packet->type = IF4_PACKET_TYPE;
prach_packet->sub_type = IF4_PRACH;
void gen_IF4p5_prach_header(IF4p5_header_t *prach_packet, int frame, int subframe) {
prach_packet->type = IF4p5_PACKET_TYPE;
prach_packet->sub_type = IF4p5_PRACH;
prach_packet->rsvd = 0;
......@@ -280,8 +286,8 @@ void gen_IF4_prach_header(IF4_header_t *prach_packet, int frame, int subframe) {
}
void malloc_IF4_buffer(PHY_VARS_eNB *eNB) {
void malloc_IF4p5_buffer(PHY_VARS_eNB *eNB) {
// Keep the size large enough
eNB->ifbuffer.tx = malloc(RAW_IF4_PRACH_SIZE_BYTES);
eNB->ifbuffer.rx = malloc(RAW_IF4_PRACH_SIZE_BYTES);
eNB->ifbuffer.tx = malloc(RAW_IF4p5_PRACH_SIZE_BYTES);
eNB->ifbuffer.rx = malloc(RAW_IF4p5_PRACH_SIZE_BYTES);
}
......@@ -41,12 +41,12 @@
#include "PHY/defs.h"
/// Macro for IF4 packet type
#define IF4_PACKET_TYPE 0x080A
#define IF4_PULFFT 0x0019
#define IF4_PDLFFT 0x0020
#define IF4_PRACH 0x0021
#define IF4p5_PACKET_TYPE 0x080A
#define IF4p5_PULFFT 0x0019
#define IF4p5_PDLFFT 0x0020
#define IF4p5_PRACH 0x0021
struct IF4_header {
struct IF4p5_header {
/// Type
uint16_t type;
/// Sub-Type
......@@ -58,17 +58,17 @@ struct IF4_header {
} __attribute__ ((__packed__));
typedef struct IF4_header IF4_header_t;
#define sizeof_IF4_header_t 12
typedef struct IF4p5_header IF4p5_header_t;
#define sizeof_IF4p5_header_t 12
void gen_IF4_dl_header(IF4_header_t*, int, int);
void gen_IF4p5_dl_header(IF4p5_header_t*, int, int);
void gen_IF4_ul_header(IF4_header_t*, int, int);
void gen_IF4p5_ul_header(IF4p5_header_t*, int, int);
void gen_IF4_prach_header(IF4_header_t*, int, int);
void gen_IF4p5_prach_header(IF4p5_header_t*, int, int);
void send_IF4(PHY_VARS_eNB*, int, int, uint16_t, int);
void send_IF4p5(PHY_VARS_eNB*, int, int, uint16_t, int);
void recv_IF4(PHY_VARS_eNB*, int*, int*, uint16_t*, uint32_t*);
void recv_IF4p5(PHY_VARS_eNB*, int*, int*, uint16_t*, uint32_t*);
void malloc_IF4_buffer(PHY_VARS_eNB*);
void malloc_IF4p5_buffer(PHY_VARS_eNB*);
......@@ -41,7 +41,7 @@
#include "PHY/defs.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe, uint8_t *seqno, uint16_t packet_type) {
......@@ -54,6 +54,8 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
uint32_t spp_eth = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_packet;
uint32_t spsf = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
if (packet_type == IF5_RRH_GW_DL) {
for (i=0; i < fp->nb_antennas_tx; i++)
......@@ -143,6 +145,8 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
}
free(tx_buffer);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
return;
}
......@@ -158,6 +162,8 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
int32_t spsf = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10;
openair0_timestamp timestamp[spsf / spp_eth];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
if (packet_type == IF5_RRH_GW_DL) {
......@@ -205,6 +211,8 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
} else {
AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );
return;
}
......@@ -1424,8 +1424,7 @@ void rx_phich(PHY_VARS_UE *ue,
void generate_phich_top(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
int16_t amp,
uint8_t sect_id,
uint8_t abstraction_flag)
uint8_t sect_id)
{
......@@ -1486,7 +1485,7 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
ulsch[UE_id]->harq_processes[harq_pid]->first_rb);
}
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
generate_phich(frame_parms,
amp,//amp*2,
nseq_PHICH,
......
......@@ -190,7 +190,7 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par
return(0);
}
void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx, int abstraction_flag)
void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx)
{
LTE_eNB_DLSCH_t *dlsch = eNB->dlsch_MCH;
......@@ -227,7 +227,7 @@ void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx, int abstrac
break;
}
if (abstraction_flag) {
if (eNB->abstraction_flag) {
eNB_transport_info[eNB->Mod_id][eNB->CC_id].cntl.pmch_flag=1;
eNB_transport_info[eNB->Mod_id][eNB->CC_id].num_pmch=1; // assumption: there is always one pmch in each SF
eNB_transport_info[eNB->Mod_id][eNB->CC_id].num_common_dci=0;
......@@ -286,13 +286,13 @@ void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id)
}
}
void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a,int abstraction_flag)
void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a)
{
int G;
int subframe = proc->subframe_tx;
if (abstraction_flag != 0) {
if (eNB->abstraction_flag != 0) {
if (eNB_transport_info_TB_index[eNB->Mod_id][eNB->CC_id]!=0)
printf("[PHY][EMU] PMCH transport block position is different than zero %d \n", eNB_transport_info_TB_index[eNB->Mod_id][eNB->CC_id]);
......
......@@ -1183,7 +1183,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
if ((eNB->node_function == eNodeB_3GPP) ||
(eNB->node_function == NGFI_RRU_IF4)) { // compute the DFTs of the PRACH temporal resources
(eNB->node_function == NGFI_RRU_IF4p5)) { // compute the DFTs of the PRACH temporal resources
// Do forward transform
for (aa=0; aa<nb_ant_rx; aa++) {
prach2 = prach[aa] + (Ncp<<1);
......@@ -1269,7 +1269,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
}
}
if (eNB->node_function == NGFI_RRU_IF4) {
if (eNB->node_function == NGFI_RRU_IF4p5) {
k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
if (k<0) {
......@@ -1281,12 +1281,10 @@ void rx_prach(PHY_VARS_eNB *eNB,
k*=2;
/// **** send_IF4 of rxsigF to RCC **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
send_IF4(eNB, eNB->proc.frame_rx, eNB->proc.subframe_rx, IF4_PRACH, k);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
send_IF4p5(eNB, eNB->proc.frame_rx, eNB->proc.subframe_rx, IF4p5_PRACH, k);
return;
} else if (eNB->node_function == NGFI_RCC_IF4) {
} else if (eNB->node_function == NGFI_RCC_IF4p5) {
k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
if (k<0) {
......@@ -1305,7 +1303,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
// in case of RCC and prach received rx_thread wakes up prach
// here onwards is for eNodeB_3GPP or NGFI_RCC_IF4
// here onwards is for eNodeB_3GPP or NGFI_RCC_IF4p5
preamble_offset_old = 99;
......
......@@ -232,7 +232,7 @@ int mch_modulation(int32_t **txdataF,
@param abstraction_flag
*/
void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a,int abstraction_flag);
void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a);
/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals)
@param phy_vars_eNB Pointer to eNB variables
......@@ -240,10 +240,8 @@ void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a,in
@param mcs MCS for MBSFN
@param ndi new data indicator
@param rdvix
@param abstraction_flag
*/
void fill_eNB_dlsch_MCH(PHY_VARS_eNB *phy_vars_eNB,int mcs,int ndi,int rvidx,int abstraction_flag);
void fill_eNB_dlsch_MCH(PHY_VARS_eNB *phy_vars_eNB,int mcs,int ndi,int rvidx);
/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals)
@param phy_vars_ue Pointer to UE variables
......@@ -1546,8 +1544,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB,
void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
eNB_rxtx_proc_t *proc,
int16_t amp,
uint8_t sect_id,
uint8_t abstraction_flag);
uint8_t sect_id);
/* \brief This routine demodulates the PHICH and updates PUSCH/ULSCH parameters.
@param phy_vars_ue Pointer to UE variables
......
......@@ -161,8 +161,9 @@ typedef enum {
eNodeB_3GPP=0, // classical eNodeB function
eNodeB_3GPP_BBU, // eNodeB with NGFI IF5
NGFI_RRU_IF5, // NGFI_RRU with IF5
NGFI_RRU_IF4, // NGFI_RRU (NGFI remote radio-unit, currently split at common - ue_specific interface, IF4)
NGFI_RCC_IF4 // NGFI_RCC (NGFI radio cloud center, currently split at common - ue_specific interface, IF4)
NGFI_RRU_IF4p5, // NGFI_RRU (NGFI remote radio-unit, currently split at common - ue_specific interface, IF4p5)
NGFI_RCC_IF4p5, // NGFI_RCC (NGFI radio cloud center, currently split at common - ue_specific interface, IF4p5)
NGFI_RAU_IF4p5
} eNB_func_t;
typedef enum {
......@@ -187,6 +188,20 @@ typedef struct ral_threshold_phy_s {
} ral_threshold_phy_t;
#endif
/// Top-level PHY Data Structure for RN
typedef struct {
/// Module ID indicator for this instance
uint8_t Mod_id;
uint32_t frame;
// phy_vars_eNB
// phy_vars ue
// cuurently only used to store and forward the PMCH
uint8_t mch_avtive[10];
uint8_t sync_area[10]; // num SF
LTE_UE_DLSCH_t *dlsch_rn_MCH[10];
} PHY_VARS_RN;
/// Context data structure for RX/TX portion of subframe processing
typedef struct {
/// Component Carrier index
......@@ -340,6 +355,15 @@ typedef struct PHY_VARS_eNB_s {
eNB_proc_t proc;
eNB_func_t node_function;
eNB_timing_t node_timing;
int abstraction_flag;
void (*do_prach)(struct PHY_VARS_eNB_s *eNB,eNB_proc_t *proc);
void (*fep)(struct PHY_VARS_eNB_s *eNB,eNB_proc_t *proc);
void (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type);
void (*proc_tx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *rn);
void (*tx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc);
void (*rx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_proc_t *proc,int *frame, int *subframe);
int (*start_rf)(struct PHY_VARS_eNB_s *eNB);
int (*start_if)(struct PHY_VARS_eNB_s *eNB);
uint8_t local_flag;
uint32_t rx_total_gain_dB;
LTE_DL_FRAME_PARMS frame_parms;
......@@ -785,19 +809,7 @@ typedef struct {
#endif
} PHY_VARS_UE;
/// Top-level PHY Data Structure for RN
typedef struct {
/// Module ID indicator for this instance
uint8_t Mod_id;
uint32_t frame;
// phy_vars_eNB
// phy_vars ue
// cuurently only used to store and forward the PMCH
uint8_t mch_avtive[10];
uint8_t sync_area[10]; // num SF
LTE_UE_DLSCH_t *dlsch_rn_MCH[10];
} PHY_VARS_RN;
#include "PHY/INIT/defs.h"
#include "PHY/LTE_REFSIG/defs.h"
......
......@@ -164,20 +164,18 @@ void phy_procedures_UE_S_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abst
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
@param phy_vars_rn pointer to the RN variables
*/
void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
/*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes.
@param phy_vars_eNB Pointer to eNB variables on which to act
@param proc Pointer to RXn-TXnp4 proc information
@param abstraction_flag Indicator of PHY abstraction
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type);
void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type);
/*! \brief Scheduling for eNB TX procedures in TDD S-subframes.
@param phy_vars_eNB Pointer to eNB variables on which to act
@param proc Pointer to RXn-TXnp4 proc information
@param abstraction_flag Indicator of PHY abstraction
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
......@@ -185,29 +183,26 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *pr
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
*/
void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag);
void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB);
/*! \brief Scheduling for eNB TX procedures in TDD S-subframes.
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type);
void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB,relaying_type_t r_type);
/*! \brief Scheduling for eNB RX procedures in TDD S-subframes.
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type);
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type);
/*! \brief Scheduling for eNB PRACH RX procedures
@param phy_vars_eNB Pointer to eNB variables on which to act
@param proc Pointer to RXn-TXnp4 proc information
@param abstraction_flag Indicator of PHY abstraction
*/
void prach_procedures(PHY_VARS_eNB *eNB,uint8_t abstraction_flag);
void prach_procedures(PHY_VARS_eNB *eNB);
/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
@param frame_parms Pointer to DL frame parameter descriptor
......
......@@ -180,7 +180,7 @@ int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
uint8_t i;
int j,CC_id;
int CC_id;
PHY_VARS_eNB *eNB;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
......@@ -295,7 +295,7 @@ void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *eNB)
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type)
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type)
{
UNUSED(r_type);
int subframe = proc->subframe_rx;
......@@ -305,7 +305,7 @@ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t abs
#endif
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
lte_eNB_I0_measurements(eNB,
subframe,
0,
......@@ -392,7 +392,7 @@ unsigned int taus(void);
DCI_PDU DCI_pdu_tmp;
void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn, int abstraction_flag,relaying_type_t r_type) {
void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,relaying_type_t r_type) {
#ifdef Rel10
......@@ -403,7 +403,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn, in
int subframe = proc->subframe_tx;
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
// This is DL-Cell spec pilots in Control region
generate_pilots_slot(eNB,
eNB->common_vars.txdataF[0],
......@@ -464,9 +464,9 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn, in
}// switch
if (mch_pduP) {
fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0, abstraction_flag);
fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0);
// Generate PMCH
generate_mch(eNB,proc,(uint8_t*)mch_pduP->payload,abstraction_flag);
generate_mch(eNB,proc,(uint8_t*)mch_pduP->payload);
} else {
LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",proc->frame_tx,subframe);
}
......@@ -474,7 +474,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn, in
#endif
}
void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstraction_flag) {
void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
int **txdataF = eNB->common_vars.txdataF[0];
......@@ -483,7 +483,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
int frame = proc->frame_tx;
// generate Cell-Specific Reference Signals for both slots
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
generate_pilots_slot(eNB,
txdataF,
......@@ -502,7 +502,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
// First half of PSS/SSS (FDD, slot 0)
if (subframe == 0) {
if ((fp->frame_type == FDD) &&
(abstraction_flag==0)) {
(eNB->abstraction_flag==0)) {
generate_pss(txdataF,
AMP,
fp,
......@@ -585,7 +585,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
/// First half of SSS (TDD, slot 1)
if ((fp->frame_type == TDD)&&
(abstraction_flag==0)){
(eNB->abstraction_flag==0)){
generate_sss(txdataF,
AMP,
fp,
......@@ -594,7 +594,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
}
/// generate PBCH
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
generate_pbch(&eNB->pbch,
txdataF,
AMP,
......@@ -611,7 +611,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
}
else if ((subframe == 1) &&
(fp->frame_type == TDD)&&
(abstraction_flag==0)) {
(eNB->abstraction_flag==0)) {
generate_pss(txdataF,
AMP,
fp,
......@@ -622,7 +622,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
// Second half of PSS/SSS (FDD, slot 10)
else if ((subframe == 5) &&
(fp->frame_type == FDD) &&
(abstraction_flag==0)) {
(eNB->abstraction_flag==0)) {
generate_pss(txdataF,
AMP,
&eNB->frame_parms,
......@@ -639,7 +639,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
// Second-half of SSS (TDD, slot 11)
else if ((subframe == 5) &&
(fp->frame_type == TDD) &&
(abstraction_flag==0)) {
(eNB->abstraction_flag==0)) {
generate_sss(txdataF,
AMP,
fp,
......@@ -650,7 +650,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstr
// Second half of PSS (TDD, slot 12)
else if ((subframe == 6) &&
(fp->frame_type == TDD) &&
(abstraction_flag==0)) {
(eNB->abstraction_flag==0)) {
generate_pss(txdataF,
AMP,
fp,
......@@ -867,7 +867,7 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
}
void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols,int abstraction_flag) {
void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols) {
int frame=proc->frame_tx;
int subframe=proc->subframe_tx;
......@@ -1025,7 +1025,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
#endif
}
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag);
// 36-212
......@@ -1083,7 +1083,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
uint8_t abstraction_flag,
relaying_type_t r_type,
PHY_VARS_RN *rn)
{
......@@ -1145,7 +1144,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
// clear the transmit data array for the current subframe
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
for (aa=0; aa<fp->nb_antennas_tx_eNB; aa++) {
memset(&eNB->common_vars.txdataF[0][aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)],
0,fp->ofdm_symbol_size*(fp->symbols_per_tti)*sizeof(int32_t));
......@@ -1153,11 +1152,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
if (is_pmch_subframe(frame,subframe,fp)) {
pmch_procedures(eNB,proc,rn,abstraction_flag,r_type);
pmch_procedures(eNB,proc,rn,r_type);
}
else {
// this is not a pmch subframe, so generate PSS/SSS/PBCH
common_signal_procedures(eNB,proc,abstraction_flag);
common_signal_procedures(eNB,proc);
}
#if defined(SMBV)
......@@ -1283,7 +1282,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
eNB->num_common_dci[(subframe)&1]=0;
}
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0) {
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",eNB->Mod_id,frame, subframe,
......@@ -1316,7 +1315,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
if ((eNB->dlsch_SI) && (eNB->dlsch_SI->active == 1)) {
pdsch_procedures(eNB,proc,eNB->dlsch_SI,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,0,num_pdcch_symbols,abstraction_flag);
pdsch_procedures(eNB,proc,eNB->dlsch_SI,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,0,num_pdcch_symbols);
#if defined(SMBV)
......@@ -1349,7 +1348,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
eNB->ulsch[(uint32_t)UE_id]->Msg3_frame,
eNB->ulsch[(uint32_t)UE_id]->Msg3_subframe);
pdsch_procedures(eNB,proc,eNB->dlsch_ra,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,1,num_pdcch_symbols,abstraction_flag);
pdsch_procedures(eNB,proc,eNB->dlsch_ra,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,1,num_pdcch_symbols);
eNB->dlsch_ra->active = 0;
......@@ -1362,7 +1361,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
(eNB->dlsch[(uint8_t)UE_id][0]->rnti>0)&&
(eNB->dlsch[(uint8_t)UE_id][0]->active == 1)) {
pdsch_procedures(eNB,proc,eNB->dlsch[(uint8_t)UE_id][0],eNB->dlsch[(uint8_t)UE_id][1],&eNB->UE_stats[(uint32_t)UE_id],0,num_pdcch_symbols,abstraction_flag);
pdsch_procedures(eNB,proc,eNB->dlsch[(uint8_t)UE_id][0],eNB->dlsch[(uint8_t)UE_id][1],&eNB->UE_stats[(uint32_t)UE_id],0,num_pdcch_symbols);
}
......@@ -1385,8 +1384,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
generate_phich_top(eNB,
proc,
AMP,
0,
abstraction_flag);
0);
}
......@@ -1395,24 +1393,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
phy_procedures_emos_eNB_TX(subframe, eNB);
#endif
#if !(defined(EXMIMO) || defined(OAI_USRP) || defined (CPRIGW))
if (abstraction_flag==0)
{
start_meas(&eNB->ofdm_mod_stats);
do_OFDM_mod(eNB->common_vars.txdataF[0],
eNB->common_vars.txdata[0],
frame,subframe<<1,
fp);
do_OFDM_mod(eNB->common_vars.txdataF[0],
eNB->common_vars.txdata[0],
frame,1+(subframe<<1),
fp);
stop_meas(&eNB->ofdm_mod_stats);
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(subframe&1),0);
stop_meas(&eNB->phy_proc_tx);
......@@ -1869,8 +1849,7 @@ void get_n1_pucch_eNB(PHY_VARS_eNB *eNB,
}
}
void prach_procedures(PHY_VARS_eNB *eNB,uint8_t abstraction_flag)
{
void prach_procedures(PHY_VARS_eNB *eNB) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
uint16_t preamble_energy_list[64],preamble_delay_list[64];
......@@ -1881,10 +1860,11 @@ void prach_procedures(PHY_VARS_eNB *eNB,uint8_t abstraction_flag)
int frame = eNB->proc.frame_prach;
uint8_t CC_id = eNB->CC_id;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
memset(&preamble_energy_list[0],0,64*sizeof(uint16_t));
memset(&preamble_delay_list[0],0,64*sizeof(uint16_t));
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",eNB->Mod_id,
frame,subframe,dB_fixed(signal_energy(&eNB->common_vars.rxdata[0][0][subframe*fp->samples_per_tti],512)) - eNB->rx_total_gain_dB);
......@@ -1984,9 +1964,10 @@ void prach_procedures(PHY_VARS_eNB *eNB,uint8_t abstraction_flag)
eNB->Mod_id,frame, subframe);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
}
void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid,const uint8_t abstraction_flag) {
void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0};
......@@ -2059,7 +2040,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
eNB->UE_stats[UE_id].sr_total++;
if (abstraction_flag == 0)
if (eNB->abstraction_flag == 0)
metric0_SR = rx_pucch(eNB,
pucch_format1,
UE_id,
......@@ -2115,7 +2096,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload);
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
......@@ -2160,7 +2141,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload);
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
......@@ -2236,7 +2217,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
#endif
if (abstraction_flag == 0)
if (eNB->abstraction_flag == 0)
metric0_SR = rx_pucch(eNB,
format,
UE_id,
......@@ -2268,7 +2249,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
// Check n1_pucch0 metric
if (n1_pucch0 != -1) {
if (abstraction_flag == 0)
if (eNB->abstraction_flag == 0)
metric0 = rx_pucch(eNB,
format,
UE_id,
......@@ -2293,7 +2274,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
// Check n1_pucch1 metric
if (n1_pucch1 != -1) {
if (abstraction_flag == 0)
if (eNB->abstraction_flag == 0)
metric1 = rx_pucch(eNB,
format,
UE_id,
......@@ -2350,7 +2331,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
}
void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid,const uint8_t abstraction_flag) {
void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid) {
uint8_t access_mode;
int num_active_cba_groups;
......@@ -2375,7 +2356,7 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p
UE_id, (uint16_t)eNB->ulsch[UE_id]->cba_rnti[UE_id%num_active_cba_groups],mode_string[eNB->UE_stats[UE_id].mode]);
#endif
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
rx_ulsch(eNB,proc,
eNB->UE_stats[UE_id].sector, // this is the effective sector id
UE_id,
......@@ -2392,7 +2373,7 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p
#endif
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
ret = ulsch_decoding(eNB,proc,
UE_id,
0, // control_only_flag
......@@ -2509,116 +2490,121 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p
}
void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_flag) {
void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
int l;
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1);
remove_7_5_kHz(eNB,proc->subframe_rx<<1);
remove_7_5_kHz(eNB,1+(proc->subframe_rx<<1));
for (l=0; l<fp->symbols_per_tti/2; l++) {
slot_fep_ul(fp,
&eNB->common_vars,
l,
proc->subframe_rx<<1,
0,
0
);
slot_fep_ul(fp,
&eNB->common_vars,
l,
1+(proc->subframe_rx<<1),
0,
0
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0);
if (eNB->node_function == NGFI_RRU_IF4p5) {
/// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
send_IF4p5(eNB, proc->frame_rx, proc->subframe_rx, IF4p5_PULFFT, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
}
}
void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
uint8_t seqno=0;
/// **** send_IF5 of rxdata to BBU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
}
void do_prach(PHY_VARS_eNB *eNB,eNB_proc_t *proc) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
// check if we have to detect PRACH first
if (is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0) {
/* accept some delay in processing - up to 5ms */
int i;
for (i = 0; i < 10 && proc->instance_cnt_prach == 0; i++) {
LOG_W(PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
usleep(500);
}
if (proc->instance_cnt_prach == 0) {
exit_fun( "PRACH thread busy" );
return;
}
// wake up thread for PRACH RX
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach );
exit_fun( "error locking mutex_prach" );
return;
}
++proc->instance_cnt_prach;
// set timing for prach thread
proc->frame_prach = proc->frame_rx;
proc->subframe_prach = proc->subframe_rx;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index);
exit_fun( "ERROR pthread_cond_signal" );
return;
}
pthread_mutex_unlock( &proc->mutex_prach );
}
}
void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB){
eNB_proc_t *proc = &eNB->proc;
const int subframe = proc->subframe_rx;
const int frame = proc->frame_rx;
uint8_t seqno=0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+(subframe&1), 1 );
start_meas(&eNB->phy_proc_rx);
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe);
#endif
if (abstraction_flag==0) {
if ((eNB->node_function == NGFI_RRU_IF4) ||
(eNB->node_function == eNodeB_3GPP) ||
(eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing
// now do common RX processing for first slot in subframe
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1);
remove_7_5_kHz(eNB,proc->subframe_rx<<1);
remove_7_5_kHz(eNB,1+(proc->subframe_rx<<1));
for (l=0; l<fp->symbols_per_tti/2; l++) {
slot_fep_ul(fp,
&eNB->common_vars,
l,
proc->subframe_rx<<1,
0,
0
);
slot_fep_ul(fp,
&eNB->common_vars,
l,
1+(proc->subframe_rx<<1),
0,
0
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0);
if (eNB->fep) eNB->fep(eNB,proc);
if (eNB->node_function == NGFI_RRU_IF4) {
/// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
send_IF4(eNB, proc->frame_rx, proc->subframe_rx, IF4_PULFFT, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
}
}
else if (eNB->node_function == NGFI_RRU_IF5) {
/// **** send_IF5 of rxdata to BBU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
}
/// **** send_IF4 of prach to RCC **** /// done in prach thread (below)
// check if we have to detect PRACH first
if ((eNB->node_function != NGFI_RRU_IF5) &&
(is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0)) { // any other node must call prach procedure
/* accept some delay in processing - up to 5ms */
int i;
for (i = 0; i < 10 && proc->instance_cnt_prach == 0; i++) {
LOG_W(PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
usleep(500);
}
if (proc->instance_cnt_prach == 0) {
exit_fun( "PRACH thread busy" );
return;
}
// wake up thread for PRACH RX
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach );
exit_fun( "error locking mutex_prach" );
return;
}
++proc->instance_cnt_prach;
// set timing for prach thread
proc->frame_prach = proc->frame_rx;
proc->subframe_prach = proc->subframe_rx;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index);
exit_fun( "ERROR pthread_cond_signal" );
return;
}
pthread_mutex_unlock( &proc->mutex_prach );
}
} else { // grab transport channel information from network interface
if (eNB->do_prach) eNB->do_prach(eNB,proc);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+(subframe&1), 0 );
}
void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const uint8_t abstraction_flag,const relaying_type_t r_type)
void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type)
{
//RX processing for ue-specific resources (i
UNUSED(r_type);
......@@ -2664,7 +2650,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
// Do PUCCH processing first
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
pucch_procedures(eNB,proc,i,harq_pid,abstraction_flag);
pucch_procedures(eNB,proc,i,harq_pid);
}
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
......@@ -2749,7 +2735,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
eNB->pusch_stats_mcs[i][(frame*10)+subframe] = eNB->ulsch[i]->harq_processes[harq_pid]->mcs;
start_meas(&eNB->ulsch_demodulation_stats);
if (abstraction_flag==0) {
if (eNB->abstraction_flag==0) {
rx_ulsch(eNB,proc,
eNB->UE_stats[i].sector, // this is the effective sector id
i,
......@@ -2770,7 +2756,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
start_meas(&eNB->ulsch_decoding_stats);
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
ret = ulsch_decoding(eNB,proc,
i,
0, // control_only_flag
......@@ -3082,7 +3068,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
} // Msg3_flag == 0
// estimate timing advance for MAC
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
sync_pos = lte_est_timing_advance_pusch(eNB,i);
eNB->UE_stats[i].timing_advance_update = sync_pos - fp->nb_prefix_samples/4; //to check
}
......@@ -3169,10 +3155,10 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
}
// CBA (non-LTE)
cba_procedures(eNB,proc,i,harq_pid,abstraction_flag);
cba_procedures(eNB,proc,i,harq_pid);
} // loop i=0 ... NUMBER_OF_UE_MAX-1
if (abstraction_flag == 0) {
if (eNB->abstraction_flag == 0) {
lte_eNB_I0_measurements(eNB,
subframe,
0,
......
......@@ -887,10 +887,12 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
enb_properties.properties[enb_properties_index]->cc_node_function[j] = eNodeB_3GPP;
} else if (strcmp(cc_node_function, "eNodeB_3GPP_BBU") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = eNodeB_3GPP_BBU;
} else if (strcmp(cc_node_function, "NGFI_RCC_IF4") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = NGFI_RCC_IF4;
} else if (strcmp(cc_node_function, "NGFI_RRU_IF4") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = NGFI_RRU_IF4;
} else if (strcmp(cc_node_function, "NGFI_RCC_IF4p5") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = NGFI_RCC_IF4p5;
} else if (strcmp(cc_node_function, "NGFI_RAU_IF4p5") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = NGFI_RAU_IF4p5;
} else if (strcmp(cc_node_function, "NGFI_RRU_IF4p5") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = NGFI_RRU_IF4p5;
} else if (strcmp(cc_node_function, "NGFI_RRU_IF5") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_function[j] = NGFI_RRU_IF5;
} else {
......
......@@ -201,7 +201,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi
int trx_eth_write_raw_IF4(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
int nblocks = nsamps;
int bytes_sent = 0;
......@@ -211,14 +211,14 @@ int trx_eth_write_raw_IF4(openair0_device *device, openair0_timestamp timestamp,
ssize_t packet_size;
if (flags == IF4_PDLFFT) {
packet_size = RAW_IF4_PDLFFT_SIZE_BYTES(nblocks);
} else if (flags == IF4_PULFFT) {
packet_size = RAW_IF4_PULFFT_SIZE_BYTES(nblocks);
if (flags == IF4p5_PDLFFT) {
packet_size = RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks);
} else if (flags == IF4p5_PULFFT) {
packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);
} else if (flags == IF5_MOBIPASS) {
packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
} else {
packet_size = RAW_IF4_PRACH_SIZE_BYTES;
packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
}
eth->tx_nsamps = nblocks;
......@@ -304,7 +304,7 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi
int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
// Read nblocks info from packet itself
int nblocks = nsamps;
......@@ -312,8 +312,8 @@ int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp,
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t;
IF4_header_t *test_header = (IF4_header_t*)(buff[0] + MAC_HEADER_SIZE_BYTES);
ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t;
IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0] + MAC_HEADER_SIZE_BYTES);
bytes_received = recv(eth->sockfd[Mod_id],
buff[0],
......@@ -327,12 +327,12 @@ int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp,
*timestamp = test_header->sub_type;
if (test_header->sub_type == IF4_PDLFFT) {
packet_size = RAW_IF4_PDLFFT_SIZE_BYTES(nblocks);
} else if (test_header->sub_type == IF4_PULFFT) {
packet_size = RAW_IF4_PULFFT_SIZE_BYTES(nblocks);
if (test_header->sub_type == IF4p5_PDLFFT) {
packet_size = RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks);
} else if (test_header->sub_type == IF4p5_PULFFT) {
packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);
} else {
packet_size = RAW_IF4_PRACH_SIZE_BYTES;
packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
}
while(bytes_received < packet_size) {
......@@ -387,7 +387,7 @@ int eth_set_dev_conf_raw(openair0_device *device) {
int eth_set_dev_conf_raw_IF4(openair0_device *device) {
int eth_set_dev_conf_raw_IF4p5(openair0_device *device) {
// use for cc_id info
int Mod_id = device->Mod_id;
......@@ -448,7 +448,7 @@ int eth_get_dev_conf_raw(openair0_device *device) {
}
int eth_get_dev_conf_raw_IF4(openair0_device *device) {
int eth_get_dev_conf_raw_IF4p5(openair0_device *device) {
// use for cc_id info
eth_state_t *eth = (eth_state_t*)device->priv;
......
......@@ -73,27 +73,27 @@ int trx_eth_start(openair0_device *device) {
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
} else if (eth->flags == ETH_RAW_IF4_MODE) {
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
if (eth_socket_init_raw(device)!=0) return -1;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if (device->host_type == BBU_HOST) {
if(eth_set_dev_conf_raw_IF4(device)!=0) return -1;
if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1;
} else {
if(eth_get_dev_conf_raw_IF4(device)!=0) return -1;
if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1;
}
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,RAW_IF4_PRACH_SIZE_BYTES)!=0) return -1;
if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
} else if (eth->flags == ETH_UDP_IF4_MODE) {
} else if (eth->flags == ETH_UDP_IF4p5_MODE) {
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
if (eth_socket_init_raw(device)!=0) return -1;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
//if (device->host_type == BBU_HOST) {
//if(eth_set_dev_conf_raw_IF4(device)!=0) return -1;
//if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1;
//} else {
//if(eth_get_dev_conf_raw_IF4(device)!=0) return -1;
//if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1;
//
/* adjust MTU wrt number of samples per packet */
// if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
......@@ -339,9 +339,9 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
} else if (eth_params->transp_preference == 0) {
eth->flags = ETH_UDP_MODE;
} else if (eth_params->transp_preference == 3) {
eth->flags = ETH_RAW_IF4_MODE;
eth->flags = ETH_RAW_IF4p5_MODE;
} else if (eth_params->transp_preference == 2) {
eth->flags = ETH_UDP_IF4_MODE;
eth->flags = ETH_UDP_IF4p5_MODE;
} else if (eth_params->transp_preference == 4) {
eth->flags = ETH_RAW_IF5_MOBIPASS;
} else {
......@@ -368,15 +368,15 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
} else if (eth->flags == ETH_UDP_MODE) {
device->trx_write_func = trx_eth_write_udp;
device->trx_read_func = trx_eth_read_udp;
} else if (eth->flags == ETH_RAW_IF4_MODE) {
device->trx_write_func = trx_eth_write_raw_IF4;
device->trx_read_func = trx_eth_read_raw_IF4;
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF4p5;
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
device->trx_write_func = trx_eth_write_raw_IF4;
device->trx_read_func = trx_eth_read_raw_IF4;
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF4p5;
} else {
//device->trx_write_func = trx_eth_write_udp_IF4;
//device->trx_read_func = trx_eth_read_udp_IF4;
//device->trx_write_func = trx_eth_write_udp_IF4p5;
//device->trx_read_func = trx_eth_read_udp_IF4p5;
}
eth->if_name[device->Mod_id] = eth_params->local_if_name;
......
......@@ -222,11 +222,11 @@ int eth_set_dev_conf_udp(openair0_device *device);
int eth_socket_init_raw(openair0_device *device);
int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_raw_IF4(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int eth_get_dev_conf_raw(openair0_device *device);
int eth_set_dev_conf_raw(openair0_device *device);
int eth_get_dev_conf_raw_IF4(openair0_device *device);
int eth_set_dev_conf_raw_IF4(openair0_device *device);
int eth_get_dev_conf_raw_IF4p5(openair0_device *device);
int eth_set_dev_conf_raw_IF4p5(openair0_device *device);
#endif
......@@ -47,8 +47,8 @@
// ETH transport preference modes
#define ETH_UDP_MODE 0
#define ETH_RAW_MODE 1
#define ETH_UDP_IF4_MODE 2
#define ETH_RAW_IF4_MODE 3
#define ETH_UDP_IF4p5_MODE 2
#define ETH_RAW_IF4p5_MODE 3
#define ETH_RAW_IF5_MOBIPASS 4
// Time domain RRH packet sizes
......@@ -58,13 +58,13 @@
#define UDP_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
#define RAW_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
// Packet sizes for IF4 interface format
// Packet sizes for IF4p5 interface format
#define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(uint16_t)*scaled_nblocks)
#define PRACH_BLOCK_SIZE_BYTES (sizeof(int16_t)*839*2) // FIX hard coded prach size (uncompressed)
#define RAW_IF4_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + PRACH_BLOCK_SIZE_BYTES)
#define RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4p5_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
// Mobipass packet sizes
#define RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES 1280
......
......@@ -173,6 +173,8 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
int len,len2;
int16_t *txdata;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
slot_offset_F = (subframe<<1)*slot_sizeF;
slot_offset = subframe*phy_vars_eNB->frame_parms.samples_per_tti;
......@@ -284,8 +286,101 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
}
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
}
void tx_fh_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
uint8_t seqno;
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL);
}
void tx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
send_IF4p5(eNB,proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0);
}
void proc_tx_full(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
uint8_t abstraction_flag,
relaying_type_t r_type,
PHY_VARS_RN *rn) {
phy_procedures_eNB_TX(eNB,proc,r_type,rn);
/* we're done, let the next one proceed */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add");
}
sync_phy_proc.phy_proc_CC_id++;
sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs;
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add");
}
do_OFDM_mod_rt(proc->subframe_tx,eNB);
if (eNB->tx_fh) eNB->tx_fh(eNB,proc);
}
void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
uint32_t symbol_number=0;
uint32_t symbol_mask, symbol_mask_full;
uint16_t packet_type;
/// **** recv_IF4 of txdataF from RCC **** ///
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = (1<<eNB->frame_parms.symbols_per_tti)-1;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
do {
recv_IF4p5(eNB, &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
symbol_mask = symbol_mask | (1<<symbol_number);
} while (symbol_mask != symbol_mask_full);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
do_OFDM_mod_rt(proc->subframe_tx, eNB);
}
void proc_tx_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
/// **** recv_IF5 of txdata from BBU **** ///
recv_IF5(eNB, &proc->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL);
}
int wait_CCs(eNB_rxtx_proc_t *proc) {
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx,&wait) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add");
return(-1);
}
// wait for our turn or oai_exit
while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) {
pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx,
&sync_phy_proc.mutex_phy_proc_tx);
}
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add");
return(-1);
}
return(0);
}
/*!
* \brief The RX UE-specific and TX thread of eNB.
......@@ -297,14 +392,16 @@ static void* eNB_thread_rxtx( void* param ) {
static int eNB_thread_rxtx_status;
eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
FILE *tx_time_file = NULL;
char tx_time_name[101];
void *txp[PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx];
void *txp[fp->nb_antennas_tx];
int txs;
uint16_t packet_type;
uint32_t symbol_number=0;
uint32_t symbol_mask, symbol_mask_full;
uint8_t seqno=0;
......@@ -435,6 +532,7 @@ static void* eNB_thread_rxtx( void* param ) {
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
start_meas( &softmodem_stats_rxtx_sf );
if (oai_exit) break;
......@@ -443,158 +541,31 @@ static void* eNB_thread_rxtx( void* param ) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB+(proc->subframe_rx&1), proc->subframe_rx );
// Common procedures
phy_procedures_eNB_common_RX(PHY_vars_eNB_g[0][proc->CC_id], 0);
// UE-specific RX processing for subframe n
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RCC_IF4)) {
// this is the ue-specific processing for the subframe and can be multi-threaded later
phy_procedures_eNB_uespec_RX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay );
}
phy_procedures_eNB_common_RX(eNB);
// Do UE-specific RX processing for subframe n if any
if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay );
// TX processing for subframe n+4
if (((PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.frame_type == TDD) &&
((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->frame_parms,proc->subframe_tx) == SF_DL) ||
(subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->frame_parms,proc->subframe_tx) == SF_S))) ||
(PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.frame_type == FDD)) {
if (((fp->frame_type == TDD) &&
((subframe_select(fp,proc->subframe_tx) == SF_DL) ||
(subframe_select(fp,proc->subframe_tx) == SF_S))) ||
(fp->frame_type == FDD)) {
/* run PHY TX procedures the one after the other for all CCs to avoid race conditions
* (may be relaxed in the future for performance reasons)
*/
if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx,&wait) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add");
break;
}
// wait for our turn or oai_exit
while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) {
pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx,
&sync_phy_proc.mutex_phy_proc_tx);
}
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add");
}
if (wait_CCs(proc)<0) break;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+(proc->subframe_tx&1), proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+(proc->subframe_tx&1), proc->subframe_tx );
if (oai_exit) break;
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RCC_IF4)) {
phy_procedures_eNB_TX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay, NULL );
/* we're done, let the next one proceed */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add");
break;
}
sync_phy_proc.phy_proc_CC_id++;
sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs;
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add");
break;
}
} else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) {
/// **** recv_IF4 of txdataF from RCC **** ///
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = (1<<PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.symbols_per_tti)-1;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
do {
recv_IF4(PHY_vars_eNB_g[0][proc->CC_id], &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
symbol_mask = symbol_mask | (1<<symbol_number);
} while (symbol_mask != symbol_mask_full);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
} else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF5) {
/// **** recv_IF5 of txdata from BBU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
recv_IF5(PHY_vars_eNB_g[0][proc->CC_id], &proc->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );
}
}
// eNodeB_3GPP, _BBU and RRU create txdata
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
}
/*
short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti];
int i;
for (i=0;i<PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti*2;i+=8) {
txdata[i] = 2047;
txdata[i+1] = 0;
txdata[i+2] = 0;
txdata[i+3] = 2047;
txdata[i+4] = -2047;
txdata[i+5] = 0;
txdata[i+6] = 0;
txdata[i+7] = -2047; }
*/
/*
// eNodeB_3GPP, RRU write to RF device
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF5)) {
// Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
int i;
for (i=0; i<PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][i][proc->subframe_tx*PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti];
txs = PHY_vars_eNB_g[0][proc->CC_id]->rfdevice.trx_write_func(&PHY_vars_eNB_g[0][proc->CC_id]->rfdevice,
(proc->timestamp_tx-openair0_cfg[0].tx_sample_advance),
txp,
PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti,
PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx,
1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff );
if (txs != PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti);
exit_fun( "problem transmitting samples" );
}
}
*/
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) {
/// **** send_IF5 of txdata to RRH **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
send_IF5(PHY_vars_eNB_g[0][proc->CC_id], proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
} else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RCC_IF4) {
/// **** send_IF4 of txdataF to RRU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
send_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc->frame_tx, proc->subframe_tx, IF4_PDLFFT, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
if (eNB->proc_tx) eNB->proc_tx(eNB, proc, no_relay, NULL );
}
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB TX proc\n");
exit_fun("nothing to add");
......@@ -611,13 +582,14 @@ static void* eNB_thread_rxtx( void* param ) {
stop_meas( &softmodem_stats_rxtx_sf );
#ifdef DEADLINE_SCHEDULER
if (opp_enabled){
#ifdef DEADLINE_SCHEDULER
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
}
}
#endif
}
print_meas_now(&softmodem_stats_rxtx_sf,"eNB_TX_SF",tx_time_file);
}
......@@ -807,10 +779,10 @@ static void* eNB_thread_asynch_rx( void* param ) {
}
} // eNodeB_3GPP_BBU
else if (eNB->node_function == NGFI_RCC_IF4) {
/// **** recv_IF4 of rxdataF from RRU **** ///
/// **** recv_IF4 of rxsigF from RRU **** ///
// get frame/subframe information from IF4 interface
else if (eNB->node_function == NGFI_RCC_IF4p5) {
/// **** recv_IF4p5 of rxdataF from RRU **** ///
/// **** recv_IF4p5 of rxsigF from RRU **** ///
// get frame/subframe information from IF4p5 interface
// timed loop (200 us)
symbol_number = 0;
......@@ -819,14 +791,12 @@ static void* eNB_thread_asynch_rx( void* param ) {
prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
recv_IF4(eNB, &frame_rx, &subframe_rx, &packet_type, &symbol_number);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
recv_IF4p5(eNB, &frame_rx, &subframe_rx, &packet_type, &symbol_number);
if (packet_type == IF4_PULFFT) {
if (packet_type == IF4p5_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;
} else if (packet_type == IF4_PRACH) {
} else if (packet_type == IF4p5_PRACH) {
prach_rx = 0;
}
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));
......@@ -845,6 +815,248 @@ static void* eNB_thread_asynch_rx( void* param ) {
}
void rx_rf(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame,int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx];
unsigned int rxs,txs;
int i;
if (proc->first_rx==0) {
// Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
for (i=0; i<fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+3)%10)*fp->samples_per_tti];
txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
txp,
fp->samples_per_tti,
fp->nb_antennas_tx,
1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
if (txs != fp->samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
exit_fun( "problem transmitting samples" );
}
}
for (i=0; i<fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
rxp,
fp->samples_per_tti,
fp->nb_antennas_rx);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
*frame = proc->frame_rx;
*subframe = proc->subframe_rx;
}
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
}
void rx_fh_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
if (proc->subframe_rx != subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
frame = proc->frame_rx;
subframe = proc->subframe_rx;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
}
void rx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_proc_t *proc,int *subframe,int *frame) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int prach_rx;
uint16_t packet_type;
uint32_t symbol_number=0;
uint32_t symbol_mask, symbol_mask_full;
symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
if (packet_type == IF4p5_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;
} else if (packet_type == IF4p5_PRACH) {
prach_rx = 0;
}
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
*frame = proc->frame_rx;
*subframe = proc->subframe_rx;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
}
int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *fp) {
int i;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
/* accept some delay in processing - up to 5ms */
for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx);
usleep(500);
}
if (proc_rxtx->instance_cnt_rxtx == 0) {
exit_fun( "TX thread busy" );
return(-1);
}
// wake up TX for subframe n+4
// lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
exit_fun( "error locking mutex_rxtx" );
return(-1);
}
++proc_rxtx->instance_cnt_rxtx;
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+3
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
// the thread can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
return(-1);
}
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
return(0);
}
void wakeup_slaves(eNB_proc_t *proc) {
int i;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
for (i=0;i<proc->num_slaves;i++) {
eNB_proc_t *slave_proc = proc->slave_proc[i];
// wake up slave FH thread
// lock the FH mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id);
exit_fun( "error locking mutex_rxtx" );
break;
}
int cnt_slave = ++slave_proc->instance_cnt_FH;
slave_proc->frame_rx = proc->frame_rx;
slave_proc->subframe_rx = proc->subframe_rx;
slave_proc->timestamp_rx = proc->timestamp_rx;
pthread_mutex_unlock( &slave_proc->mutex_FH );
if (cnt_slave == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&slave_proc->cond_FH) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id);
exit_fun( "ERROR pthread_cond_signal" );
break;
}
} else {
LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave);
exit_fun( "FH thread busy" );
break;
}
}
}
/*!
* \brief The Fronthaul thread of RRU/RAU/RCC/eNB
* In the case of RRU/eNB, handles interface with external RF
......@@ -859,19 +1071,15 @@ static void* eNB_thread_FH( void* param ) {
eNB_proc_t *proc = (eNB_proc_t*)param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx];
unsigned int rxs,txs;
FILE *rx_time_file = NULL;
char rx_time_name[101];
struct timespec wait;
int i;
int prach_rx;
uint16_t packet_type;
uint32_t symbol_number=0;
uint32_t symbol_mask, symbol_mask_full;
int i;
int subframe=0, frame=0;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
......@@ -994,32 +1202,16 @@ static void* eNB_thread_FH( void* param ) {
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif
// Create buffer for IF device and free when stopping
if (eNB->node_function == NGFI_RCC_IF4 || eNB->node_function == NGFI_RRU_IF4) {
malloc_IF4_buffer(eNB);
} else if (eNB->node_function == NGFI_RRU_IF5 || eNB->node_function == eNodeB_3GPP_BBU) {
//malloc_IF5_buffer(eNB);
} else {
eNB->ifbuffer.tx = NULL;
eNB->ifbuffer.rx = NULL;
}
// Start RF device if any
if (eNB->start_rf)
if (eNB->start_rf(eNB) != 0)
LOG_E(HW,"Could not start the RF device\n");
// Start IF device for this CC
if (eNB->node_function != eNodeB_3GPP) {
if (eNB->ifdevice.trx_start_func(&eNB->ifdevice) != 0 )
// Start IF device if any
if (eNB->start_if)
if (eNB->start_if(eNB) != 0)
LOG_E(HW,"Could not start the IF device\n");
}
// Start RF device for this CC
if ((eNB->node_function == eNodeB_3GPP) ||
(eNB->node_function == NGFI_RRU_IF4) ||
(eNB->node_function == NGFI_RRU_IF5)) {
if (eNB->rfdevice.trx_start_func(&eNB->rfdevice) != 0 )
LOG_E(HW,"Could not start the RF device\n");
}
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) {
......@@ -1035,7 +1227,7 @@ static void* eNB_thread_FH( void* param ) {
// This case is for synchronization to another thread
if ((eNB->node_timing == synch_to_other) &&
((eNB->node_function == NGFI_RCC_IF4) ||
((eNB->node_function == NGFI_RCC_IF4p5) ||
(eNB->node_function == eNodeB_3GPP_BBU))) {
//wait for event
......@@ -1056,232 +1248,24 @@ static void* eNB_thread_FH( void* param ) {
}
// Remaining cases are all for synchronization on FH interface
else if ((eNB->node_timing == synch_to_ext_device) &&
((eNB->node_function == NGFI_RRU_IF4) ||
(eNB->node_function == NGFI_RRU_IF5) ||
(eNB->node_function == eNodeB_3GPP))) { // acquisition from RF
if (proc->first_rx==0) {
// Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
for (i=0; i<PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][i][((proc->subframe_rx+3)%10)*fp->samples_per_tti];
txs = PHY_vars_eNB_g[0][proc->CC_id]->rfdevice.trx_write_func(&PHY_vars_eNB_g[0][proc->CC_id]->rfdevice,
proc->timestamp_rx+(3*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
txp,
fp->samples_per_tti,
fp->nb_antennas_tx,
1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
if (txs != PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
exit_fun( "problem transmitting samples" );
}
}
for (i=0; i<fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&proc->timestamp_rx,
rxp,
fp->samples_per_tti,
fp->nb_antennas_rx);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
if (proc->subframe_rx != subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
frame = proc->frame_rx;
subframe = proc->subframe_rx;
}
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
} // node_timing==synch_to_ext_device && node_function == RRU || eNodeB
else if ((eNB->node_timing == synch_to_ext_device) &&
(eNB->node_function == eNodeB_3GPP_BBU)) { // acquisition from IF
/// **** recv_IF5 of rxdata from RRH **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
recv_IF5(eNB, &proc->timestamp_rx, subframe, IF5_RRH_GW_UL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
if (proc->subframe_rx != subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
frame = proc->frame_rx;
subframe = proc->subframe_rx;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
} // eNodeB_3GPP_BBU && node_timing == synch_to_ext_device
else if ((eNB->node_timing == synch_to_ext_device) &&
(eNB->node_function == NGFI_RCC_IF4)) {
/// **** recv_IF4 of rxdataF from RRU **** ///
/// **** recv_IF4 of rxsigF from RRU **** ///
// timed loop (200 us)
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
recv_IF4(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
if (packet_type == IF4_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;
} else if (packet_type == IF4_PRACH) {
prach_rx = 0;
}
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));
if (proc->first_rx == 0) {
if (proc->subframe_rx != subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
frame = proc->frame_rx;
subframe = proc->subframe_rx;
}
else if ((eNB->node_timing == synch_to_ext_device) &&
(eNB->rx_fh))
eNB->rx_fh(eNB,proc,&frame,&subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
} // node_timing == synch_to_externs, node_function = NGFI_IF4
else { // should not get here
AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
AssertFatal(1==0, "Unknown fronthaul interface : eNB->node_function %d",eNB->node_function);
}
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
// At this point, all information for subframe has been received on FH interface
// If this proc is to provide synchronization, do so
for (i=0;i<proc->num_slaves;i++) {
eNB_proc_t *slave_proc = proc->slave_proc[i];
// wake up slave FH thread
// lock the FH mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id);
exit_fun( "error locking mutex_rxtx" );
break;
}
int cnt_slave = ++slave_proc->instance_cnt_FH;
slave_proc->frame_rx = proc->frame_rx;
slave_proc->subframe_rx = proc->subframe_rx;
slave_proc->timestamp_rx = proc->timestamp_rx;
pthread_mutex_unlock( &slave_proc->mutex_FH );
if (cnt_slave == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&slave_proc->cond_FH) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id);
exit_fun( "ERROR pthread_cond_signal" );
break;
}
} else {
LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave);
exit_fun( "FH thread busy" );
break;
}
}
wakeup_slaves(proc);
// wake up RXn_TXnp4 thread for the subframe
// choose even or odd thread for RXn-TXnp4 processing
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[proc->subframe_rx&1];
/* accept some delay in processing - up to 5ms */
for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx);
usleep(500);
}
if (proc_rxtx->instance_cnt_rxtx == 0) {
exit_fun( "TX thread busy" );
if (wakeup_rxtx(proc,&proc->proc_rxtx[proc->subframe_rx&1],fp) < 0)
break;
}
// wake up TX for subframe n+4
// lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
exit_fun( "error locking mutex_rxtx" );
break;
}
++proc_rxtx->instance_cnt_rxtx;
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+3
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
// the thread can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
break;
}
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
stop_meas( &softmodem_stats_rxtx_sf );
#ifdef DEADLINE_SCHEDULER
......@@ -1453,9 +1437,8 @@ static void* eNB_thread_prach( void* param ) {
break;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
prach_procedures(eNB,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
prach_procedures(eNB);
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n");
......@@ -1732,17 +1715,95 @@ void print_opp_meas(void) {
}
}
int start_if(PHY_VARS_eNB *eNB) {
return(eNB->ifdevice.trx_start_func(&eNB->ifdevice));
}
int start_rf(PHY_VARS_eNB *eNB) {
return(eNB->rfdevice.trx_start_func(&eNB->rfdevice));
}
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst) {
extern eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_proc_t *proc);
extern eNB_fep_full(PHY_VARS_eNB *eNB,eNB_proc_t *proc);
extern do_prach(PHY_VARS_eNB *eNB,eNB_proc_t *proc);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst) {
int CC_id;
int inst;
PHY_VARS_eNB *eNB;
for (inst=0;inst<nb_inst;inst++) {
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
PHY_vars_eNB_g[inst][CC_id]->node_function = node_function[CC_id];
PHY_vars_eNB_g[inst][CC_id]->node_timing = node_timing[CC_id];
eNB = PHY_vars_eNB_g[inst][CC_id];
eNB->node_function = node_function[CC_id];
eNB->node_timing = node_timing[CC_id];
eNB->abstraction_flag = 0;
LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]);
switch (node_function[CC_id]) {
case NGFI_RRU_IF5:
eNB->do_prach = NULL;
eNB->fep = eNB_fep_rru_if5;
eNB->proc_uespec_rx = NULL;
eNB->proc_tx = NULL;
eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf;
eNB->start_rf = start_rf;
eNB->start_if = start_if;
break;
case NGFI_RRU_IF4p5:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->proc_uespec_rx = NULL;
eNB->proc_tx = proc_tx_rru_if4p5;
eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf;
eNB->start_rf = start_rf;
eNB->start_if = start_if;
malloc_IF4p5_buffer(eNB);
break;
case eNodeB_3GPP:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = NULL;
eNB->rx_fh = rx_rf;
eNB->start_rf = start_rf;
eNB->start_if = NULL;
break;
case eNodeB_3GPP_BBU:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = tx_fh_if5;
eNB->rx_fh = rx_fh_if5;
eNB->start_rf = NULL;
eNB->start_if = start_if;
break;
case NGFI_RCC_IF4p5:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = tx_fh_if4p5;
eNB->rx_fh = rx_fh_if4p5;
eNB->start_rf = NULL;
eNB->start_if = start_if;
malloc_IF4p5_buffer(eNB);
break;
case NGFI_RAU_IF4p5:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = tx_fh_if4p5;
eNB->rx_fh = rx_fh_if4p5;
eNB->start_rf = NULL;
eNB->start_if = start_if;
malloc_IF4p5_buffer(eNB);
break;
}
}
init_eNB_proc(inst);
......
......@@ -1056,9 +1056,9 @@ static void get_options (int argc, char **argv)
if (enb_properties->properties[i]->rrh_gw_config[j].raw == 1) {
(eth_params+j)->transp_preference = ETH_RAW_MODE;
} else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4 == 1) {
(eth_params+j)->transp_preference = ETH_RAW_IF4_MODE;
(eth_params+j)->transp_preference = ETH_RAW_IF4p5_MODE;
} else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4 == 1) {
(eth_params+j)->transp_preference = ETH_UDP_IF4_MODE;
(eth_params+j)->transp_preference = ETH_UDP_IF4p5_MODE;
} else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
(eth_params+j)->transp_preference = ETH_RAW_IF5_MOBIPASS;
} else {
......@@ -1645,7 +1645,7 @@ int main( int argc, char **argv )
if (UE_flag == 0) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (node_function[CC_id] == NGFI_RRU_IF4 || node_function[CC_id] == NGFI_RRU_IF5) {
if (node_function[CC_id] == NGFI_RRU_IF4p5 || node_function[CC_id] == NGFI_RRU_IF5) {
PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = RRH_HOST;
PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = RRH_HOST;
} else {
......@@ -1667,7 +1667,7 @@ int main( int argc, char **argv )
// Load RF device and initialize
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (node_function[CC_id] == NGFI_RRU_IF5 || node_function[CC_id] == NGFI_RRU_IF4 || node_function[CC_id] == eNodeB_3GPP) {
if (node_function[CC_id] == NGFI_RRU_IF5 || node_function[CC_id] == NGFI_RRU_IF4p5 || node_function[CC_id] == eNodeB_3GPP) {
if (mode!=loop_through_memory) {
returns= (UE_flag == 0) ?
openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]) :
......
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