enb.c 26.9 KB
Newer Older
1 2 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
4
#include <unistd.h>
5
#include <pthread.h>
6
#include <signal.h>
7 8 9 10 11 12
#include "database.h"
#include "event.h"
#include "handler.h"
#include "logger/logger.h"
#include "view/view.h"
#include "gui/gui.h"
13
#include "filter/filter.h"
14 15 16
#include "utils.h"
#include "../T_defs.h"
#include "event_selector.h"
Cedric Roux's avatar
Cedric Roux committed
17
#include "openair_logo.h"
18
#include "config.h"
19

Cedric Roux's avatar
Cedric Roux committed
20
typedef struct {
21
  view *phyview;
Cedric Roux's avatar
Cedric Roux committed
22 23 24
  view *macview;
  view *rlcview;
  view *pdcpview;
Cedric Roux's avatar
Cedric Roux committed
25
  view *rrcview;
Cedric Roux's avatar
Cedric Roux committed
26
  view *legacy;
Cedric Roux's avatar
Cedric Roux committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
  widget *current_ue_label;
  widget *prev_ue_button;
  widget *next_ue_button;
  widget *pusch_iq_ue_xy_plot;
  widget *ul_estimate_ue_xy_plot;
  widget *pucch1_energy_ue_xy_plot;
  widget *pucch_iq_ue_xy_plot;
  widget *dl_ul_harq_ue_label;
  logger *pusch_iq_ue_logger;
  logger *ul_estimate_ue_logger;
  logger *pucch1_energy_ue_threshold_logger;
  logger *pucch1_energy_ue_energy_logger;
  logger *pucch_iq_ue_logger;
  logger *dl_dci_logger[8];
  logger *dl_ack_logger[8];
  logger *dl_nack_logger[8];
  logger *ul_dci_logger[8];
  logger *ul_dci_retransmission_logger[8];
  logger *ul_ack_logger[8];
  logger *ul_nack_logger[8];
Cedric Roux's avatar
Cedric Roux committed
47 48
} enb_gui;

49 50 51 52 53
typedef struct {
  int socket;
  int *is_on;
  int nevents;
  pthread_mutex_t lock;
Cedric Roux's avatar
Cedric Roux committed
54 55 56
  enb_gui *e;
  int ue;                /* what UE is displayed in the UE specific views */
  void *database;
57 58 59 60 61 62 63 64 65 66 67 68
} enb_data;

void is_on_changed(void *_d)
{
  enb_data *d = _d;
  char t;

  if (pthread_mutex_lock(&d->lock)) abort();

  if (d->socket == -1) goto no_connection;

  t = 1;
69 70 71
  if (socket_send(d->socket, &t, 1) == -1 ||
      socket_send(d->socket, &d->nevents, sizeof(int)) == -1 ||
      socket_send(d->socket, d->is_on, d->nevents * sizeof(int)) == -1)
72
    goto connection_dies;
73 74 75

no_connection:
  if (pthread_mutex_unlock(&d->lock)) abort();
76 77 78 79 80 81
  return;

connection_dies:
  close(d->socket);
  d->socket = -1;
  if (pthread_mutex_unlock(&d->lock)) abort();
82 83
}

84 85 86 87 88 89 90 91 92 93 94 95
void usage(void)
{
  printf(
"options:\n"
"    -d <database file>        this option is mandatory\n"
"    -on <GROUP or ID>         turn log ON for given GROUP or ID\n"
"    -off <GROUP or ID>        turn log OFF for given GROUP or ID\n"
"    -ON                       turn all logs ON\n"
"    -OFF                      turn all logs OFF\n"
"                              note: you may pass several -on/-off/-ON/-OFF,\n"
"                                    they will be processed in order\n"
"                                    by default, all is off\n"
96 97
"    -ip <host>                connect to given IP address (default %s)\n"
"    -p <port>                 connect to given port (default %d)\n"
98
"    -debug-gui                activate GUI debug logs\n",
99
  DEFAULT_REMOTE_IP,
100 101 102 103 104 105 106 107 108 109 110 111
  DEFAULT_REMOTE_PORT
  );
  exit(1);
}

static void *gui_thread(void *_g)
{
  gui *g = _g;
  gui_loop(g);
  return NULL;
}

Cedric Roux's avatar
Cedric Roux committed
112
static filter *ticktime_filter(void *database, char *event, int i, int ue)
113
{
Cedric Roux's avatar
Cedric Roux committed
114
  /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0" */
115 116 117 118
  return
    filter_and(
      filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)),
      filter_and(
Cedric Roux's avatar
Cedric Roux committed
119
        filter_eq(filter_evarg(database, event, "UE_id"), filter_int(ue)),
120 121 122
        filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0))));
}

