From 0317d6725bc3fac2a299f9df65162cc67e53fb60 Mon Sep 17 00:00:00 2001
From: Laurent THOMAS <laurent.thomas@open-cells.com>
Date: Fri, 2 Apr 2021 10:12:13 +0200
Subject: [PATCH] sanitize, calibration tool kickoff

---
 cmake_targets/CMakeLists.txt           |  12 +
 cmake_targets/tools/run_enb_s1_usrp    |  13 -
 common/utils/system.c                  |  26 +-
 common/utils/system.h                  |   8 +-
 executables/nr-softmodem.c             |   1 -
 executables/nr-softmodem.h             |   4 -
 executables/ocp-gnb.c                  |   3 -
 openair1/PHY/TOOLS/calibration_scope.c | 387 +++++++++++++++++++++++++
 openair1/PHY/TOOLS/calibration_scope.h |   5 +
 openair1/PHY/TOOLS/calibration_test.c  | 329 +++++++++++++++++++++
 openair2/GNB_APP/gnb_paramdef.h        |  10 +-
 openair2/SIMULATION/NR_RRC/itti_sim.c  |   3 -
 openair2/UTIL/OCG/OCG.h                |   1 -
 targets/ARCH/COMMON/common_lib.h       |   1 +
 14 files changed, 762 insertions(+), 41 deletions(-)
 create mode 100644 openair1/PHY/TOOLS/calibration_scope.c
 create mode 100644 openair1/PHY/TOOLS/calibration_scope.h
 create mode 100644 openair1/PHY/TOOLS/calibration_test.c

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 7643fedb9d3..477dfb79766 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -2797,6 +2797,7 @@ add_library(rfsimulator MODULE
   ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
   ${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c
   ${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c
+  ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
 	)
 target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES})
 
@@ -3181,6 +3182,17 @@ target_link_libraries (dlsim_tm4
   pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB}
   )
 
+add_executable(rftest 
+  ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c
+  ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_scope.c
+  ${OPENAIR_DIR}/common/utils/system.c
+  ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+  ${OPENAIR_DIR}/executables/softmodem-common.c
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
+)
+target_link_libraries(rftest minimal_lib PHY_NR_COMMON pthread dl m forms ${T_LIB} )
+
 add_executable(polartest 
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
   ${OPENAIR_DIR}/common/utils/backtrace.c
diff --git a/cmake_targets/tools/run_enb_s1_usrp b/cmake_targets/tools/run_enb_s1_usrp
index e1191266830..1a4c6b10b83 100755
--- a/cmake_targets/tools/run_enb_s1_usrp
+++ b/cmake_targets/tools/run_enb_s1_usrp
@@ -101,7 +101,6 @@ function main()
   local -i run_gdb=0
   local -i show_stdout=0
   local    exe_arguments=""
-  local    itti_dump_file=""
   
   until [ -z "$1" ]
     do
@@ -154,18 +153,6 @@ function main()
             exe_arguments="$exe_arguments --rf-config-file=$rf_config_file"
 	fi 
         ;;      
-     -K | --itti-dump-file)
-        itti_dump_file=$2
-        # can omit file name if last arg on the line
-        if [ "x$itti_dump_file" = "x" ]; then
-          itti_dump_file="/tmp/enb_s1_usrp_itti.log"
-          shift 1;
-        else
-          shift 2;
-        fi
-        echo "setting ITTI dump file to: $itti_dump_file"
-        exe_arguments="$exe_arguments -K $itti_dump_file"
-        ;;      
       -m | --mscgen)
         g_msc_dir=$2
         # can omit file name if last arg on the line
diff --git a/common/utils/system.c b/common/utils/system.c
index 1bd5c7d39bc..239ea525c7a 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -199,15 +199,26 @@ void start_background_system(void) {
 
 void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
   pthread_attr_t attr;
-  pthread_attr_init(&attr);
-  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-  pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-  pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+  int ret;
+  AssertFatal(0==(ret=pthread_attr_init(&attr)),"ret: %d, errno: %d\n",ret, errno);
+  AssertFatal(0==(ret=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)),"ret: %d, errno: %d\n",ret, errno);
+  AssertFatal(0==(ret=pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)),"ret: %d, errno: %d\n",ret, errno);
+  AssertFatal(0==(ret=pthread_attr_setschedpolicy(&attr, SCHED_OAI)),"ret: %d, errno: %d\n",ret, errno);
+  if(priority<sched_get_priority_min(SCHED_OAI) || priority>sched_get_priority_max(SCHED_FIFO)) {
+    LOG_E(TMR,"Prio not possible: %d, min is %d, max: %d, forced in the range\n", 
+              priority, 
+              sched_get_priority_min(SCHED_OAI),
+              sched_get_priority_max(SCHED_OAI));
+    if(priority<sched_get_priority_min(SCHED_OAI))
+      priority=sched_get_priority_min(SCHED_OAI);
+    if(priority>sched_get_priority_max(SCHED_OAI))
+      priority=sched_get_priority_max(SCHED_OAI);
+  }
+  AssertFatal(priority<=sched_get_priority_max(SCHED_OAI),"");
   struct sched_param sparam={0};
   sparam.sched_priority = priority;
