Commit 4bf5f598 authored by laurent's avatar laurent

begining functional split 6

parent ebd40e8d
#define MTU 65536
#define UDP_TIMEOUT 100000L // in nano second
receiveSubFrame(int sock) {
//read all subframe data from the control unit
char * buf[MTU];
int ret=recv(sock, buf, sizeof(buf), 0);
if ( ret==-1) {
if ( errno == EWOULDBLOCK || errno== EINTR ) {
finishSubframeRecv();
} else {
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
return;
}
} else {
}
}
void pdsch_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
int harq_pid,
LTE_eNB_DLSCH_t *dlsch,
LTE_eNB_DLSCH_t *dlsch1,
LTE_eNB_UE_stats *ue_stats,
int ra_flag) {
int frame=proc->frame_tx;
int subframe=proc->subframe_tx;
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
// 36-212
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
// Replace dlsch_encoding
// data is in
// dlsch->harq_processes[harq_pid]->e
feedDlschBuffers(eNB,
dlsch_harq->pdu,
dlsch_harq->pdsch_start,
dlsch,
frame,
subframe,
&eNB->dlsch_rate_matching_stats,
&eNB->dlsch_turbo_encoding_stats,
&eNB->dlsch_turbo_encoding_waiting_stats,
&eNB->dlsch_turbo_encoding_main_stats,
&eNB->dlsch_turbo_encoding_wakeup_stats0,
&eNB->dlsch_turbo_encoding_wakeup_stats1,
&eNB->dlsch_interleaving_stats);
// 36-211
dlsch_scrambling(fp,
0,
dlsch,
harq_pid,
get_G(fp,
dlsch_harq->nb_rb,
dlsch_harq->rb_alloc,
dlsch_harq->Qm,
dlsch_harq->Nl,
dlsch_harq->pdsch_start,
frame,subframe,
0),
0,
frame,
subframe<<1);
dlsch_modulation(eNB,
eNB->common_vars.txdataF,
AMP,
frame,
subframe,
dlsch_harq->pdsch_start,
dlsch,
dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
}
dlsch->active = 0;
dlsch_harq->round++;
}
phy_procedures_eNB_TX_fs6() {
receiveSubFrame();
// We got
// subframe number
//
for (aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) {
memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * fp->symbols_per_tti],
0,
fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
}
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
if (is_pmch_subframe(frame,subframe,fp)) {
pmch_procedures(eNB,proc);
} else {
// this is not a pmch subframe, so generate PSS/SSS/PBCH
common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx);
}
}
if (ul_subframe < 10)if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
else
#endif
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
if (eNB->ulsch[i]) {
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
/* Store first_rb and n_DMRS for correct PHICH generation below.
* For PHICH generation we need "old" values of last scheduling
* for this HARQ process. 'generate_eNB_dlsch_params' below will
* overwrite first_rb and n_DMRS and 'generate_phich_top', done
* after 'generate_eNB_dlsch_params', would use the "new" values
* instead of the "old" ones.
*
* This has been tested for FDD only, may be wrong for TDD.
*
* TODO: maybe we should restructure the code to be sure it
* is done correctly. The main concern is if the code
* changes and first_rb and n_DMRS are modified before
* we reach here, then the PHICH processing will be wrong,
* using wrong first_rb and n_DMRS values to compute
* ngroup_PHICH and nseq_PHICH.
*
* TODO: check if that works with TDD.
*/
ulsch_harq->previous_first_rb = ulsch_harq->first_rb;
ulsch_harq->previous_n_DMRS = ulsch_harq->n_DMRS;
}
}
}
num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols;
num_dci = eNB->pdcch_vars[subframe&1].num_dci;
if (num_dci > 0)
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
generate_dci_top(num_pdcch_symbols,
num_dci,
&eNB->pdcch_vars[subframe&1].dci_alloc[0],
0,
AMP,
fp,
eNB->common_vars.txdataF,
subframe);
num_mdci = eNB->mpdcch_vars[subframe &1].num_dci;
if (num_mdci > 0) {
generate_mdci_top (eNB, frame, subframe, AMP, eNB->common_vars.txdataF);
}
}
// Now scan UE specific DLSCH
LTE_eNB_DLSCH_t *dlsch0,*dlsch1;
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
dlsch0 = eNB->dlsch[(uint8_t)UE_id][0];
dlsch1 = eNB->dlsch[(uint8_t)UE_id][1];
if ((dlsch0)&&(dlsch0->rnti>0)&&
(dlsch0->active == 1)
) {
// get harq_pid
harq_pid = dlsch0->harq_ids[frame%2][subframe];
AssertFatal(harq_pid>=0,"harq_pid is negative\n");
if (harq_pid>=8) {
if (dlsch0->ue_type==0)
LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x \n",
harq_pid,UE_id,frame,subframe,dlsch0->rnti);
} else {
// generate pdsch
pdsch_procedures_fs6(eNB,
proc,
harq_pid,
dlsch0,
dlsch1,
&eNB->UE_stats[(uint32_t)UE_id],
0);
}
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
(dlsch0->active == 0)
) {
// clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
dlsch0->subframe_tx[subframe]=0;
}
}
generate_phich_top(eNB,
proc,
AMP);
}
DL_thread_fs6() {
receiveSubFrame();
phy_procedures_eNB_TX_fs6();
ru->feptx_prec(ru);
ru->feptx_ofdm(ru);
ru->fh_south_out(ru);
}
int createListner (port) {
int sock;
AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, "");
struct sockaddr_in addr = {
sin_family:
AF_INET,
sin_port:
htons(port),
sin_addr:
{ s_addr: INADDR_ANY }
};
AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,"");
struct timeval tv={0,UDP_TIMEOUT};
AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
}
DL_thread_frequency() {
frequency_t header;
full_read(&header,
#ifndef __SPLIT_HEADERS_H
#define __SPLIT_HEADERS_H
struct frequency_s {
int frame;
int subframe;
int timestamp;
int sampleSize;
int nbAnt
int nbSamples;
} frequency_t;
#endif
...@@ -431,7 +431,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -431,7 +431,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0; if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
else else
#endif #endif
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
......
...@@ -1354,7 +1354,7 @@ int main(int argc, char **argv) { ...@@ -1354,7 +1354,7 @@ int main(int argc, char **argv) {
printStatIndent2(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" ); printStatIndent2(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" );
printStatIndent2(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" ); printStatIndent2(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" );
printStatIndent2(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" ); printStatIndent2(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" );
printf("|__ turbo_decoder(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", printf(" |__ turbo_decoder(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n",
eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ?
eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : eNB->ulsch[0]->harq_processes[harq_pid]->Kminus :
eNB->ulsch[0]->harq_processes[harq_pid]->Kplus, eNB->ulsch[0]->harq_processes[harq_pid]->Kplus,
......
...@@ -105,7 +105,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param ...@@ -105,7 +105,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
if ( IS_SOFTMODEM_BASICSIM ) { if ( IS_SOFTMODEM_BASICSIM ) {
libname=OAI_BASICSIM_LIBNAME; libname=OAI_BASICSIM_LIBNAME;
shlib_fdesc[0].fname="device_init"; shlib_fdesc[0].fname="device_init";
} else if ( IS_SOFTMODEM_RFSIM ) { } else if ( IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
libname=OAI_RFSIM_LIBNAME; libname=OAI_RFSIM_LIBNAME;
shlib_fdesc[0].fname="device_init"; shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_LOCAL_RADIO_HEAD) { } else if (flag == RAU_LOCAL_RADIO_HEAD) {
......
...@@ -102,6 +102,10 @@ typedef enum { ...@@ -102,6 +102,10 @@ typedef enum {
IRIS_DEV, IRIS_DEV,
/*!\brief device is NONE*/ /*!\brief device is NONE*/
NONE_DEV, NONE_DEV,
/*!\brief device is ADRV9371_ZC706 */
ADRV9371_ZC706_DEV,
/*!\brief device is UEDv2 */
UEDv2_DEV,
MAX_RF_DEV_TYPE MAX_RF_DEV_TYPE
} dev_type_t; } dev_type_t;
...@@ -214,6 +218,14 @@ typedef struct { ...@@ -214,6 +218,14 @@ typedef struct {
int iq_rxrescale; int iq_rxrescale;
//! Configuration file for LMS7002M //! Configuration file for LMS7002M
char *configFilename; char *configFilename;
//! remote IP/MAC addr for Ethernet interface
char *remote_addr;
//! remote port number for Ethernet interface
unsigned int remote_port;
//! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
char *my_addr;
//! local port number for Ethernet interface (eNB/BBU, UE)
unsigned int my_port;
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
unsigned short sf_mode; // 1=record, 2=replay unsigned short sf_mode; // 1=record, 2=replay
char sf_filename[1024]; // subframes file path char sf_filename[1024]; // subframes file path
...@@ -223,6 +235,13 @@ typedef struct { ...@@ -223,6 +235,13 @@ typedef struct {
unsigned int sf_write_delay; // write delay in replay mode unsigned int sf_write_delay; // write delay in replay mode
unsigned int eth_mtu; // ethernet MTU unsigned int eth_mtu; // ethernet MTU
#endif #endif
//! number of samples per tti
unsigned int samples_per_tti;
//! the sample rate for receive.
double rx_sample_rate;
//! the sample rate for transmit.
double tx_sample_rate;
} openair0_config_t; } openair0_config_t;
/*! \brief RF mapping */ /*! \brief RF mapping */
...@@ -384,6 +403,31 @@ struct openair0_device_t { ...@@ -384,6 +403,31 @@ struct openair0_device_t {
typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
/* type of transport init function, implemented in shared lib */ /* type of transport init function, implemented in shared lib */
typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record
#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record
#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record
#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record
#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record
#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record
#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record
#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
#define sample_t uint32_t // 2*16 bits complex number
typedef struct {
uint64_t magic; // Magic value (see defines above)
uint32_t size; // Number of samples per antenna to follow this header
uint32_t nbAnt; // Total number of antennas following this header
// Samples per antenna follow this header,
// i.e. nbAnt = 2 => this header+samples_antenna_0+samples_antenna_1
// data following this header in bytes is nbAnt*size*sizeof(sample_t)
uint64_t timestamp; // Timestamp value of first sample
uint32_t option_value; // Option value
uint32_t option_flag; // Option flag
} samplesBlockHeader_t;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
...@@ -408,7 +452,7 @@ openair0_timestamp get_usrp_time(openair0_device *device); ...@@ -408,7 +452,7 @@ openair0_timestamp get_usrp_time(openair0_device *device);
* \returns 0 in success * \returns 0 in success
*/ */
int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg); int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg);
#define gettid() syscall(__NR_gettid)
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -24,28 +24,23 @@ ...@@ -24,28 +24,23 @@
#define PORT 4043 //TCP port for this simulator #define PORT 4043 //TCP port for this simulator
#define CirSize 3072000 // 100ms is enough #define CirSize 3072000 // 100ms is enough
#define MaxBlock 30000
#define sample_t uint32_t // 2*16 bits complex number #define sample_t uint32_t // 2*16 bits complex number
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
#define MAGICeNB 0xA5A5A5A5A5A5A5A5
#define MAGICUE 0x5A5A5A5A5A5A5A5A
typedef struct { #define sample_t uint32_t // 2*16 bits complex number
uint64_t magic;
uint32_t size;
uint32_t nbAnt;
uint64_t timestamp;
} transferHeader;
typedef struct buffer_s { typedef struct buffer_s {
int conn_sock; int conn_sock;
bool alreadyRead; bool readEnabled;
uint64_t lastReceivedTS; uint64_t lastReceivedTS;
uint64_t lastWroteTS;
bool headerMode; bool headerMode;
transferHeader th; samplesBlockHeader_t th;
char *transferPtr; char *transferPtr;
uint64_t remainToTransfer; uint64_t remainToTransfer;
char *circularBufEnd; int nbAnt;
sample_t *circularBuf; sample_t *circularBuf;
} buffer_t; } buffer_t;
...@@ -55,19 +50,22 @@ typedef struct { ...@@ -55,19 +50,22 @@ typedef struct {
uint64_t typeStamp; uint64_t typeStamp;
uint64_t initialAhead; uint64_t initialAhead;
char *ip; char *ip;
int saveIQfile;
buffer_t buf[FD_SETSIZE]; buffer_t buf[FD_SETSIZE];
} rfsimulator_state_t; } rfsimulator_state_t;
void allocCirBuf(rfsimulator_state_t *bridge, int sock) { void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
buffer_t *ptr=&bridge->buf[sock]; buffer_t *ptr=&bridge->buf[sock];
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
ptr->conn_sock=sock; ptr->conn_sock=sock;
ptr->headerMode=true; ptr->headerMode=true;
ptr->transferPtr=(char *)&ptr->th; ptr->transferPtr=(char *)&ptr->th;
ptr->remainToTransfer=sizeof(transferHeader); ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
int sendbuff=1000*1000*10; int sendbuff=1000*1000*10;
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
int tcp_maxseg = 1400;
AssertFatal ( setsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, &tcp_maxseg,sizeof(tcp_maxseg)) == 0, "");
struct epoll_event ev= {0}; struct epoll_event ev= {0};
ev.events = EPOLLIN | EPOLLRDHUP; ev.events = EPOLLIN | EPOLLRDHUP;
ev.data.fd = sock; ev.data.fd = sock;
...@@ -87,7 +85,7 @@ void socketError(rfsimulator_state_t *bridge, int sock) { ...@@ -87,7 +85,7 @@ void socketError(rfsimulator_state_t *bridge, int sock) {
LOG_W(HW,"Lost socket \n"); LOG_W(HW,"Lost socket \n");
removeCirBuf(bridge, sock); removeCirBuf(bridge, sock);
if (bridge->typeStamp==MAGICUE) if (bridge->typeStamp==UE_MAGICDL_FDD)
exit(1); exit(1);
} }
} }
...@@ -120,6 +118,11 @@ void setblocking(int sock, enum blocking_t active) { ...@@ -120,6 +118,11 @@ void setblocking(int sock, enum blocking_t active) {
static bool flushInput(rfsimulator_state_t *t); static bool flushInput(rfsimulator_state_t *t);
void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
if (t->saveIQfile != -1) {
if (write(t->saveIQfile, _buf, count) != count )
LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno));
}
char *buf = _buf; char *buf = _buf;
int l; int l;
setblocking(fd, notBlocking); setblocking(fd, notBlocking);
...@@ -145,7 +148,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { ...@@ -145,7 +148,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
int server_start(openair0_device *device) { int server_start(openair0_device *device) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
t->typeStamp=MAGICeNB; t->typeStamp=ENB_MAGICDL_FDD;
AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
int enable = 1; int enable = 1;
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
...@@ -168,7 +171,7 @@ sin_addr: ...@@ -168,7 +171,7 @@ sin_addr:
int start_ue(openair0_device *device) { int start_ue(openair0_device *device) {
rfsimulator_state_t *t = device->priv; rfsimulator_state_t *t = device->priv;
t->typeStamp=MAGICUE; t->typeStamp=UE_MAGICDL_FDD;
int sock; int sock;
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
struct sockaddr_in addr = { struct sockaddr_in addr = {
...@@ -196,43 +199,104 @@ sin_addr: ...@@ -196,43 +199,104 @@ sin_addr:
setblocking(sock, notBlocking); setblocking(sock, notBlocking);
allocCirBuf(t, sock); allocCirBuf(t, sock);
t->buf[sock].alreadyRead=true; // UE will start blocking on read t->buf[sock].readEnabled=true; // UE will start blocking on read
return 0; return 0;
} }
uint64_t lwrote;
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
rfsimulator_state_t *t = device->priv; rfsimulator_state_t *t = device->priv;
// We do small blocks because the UE and the eNB are not aligned
// So large blocks can lead to deadlock (each side waits a incoming block completed)
int curBeg=0;
for (int i=0; i<FD_SETSIZE; i++) { do {
buffer_t *ptr=&t->buf[i]; int sizeToSend=min(nsamps-curBeg,MaxBlock);
if (ptr->conn_sock >= 0 ) { for (int i=0; i<FD_SETSIZE; i++) {
transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp}; buffer_t *ptr=&t->buf[i];
fullwrite(ptr->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; a<nbAnt; a++) { if (ptr->conn_sock >= 0 ) {
sample_t *in=(sample_t *)samplesVoid[a]; samplesBlockHeader_t header= {t->typeStamp, sizeToSend, nbAnt, timestamp+curBeg};
fullwrite(ptr->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[sizeToSend][nbAnt];
for(int s=0; s<nsamps; s++) for(int a=0; a<nbAnt; a++) {
tmpSamples[s][a]=in[s]; sample_t *in=((sample_t *)samplesVoid[a]) + curBeg;
}
if (ptr->conn_sock >= 0 ) for(int s=0; s<sizeToSend; s++)
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t); tmpSamples[s][a]=in[s];
}
if (ptr->conn_sock >= 0 ) {
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(sizeToSend,nbAnt), t);
ptr->lastWroteTS=timestamp+curBeg+sizeToSend;
}
}
} }
}
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); sizeToSend, timestamp+curBeg, timestamp+curBeg+sizeToSend,
signal_energy(samplesVoid[0]+curBeg, sizeToSend) );
curBeg+=sizeToSend;
} while ( curBeg < nsamps ) ;
return nsamps; return nsamps;
} }
static void oneTransferDone(rfsimulator_state_t *t, buffer_t *b) {
// check the header and start block transfer
if ( b->headerMode==true) {
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
b->headerMode=false;
if ( b->lastReceivedTS != b->th.timestamp && b->readEnabled && b->lastReceivedTS ) {
int nbAnt= b->th.nbAnt;
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ )
for (int a=0; a < nbAnt; a++)
b->circularBuf[(index*nbAnt+a)%CirSize]=0;
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
}
if ( b->readEnabled && b->lastReceivedTS && b->lastWroteTS)
AssertFatal( fabs((double)b->lastReceivedTS - (double)b->lastWroteTS) < (double)CirSize,
"Difference between Rx/Tx timestamps impossible, Rx: %lu, T:%lu\n",
b->lastReceivedTS, b->lastWroteTS);
else
printf("diff: %f\n", abs((double)b->lastReceivedTS - (double)b->lastWroteTS)/1000.0);
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
} else {
LOG_I(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
// in NB case, the UE started to write, since this event, we will wait it's data
// This is needed because the UE doesn't write in initial sync mode
// in UE case, the UE is already in this state (at connection time)
b->readEnabled=true;
b->lastReceivedTS=b->th.timestamp+b->th.size;
// First block in UE, resync with the eNB current TS
if ( t->nextTimestamp == 0 ) {
t->nextTimestamp=b->lastReceivedTS-b->th.size;
LOG_I(HW,"Ue synchro on NB timestamp: %lu\n", t->nextTimestamp);
}
b->headerMode=true;
b->transferPtr=(char *)&b->th;
b->remainToTransfer=sizeof(samplesBlockHeader_t);
b->th.magic=-1;
}
}
static bool flushInput(rfsimulator_state_t *t) { static bool flushInput(rfsimulator_state_t *t) {
// Process all incoming events on sockets // Process all incoming events on sockets
// store the data in lists // store the data in lists
struct epoll_event events[FD_SETSIZE]= {0}; struct epoll_event events[FD_SETSIZE]= {0};
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200); int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 2);
if ( nfds==-1 ) { if ( nfds==-1 ) {
if ( errno==EINTR || errno==EAGAIN ) if ( errno==EINTR || errno==EAGAIN )
...@@ -264,13 +328,14 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -264,13 +328,14 @@ static bool flushInput(rfsimulator_state_t *t) {
} }
int blockSz; int blockSz;
char * circularBufEnd=((char *)b->circularBuf)+sampleToByte(CirSize,1);
if ( b->headerMode) if ( b->headerMode)
blockSz=b->remainToTransfer; blockSz=b->remainToTransfer;
else else
blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ? blockSz= b->transferPtr+b->remainToTransfer < circularBufEnd ?
b->remainToTransfer : b->remainToTransfer :
b->circularBufEnd - 1 - b->transferPtr ; circularBufEnd - 1 - b->transferPtr ;
int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT); int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
...@@ -285,46 +350,11 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -285,46 +350,11 @@ static bool flushInput(rfsimulator_state_t *t) {
AssertFatal((b->remainToTransfer-=sz) >= 0, ""); AssertFatal((b->remainToTransfer-=sz) >= 0, "");
b->transferPtr+=sz; b->transferPtr+=sz;
if (b->transferPtr==b->circularBufEnd - 1) if (b->transferPtr==circularBufEnd - 1)
b->transferPtr=(char *)b->circularBuf; b->transferPtr=(char *)b->circularBuf;
// check the header and start block transfer if ( b->remainToTransfer==0) {
if ( b->headerMode==true && b->remainToTransfer==0) { oneTransferDone(t,b);
AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) ||
(t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
b->headerMode=false;
b->alreadyRead=true;
if ( b->lastReceivedTS != b->th.timestamp) {
int nbAnt= b->th.nbAnt;
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ )
for (int a=0; a < nbAnt; a++)
b->circularBuf[(index*nbAnt+a)%CirSize]=0;
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
}
b->lastReceivedTS=b->th.timestamp;
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
}
if ( b->headerMode==false ) {
b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
if ( b->remainToTransfer==0) {
LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
// First block in UE, resync with the eNB current TS
if ( t->nextTimestamp == 0 )
t->nextTimestamp=b->lastReceivedTS-b->th.size;
b->headerMode=true;
b->transferPtr=(char *)&b->th;
b->remainToTransfer=sizeof(transferHeader);
b->th.magic=-1;
}
} }
} }
} }
...@@ -367,7 +397,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -367,7 +397,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
for ( int sock=0; sock<FD_SETSIZE; sock++) for ( int sock=0; sock<FD_SETSIZE; sock++)
if ( t->buf[sock].circularBuf && if ( t->buf[sock].circularBuf &&
t->buf[sock].alreadyRead && //>= t->initialAhead && t->buf[sock].readEnabled &&
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) { (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
have_to_wait=true; have_to_wait=true;
break; break;
...@@ -390,7 +420,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -390,7 +420,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
for (int sock=0; sock<FD_SETSIZE; sock++) { for (int sock=0; sock<FD_SETSIZE; sock++) {
buffer_t *ptr=&t->buf[sock]; buffer_t *ptr=&t->buf[sock];
if ( ptr->circularBuf && ptr->alreadyRead ) { if ( ptr->circularBuf && ptr->readEnabled ) {
for (int a=0; a<nbAnt; a++) { for (int a=0; a<nbAnt; a++) {
sample_t *out=(sample_t *)samplesVoid[a]; sample_t *out=(sample_t *)samplesVoid[a];
...@@ -438,7 +468,7 @@ int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_c ...@@ -438,7 +468,7 @@ int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_c
__attribute__((__visibility__("default"))) __attribute__((__visibility__("default")))
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
//set_log(HW,OAILOG_DEBUG); set_log(HW,OAILOG_DEBUG);
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) { if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) {
...@@ -447,10 +477,22 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -447,10 +477,22 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
} }
rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
MAGICeNB: ENB_MAGICDL_FDD:
MAGICUE; UE_MAGICDL_FDD;
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE"); LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "eNB" : "UE");
device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ? char *saveF;
if ((saveF=getenv("saveIQfile")) != NULL) {
rfsimulator->saveIQfile=open(saveF,O_APPEND| O_CREAT|O_TRUNC | O_WRONLY, 0666);
if ( rfsimulator->saveIQfile != -1 )
LOG_I(HW,"rfsimulator: will save written IQ samples in %s\n", saveF);
else
LOG_E(HW, "can't open %s for IQ saving (%s)\n", saveF, strerror(errno));
} else
rfsimulator->saveIQfile = -1;
device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ?
server_start : server_start :
start_ue; start_ue;
device->trx_get_stats_func = rfsimulator_get_stats; device->trx_get_stats_func = rfsimulator_get_stats;
......
...@@ -148,7 +148,7 @@ int attach_rru(RU_t *ru) { ...@@ -148,7 +148,7 @@ int attach_rru(RU_t *ru) {
RRU_CONFIG_msg_t rru_config_msg; RRU_CONFIG_msg_t rru_config_msg;
int received_capabilities=0; int received_capabilities=0;
wait_eNBs(); wait_eNBs();
LOG_ENTER(PHY);
// Wait for capabilities // Wait for capabilities
while (received_capabilities==0) { while (received_capabilities==0) {
memset((void *)&rru_config_msg,0,sizeof(rru_config_msg)); memset((void *)&rru_config_msg,0,sizeof(rru_config_msg));
...@@ -208,7 +208,7 @@ int connect_rau(RU_t *ru) { ...@@ -208,7 +208,7 @@ int connect_rau(RU_t *ru) {
RRU_capabilities_t *cap; RRU_capabilities_t *cap;
int i; int i;
int len; int len;
LOG_ENTER(PHY);
// wait for RAU_tick // wait for RAU_tick
while (tick_received == 0) { while (tick_received == 0) {
msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE;
...@@ -299,7 +299,7 @@ int connect_rau(RU_t *ru) { ...@@ -299,7 +299,7 @@ int connect_rau(RU_t *ru) {
// southbound IF5 fronthaul for 16-bit OAI format // southbound IF5 fronthaul for 16-bit OAI format
static inline void fh_if5_south_out(RU_t *ru) { static inline void fh_if5_south_out(RU_t *ru) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_ENTER(PHY);
send_IF5(ru, ru->proc.timestamp_tx, ru->proc.subframe_tx, &ru->seqno, IF5_RRH_GW_DL); send_IF5(ru, ru->proc.timestamp_tx, ru->proc.subframe_tx, &ru->seqno, IF5_RRH_GW_DL);
} }
...@@ -315,7 +315,7 @@ static inline void fh_if4p5_south_out(RU_t *ru) { ...@@ -315,7 +315,7 @@ static inline void fh_if4p5_south_out(RU_t *ru) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.subframe_tx); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.subframe_tx);
LOG_ENTER(PHY);
if (subframe_select(&ru->frame_parms,ru->proc.subframe_tx)!=SF_UL) if (subframe_select(&ru->frame_parms,ru->proc.subframe_tx)!=SF_UL)
send_IF4p5(ru,ru->proc.frame_tx, ru->proc.subframe_tx, IF4p5_PDLFFT); send_IF4p5(ru,ru->proc.frame_tx, ru->proc.subframe_tx, IF4p5_PDLFFT);
} }
...@@ -327,6 +327,7 @@ static inline void fh_if4p5_south_out(RU_t *ru) { ...@@ -327,6 +327,7 @@ static inline void fh_if4p5_south_out(RU_t *ru) {
void fh_if5_south_in(RU_t *ru,int *frame, int *subframe) { void fh_if5_south_in(RU_t *ru,int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
RU_proc_t *proc = &ru->proc; RU_proc_t *proc = &ru->proc;
LOG_ENTER(PHY);
recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
...@@ -358,14 +359,14 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { ...@@ -358,14 +359,14 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) {
uint16_t packet_type; uint16_t packet_type;
uint32_t symbol_number=0; uint32_t symbol_number=0;
uint32_t symbol_mask_full; uint32_t symbol_mask_full;
LOG_ENTER(PHY);
if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S))
symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1; symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1;
else else
symbol_mask_full = (1<<fp->symbols_per_tti)-1; symbol_mask_full = (1<<fp->symbols_per_tti)-1;
AssertFatal(proc->symbol_mask[*subframe]==0,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]); AssertFatal(proc->symbol_mask[*subframe]==0,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]);
LOG_D(PHY,"start rcv IF4p5 \n");
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number); recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
...@@ -382,6 +383,7 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { ...@@ -382,6 +383,7 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) {
LOG_D(PHY,"rx_fh_if4p5: subframe %d symbol mask %x\n",*subframe,proc->symbol_mask[*subframe]); LOG_D(PHY,"rx_fh_if4p5: subframe %d symbol mask %x\n",*subframe,proc->symbol_mask[*subframe]);
} while(proc->symbol_mask[*subframe] != symbol_mask_full); } while(proc->symbol_mask[*subframe] != symbol_mask_full);
LOG_D(PHY,"Done rcv IF4p5 \n");
//caculate timestamp_rx, timestamp_tx based on frame and subframe //caculate timestamp_rx, timestamp_tx based on frame and subframe
proc->subframe_rx = sf; proc->subframe_rx = sf;
...@@ -482,6 +484,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) { ...@@ -482,6 +484,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) {
symbol_mask = (1<<fp->symbols_per_tti)-1; symbol_mask = (1<<fp->symbols_per_tti)-1;
prach_rx = 0; prach_rx = 0;
LOG_D(PHY,"start rcv IF4p5 \n");
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5(ru, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); recv_IF4p5(ru, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
...@@ -578,6 +581,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { ...@@ -578,6 +581,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
uint16_t packet_type; uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full; uint32_t symbol_number,symbol_mask,symbol_mask_full;
int subframe_tx,frame_tx; int subframe_tx,frame_tx;
LOG_ENTER(PHY);
LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru); LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru);
symbol_number = 0; symbol_number = 0;
symbol_mask = 0; symbol_mask = 0;
...@@ -643,7 +647,7 @@ void fh_if4p5_north_out(RU_t *ru) { ...@@ -643,7 +647,7 @@ void fh_if4p5_north_out(RU_t *ru) {
RU_proc_t *proc=&ru->proc; RU_proc_t *proc=&ru->proc;
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
const int subframe = proc->subframe_rx; const int subframe = proc->subframe_rx;
LOG_ENTER(PHY);
if (ru->idx==0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); if (ru->idx==0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx );
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) {
...@@ -712,6 +716,8 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { ...@@ -712,6 +716,8 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
unsigned int rxs; unsigned int rxs;
int i; int i;
openair0_timestamp ts=0,old_ts=0; openair0_timestamp ts=0,old_ts=0;
LOG_ENTER(PHY);
LOG_D(PHY,"%s:%d start rx_rf \n", __FILE__,__LINE__);
for (i=0; i<ru->nb_rx; i++) for (i=0; i<ru->nb_rx; i++)
rxp[i] = (void *)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; rxp[i] = (void *)&ru->common.rxdata[i][*subframe*fp->samples_per_tti];
...@@ -820,6 +826,7 @@ void tx_rf(RU_t *ru) { ...@@ -820,6 +826,7 @@ void tx_rf(RU_t *ru) {
lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10); lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10);
lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10); lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10);
int sf_extension = 0; int sf_extension = 0;
LOG_D(PHY,"start tx_rf \n");
if ((SF_type == SF_DL) || if ((SF_type == SF_DL) ||
(SF_type == SF_S)) { (SF_type == SF_S)) {
...@@ -935,6 +942,7 @@ static void *ru_thread_asynch_rxtx( void *param ) { ...@@ -935,6 +942,7 @@ static void *ru_thread_asynch_rxtx( void *param ) {
printf( "devices ok (ru_thread_asynch_rx)\n"); printf( "devices ok (ru_thread_asynch_rx)\n");
while (!oai_exit) { while (!oai_exit) {
LOG_ENTER(PHY);
if (oai_exit) break; if (oai_exit) break;
if (subframe==9) { if (subframe==9) {
...@@ -968,7 +976,7 @@ void wakeup_slaves(RU_proc_t *proc) { ...@@ -968,7 +976,7 @@ void wakeup_slaves(RU_proc_t *proc) {
struct timespec wait; struct timespec wait;
wait.tv_sec=0; wait.tv_sec=0;
wait.tv_nsec=5000000L; wait.tv_nsec=5000000L;
LOG_ENTER(PHY);
for (i=0; i<proc->num_slaves; i++) { for (i=0; i<proc->num_slaves; i++) {
RU_proc_t *slave_proc = proc->slave_proc[i]; RU_proc_t *slave_proc = proc->slave_proc[i];
...@@ -1029,7 +1037,7 @@ static void *ru_thread_prach( void *param ) { ...@@ -1029,7 +1037,7 @@ static void *ru_thread_prach( void *param ) {
if (oai_exit) break; if (oai_exit) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
LOG_ENTER(PHY);
if (ru->eNB_list[0]) { if (ru->eNB_list[0]) {
prach_procedures( prach_procedures(
ru->eNB_list[0] ru->eNB_list[0]
...@@ -1075,7 +1083,7 @@ static void *ru_thread_prach_br( void *param ) { ...@@ -1075,7 +1083,7 @@ static void *ru_thread_prach_br( void *param ) {
if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"ru_prach_thread_br") < 0) break; if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"ru_prach_thread_br") < 0) break;
if (oai_exit) break; if (oai_exit) break;
LOG_ENTER(PHY);
rx_prach(NULL, rx_prach(NULL,
ru, ru,
NULL, NULL,
...@@ -1098,7 +1106,7 @@ int wakeup_synch(RU_t *ru) { ...@@ -1098,7 +1106,7 @@ int wakeup_synch(RU_t *ru) {
struct timespec wait; struct timespec wait;
wait.tv_sec=0; wait.tv_sec=0;
wait.tv_nsec=5000000L; wait.tv_nsec=5000000L;
LOG_ENTER(PHY);
// wake up synch thread // wake up synch thread
// lock the synch mutex and make sure the thread is ready // lock the synch mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) { if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) {
...@@ -1135,7 +1143,7 @@ void do_ru_synch(RU_t *ru) { ...@@ -1135,7 +1143,7 @@ void do_ru_synch(RU_t *ru) {
double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0]; double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0];
double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0]; double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0];
LOG_ENTER(PHY);
for (i=0; i<4; i++) { for (i=0; i<4; i++) {
ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i]; ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i];
ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1; ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1;
...@@ -1198,7 +1206,7 @@ void wakeup_L1s(RU_t *ru) { ...@@ -1198,7 +1206,7 @@ void wakeup_L1s(RU_t *ru) {
int i; int i;
PHY_VARS_eNB **eNB_list = ru->eNB_list; PHY_VARS_eNB **eNB_list = ru->eNB_list;
LOG_D(PHY,"wakeup_L1s (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); LOG_D(PHY,"wakeup_L1s (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
LOG_ENTER(PHY);
if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
// call eNB function directly // call eNB function directly
char string[20]; char string[20];
...@@ -1496,7 +1504,7 @@ static void *ru_thread_tx( void *param ) { ...@@ -1496,7 +1504,7 @@ static void *ru_thread_tx( void *param ) {
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
if (oai_exit) break; if (oai_exit) break;
LOG_ENTER(PHY);
// do TX front-end processing if needed (precoding and/or IDFTs) // do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru); if (ru->feptx_prec) ru->feptx_prec(ru);
...@@ -1644,7 +1652,7 @@ static void *ru_thread( void *param ) { ...@@ -1644,7 +1652,7 @@ static void *ru_thread( void *param ) {
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,sched_getcpu()); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,sched_getcpu());
LOG_ENTER(PHY);
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines. // They are set on the first rx/tx in the underly FH routines.
if (subframe==9) { if (subframe==9) {
......
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