Cedric Roux's avatar
Cedric Roux committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
static void set_current_ue(gui *g, enb_data *e, int ue)
{
  int i;
  char s[256];

  sprintf(s, "[UE %d]  ", ue);
  label_set_text(g, e->e->current_ue_label, s);
  sprintf(s, "PUSCH IQ [UE %d]", ue);
  xy_plot_set_title(g, e->e->pusch_iq_ue_xy_plot, s);
  sprintf(s, "UL estimated channel [UE %d]", ue);
  xy_plot_set_title(g, e->e->ul_estimate_ue_xy_plot, s);
  sprintf(s, "PUCCH1 energy (SR) [UE %d]", ue);
  xy_plot_set_title(g, e->e->pucch1_energy_ue_xy_plot, s);
  sprintf(s, "PUCCH IQ [UE %d]", ue);
  xy_plot_set_title(g, e->e->pucch_iq_ue_xy_plot, s);
  sprintf(s, "DL/UL HARQ (x8) [UE %d]", ue);
  label_set_text(g, e->e->dl_ul_harq_ue_label, s);

  logger_set_filter(e->e->pusch_iq_ue_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_PUSCH_IQ", "UE_ID"),
        filter_int(ue)));
  logger_set_filter(e->e->ul_estimate_ue_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_UL_CHANNEL_ESTIMATE", "UE_ID"),
        filter_int(ue)));
  logger_set_filter(e->e->pucch1_energy_ue_threshold_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
        filter_int(ue)));
  logger_set_filter(e->e->pucch1_energy_ue_energy_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
        filter_int(ue)));
  logger_set_filter(e->e->pucch_iq_ue_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_PUCCH_1AB_IQ", "UE_ID"),
        filter_int(ue)));
  for (i = 0; i < 8; i++) {
    logger_set_filter(e->e->dl_dci_logger[i],
        ticktime_filter(e->database, "ENB_PHY_DLSCH_UE_DCI", i, ue));
    logger_set_filter(e->e->dl_ack_logger[i],
        ticktime_filter(e->database, "ENB_PHY_DLSCH_UE_ACK", i, ue));
    logger_set_filter(e->e->dl_nack_logger[i],
        ticktime_filter(e->database, "ENB_PHY_DLSCH_UE_NACK", i, ue));
    logger_set_filter(e->e->ul_dci_logger[i],
        ticktime_filter(e->database, "ENB_PHY_ULSCH_UE_DCI", i, ue));
    logger_set_filter(e->e->ul_dci_retransmission_logger[i],
        ticktime_filter(e->database,
            "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", i, ue));
    logger_set_filter(e->e->ul_ack_logger[i],
        ticktime_filter(e->database, "ENB_PHY_ULSCH_UE_ACK", i, ue));
    logger_set_filter(e->e->ul_nack_logger[i],
        ticktime_filter(e->database, "ENB_PHY_ULSCH_UE_NACK", i, ue));
  }
}

static void click(void *private, gui *g,
    char *notification, widget *w, void *notification_data)
{
  int *d = notification_data;
  int button = d[0];
  enb_data *ed = private;
  enb_gui *e = ed->e;
  int ue = ed->ue;

  if (button != 1) return;
  if (w == e->prev_ue_button) { ue--; if (ue < 0) ue = 0; }
  if (w == e->next_ue_button) ue++;

Cedric Roux's avatar
Cedric Roux committed
193 194 195 196 197 198
  if (pthread_mutex_lock(&ed->lock)) abort();
  if (ue != ed->ue) {
    set_current_ue(g, ed, ue);
    ed->ue = ue;
  }
  if (pthread_mutex_unlock(&ed->lock)) abort();
Cedric Roux's avatar
Cedric Roux committed
199 200 201 202
}

static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
    enb_data *ed)