-  pthread_attr_setschedparam(&attr, &sparam);
-
-  pthread_create(t, &attr, func, param);
+  AssertFatal(0==(ret=pthread_attr_setschedparam(&attr, &sparam)),"ret: %d, errno: %d\n",ret, errno);
+  AssertFatal(0==(ret=pthread_create(t, &attr, func, param)),"ret: %d, errno: %d\n",ret, errno);
 
   pthread_setname_np(*t, name);
   if (affinity != -1 ) {
@@ -216,7 +227,6 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name,
     CPU_SET(affinity, &cpuset);
     AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
   }
-
   pthread_attr_destroy(&attr);
 }
 
diff --git a/common/utils/system.h b/common/utils/system.h
index 760b7840a5d..46316f6db68 100644
--- a/common/utils/system.h
+++ b/common/utils/system.h
@@ -46,9 +46,11 @@ void set_latency_target(void);
 void configure_linux(void);
 
 void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
-#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
-#define OAI_PRIORITY_RT sched_get_priority_min(SCHED_FIFO+10)
-#define OAI_PRIORITY_RT_MAX sched_get_priority_min(SCHED_FIFO+20)
+ 
+#define SCHED_OAI SCHED_RR
+#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_OAI)
+#define OAI_PRIORITY_RT sched_get_priority_min(SCHED_OAI)+1
+#define OAI_PRIORITY_RT_MAX sched_get_priority_min(SCHED_OAI)+2
 
 void thread_top_init(char *thread_name,
                      int affinity,
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 63c06563d28..692e4d530fc 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -114,7 +114,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 //Temp fix for inexistent NR upper layer
 unsigned char NB_gNB_INST = 1;
 
-static char                    *itti_dump_file = NULL;
 
 int UE_scan = 1;
 int UE_scan_carrier = 0;
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index d6cfe6b906a..18a6fe42d0f 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -18,13 +18,9 @@
 /*   optname                helpstr                 paramflags        XXXptr                              defXXXval                   type         numelt               */
 /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define CMDLINE_PARAMS_DESC_GNB {  \
-    {"mmapped-dma",           CONFIG_HLP_DMAMAP,      PARAMFLAG_BOOL,   uptr:&mmapped_dma,                  defintval:0,                   TYPE_INT,    0},        \
     {"single-thread-disable", CONFIG_HLP_NOSNGLT,     PARAMFLAG_BOOL,   iptr:&single_thread_flag,           defintval:1,                   TYPE_INT,    0},        \
     {"A" ,                    CONFIG_HLP_TADV,        0,                uptr:&timing_advance,               defintval:0,                   TYPE_UINT,   0},        \
     {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL,   i8ptr:&threequarter_fs,             defintval:0,                   TYPE_INT8,   0},        \
-    {"K" ,                    CONFIG_HLP_ITTIL,       PARAMFLAG_NOFREE, strptr:&itti_dump_file,             defstrval:"/tmp/itti.dump",    TYPE_STRING, 0},        \
-    {"m" ,                    CONFIG_HLP_DLMCS,       0,                uptr:&target_dl_mcs,                defintval:0,                   TYPE_UINT,   0},        \
-    {"t" ,                    CONFIG_HLP_ULMCS,       0,                uptr:&target_ul_mcs,                defintval:0,                   TYPE_UINT,   0},        \
     {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0,                iptr:&usrp_tx_thread,               defstrval:0,                   TYPE_INT,    0},        \
     {"s" ,                    CONFIG_HLP_SNR,         0,                dblptr:&snr_dB,                     defdblval:25,                  TYPE_DOUBLE, 0},        \
   }
diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c
index 9a09a1247cc..1f851321860 100644
--- a/executables/ocp-gnb.c
+++ b/executables/ocp-gnb.c
@@ -61,8 +61,6 @@ uint32_t do_forms=0;
 unsigned int mmapped_dma=0;
 int8_t threequarter_fs=0;
 
-uint32_t target_dl_mcs = 28; //maximum allowed mcs
-uint32_t target_ul_mcs = 20;
 int chain_offset=0;
 uint16_t sl_ahead=6;
 uint16_t sf_ahead=6;
@@ -122,7 +120,6 @@ int restart_L1L2(module_id_t gnb_id) {
 }
 
 static int wait_for_sync = 0;
-static char *itti_dump_file = NULL;
 static double snr_dB=20;
 static int DEFBANDS[] = {7};
 static int DEFENBS[] = {0};
diff --git a/openair1/PHY/TOOLS/calibration_scope.c b/openair1/PHY/TOOLS/calibration_scope.c
new file mode 100644
index 00000000000..da1acb51757
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_scope.c
@@ -0,0 +1,387 @@
+#include <stdlib.h>
+#include <openair1/PHY/impl_defs_top.h>
+#include "executables/softmodem-common.h"
+#include "executables/nr-softmodem-common.h"
+#include <forms.h>
+#include <openair1/PHY/TOOLS/calibration_scope.h>
+
+#define TPUT_WINDOW_LENGTH 100
+#define ScaleZone 4
+
+const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
+const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
+
+typedef struct {
+  int16_t r;
+  int16_t i;
+} scopeSample_t;
+#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
+typedef struct {
+  void ** samplesRx;
+  openair0_device *rfdevice;
+} calibData_t;
+
+typedef struct OAIgraph {
+  FL_OBJECT *graph;
+  FL_OBJECT *text;
+  float maxX;
+  float maxY;
+  float minX;
+  float minY;
+  int x;
+  int y;
+  int w;
+  int h;
+  int waterFallh;
+  double *waterFallAvg;
+  boolean_t initDone;
+  int iteration;
+  void (*funct) (struct OAIgraph *graph, calibData_t *);
+} OAIgraph_t;
+
+
+/* Forms and Objects */
+typedef struct {
+  calibData_t * context;
+  FL_FORM    *phy_scope;
+  OAIgraph_t graph[20];
+  FL_OBJECT *button_0;
+} OAI_phy_scope_t;
+
+typedef struct {
+  FL_FORM    *stats_form;
+  void       *vdata;
+  char       *cdata;
+  long        ldata;
+  FL_OBJECT *stats_text;
+  FL_OBJECT *stats_button;
+} FD_stats_form;
+
+static void drawsymbol(FL_OBJECT *obj, int id,
+                       FL_POINT *p, int n, int w, int h) {
+  fl_points( p, n, FL_YELLOW);
+}
+
+#define WATERFALL 10000
+
+static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+  if (type==WATERFALL) {
+    graph->waterFallh=h-15;
+    graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh);
+
+    for (int i=0; i< graph->waterFallh; i++)
+      graph->waterFallAvg[i]=0;
+
+    graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label);
+    graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label);
+    fl_set_object_lcolor(graph->text,FL_WHITE);
+    fl_set_object_color(graph->text, FL_BLACK, FL_BLACK);
+    fl_set_object_lalign(graph->text, FL_ALIGN_CENTER );
+  } else {
+    graph->graph=fl_add_xyplot(type, x, y, w, h, label);
+    fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color
+    fl_set_object_color(graph->graph, FL_BLACK, pointColor);
+
+    for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++)
+      fl_set_xyplot_symbol(graph->graph, i, drawsymbol);
+  }
+
+  graph->x=x;
+  graph->y=y;
+  graph->w=w;
+  graph->h=h;
+  graph->maxX=0;
+  graph->maxY=0;
+  graph->minX=0;
+  graph->minY=0;
+  graph->initDone=false;
+  graph->iteration=0;
+}
+
+static OAIgraph_t calibrationCommonGraph( void (*funct) (OAIgraph_t *graph, calibData_t *context),
+                                  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);
+  graph.funct=funct;
+  return graph;
+}
+
+
+static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) {
+  if ( maxX > graph->maxX ||  minX < graph->minX ||
+       abs(maxX-graph->maxX)>abs(graph->maxX)/2 ||
+       abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) {
+    graph->maxX/=2;
+    graph->minX/=2;
+    graph->maxX=max(graph->maxX,maxX);
+    graph->minX=min(graph->minX,minX);
+    fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2);
+  }
+
+  if ( maxY > graph->maxY || minY < graph->minY ||
+       abs(maxY-graph->maxY)>abs(graph->maxY)/2 ||
+       abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) {
+    graph->maxY/=2;
+    graph->minY/=2;
+    graph->maxY=max(graph->maxY,maxY);
+    graph->minY=min(graph->minY,minY);
+    fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2);
+  }
+}
+
+static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) {
+  float *old_x;
+  float *old_y;
+  int old_len=-1;
+
+  if (graph->iteration >1)
+    fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
+
+  if (old_len != len) {
+    LOG_W(HW,"allocating graph of %d scope\n", len);
+    float values[len];
+    float time[len];
+
+    // make time in case we will use it
+    for (int i=0; i<len; i++)
+      time[i] = values[i] = i;
+
+    if (layer==0)
+      fl_set_xyplot_data(graph->graph,time,values,len,"","","");
+    else
+      fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]);
+
+    fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
+    AssertFatal(old_len==len,"");
+  }
+
+  *x=old_x;
+  *y=old_y;
+}
+
+static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) {
+  fl_redraw_object(graph->graph);
+
+  if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
+    float maxX=0, maxY=0, minX=0, minY=0;
+
+    for (int k=0; k<len; k++) {
+      maxX=max(maxX,x[k]);
+      minX=min(minX,x[k]);
+      maxY=max(maxY,y[k]);
+      minY=min(minY,y[k]);
+    }
+
+    setRange(graph, minX-5, maxX+5, minY-5, maxY+5);
+  }
+
+  graph->iteration++;
+}
+
+static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
+  if ( values == NULL )
+     return;
+  fl_winset(FL_ObjWin(graph->graph));
+  const int samplesPerPixel=datasize/graph->w;
+  int displayPart=graph->waterFallh-ScaleZone;
+  int row=graph->iteration%displayPart;
+  double avg=0;
+
+  for (int i=0; i < displayPart; i++)
+    avg+=graph->waterFallAvg[i];
+
+  avg/=displayPart;
+  graph->waterFallAvg[row]=0;
+
+  for (int pix=0; pix<graph->w; pix++) {
+    scopeSample_t *end=values+(pix+1)*samplesPerPixel;
+    end-=2;
+    AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize);
+    double val=0;
+
+    for (scopeSample_t *s=values+(pix)*samplesPerPixel;
+         s <end;
+         s++)
+      val += SquaredNorm(*s);
+
+    val/=samplesPerPixel;
+    graph->waterFallAvg[row]+=val/graph->w;
+    int col=0;
+
+    if (val > avg*2 )
+      col=1;
+
+    if (val > avg*10 )
+      col=2;
+
+    if (val > avg*100 )
+      col=3;
+
+    fl_point(pix, graph->iteration%displayPart, water_colors[col]);
+  }
+
+  if (graph->initDone==false) {
+    for ( int i=0; i < graph->waterFallh; i++ )
+      for ( int j = 0 ; j < graph->w ; j++ )
+        fl_point(j, i, FL_BLACK);
+
+    for ( int i=1; i<divisions; i++)
+      for (int j= displayPart; j<graph->waterFallh; j++)
+        fl_point(i*(graph->w/divisions),j, FL_WHITE);
+
+    graph->initDone=true;
+  }
+
+  fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg));
+  graph->iteration++;
+}
+
+static void genericPowerPerAntena(OAIgraph_t  *graph, const int nb_ant, const scopeSample_t **data, const int len) {
+  float *values, *time;
+  oai_xygraph_getbuff(graph, &time, &values, len, 0);
+
+  for (int ant=0; ant<nb_ant; ant++) {
+    if (data[ant] != NULL) {
+      for (int i=0; i<len; i++) {
+        values[i] = SquaredNorm(data[ant][i]);
+      }
+
+      oai_xygraph(graph,time,values, len, ant, 10);
+    }
+  }
+}
+
+static void gNBWaterFall (OAIgraph_t *graph, calibData_t *context) {
+  //use 1st antenna
+  genericWaterFall(graph, (scopeSample_t *)context->samplesRx[0],
+                   0, 0,
+                   "X axis:one frame in time");
+}
+static void gNBfreqWaterFall  (OAIgraph_t *graph, calibData_t *context) {
+  //use 1st antenna
+  genericWaterFall(graph, (scopeSample_t *)context->samplesRx[0],
+                   0, 0,
+                   "X axis:one frame in time");
+}
+static void timeResponse (OAIgraph_t *graph, calibData_t *context) {
+  #if 0
+  const int len=2*phy_vars_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 (data != NULL) {
+      for (int i=0; i<len; i++) {
+        values[i] = SquaredNorm(data[i]);
+      }
+
+      oai_xygraph(graph,time,values, len, ue, 10);
+    }
+  }
+  #endif
+}
+
+static void puschIQ (OAIgraph_t *graph, calibData_t *context) {
+  #if 0
+  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_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 (pusch_comp) {
+      for (int k=0; k<sz; k++ ) {
+        I[k] = pusch_comp[k].r;
+        Q[k] = pusch_comp[k].i;
+      }
+
+      oai_xygraph(graph,I,Q,sz,ue,10);
+    }
+  }
+  #endif
+}
+
+
+static OAI_phy_scope_t *createScopeCalibration(calibData_t * context) {
+  FL_OBJECT *obj;
+  OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
+  fdui->context=context;
+  // Define form
+  fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
+  // This the whole UI box
+  obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
+  fl_set_object_color( obj, FL_BLACK, FL_WHITE );
+  int curY=0,x,y,w,h;
+  // Received signal
+  fdui->graph[0] = calibrationCommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100,
+                                   "Received Signal (Time-Domain, one frame)", FL_RED );
+  
+  // Time-domain channel response
+  //fdui->graph[1] = calibrationCommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100, "SRS Frequency Response (samples, abs)", FL_RED );
+  fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
+  curY+=h;
+  // Frequency-domain channel response
+  fdui->graph[1] = calibrationCommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100,
+                                   "Channel Frequency domain (RE, one frame)", FL_RED );
+  fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
+  curY+=h+20;
+  // LLR of PUSCH
+  //fdui->graph[3] = calibrationCommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+  // I/Q PUSCH comp
+  fdui->graph[2] = calibrationCommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200,
+                                   "PUSCH I/Q of MF Output", FL_YELLOW );
+  fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
+  curY+=h;
+  //fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h);
+  curY+=h;
+  fdui->graph[3].graph=NULL;
+  fl_end_form( );
+  fdui->phy_scope->fdui = fdui;
+  fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
+  return fdui;
+}
+
+void calibrationScope(OAI_phy_scope_t  *form) {
+  int i=0;
+
+  while (form->graph[i].graph) {
+    form->graph[i].funct(form->graph+i, form->context);
+    i++;
+  }
+
+  //fl_check_forms();
+}
+
+static void *scopeThread(void *arg) {
+  calibData_t * context = (calibData_t *)arg;
+  size_t stksize=0;
+  pthread_attr_t atr;
+  pthread_attr_init(&atr);
+  pthread_attr_getstacksize(&atr, &stksize);
+  pthread_attr_setstacksize(&atr,32*1024*1024 );
+  sleep(3); // no clean interthread barriers
+  int fl_argc=1;
+  char *name="Calibration-scope";
+  fl_initialize (&fl_argc, &name, NULL, 0, 0);
+  OAI_phy_scope_t  *form = createScopeCalibration(context);
+
+  while (!oai_exit) {
+    calibrationScope(form);
+    usleep(99*1000);
+  }
+
+  return NULL;
+}
+
+void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice) {
+  pthread_t forms_thread;
+  calibData_t * tmp=(calibData_t *) malloc(sizeof(*tmp));
+  tmp->samplesRx=samplesRx;
+  tmp->rfdevice=rfdevice;
+  threadCreate(&forms_thread, scopeThread, (void*) tmp, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
diff --git a/openair1/PHY/TOOLS/calibration_scope.h b/openair1/PHY/TOOLS/calibration_scope.h
new file mode 100644
index 00000000000..052a1a6b6e5
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_scope.h
@@ -0,0 +1,5 @@
+#ifndef CALIB_SCOPE_H
+#define CALIB_SCOPE_H
+
+void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice);
+#endif
diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c
new file mode 100644
index 00000000000..376315734a9
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_test.c
@@ -0,0 +1,329 @@
+#include <stdint.h>
+#include <openair1/PHY/impl_defs_top.h>
+#include <targets/ARCH/COMMON/common_lib.h>
+#include <executables/softmodem-common.h>
+#include <openair1/PHY/TOOLS/calibration_scope.h>
+
+
+volatile int oai_exit=false;
+unsigned int mmapped_dma=0;
+int      single_thread_flag;
+uint32_t timing_advance;
+int8_t threequarter_fs;
+int usrp_tx_thread;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+int opp_enabled;
+static double snr_dB=20;
+#include <executables/nr-softmodem.h>
+
+int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;}
+void nfapi_setmode(nfapi_mode_t nfapi_mode) {}
+void set_taus_seed(unsigned int seed_init){};
+
+int main(int argc, char **argv) {
+  ///static configuration for NR at the moment
+  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  }
+  set_softmodem_sighandler();
+  setvbuf(stdout, NULL, _IONBF, 0);
+  setvbuf(stderr, NULL, _IONBF, 0);
+  logInit();
+   paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
+
+  CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
+  get_common_options(SOFTMODEM_GNB_BIT );
+  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
+  CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
+  configure_linux();
+
+    
+  int N_RB=50;
+  int subCarrierFreq=30e3;
+  int sampling_rate=30.72e6;
+  int DFT=2048;
+  int TxAdvanceInDFTSize=12;
+  int antennas=1;
+  uint64_t freq=3619.200e6;
+  int rxGain=90;
+  int txGain=90;
+  int filterBand=40e6;
+  char * usrp_addrs="type=b200";
+
+  openair0_config_t openair0_cfg= {
+    //! Module ID for this configuration
+    .Mod_id=0,
+    //! device log level
+    .log_level=0,
+    //! duplexing mode
+    .duplex_mode=0,
+    //! number of downlink resource blocks
+    .num_rb_dl=N_RB,
+    //! number of samples per frame
+    .samples_per_frame=0,
+    //! the sample rate for both transmit and receive.
+    .sample_rate=sampling_rate,
+    //device is doing mmapped DMA transfers
+    .mmapped_dma=0,
+    //! offset in samples between TX and RX paths
+    .tx_sample_advance=0,
+    //! samples per packet on the fronthaul interface
+    .samples_per_packet=1024,
+    //! number of RX channels (=RX antennas)
+    .rx_num_channels=antennas,
+    //! number of TX channels (=TX antennas)
+    .tx_num_channels=antennas,
+    //! \brief Center frequency in Hz for RX.
+    //! index: [0..rx_num_channels[
+    .rx_freq={freq,freq,freq,freq},
+    //! \brief Center frequency in Hz for TX.
+    //! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels
+    .tx_freq={freq,freq,freq,freq},
+    //! \brief memory
+    //! \brief Pointer to Calibration table for RX gains
+    .rx_gain_calib_table=NULL,
+    //! mode for rxgain (ExpressMIMO2)
+    .rxg_mode={0},
+    //! \brief Gain for RX in dB.
+    //! index: [0..rx_num_channels]
+    .rx_gain={rxGain,rxGain,rxGain,rxGain},
+    //! \brief Gain offset (for calibration) in dB
+    //! index: [0..rx_num_channels]
+    .rx_gain_offset={0},
+    //! gain for TX in dB
+    .tx_gain={txGain,txGain,txGain,txGain},
+    //! RX bandwidth in Hz
+    .rx_bw=filterBand,
+    //! TX bandwidth in Hz
+    .tx_bw=filterBand,
+    //! clock source
+    .clock_source=external,//internal gpsdo external
+    //! timing_source
+    .time_source=internal, //internal gpsdo external
+    //! Manual SDR IP address
+    //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+    .sdr_addrs=usrp_addrs,
+    //! Auto calibration flag
+    .autocal={0},
+    //! rf devices work with x bits iqs when oai have its own iq format
+    //! the two following parameters are used to convert iqs
+    .iq_txshift=0,
+    .iq_rxrescale=0,
+    //! Configuration file for LMS7002M
+    .configFilename="",
+    //! remote IP/MAC addr for Ethernet interface
+    .remote_addr="",
+    //! remote port number for Ethernet interface
+    .remote_port=0,
+    //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
+    .my_addr=0,
+    //! local port number for Ethernet interface (eNB/BBU, UE)
+    .my_port=0,
+    //! record player configuration, definition in record_player.h
+    .recplay_mode=0,
+    .recplay_conf=NULL,
+    //! number of samples per tti
+    .samples_per_tti=0,
+    //! check for threequarter sampling rate
+    .threequarter_fs=0,
+  };
+  //-----------------------
+  openair0_device rfdevice= {
+    /*!tx write thread*/
+    //.write_thread={0},
+    /*!brief Module ID of this device */
+    .Mod_id=0,
+    /*!brief Component Carrier ID of this device */
+    .CC_id=0,
+    /*!brief Type of this device */
+    .type=NONE_DEV,
+    /*!brief Transport protocol type that the device supports (in case I/Q samples need to be transported) */
+    .transp_type=NONE_TP,
+    /*!brief Type of the device's host (RAU/RRU) */
+    .host_type=MIN_HOST_TYPE,
+    /* !brief RF frontend parameters set by application */
+    .openair0_cfg=NULL, //set by device_init
+    /* !brief ETH params set by application */
+    .eth_params=NULL,
+    //! record player data, definition in record_player.h
+    .recplay_state=NULL,
+    /* !brief Indicates if device already initialized */
+    .is_init=0,
+    /*!brief Can be used by driver to hold internal structure*/
+    .priv=NULL,
+    /* Functions API, which are called by the application*/
+    /*! \brief Called to start the transceiver. Return 0 if OK, < 0 if error
+        @param device pointer to the device structure specific to the RF hardware target
+    */
+    .trx_start_func=NULL,
+
+    /*! \brief Called to configure the device
+         @param device pointer to the device structure specific to the RF hardware target
+     */
+    .trx_config_func=NULL,
+
+    /*! \brief Called to send a request message between RAU-RRU on control port
+        @param device pointer to the device structure specific to the RF hardware target
+        @param msg pointer to the message structure passed between RAU-RRU
+        @param msg_len length of the message
+    */
+    .trx_ctlsend_func=NULL,
+
+    /*! \brief Called to receive a reply  message between RAU-RRU on control port
+        @param device pointer to the device structure specific to the RF hardware target
+        @param msg pointer to the message structure passed between RAU-RRU
+        @param msg_len length of the message
+    */
+    .trx_ctlrecv_func=NULL,
+
+    /*! \brief Called to send samples to the RF target
+          @param device pointer to the device structure specific to the RF hardware target
+        @param timestamp The timestamp at whicch the first sample MUST be sent
+        @param buff Buffer which holds the samples (2 dimensional)
+        @param nsamps number of samples to be sent
+        @param number of antennas
+        @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+    */
+    .trx_write_func=NULL,
+
+    /*! \brief Called to send samples to the RF target
+        @param device pointer to the device structure specific to the RF hardware target
+        @param timestamp The timestamp at whicch the first sample MUST be sent
+        @param buff Buffer which holds the samples (1 dimensional)
+        @param nsamps number of samples to be sent
+        @param antenna_id index of the antenna if the device has multiple anteannas
+        @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+    */
+    .trx_write_func2=NULL,
+
+    /*! \brief Receive samples from hardware.
+     * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+     * the first channel. *ptimestamp is the time at which the first sample
+     * was received.
+     * \param device the hardware to use
+     * \param[out] ptimestamp the time at which the first sample was received.
+     * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
+     * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+     * \param num_antennas number of antennas from which to receive samples
+     * \returns the number of sample read
+     */
+
+    .trx_read_func=NULL,
+
+    /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns.
+     * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+     * the first channel. *ptimestamp is the time at which the first sample
+     * was received.
+     * \param device the hardware to use
+     * \param[out] ptimestamp the time at which the first sample was received.
+     * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps.
+     * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+     * \param antenna_id Index of antenna from which samples were received
+     * \returns the number of sample read
+     */
+    .trx_read_func2=NULL,
+
+    /*! \brief print the device statistics
+     * \param device the hardware to use
+     * \returns  0 on success
+     */
+    /*! \brief print the device statistics
+       * \param device the hardware to use
+       * \returns  0 on success
+       */
+    .trx_get_stats_func=NULL,
+
+    /*! \brief Reset device statistics
+     * \param device the hardware to use
+     * \returns 0 in success
+     */
+    .trx_reset_stats_func=NULL,
+
+    /*! \brief Terminate operation of the transceiver -- free all associated resources
+     * \param device the hardware to use
+     */
+    .trx_end_func=NULL,
+
+    /*! \brief Stop operation of the transceiver
+     */
+    .trx_stop_func=NULL,
+
+    /* Functions API related to UE*/
+
+    /*! \brief Set RX feaquencies
+     * \param device the hardware to use
+     * \param openair0_cfg RF frontend parameters set by application
+     * \param exmimo_dump_config  dump EXMIMO configuration
+     * \returns 0 in success
+     */
+    .trx_set_freq_func=NULL,
+
+    /*! \brief Set gains
+     * \param device the hardware to use
+     * \param openair0_cfg RF frontend parameters set by application
+     * \returns 0 in success
+     */
+    .trx_set_gains_func=NULL,
+
+    /*! \brief RRU Configuration callback
+     * \param idx RU index
+     * \param arg pointer to capabilities or configuration
+     */
+    .configure_rru=NULL,
+    /*! \brief Pointer to generic RRU private information
+       */
+    .thirdparty_priv=NULL,
+    .thirdparty_init=NULL,
+    /*! \brief Callback for Third-party RRU Cleanup routine
+       \param device the hardware configuration to use
+     */
+    .thirdparty_cleanup=NULL,
+
+    /*! \brief Callback for Third-party start streaming routine
+       \param device the hardware configuration to use
+     */
+    .thirdparty_startstreaming=NULL,
+
+    /*! \brief RRU Configuration callback
+     * \param idx RU index
+     * \param arg pointer to capabilities or configuration
+     */
+    .trx_write_init=NULL,
+    /* \brief Get internal parameter
+     * \param id parameter to get
+     * \return a pointer to the parameter
+     */
+    .get_internal_parameter=NULL,
+  };
+  
+  openair0_device_load(&rfdevice,&openair0_cfg);
+
+  void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+  void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+  
+  for (int i=0; i<antennas; i++) {
+    samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
+    samplesTx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
+  }
+
+  CalibrationInitScope(samplesRx, &rfdevice);
+  openair0_timestamp timestamp=0;
+  rfdevice.trx_start_func(&rfdevice);
+  
+  while(!oai_exit) {
+    int readBlockSize = rfdevice.trx_read_func(&rfdevice,
+					       &timestamp,
+					       samplesTx,
+					       DFT,
+					       antennas);
+    int txs = rfdevice.trx_write_func(&rfdevice,
+					    timestamp+TxAdvanceInDFTSize*DFT,
+					    samplesRx,
+					    DFT,
+					    antennas,
+					    0);
+  }
+
+  return 0;
+}
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index 8b326d58c9b..0bf7cb3892e 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -324,12 +324,12 @@ typedef enum {
 /*   optname                                            helpstr   paramflags    XXXptr              defXXXval             type           numelt     */
 /*--------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define GNBNETPARAMS_DESC {  \
-{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF,        NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
-{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF,          NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
-{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU,           NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
-{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU,                NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
+{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF,        NULL,      0,         strptr:NULL,         defstrval:"lo",      TYPE_STRING,      0},      \
+{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF,          NULL,      0,         strptr:NULL,         defstrval:"127.0.0.1",      TYPE_STRING,      0},      \
+{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU,           NULL,      0,         strptr:NULL,         defstrval:"lo",      TYPE_STRING,      0},      \
+{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU,                NULL,      0,         strptr:NULL,         defstrval:"127.0.0.1",      TYPE_STRING,      0},      \
 {GNB_CONFIG_STRING_GNB_PORT_FOR_NGU,                     NULL,      0,         uptr:NULL,           defintval:2152L,     TYPE_UINT,        0},      \
-{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C,                NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
+{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C,                NULL,      0,         strptr:NULL,         defstrval:"127.0.0.1",      TYPE_STRING,      0},      \
 {GNB_CONFIG_STRING_ENB_PORT_FOR_X2C,                     NULL,      0,         uptr:NULL,           defintval:0L,        TYPE_UINT,        0}      \
 }   
 
diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c
index 9b35ea67210..8b00636bf88 100644
--- a/openair2/SIMULATION/NR_RRC/itti_sim.c
+++ b/openair2/SIMULATION/NR_RRC/itti_sim.c
@@ -87,8 +87,6 @@ pthread_mutex_t nfapi_sync_mutex;
 int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
 
 uint8_t nfapi_mode = 0; // Default to monolithic mode
-uint32_t target_dl_mcs = 28;
-uint32_t target_ul_mcs = 20;
 uint32_t timing_advance = 0;
 uint64_t num_missed_slots=0;
 
@@ -120,7 +118,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 //Temp fix for inexistent NR upper layer
 unsigned char NB_gNB_INST = 1;
 
-static char                    *itti_dump_file = NULL;
 
 int UE_scan = 1;
 int UE_scan_carrier = 0;
diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h
index 34190f7d158..73f2f26d080 100644
--- a/openair2/UTIL/OCG/OCG.h
+++ b/openair2/UTIL/OCG/OCG.h
@@ -667,7 +667,6 @@ typedef struct {
   unsigned char omv_enabled; // openair mobility visulizer
   unsigned char opp_enabled; // openair performance profiler
   unsigned char oeh_enabled; // openair event handler, with CLI this could provide a remote event management
-  char *itti_dump_file;
   unsigned char vcd_enabled;
   char *vcd_file;
   unsigned char eMBMS_active_state;
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 93e9ffb52f8..2ab6d29d309 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -33,6 +33,7 @@
 #ifndef COMMON_LIB_H
 #define COMMON_LIB_H
 #include <stdint.h>
+#include <stdio.h>
 #include <sys/types.h>
 #include <openair1/PHY/TOOLS/tools_defs.h>
 #include "record_player.h"
-- 
GitLab