record/replay for 5G, nrscope bug fix
This commit is contained in:
@@ -1318,7 +1318,7 @@ int main ( int argc, char **argv ) {
|
||||
|
||||
// end of CI modifications
|
||||
//getchar();
|
||||
if(IS_SOFTMODEM_DOFORMS)
|
||||
if(IS_SOFTMODEM_DOSCOPE)
|
||||
load_softscope("enb", NULL);
|
||||
|
||||
itti_wait_tasks_end();
|
||||
@@ -1327,7 +1327,7 @@ int main ( int argc, char **argv ) {
|
||||
// stop threads
|
||||
|
||||
if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
|
||||
if(IS_SOFTMODEM_DOFORMS)
|
||||
if(IS_SOFTMODEM_DOSCOPE)
|
||||
end_forms();
|
||||
|
||||
LOG_I(ENB_APP,"stopping MODEM threads\n");
|
||||
|
||||
+3
-2
@@ -89,7 +89,7 @@ static int DEFBFW[] = {0x00007fff};
|
||||
|
||||
#include "s1ap_eNB.h"
|
||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
|
||||
|
||||
#include "T.h"
|
||||
@@ -1593,7 +1593,8 @@ void *ru_thread( void *param ) {
|
||||
for (aa=0;aa<ru->nb_rx;aa++)
|
||||
memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa],
|
||||
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
|
||||
if (IS_SOFTMODEM_DOSCOPE && RC.gNB[0]->scopeData)
|
||||
((scopeData_t*)RC.gNB[0]->scopeData)->slotFunc(ru->common.rxdataF[0],proc->tti_rx, RC.gNB[0]->scopeData);
|
||||
// Do PRACH RU processing
|
||||
|
||||
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
|
||||
|
||||
@@ -900,7 +900,7 @@ if(!IS_SOFTMODEM_NOS1)
|
||||
printf("RC.nb_RU:%d\n", RC.nb_RU);
|
||||
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
|
||||
printf("ALL RUs ready - init gNBs\n");
|
||||
if(IS_SOFTMODEM_DOFORMS) {
|
||||
if(IS_SOFTMODEM_DOSCOPE) {
|
||||
sleep(1);
|
||||
scopeParms_t p;
|
||||
p.argc=&argc;
|
||||
|
||||
@@ -551,7 +551,7 @@ int main( int argc, char **argv ) {
|
||||
configure_linux();
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
|
||||
if(IS_SOFTMODEM_DOFORMS) {
|
||||
if(IS_SOFTMODEM_DOSCOPE) {
|
||||
load_softscope("nr",PHY_vars_UE_g[0][0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -996,7 +996,7 @@ int main( int argc, char **argv ) {
|
||||
(void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW);
|
||||
}
|
||||
|
||||
if(IS_SOFTMODEM_DOFORMS) {
|
||||
if(IS_SOFTMODEM_DOSCOPE) {
|
||||
scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]};
|
||||
load_softscope("nr",&tmp);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ void get_common_options(uint32_t execmask) {
|
||||
}
|
||||
|
||||
if (do_forms) {
|
||||
set_softmodem_optmask(SOFTMODEM_DOFORMS_BIT);
|
||||
set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT);
|
||||
}
|
||||
|
||||
if(parallel_config != NULL) set_parallel_conf(parallel_config);
|
||||
|
||||
@@ -188,7 +188,7 @@ extern "C"
|
||||
#define SOFTMODEM_RFSIM_BIT (1<<10)
|
||||
#define SOFTMODEM_BASICSIM_BIT (1<<11)
|
||||
#define SOFTMODEM_SIML1_BIT (1<<12)
|
||||
#define SOFTMODEM_DOFORMS_BIT (1<<15)
|
||||
#define SOFTMODEM_DOSCOPE_BIT (1<<15)
|
||||
#define SOFTMODEM_RECPLAY_BIT (1<<16)
|
||||
#define SOFTMODEM_ENB_BIT (1<<20)
|
||||
#define SOFTMODEM_GNB_BIT (1<<21)
|
||||
@@ -204,7 +204,7 @@ extern "C"
|
||||
#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
|
||||
#define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT)
|
||||
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
|
||||
#define IS_SOFTMODEM_DOFORMS ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT)
|
||||
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
|
||||
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
|
||||
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
|
||||
#define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT)
|
||||
|
||||
@@ -56,7 +56,7 @@ typedef struct OAIgraph {
|
||||
double *waterFallAvg;
|
||||
boolean_t initDone;
|
||||
int iteration;
|
||||
void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
|
||||
void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id);
|
||||
void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
|
||||
} OAIgraph_t;
|
||||
|
||||
@@ -132,7 +132,7 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_
|
||||
graph->iteration=0;
|
||||
}
|
||||
|
||||
static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
|
||||
static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, scopeData_t *p, int UE_id),
|
||||
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
||||
OAIgraph_t graph;
|
||||
commonGraph(&graph, type, x, y, w, h, label, pointColor);
|
||||
@@ -223,7 +223,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye
|
||||
|
||||
static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
|
||||
if ( values == NULL )
|
||||
return;
|
||||
return;
|
||||
|
||||
fl_winset(FL_ObjWin(graph->graph));
|
||||
const int samplesPerPixel=datasize/graph->w;
|
||||
int displayPart=graph->waterFallh-ScaleZone;
|
||||
@@ -318,10 +319,10 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc
|
||||
}
|
||||
}
|
||||
|
||||
static void gNBWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
static void gNBWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
|
||||
//use 1st antenna
|
||||
genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0],
|
||||
genericWaterFall(graph, (scopeSample_t *)p->ru->common.rxdata[0],
|
||||
frame_parms->samples_per_frame, frame_parms->slots_per_frame,
|
||||
"X axis:one frame in time");
|
||||
}
|
||||
@@ -339,31 +340,35 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy
|
||||
}
|
||||
*/
|
||||
|
||||
static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
|
||||
static void timeResponse (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
const int len=2*p->gNB->frame_parms.ofdm_symbol_size;
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
const int ant=0; // display antenna 0 for each UE
|
||||
|
||||
for (int ue=0; ue<nb_UEs; ue++) {
|
||||
scopeSample_t *data= (scopeSample_t *)phy_vars_gnb->pusch_vars[ue]->ul_ch_estimates_time[ant];
|
||||
if ( p->gNB->pusch_vars && p->gNB->pusch_vars[ue] &&
|
||||
p->gNB->pusch_vars[ue]->ul_ch_estimates_time &&
|
||||
p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant] ) {
|
||||
scopeSample_t *data= (scopeSample_t *)p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant];
|
||||
|
||||
if (data != NULL) {
|
||||
for (int i=0; i<len; i++) {
|
||||
values[i] = SquaredNorm(data[i]);
|
||||
if (data != NULL) {
|
||||
for (int i=0; i<len; i++) {
|
||||
values[i] = SquaredNorm(data[i]);
|
||||
}
|
||||
|
||||
oai_xygraph(graph,time,values, len, ue, 10);
|
||||
}
|
||||
|
||||
oai_xygraph(graph,time,values, len, ue, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gNBfreqWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
static void gNBfreqWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
|
||||
//use 1st antenna
|
||||
genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP,
|
||||
genericWaterFall(graph, (scopeSample_t *)p->rxdataF, frame_parms->samples_per_frame_wCP,
|
||||
frame_parms->slots_per_frame,
|
||||
"X axis: Frequency domain, one frame");
|
||||
"X axis: Frequency domain, one subframe");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -375,16 +380,18 @@ static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU
|
||||
}
|
||||
*/
|
||||
|
||||
static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
static void puschLLR (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
//int Qm = 2;
|
||||
int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
|
||||
|
||||
for (int ue=0; ue<nb_UEs; ue++) {
|
||||
int16_t *pusch_llr = (int16_t *)phy_vars_gnb->pusch_vars[ue]->llr;
|
||||
float *llr, *bit;
|
||||
oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
|
||||
if ( p->gNB->pusch_vars &&
|
||||
p->gNB->pusch_vars[ue] &&
|
||||
p->gNB->pusch_vars[ue]->llr ) {
|
||||
int16_t *pusch_llr = (int16_t *)p->gNB->pusch_vars[ue]->llr;
|
||||
float *llr, *bit;
|
||||
oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
|
||||
|
||||
if (pusch_llr) {
|
||||
for (int i=0; i<coded_bits_per_codeword; i++) {
|
||||
llr[i] = (float) pusch_llr[i];
|
||||
}
|
||||
@@ -394,16 +401,19 @@ static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_v
|
||||
}
|
||||
}
|
||||
|
||||
static void puschIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
static void puschIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
|
||||
int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
|
||||
|
||||
for (int ue=0; ue<nb_UEs; ue++) {
|
||||
scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[ue]->rxdataF_comp[0];
|
||||
float *I, *Q;
|
||||
oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
|
||||
if ( p->gNB->pusch_vars &&
|
||||
p->gNB->pusch_vars[ue] &&
|
||||
p->gNB->pusch_vars[ue]->rxdataF_comp &&
|
||||
p->gNB->pusch_vars[ue]->rxdataF_comp[0] ) {
|
||||
scopeSample_t *pusch_comp = (scopeSample_t *) p->gNB->pusch_vars[ue]->rxdataF_comp[0];
|
||||
float *I, *Q;
|
||||
oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
|
||||
|
||||
if (pusch_comp) {
|
||||
for (int k=0; k<sz; k++ ) {
|
||||
I[k] = pusch_comp[k].r;
|
||||
Q[k] = pusch_comp[k].i;
|
||||
@@ -414,7 +424,7 @@ static void puschIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_va
|
||||
}
|
||||
}
|
||||
|
||||
static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
static void pucchEnergy (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
// PUSCH I/Q of MF Output
|
||||
/*
|
||||
int32_t *pucch1ab_comp = (int32_t *) NULL; //phy_vars_gnb->pucch1ab_stats[UE_id];
|
||||
@@ -440,10 +450,10 @@ static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *ph
|
||||
*/
|
||||
}
|
||||
|
||||
static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
}
|
||||
|
||||
static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
// PUSCH Throughput
|
||||
/*
|
||||
float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
@@ -510,8 +520,7 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) {
|
||||
|
||||
static const int scope_enb_num_ue = 1;
|
||||
void phy_scope_gNB(OAI_phy_scope_t *form,
|
||||
PHY_VARS_gNB *phy_vars_gnb,
|
||||
RU_t *phy_vars_ru,
|
||||
scopeData_t *p,
|
||||
int UE_id) {
|
||||
static OAI_phy_scope_t *rememberForm=NULL;
|
||||
|
||||
@@ -526,7 +535,7 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
|
||||
int i=0;
|
||||
|
||||
while (form->graph[i].graph) {
|
||||
form->graph[i].gNBfunct(form->graph+i, phy_vars_gnb, phy_vars_ru, UE_id);
|
||||
form->graph[i].gNBfunct(form->graph+i, p, UE_id);
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -534,7 +543,7 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
|
||||
}
|
||||
|
||||
static void *scope_thread_gNB(void *arg) {
|
||||
scopeParms_t *p=(scopeParms_t *) arg;
|
||||
scopeData_t *p=(scopeData_t *) arg;
|
||||
//# ifdef ENABLE_XFORMS_WRITE_STATS
|
||||
// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
|
||||
//#endif
|
||||
@@ -543,12 +552,6 @@ static void *scope_thread_gNB(void *arg) {
|
||||
pthread_attr_init(&atr);
|
||||
pthread_attr_getstacksize(&atr, &stksize);
|
||||
pthread_attr_setstacksize(&atr,32*1024*1024 );
|
||||
p.gNB->scopeData=calloc(sizeof(nrscope_t));
|
||||
nrscope_t scope=(nrscope_t*) p.gNB->scopeData;
|
||||
scope->rxdataF=(int32_t **)malloc16(Prx*sizeof(int32_t*));
|
||||
for (int i=0; i < p.gNB->gNB_config.carrier_config.num_rx_ant.value; ; i++)
|
||||
scope->rxdataF[i] = (scopeSample_t*)malloc16_clear(p->gNB.frme_parms.samples_per_frame_wCP*sizeof(scopeSample_t));
|
||||
|
||||
sleep(3); // no clean interthread barriers
|
||||
int fl_argc=1;
|
||||
char *name="5G-gNB-scope";
|
||||
@@ -557,18 +560,31 @@ static void *scope_thread_gNB(void *arg) {
|
||||
OAI_phy_scope_t *form_gnb = create_phy_scope_gnb();
|
||||
|
||||
while (!oai_exit) {
|
||||
phy_scope_gNB(form_gnb, p->gNB, p->ru, nb_ue);
|
||||
phy_scope_gNB(form_gnb, p, nb_ue);
|
||||
usleep(99*1000);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void copyRxdataF(int32_t *data, int slot, void *scopeData) {
|
||||
scopeData_t *scope=(scopeData_t *)scopeData;
|
||||
memcpy(scope->rxdataF + slot*scope->gNB->frame_parms.samples_per_slot_wCP,
|
||||
data,
|
||||
scope->gNB->frame_parms.samples_per_slot_wCP);
|
||||
}
|
||||
|
||||
void gNBinitScope(scopeParms_t *p) {
|
||||
static scopeParms_t parms;
|
||||
memcpy(&parms,p,sizeof(parms));
|
||||
AssertFatal(p->gNB->scopeData=malloc(sizeof(scopeData_t)),"");
|
||||
scopeData_t *scope=(scopeData_t *) p->gNB->scopeData;
|
||||
scope->argc=p->argc;
|
||||
scope->argv=p->argv;
|
||||
scope->ru=p->ru;
|
||||
scope->gNB=p->gNB;
|
||||
scope->slotFunc=copyRxdataF;
|
||||
AssertFatal(scope->rxdataF=(int32_t *) calloc(p->gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t),1),"");
|
||||
pthread_t forms_thread;
|
||||
threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
|
||||
threadCreate(&forms_thread, scope_thread_gNB, p->gNB->scopeData, "scope", -1, OAI_PRIORITY_RT_LOW);
|
||||
}
|
||||
|
||||
static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
|
||||
@@ -33,13 +33,7 @@
|
||||
//#include "PHY/impl_defs_top.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
typedef struct {
|
||||
int *argc;
|
||||
char **argv;
|
||||
RU_t *ru;
|
||||
PHY_VARS_gNB *gNB;
|
||||
} scopeParms_t;
|
||||
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "phy_scope_interface.h"
|
||||
|
||||
#define SOFTSCOPE_ENDFUNC_IDX 0
|
||||
|
||||
static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}};
|
||||
|
||||
int load_softscope(char *exectype, void *initarg) {
|
||||
|
||||
@@ -29,7 +29,26 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef __PHY_SCOPE_INTERFACE_H__
|
||||
#define __PHY_SCOPE_INTERFACE_H__
|
||||
#include <openair1/PHY/defs_gNB.h>
|
||||
typedef struct {
|
||||
int *argc;
|
||||
char **argv;
|
||||
RU_t *ru;
|
||||
PHY_VARS_gNB *gNB;
|
||||
} scopeParms_t;
|
||||
|
||||
|
||||
typedef struct scopeData_s {
|
||||
int *argc;
|
||||
char **argv;
|
||||
RU_t *ru;
|
||||
PHY_VARS_gNB *gNB;
|
||||
int32_t * rxdataF;
|
||||
void (*slotFunc)(int32_t* data, int slot, void * scopeData);
|
||||
} scopeData_t;
|
||||
|
||||
int load_softscope(char *exectype, void *initarg);
|
||||
int end_forms(void) ;
|
||||
#endif
|
||||
|
||||
@@ -68,8 +68,10 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
|
||||
*recplay_conf=NULL;
|
||||
}
|
||||
|
||||
if (u_sf_replay == 1) return RECPLAY_REPLAYMODE;
|
||||
else if (u_sf_record == 1) return RECPLAY_RECORDMODE;
|
||||
if (u_sf_replay == 1)
|
||||
return RECPLAY_REPLAYMODE;
|
||||
else if (u_sf_record == 1)
|
||||
return RECPLAY_RECORDMODE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -80,7 +82,7 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
|
||||
*/
|
||||
void iqrecorder_end(openair0_device *device) {
|
||||
if (device->recplay_state != NULL) { // subframes store
|
||||
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,OAIIQFILE_ID};
|
||||
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
|
||||
recplay_state_t *rs = device->recplay_state;
|
||||
recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf;
|
||||
rs->pFile = fopen (rc->u_sf_filename,"wb+");
|
||||
@@ -91,16 +93,20 @@ void iqrecorder_end(openair0_device *device) {
|
||||
unsigned int i = 0;
|
||||
unsigned int modu = 0;
|
||||
|
||||
if ((modu = rs->nb_samples % 10) != 0) {
|
||||
rs->nb_samples -= modu; // store entire number of frames
|
||||
if ((modu = rs->nbSamplesBlocks % 10) != 0) {
|
||||
rs->nbSamplesBlocks -= modu; // store entire number of frames
|
||||
}
|
||||
|
||||
fh.nbSamplesBlocks=rs->nbSamplesBlocks;
|
||||
LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename );
|
||||
fwrite(&fh, sizeof(fh), 1, rs->pFile);
|
||||
LOG_UI(HW,"Writing %u subframes to %s \n",rs->nb_samples, rc->u_sf_filename );
|
||||
LOG_UI(HW,"Writing %u subframes to %s \n",rs->nbSamplesBlocks, rc->u_sf_filename );
|
||||
uint8_t *ptr=(uint8_t *)rs->ms_sample;
|
||||
|
||||
for (i = 0; i < rs->nb_samples; i++) {
|
||||
fwrite(rs->ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), rs->pFile);
|
||||
for (i = 0; i < rs->nbSamplesBlocks; i++) {
|
||||
int blockBytes=sizeof(iqrec_t)+((iqrec_t *)ptr)->nbBytes;
|
||||
fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile);
|
||||
ptr+=blockBytes;
|
||||
}
|
||||
|
||||
fclose (rs->pFile);
|
||||
@@ -112,4 +118,4 @@ void iqrecorder_end(openair0_device *device) {
|
||||
rs->ms_sample = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,21 +46,22 @@ extern "C"
|
||||
#define BELL_LABS_IQ_HEADER 0xabababababababab
|
||||
#define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now
|
||||
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
|
||||
#define MAX_BELL_LABS_IQ_BYTES_PER_SF BELL_LABS_IQ_BYTES_PER_SF*10
|
||||
|
||||
#define OAIIQFILE_ID "OIQF"
|
||||
#define OAIIQFILE_ID {'O', 'I','Q','F'}
|
||||
typedef struct {
|
||||
uint64_t devtype;
|
||||
uint64_t tx_sample_advance;
|
||||
double bw;
|
||||
unsigned int nbSamplesBlocks;
|
||||
char oaiid[4];
|
||||
} iqfile_header_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t header;
|
||||
int64_t ts;
|
||||
int64_t rfu1;
|
||||
int64_t nbBytes;
|
||||
int64_t rfu2; // pad for 256 bits alignement required by AVX2
|
||||
unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe
|
||||
} iqrec_t;
|
||||
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
|
||||
#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name
|
||||
@@ -114,14 +115,16 @@ typedef struct {
|
||||
int use_mmap; // default is to use mmap
|
||||
size_t mapsize;
|
||||
FILE *pFile;
|
||||
int mmapfd;
|
||||
int iqfd;
|
||||
int fd;
|
||||
iqrec_t *ms_sample; // memory for all subframes
|
||||
unsigned int nb_samples;
|
||||
unsigned int nbSamplesBlocks;
|
||||
uint8_t *currentPtr;
|
||||
uint64_t currentTs;
|
||||
unsigned int curSamplesBlock;
|
||||
int64_t wrap_count;
|
||||
size_t maxSizeBytes;
|
||||
} recplay_state_t;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,18 +40,15 @@
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) {
|
||||
AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),
|
||||
"iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n",
|
||||
iq_fh->oaiid);
|
||||
char tmp[4]=OAIIQFILE_ID;
|
||||
AssertFatal((memcmp(iq_fh->oaiid,tmp,sizeof(iq_fh->oaiid)) == 0),
|
||||
"iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n",
|
||||
iq_fh->oaiid);
|
||||
device->type = iq_fh->devtype;
|
||||
device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance;
|
||||
device->openair0_cfg[0].tx_bw = device->openair0_cfg[0].rx_bw = iq_fh->bw;
|
||||
device->recplay_state->nbSamplesBlocks=iq_fh->nbSamplesBlocks;
|
||||
LOG_UI(HW,"Replay iqs from %s device, bandwidth %e\n",get_devname(iq_fh->devtype),iq_fh->bw);
|
||||
}
|
||||
|
||||
@@ -63,89 +60,73 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
|
||||
recplay_state_t *s = device->recplay_state;
|
||||
recplay_conf_t *c = openair0_cfg->recplay_conf;
|
||||
|
||||
struct stat sb;
|
||||
s->fd = open(c->u_sf_filename, O_RDONLY );
|
||||
if (s->fd >= 0 ) {
|
||||
fstat(s->fd, &sb);
|
||||
} else {
|
||||
LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (s->use_mmap) {
|
||||
// use mmap
|
||||
s->mmapfd = open(c->u_sf_filename, O_RDONLY );
|
||||
|
||||
if (s->mmapfd != 0) {
|
||||
struct stat sb;
|
||||
fstat(s->mmapfd, &sb);
|
||||
s->mapsize=sb.st_size;
|
||||
LOG_I(HW,"Loading subframes using mmap() from %s size=%lu bytes ...\n",c->u_sf_filename, (uint64_t)sb.st_size );
|
||||
void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) ;
|
||||
s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) + sizeof(iqfile_header_t));
|
||||
void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) ;
|
||||
s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) + sizeof(iqfile_header_t));
|
||||
|
||||
if (mptr != MAP_FAILED) {
|
||||
parse_iqfile_header(device, (iqfile_header_t *)mptr);
|
||||
s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t));
|
||||
s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t)) / sizeof(iqrec_t));
|
||||
int aligned = (((unsigned long)s->ms_sample & 31) == 0)? 1:0;
|
||||
LOG_I(HW,"Loaded %u subframes.\n",s->nb_samples );
|
||||
|
||||
if (aligned == 0) {
|
||||
LOG_E(HW, "mmap address is not 32 bytes aligned, exiting.\n" );
|
||||
close(s->mmapfd);
|
||||
exit(-1);
|
||||
}
|
||||
LOG_I(HW,"Loaded %u subframes.\n",s->nbSamplesBlocks );
|
||||
} else {
|
||||
LOG_E(HW,"Cannot mmap file, exiting.\n");
|
||||
close(s->mmapfd);
|
||||
close(s->fd);
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename );
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
s->iqfd = open(c->u_sf_filename, O_RDONLY);
|
||||
iqfile_header_t fh;
|
||||
size_t hs = read(s->fd,&fh,sizeof(fh));
|
||||
|
||||
if (s->iqfd != 0) {
|
||||
struct stat sb;
|
||||
iqfile_header_t fh;
|
||||
size_t hs = read(s->iqfd,&fh,sizeof(fh));
|
||||
|
||||
if (hs == sizeof(fh)) {
|
||||
parse_iqfile_header(device, &fh);
|
||||
fstat(s->iqfd, &sb);
|
||||
if (hs == sizeof(fh)) {
|
||||
parse_iqfile_header(device, &fh);
|
||||
fstat(s->fd, &sb);
|
||||
s->mapsize=sb.st_size;
|
||||
s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t))/ sizeof(iqrec_t));
|
||||
LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nb_samples, c->u_sf_filename,(uint64_t)sb.st_size);
|
||||
LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nbSamplesBlocks, c->u_sf_filename,(uint64_t)sb.st_size);
|
||||
// allocate buffer for 1 sample at a time
|
||||
s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t));
|
||||
s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)+MAX_BELL_LABS_IQ_BYTES_PER_SF*4);
|
||||
|
||||
if (s->ms_sample == NULL) {
|
||||
LOG_E(HW,"Memory allocation failed for individual subframe replay mode.\n" );
|
||||
close(s->iqfd);
|
||||
close(s->fd);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(s->ms_sample, 0, sizeof(iqrec_t));
|
||||
|
||||
// point at beginning of iqs in file
|
||||
if (lseek(s->iqfd,sizeof(iqfile_header_t), SEEK_SET) == 0) {
|
||||
if (lseek(s->fd,sizeof(iqfile_header_t), SEEK_SET) == 0) {
|
||||
LOG_I(HW,"Initial seek at beginning of the file\n" );
|
||||
} else {
|
||||
LOG_I(HW,"Problem initial seek at beginning of the file\n");
|
||||
}
|
||||
} else {
|
||||
LOG_E(HW,"Cannot read header in %s exiting.\n",c->u_sf_filename );
|
||||
close(s->iqfd);
|
||||
close(s->fd);
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
LOG_E(HW,"Cannot open %s exiting.\n",c->u_sf_filename );
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
s->currentPtr=(uint8_t *)s->ms_sample;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief start the oai iq player
|
||||
* \param device, the hardware used
|
||||
*/
|
||||
static int trx_iqplayer_start(openair0_device *device){
|
||||
return 0;
|
||||
static int trx_iqplayer_start(openair0_device *device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief Terminate operation of the oai iq player
|
||||
@@ -157,28 +138,22 @@ static void trx_iqplayer_end(openair0_device *device) {
|
||||
|
||||
if (device->recplay_state == NULL)
|
||||
return;
|
||||
|
||||
|
||||
if (device->recplay_state->use_mmap) {
|
||||
if (device->recplay_state->ms_sample != MAP_FAILED) {
|
||||
munmap(device->recplay_state->ms_sample, device->recplay_state->mapsize);
|
||||
device->recplay_state->ms_sample = NULL;
|
||||
}
|
||||
|
||||
if (device->recplay_state->mmapfd != 0) {
|
||||
close(device->recplay_state->mmapfd);
|
||||
device->recplay_state->mmapfd = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (device->recplay_state->ms_sample != NULL) {
|
||||
free(device->recplay_state->ms_sample);
|
||||
device->recplay_state->ms_sample = NULL;
|
||||
}
|
||||
|
||||
if (device->recplay_state->iqfd != 0) {
|
||||
close(device->recplay_state->iqfd);
|
||||
device->recplay_state->iqfd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
device->recplay_state->ms_sample = NULL;
|
||||
if (device->recplay_state->fd >= 0) {
|
||||
close(device->recplay_state->fd);
|
||||
device->recplay_state->fd = -1;
|
||||
}
|
||||
|
||||
}
|
||||
/*! \brief Write iqs function when in replay mode, just introduce a delay, as configured at init time,
|
||||
@param device pointer to the device structure specific to the RF hardware target
|
||||
@@ -208,93 +183,68 @@ static int trx_iqplayer_write(openair0_device *device, openair0_timestamp timest
|
||||
* \returns the number of sample read
|
||||
*/
|
||||
static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
|
||||
int samples_received=0;
|
||||
static unsigned int cur_samples;
|
||||
static int64_t wrap_count;
|
||||
static int64_t wrap_ts;
|
||||
recplay_state_t *s = device->recplay_state;
|
||||
|
||||
if (cur_samples == s->nb_samples) {
|
||||
cur_samples = 0;
|
||||
wrap_count++;
|
||||
if (s->curSamplesBlock==0 && s->wrap_count==0 )
|
||||
s->currentTs=s->ms_sample->ts;
|
||||
|
||||
if (s->curSamplesBlock == s->nbSamplesBlocks) {
|
||||
LOG_I(HW, "wrapping on iq file (%ld)\n", s->wrap_count);
|
||||
s->curSamplesBlock = 0;
|
||||
s->wrap_count++;
|
||||
|
||||
if (wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) {
|
||||
LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n",device->openair0_cfg->recplay_conf->u_sf_loops);
|
||||
if (s->wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) {
|
||||
LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n",
|
||||
device->openair0_cfg->recplay_conf->u_sf_loops);
|
||||
exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n");
|
||||
}
|
||||
|
||||
wrap_ts = wrap_count * (s->nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000));
|
||||
LOG_I(HW,"go back at the beginning of IQ file");
|
||||
device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample;
|
||||
|
||||
if (!device->recplay_state->use_mmap) {
|
||||
if (lseek(device->recplay_state->iqfd, 0, SEEK_SET) == 0) {
|
||||
LOG_I(HW,"Seeking at the beginning of IQ file");
|
||||
} else {
|
||||
LOG_I(HW, "Problem seeking at the beginning of IQ file");
|
||||
if (!s->use_mmap) {
|
||||
if (lseek(device->recplay_state->fd, 0, SEEK_SET) != 0) {
|
||||
LOG_E(HW, "Problem seeking at the beginning of IQ file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s->use_mmap) {
|
||||
if (cur_samples < s->nb_samples) {
|
||||
*ptimestamp = (s->ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts;
|
||||
|
||||
if (cur_samples == 0) {
|
||||
LOG_I(HW,"starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu\n", wrap_count,wrap_ts,*ptimestamp);
|
||||
}
|
||||
|
||||
memcpy(buff[0], &s->ms_sample[cur_samples].samples[0], nsamps*4);
|
||||
cur_samples++;
|
||||
}
|
||||
} else {
|
||||
if (!s->use_mmap) {
|
||||
// read sample from file
|
||||
if (read(s->iqfd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
|
||||
LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*cur_samples );
|
||||
close(s->iqfd);
|
||||
free(s->ms_sample);
|
||||
s->ms_sample = NULL;
|
||||
s->iqfd = 0;
|
||||
if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
|
||||
LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (cur_samples < s->nb_samples) {
|
||||
static int64_t ts0 = 0;
|
||||
|
||||
if ((cur_samples == 0) && (wrap_count == 0)) {
|
||||
ts0 = s->ms_sample->ts;
|
||||
}
|
||||
|
||||
*ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts;
|
||||
|
||||
if (cur_samples == 0) {
|
||||
LOG_I(HW, "starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu ",wrap_count,wrap_ts, *ptimestamp);
|
||||
}
|
||||
|
||||
memcpy(buff[0], &s->ms_sample->samples[0], nsamps*4);
|
||||
cur_samples++;
|
||||
// Prepare for next read
|
||||
off_t where = lseek(s->iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET);
|
||||
|
||||
if (where < 0) {
|
||||
LOG_E(HW,"Cannot lseek in iqfile: %s\n",strerror(errno));
|
||||
} else {
|
||||
if (read(s->fd, s->ms_sample+1, s->ms_sample->nbBytes) != s->ms_sample->nbBytes) {
|
||||
LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock );
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iqrec_t *curHeader=(iqrec_t *)s->currentPtr;
|
||||
AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" );
|
||||
// the current timestamp is the stored timestamp until we wrap on input
|
||||
// USRP shifts 1 sample time to time
|
||||
AssertFatal(s->wrap_count !=0 || abs(curHeader->ts-s->currentTs) < 5 ,"");
|
||||
AssertFatal(nsamps*4==curHeader->nbBytes,"");
|
||||
*ptimestamp = s->currentTs;
|
||||
memcpy(buff[0], curHeader+1, nsamps*4);
|
||||
s->curSamplesBlock++;
|
||||
// Prepare for next read
|
||||
s->currentTs+=nsamps;
|
||||
|
||||
if (s->use_mmap)
|
||||
s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes;
|
||||
|
||||
struct timespec req;
|
||||
|
||||
req.tv_sec = 0;
|
||||
|
||||
req.tv_nsec = (device->openair0_cfg[0].recplay_conf->u_sf_read_delay) * 1000;
|
||||
|
||||
nanosleep(&req, NULL);
|
||||
|
||||
LOG_D(HW, "returning %d samples at ts %lu\n", nsamps, *ptimestamp);
|
||||
return nsamps;
|
||||
|
||||
return samples_received;
|
||||
}
|
||||
|
||||
|
||||
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
device->openair0_cfg = openair0_cfg;
|
||||
device->trx_start_func = trx_iqplayer_start;
|
||||
@@ -313,5 +263,4 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
LOG_UI(HW,"iqplayer device initialized, replay %s for %i iterations",openair0_cfg->recplay_conf->u_sf_filename,openair0_cfg->recplay_conf->u_sf_loops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -727,7 +727,7 @@ int main ( int argc, char **argv )
|
||||
fflush(stderr);
|
||||
// end of CI modifications
|
||||
//getchar();
|
||||
if(IS_SOFTMODEM_DOFORMS)
|
||||
if(IS_SOFTMODEM_DOSCOPE)
|
||||
load_softscope("enb",NULL);
|
||||
itti_wait_tasks_end();
|
||||
oai_exit=1;
|
||||
@@ -735,7 +735,7 @@ int main ( int argc, char **argv )
|
||||
// stop threads
|
||||
|
||||
if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
|
||||
if(IS_SOFTMODEM_DOFORMS)
|
||||
if(IS_SOFTMODEM_DOSCOPE)
|
||||
end_forms();
|
||||
|
||||
LOG_I(ENB_APP,"stopping MODEM threads\n");
|
||||
|
||||
@@ -758,7 +758,7 @@ int main( int argc, char **argv ) {
|
||||
PHY_vars_UE_g[0][0]->no_timing_correction = 1;
|
||||
}
|
||||
|
||||
if(IS_SOFTMODEM_DOFORMS)
|
||||
if(IS_SOFTMODEM_DOSCOPE)
|
||||
load_softscope("ue",NULL);
|
||||
|
||||
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
|
||||
@@ -783,7 +783,7 @@ int main( int argc, char **argv ) {
|
||||
printf("oai_exit=%d\n",oai_exit);
|
||||
|
||||
// stop threads
|
||||
if(IS_SOFTMODEM_DOFORMS)
|
||||
if(IS_SOFTMODEM_DOSCOPE)
|
||||
end_forms();
|
||||
|
||||
printf("stopping MODEM threads\n");
|
||||
|
||||
Reference in New Issue
Block a user