203 204 205
{
  widget *main_window;
  widget *top_container;
Cedric Roux's avatar
Cedric Roux committed
206
  widget *line, *col;
Cedric Roux's avatar
Cedric Roux committed
207
  widget *logo;
208 209 210
  widget *input_signal_plot;
  logger *input_signal_log;
  view *input_signal_view;
Cedric Roux's avatar
Cedric Roux committed
211
  widget *timeline_plot;
212 213 214
  logger *timelog;
  view *timeview;
  view *subview;
Cedric Roux's avatar
Cedric Roux committed
215 216
  widget *text;
  view *textview;
Cedric Roux's avatar
Cedric Roux committed
217
  int i;
Cedric Roux's avatar
Cedric Roux committed
218
  widget *w, *w2;
219 220
  view *v;
  logger *l;
221

222
  main_window = new_toplevel_window(g, 1200, 900, "eNB tracer");
223 224 225 226 227
  top_container = new_container(g, VERTICAL);
  widget_add_child(g, main_window, top_container, -1);

  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
Cedric Roux's avatar
Cedric Roux committed
228
  logo = new_image(g, openair_logo_png, openair_logo_png_len);
Cedric Roux's avatar
Cedric Roux committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248

  /* logo + prev/next UE buttons */
  col = new_container(g, VERTICAL);
  widget_add_child(g, col, logo, -1);
  w = new_container(g, HORIZONTAL);
  widget_add_child(g, col, w, -1);
  w2 = new_label(g, "");
  widget_add_child(g, w, w2, -1);
  e->current_ue_label = w2;
  /* TODO: use button widget, not label widget */
  w2 = new_label(g, "  [prev UE]  ");
  widget_add_child(g, w, w2, -1);
  label_set_clickable(g, w2, 1);
  e->prev_ue_button = w2;
  w2 = new_label(g, "  [next UE]  ");
  widget_add_child(g, w, w2, -1);
  label_set_clickable(g, w2, 1);
  e->next_ue_button = w2;
  widget_add_child(g, line, col, -1);

249 250 251 252
  input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20);
  widget_add_child(g, line, input_signal_plot, -1);
  xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70);
  input_signal_log = new_framelog(h, database,
253
      "ENB_PHY_INPUT_SIGNAL", "subframe", "rxdata");
254 255 256 257 258
  /* a skip value of 10 means to process 1 frame over 10, that is
   * more or less 10 frames per second
   */
  framelog_set_skip(input_signal_log, 10);
  input_signal_view = new_view_xy(7680*10, 10,
259
      g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE);
260
  logger_add_view(input_signal_log, input_signal_view);
Cedric Roux's avatar
Cedric Roux committed
261

Cedric Roux's avatar
Cedric Roux committed
262 263 264
  /* UE x PUSCH IQ data */
  w = new_xy_plot(g, 55, 55, "", 50);
  e->pusch_iq_ue_xy_plot = w;
265 266 267 268 269 270
  widget_add_child(g, line, w, -1);
  xy_plot_set_range(g, w, -1000, 1000, -1000, 1000);
  l = new_iqlog(h, database, "ENB_PHY_PUSCH_IQ", "nb_rb",
      "N_RB_UL", "symbols_per_tti", "pusch_comp");
  v = new_view_xy(100*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
  logger_add_view(l, v);
Cedric Roux's avatar
Cedric Roux committed
271
  e->pusch_iq_ue_logger = l;
272

Cedric Roux's avatar
Cedric Roux committed
273 274 275
  /* UE x estimated UL channel */
  w = new_xy_plot(g, 280, 55, "", 50);
  e->ul_estimate_ue_xy_plot = w;
276 277 278 279 280 281 282 283
  widget_add_child(g, line, w, -1);
  xy_plot_set_range(g, w, 0, 512*10, -10, 80);
  l = new_framelog(h, database,
      "ENB_PHY_UL_CHANNEL_ESTIMATE", "subframe", "chest_t");
  //framelog_set_skip(input_signal_log, 10);
  framelog_set_update_only_at_sf9(l, 0);
  v = new_view_xy(512*10, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE);
  logger_add_view(l, v);
Cedric Roux's avatar
Cedric Roux committed
284
  e->ul_estimate_ue_logger = l;
285

Cedric Roux's avatar
Cedric Roux committed
286 287 288
  /* UE x PUCCH energy */
  w = new_xy_plot(g, 128, 55, "", 50);
  e->pucch1_energy_ue_xy_plot = w;
Cedric Roux's avatar
Cedric Roux committed
289 290 291 292 293 294
  widget_add_child(g, line, w, -1);
  xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
  l = new_ttilog(h, database,
      "ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "threshold", 0);
  v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
  logger_add_view(l, v);
Cedric Roux's avatar
Cedric Roux committed
295
  e->pucch1_energy_ue_threshold_logger = l;
Cedric Roux's avatar
Cedric Roux committed
296 297 298 299
  l = new_ttilog(h, database,
      "ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "energy", 1);
  v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
  logger_add_view(l, v);
Cedric Roux's avatar
Cedric Roux committed
300
  e->pucch1_energy_ue_energy_logger = l;
Cedric Roux's avatar
Cedric Roux committed
301

Cedric Roux's avatar
Cedric Roux committed
302 303 304
  /* UE x PUCCH IQ data */
  w = new_xy_plot(g, 55, 55, "", 50);
  e->pucch_iq_ue_xy_plot = w;
Cedric Roux's avatar
Cedric Roux committed
305
  widget_add_child(g, line, w, -1);
Cedric Roux's avatar
Cedric Roux committed
306
  xy_plot_set_range(g, w, -2000, 2000, -2000, 2000);
Cedric Roux's avatar
Cedric Roux committed
307 308 309
  l = new_iqdotlog(h, database, "ENB_PHY_PUCCH_1AB_IQ", "I", "Q");
  v = new_view_xy(500, 10, g, w, new_color(g,"#000"), XY_LOOP_MODE);
  logger_add_view(l, v);
Cedric Roux's avatar
Cedric Roux committed
310
  e->pucch_iq_ue_logger = l;
Cedric Roux's avatar
Cedric Roux committed
311

312
  /* downlink/uplink UE DCIs */
Cedric Roux's avatar
Cedric Roux committed
313
  widget_add_child(g, top_container,
Cedric Roux's avatar
Cedric Roux committed
314
      new_label(g,"DL/UL TICK/DCI/ACK/NACK [all UEs]"), -1);
Cedric Roux's avatar
Cedric Roux committed
315 316
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
317
  timeline_plot = new_timeline(g, 512, 8, 5);
Cedric Roux's avatar
Cedric Roux committed
318 319
  widget_add_child(g, line, timeline_plot, -1);
  container_set_child_growable(g, line, timeline_plot, 1);
320
  for (i = 0; i < 8; i++)
Cedric Roux's avatar
Cedric Roux committed
321
    timeline_set_subline_background_color(g, timeline_plot, i,
Cedric Roux's avatar
Cedric Roux committed
322
        new_color(g, i==0 || i==4 ? "#aaf" : "#eee"));
323
  timeview = new_view_time(3600, 10, g, timeline_plot);
324
  /* DL tick logging */
325
  timelog = new_timelog(h, database, "ENB_PHY_DL_TICK");
Cedric Roux's avatar
Cedric Roux committed
326
  subview = new_subview_time(timeview, 0, new_color(g, "#77c"), 3600*1000);
327
  logger_add_view(timelog, subview);
328
  /* DL DCI logging */
329
  timelog = new_timelog(h, database, "ENB_PHY_DLSCH_UE_DCI");
330
  subview = new_subview_time(timeview, 1, new_color(g, "#228"), 3600*1000);
331
  logger_add_view(timelog, subview);
332
  /* DL ACK */
333
  timelog = new_timelog(h, database, "ENB_PHY_DLSCH_UE_ACK");
334
  subview = new_subview_time(timeview, 2, new_color(g, "#282"), 3600*1000);
335
  logger_add_view(timelog, subview);
336
  /* DL NACK */
337
  timelog = new_timelog(h, database, "ENB_PHY_DLSCH_UE_NACK");
338
  subview = new_subview_time(timeview, 3, new_color(g, "#f22"), 3600*1000);
339
  logger_add_view(timelog, subview);
340

341
  /* UL tick logging */
342
  timelog = new_timelog(h, database, "ENB_PHY_UL_TICK");
Cedric Roux's avatar
Cedric Roux committed
343
  subview = new_subview_time(timeview, 4, new_color(g, "#77c"), 3600*1000);
344
  logger_add_view(timelog, subview);
345
  /* UL DCI logging */
346
  timelog = new_timelog(h, database, "ENB_PHY_ULSCH_UE_DCI");
347 348 349
  subview = new_subview_time(timeview, 5, new_color(g, "#228"), 3600*1000);
  logger_add_view(timelog, subview);
  /* UL retransmission without DCI logging */
350
  timelog = new_timelog(h,database,"ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION");
351 352 353
  subview = new_subview_time(timeview, 5, new_color(g, "#f22"), 3600*1000);
  logger_add_view(timelog, subview);
  /* UL ACK */
354
  timelog = new_timelog(h, database, "ENB_PHY_ULSCH_UE_ACK");
355 356 357
  subview = new_subview_time(timeview, 6, new_color(g, "#282"), 3600*1000);
  logger_add_view(timelog, subview);
  /* UL NACK */
358
  timelog = new_timelog(h, database, "ENB_PHY_ULSCH_UE_NACK");
359 360
  subview = new_subview_time(timeview, 7, new_color(g, "#f22"), 3600*1000);
  logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
361

362
  /* harq processes' ticktime view */
Cedric Roux's avatar
Cedric Roux committed
363 364
  e->dl_ul_harq_ue_label = new_label(g, "");
  widget_add_child(g, top_container, e->dl_ul_harq_ue_label, -1);
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
  timeline_plot = new_timeline(g, 512, 2*8+2, 3);
  widget_add_child(g, line, timeline_plot, -1);
  container_set_child_growable(g, line, timeline_plot, 1);
  for (i = 0; i < 2*8+2; i++)
    timeline_set_subline_background_color(g, timeline_plot, i,
        new_color(g, i==0 || i==9 ? "#ddd" : (i%9)&1 ? "#e6e6e6" : "#eee"));
  timeview = new_view_ticktime(10, g, timeline_plot);
  ticktime_set_tick(timeview,
      new_ticklog(h, database, "ENB_MASTER_TICK", "frame", "subframe"));
  /* tick */
  timelog = new_ticklog(h, database, "ENB_MASTER_TICK", "frame", "subframe");
  /* tick on DL view */
  subview = new_subview_ticktime(timeview, 0, new_color(g,"#bbb"), 3600*1000);
  logger_add_view(timelog, subview);
  /* tick on UL view */
  subview = new_subview_ticktime(timeview, 9, new_color(g,"#bbb"), 3600*1000);
  logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
384
  /* DL DCI */
385
  for (i = 0; i < 8; i++) {
386
    timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_DCI",
387 388 389 390
        "frame", "subframe");
    subview = new_subview_ticktime(timeview, i+1,
        new_color(g,"#55f"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
391
    e->dl_dci_logger[i] = timelog;
392 393 394
  }
  /* DL ACK */
  for (i = 0; i < 8; i++) {
395
    timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_ACK",
396 397 398 399
        "frame", "subframe");
    subview = new_subview_ticktime(timeview, i+1,
        new_color(g,"#282"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
400
    e->dl_ack_logger[i] = timelog;
401 402 403
  }
  /* DL NACK */
  for (i = 0; i < 8; i++) {
404
    timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_NACK",
405 406 407 408
        "frame", "subframe");
    subview = new_subview_ticktime(timeview, i+1,
        new_color(g,"#f22"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
409
    e->dl_nack_logger[i] = timelog;
410
  }
Cedric Roux's avatar
Cedric Roux committed
411
  /* UL DCI/retransmission without DCI */
412 413
  for (i = 0; i < 8; i++) {
    /* first transmission */
414
    timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_DCI",
415 416 417 418
        "frame", "subframe");
    subview = new_subview_ticktime(timeview, i+9+1,
        new_color(g,"#55f"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
419
    e->ul_dci_logger[i] = timelog;
420
    /* retransmission */
421 422
    timelog = new_ticklog(h, database,
        "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe");
423 424 425
    subview = new_subview_ticktime(timeview, i+9+1,
        new_color(g,"#99f"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
426
    e->ul_dci_retransmission_logger[i] = timelog;
427 428 429
  }
  /* UL ACK */
  for (i = 0; i < 8; i++) {
430
    timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_ACK",
431 432 433 434
        "frame", "subframe");
    subview = new_subview_ticktime(timeview, i+9+1,
        new_color(g,"#282"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
435
    e->ul_ack_logger[i] = timelog;
436 437 438
  }
  /* UL NACK */
  for (i = 0; i < 8; i++) {
439
    timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_NACK",
440 441 442 443
        "frame", "subframe");
    subview = new_subview_ticktime(timeview, i+9+1,
        new_color(g,"#f22"), 3600*1000);
    logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
444
    e->ul_nack_logger[i] = timelog;
445 446
  }

Cedric Roux's avatar
Cedric Roux committed
447 448 449 450 451 452 453 454 455 456 457 458 459 460
  /* phy/mac/rlc/pdcp/rrc textlog */
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
  container_set_child_growable(g, top_container, line, 1);

  /* phy */
  col = new_container(g, VERTICAL);
  widget_add_child(g, line, col, -1);
  container_set_child_growable(g, line, col, 1);
  widget_add_child(g, col, new_label(g, "PHY"), -1);
  text = new_textlist(g, 100, 10, new_color(g, "#afa"));
  widget_add_child(g, col, text, -1);
  container_set_child_growable(g, col, text, 1);
  textview = new_view_textlist(10000, 10, g, text);
461
  e->phyview = textview;
Cedric Roux's avatar
Cedric Roux committed
462 463 464 465 466 467 468 469 470 471

  /* mac */
  col = new_container(g, VERTICAL);
  widget_add_child(g, line, col, -1);
  container_set_child_growable(g, line, col, 1);
  widget_add_child(g, col, new_label(g, "MAC"), -1);
  text = new_textlist(g, 100, 10, new_color(g, "#adf"));
  widget_add_child(g, col, text, -1);
  container_set_child_growable(g, col, text, 1);
  textview = new_view_textlist(10000, 10, g, text);
Cedric Roux's avatar
Cedric Roux committed
472
  e->macview = textview;
Cedric Roux's avatar
Cedric Roux committed
473

474 475 476 477
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
  container_set_child_growable(g, top_container, line, 1);

Cedric Roux's avatar
Cedric Roux committed
478 479 480 481 482 483 484 485 486
  /* rlc */
  col = new_container(g, VERTICAL);
  widget_add_child(g, line, col, -1);
  container_set_child_growable(g, line, col, 1);
  widget_add_child(g, col, new_label(g, "RLC"), -1);
  text = new_textlist(g, 100, 10, new_color(g, "#aff"));
  widget_add_child(g, col, text, -1);
  container_set_child_growable(g, col, text, 1);
  textview = new_view_textlist(10000, 10, g, text);
Cedric Roux's avatar
Cedric Roux committed
487
  e->rlcview = textview;
Cedric Roux's avatar
Cedric Roux committed
488 489 490 491 492 493 494 495 496 497

  /* pdcp */
  col = new_container(g, VERTICAL);
  widget_add_child(g, line, col, -1);
  container_set_child_growable(g, line, col, 1);
  widget_add_child(g, col, new_label(g, "PDCP"), -1);
  text = new_textlist(g, 100, 10, new_color(g, "#ed9"));
  widget_add_child(g, col, text, -1);
  container_set_child_growable(g, col, text, 1);
  textview = new_view_textlist(10000, 10, g, text);
Cedric Roux's avatar
Cedric Roux committed
498
  e->pdcpview = textview;
Cedric Roux's avatar
Cedric Roux committed
499

500 501 502 503
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
  container_set_child_growable(g, top_container, line, 1);

Cedric Roux's avatar
Cedric Roux committed
504 505 506 507 508 509 510 511 512 513
  /* rrc */
  col = new_container(g, VERTICAL);
  widget_add_child(g, line, col, -1);
  container_set_child_growable(g, line, col, 1);
  widget_add_child(g, col, new_label(g, "RRC"), -1);
  text = new_textlist(g, 100, 10, new_color(g, "#fdb"));
  widget_add_child(g, col, text, -1);
  container_set_child_growable(g, col, text, 1);
  textview = new_view_textlist(10000, 10, g, text);
  e->rrcview = textview;
Cedric Roux's avatar
Cedric Roux committed
514 515 516 517 518 519 520

  /* legacy logs (LOG_I, LOG_D, ...) */
  widget_add_child(g, top_container, new_label(g, "LEGACY"), -1);
  text = new_textlist(g, 100, 10, new_color(g, "#eeb"));
  widget_add_child(g, top_container, text, -1);
  container_set_child_growable(g, top_container, text, 1);
  e->legacy = new_view_textlist(10000, 10, g, text);
Cedric Roux's avatar
Cedric Roux committed
521 522 523 524

  set_current_ue(g, ed, 0);
  register_notifier(g, "click", e->prev_ue_button, click, ed);
  register_notifier(g, "click", e->next_ue_button, click, ed);
Cedric Roux's avatar
Cedric Roux committed
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
}

void view_add_log(view *v, char *log, event_handler *h, void *database,
    int *is_on)
{
  logger *textlog;
  char *name, *desc;

  database_get_generic_description(database,
      event_id_from_name(database, log), &name, &desc);
  textlog = new_textlog(h, database, name, desc);
  logger_add_view(textlog, v);
  free(name);
  free(desc);

  on_off(database, log, is_on, 1);
541 542 543 544 545 546 547
}

int main(int n, char **v)
{
  extern int volatile gui_logd;
  char *database_filename = NULL;
  void *database;
548
  char *ip = DEFAULT_REMOTE_IP;
549 550 551 552 553 554 555 556 557
  int port = DEFAULT_REMOTE_PORT;
  char **on_off_name;
  int *on_off_action;
  int on_off_n = 0;
  int *is_on;
  int number_of_events;
  int i;
  event_handler *h;
  gui *g;
Cedric Roux's avatar
Cedric Roux committed
558
  enb_gui eg;
559
  enb_data enb_data;
560

561 562 563
  /* write on a socket fails if the other end is closed and we get SIGPIPE */
  if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();

564 565 566 567 568 569 570
  on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort();
  on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort();

  for (i = 1; i < n; i++) {
    if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
    if (!strcmp(v[i], "-d"))
      { if (i > n-2) usage(); database_filename = v[++i]; continue; }
571
    if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
    if (!strcmp(v[i], "-p"))
      { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
    if (!strcmp(v[i], "-on")) { if (i > n-2) usage();
      on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; }
    if (!strcmp(v[i], "-off")) { if (i > n-2) usage();
      on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; }
    if (!strcmp(v[i], "-ON"))
      { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; }
    if (!strcmp(v[i], "-OFF"))
      { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; }
    if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; }
    usage();
  }

  if (database_filename == NULL) {
    printf("ERROR: provide a database file (-d)\n");
    exit(1);
  }

  database = parse_database(database_filename);

593
  load_config_file(database_filename);
594

595 596 597 598 599 600 601 602 603
  number_of_events = number_of_ids(database);
  is_on = calloc(number_of_events, sizeof(int));
  if (is_on == NULL) abort();

  h = new_handler(database);

  g = gui_init();
  new_thread(gui_thread, g);

Cedric Roux's avatar
Cedric Roux committed
604 605 606 607 608
  enb_data.ue = 0;
  enb_data.e = &eg;
  enb_data.database = database;

  enb_main_gui(&eg, g, h, database, &enb_data);
609

Cedric Roux's avatar
Cedric Roux committed
610 611 612 613
  for (i = 0; i < number_of_events; i++) {
    logger *textlog;
    char *name, *desc;
    database_get_generic_description(database, i, &name, &desc);
Cedric Roux's avatar
Cedric Roux committed
614 615 616 617
    if (!strncmp(name, "LEGACY_", 7)) {
      textlog = new_textlog(h, database, name, desc);
      logger_add_view(textlog, eg.legacy);
    }
Cedric Roux's avatar
Cedric Roux committed
618 619 620 621
    free(name);
    free(desc);
  }

622
  on_off(database, "ENB_PHY_INPUT_SIGNAL", is_on, 1);
623
  on_off(database, "ENB_PHY_UL_CHANNEL_ESTIMATE", is_on, 1);
624 625 626 627 628 629 630 631 632
  on_off(database, "ENB_PHY_DL_TICK", is_on, 1);
  on_off(database, "ENB_PHY_DLSCH_UE_DCI", is_on, 1);
  on_off(database, "ENB_PHY_DLSCH_UE_ACK", is_on, 1);
  on_off(database, "ENB_PHY_DLSCH_UE_NACK", is_on, 1);
  on_off(database, "ENB_PHY_UL_TICK", is_on, 1);
  on_off(database, "ENB_PHY_ULSCH_UE_DCI", is_on, 1);
  on_off(database, "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", is_on, 1);
  on_off(database, "ENB_PHY_ULSCH_UE_ACK", is_on, 1);
  on_off(database, "ENB_PHY_ULSCH_UE_NACK", is_on, 1);
633
  on_off(database, "ENB_MASTER_TICK", is_on, 1);
634
  on_off(database, "ENB_PHY_PUSCH_IQ", is_on, 1);
Cedric Roux's avatar
Cedric Roux committed
635 636
  on_off(database, "ENB_PHY_PUCCH_1_ENERGY", is_on, 1);
  on_off(database, "ENB_PHY_PUCCH_1AB_IQ", is_on, 1);
637

638 639 640
  on_off(database, "LEGACY_GROUP_INFO", is_on, 1);
  on_off(database, "LEGACY_GROUP_ERROR", is_on, 1);
  on_off(database, "LEGACY_GROUP_WARNING", is_on, 1);
641

642 643 644 645 646
  view_add_log(eg.phyview, "ENB_PHY_DLSCH_UE_DCI", h, database, is_on);
  view_add_log(eg.phyview, "ENB_PHY_DLSCH_UE_ACK", h, database, is_on);
  view_add_log(eg.phyview, "ENB_PHY_DLSCH_UE_NACK", h, database, is_on);
  view_add_log(eg.phyview, "ENB_PHY_ULSCH_UE_DCI", h, database, is_on);
  view_add_log(eg.phyview, "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION",
647
      h, database, is_on);
648 649
  view_add_log(eg.phyview, "ENB_PHY_ULSCH_UE_ACK", h, database, is_on);
  view_add_log(eg.phyview, "ENB_PHY_ULSCH_UE_NACK", h, database, is_on);
650

Cedric Roux's avatar
Cedric Roux committed
651 652 653 654 655
  view_add_log(eg.macview, "ENB_MAC_UE_DL_SDU", h, database, is_on);
  view_add_log(eg.macview, "ENB_MAC_UE_UL_SCHEDULE", h, database, is_on);
  view_add_log(eg.macview, "ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION",
      h, database, is_on);
  view_add_log(eg.macview, "ENB_MAC_UE_UL_PDU", h, database, is_on);
656
  view_add_log(eg.macview, "ENB_MAC_UE_UL_PDU_WITH_DATA", h, database, is_on);
Cedric Roux's avatar
Cedric Roux committed
657
  view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU", h, database, is_on);
658
  view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU_WITH_DATA", h, database, is_on);
Cedric Roux's avatar
Cedric Roux committed
659 660 661 662 663 664 665 666 667 668
  view_add_log(eg.macview, "ENB_MAC_UE_UL_CE", h, database, is_on);

  view_add_log(eg.rlcview, "ENB_RLC_DL", h, database, is_on);
  view_add_log(eg.rlcview, "ENB_RLC_UL", h, database, is_on);
  view_add_log(eg.rlcview, "ENB_RLC_MAC_DL", h, database, is_on);
  view_add_log(eg.rlcview, "ENB_RLC_MAC_UL", h, database, is_on);

  view_add_log(eg.pdcpview, "ENB_PDCP_UL", h, database, is_on);
  view_add_log(eg.pdcpview, "ENB_PDCP_DL", h, database, is_on);

Cedric Roux's avatar
Cedric Roux committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMMAND",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UE_CAPABILITY_ENQUIRY",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REJECT",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_RELEASE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_RECONFIGURATION",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_MEASUREMENT_REPORT",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_HANDOVER_PREPARATION_INFORMATION",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UL_CCCH_DATA_IN",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UL_DCCH_DATA_IN",
      h, database, is_on);
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
  view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMPLETE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_FAILURE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UE_CAPABILITY_INFORMATION",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REQUEST",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UL_INFORMATION_TRANSFER",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_COUNTER_CHECK_RESPONSE",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UE_INFORMATION_RESPONSE_R9",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_PROXIMITY_INDICATION_R9",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_RECONFIGURATION_COMPLETE_R10",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_MBMS_COUNTING_RESPONSE_R10",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION",
      h, database, is_on);
  view_add_log(eg.rrcview, "ENB_RRC_UNKNOW_MESSAGE",
      h, database, is_on);
Cedric Roux's avatar
Cedric Roux committed
725

726 727 728 729
  /* deactivate those two by default, they are a bit heavy */
  on_off(database, "ENB_MAC_UE_UL_SDU_WITH_DATA", is_on, 0);
  on_off(database, "ENB_MAC_UE_UL_PDU_WITH_DATA", is_on, 0);

730 731 732
  for (i = 0; i < on_off_n; i++)
    on_off(database, on_off_name[i], is_on, on_off_action[i]);

733 734 735 736 737
  enb_data.socket = -1;
  enb_data.is_on = is_on;
  enb_data.nevents = number_of_events;
  if (pthread_mutex_init(&enb_data.lock, NULL)) abort();
  setup_event_selector(g, database, is_on, is_on_changed, &enb_data);
738

739 740
restart:
  clear_remote_config();
741
  enb_data.socket = connect_to(ip, port);
742

743 744
  /* send the first message - activate selected traces */
  is_on_changed(&enb_data);
745 746 747 748 749

  /* read messages */
  while (1) {
    char v[T_BUFFER_MAX];
    event e;
750
    e = get_event(enb_data.socket, v, database);
751
    if (e.type == -1) goto restart;
Cedric Roux's avatar
Cedric Roux committed
752
    if (pthread_mutex_lock(&enb_data.lock)) abort();
753
    handle_event(h, e);
Cedric Roux's avatar
Cedric Roux committed
754
    if (pthread_mutex_unlock(&enb_data.lock)) abort();
755 756 757 758
  }

  return 0;
}