enb.c 28.3 KB
Newer Older
1
2
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Cedric Roux's avatar
Cedric Roux committed
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
  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;
35
36
  widget *dl_mcs_xy_plot;
  widget *ul_mcs_xy_plot;
Cedric Roux's avatar
Cedric Roux committed
37
38
39
40
41
42
43
44
45
46
47
48
  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];
49
50
  logger *dl_mcs_logger;
  logger *ul_mcs_logger;
Cedric Roux's avatar
Cedric Roux committed
51
52
} enb_gui;

53
54
55
56
57
typedef struct {
  int socket;
  int *is_on;
  int nevents;
  pthread_mutex_t lock;
Cedric Roux's avatar
Cedric Roux committed
58
59
60
  enb_gui *e;
  int ue;                /* what UE is displayed in the UE specific views */
  void *database;
61
62
63
64
65
66
67
68
69
70
71
72
} 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;
73
74
75
  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)
Cedric Roux's avatar
Cedric Roux committed
76
    goto connection_dies;
77
78
79

no_connection:
  if (pthread_mutex_unlock(&d->lock)) abort();
Cedric Roux's avatar
Cedric Roux committed
80
81
82
83
84
85
  return;

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

88
89
90
91
92
93
94
95
96
97
98
99
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"
100
101
"    -ip <host>                connect to given IP address (default %s)\n"
"    -p <port>                 connect to given port (default %d)\n"
102
"    -debug-gui                activate GUI debug logs\n",
103
  DEFAULT_REMOTE_IP,
104
105
106
107
108
109
110
111
112
113
114
115
  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
116
static filter *ticktime_filter(void *database, char *event, int i, int ue)
117
{
Cedric Roux's avatar
cleanup    
Cedric Roux committed
118
  /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0" */
119
120
121
122
  return
    filter_and(
      filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)),
      filter_and(
Cedric Roux's avatar
Cedric Roux committed
123
        filter_eq(filter_evarg(database, event, "UE_id"), filter_int(ue)),
124
125
126
        filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0))));
}

Cedric Roux's avatar
Cedric Roux committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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);
144
145
146
147
  sprintf(s, "DL MCS [UE %d]", ue);
  xy_plot_set_title(g, e->e->dl_mcs_xy_plot, s);
  sprintf(s, "UL MCS [UE %d]", ue);
  xy_plot_set_title(g, e->e->ul_mcs_xy_plot, s);
Cedric Roux's avatar
Cedric Roux committed
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

  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));
  }
186
187
188
189
190
191
192
193
  logger_set_filter(e->e->dl_mcs_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_DLSCH_UE_DCI", "UE_id"),
        filter_int(ue)));
  logger_set_filter(e->e->ul_mcs_logger,
      filter_eq(
        filter_evarg(e->database, "ENB_PHY_ULSCH_UE_DCI", "UE_id"),
        filter_int(ue)));
Cedric Roux's avatar
Cedric Roux committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
}

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
209
210
211
212
213
214
  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
215
216
217
218
}

static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
    enb_data *ed)
219
220
221
{
  widget *main_window;
  widget *top_container;
Cedric Roux's avatar
Cedric Roux committed
222
  widget *line, *col;
Cedric Roux's avatar
Cedric Roux committed
223
  widget *logo;
224
225
226
  widget *input_signal_plot;
  logger *input_signal_log;
  view *input_signal_view;
Cedric Roux's avatar
Cedric Roux committed
227
  widget *timeline_plot;
228
229
230
  logger *timelog;
  view *timeview;
  view *subview;
Cedric Roux's avatar
Cedric Roux committed
231
232
  widget *text;
  view *textview;
Cedric Roux's avatar
Cedric Roux committed
233
  int i;
Cedric Roux's avatar
Cedric Roux committed
234
  widget *w, *w2;
235
236
  view *v;
  logger *l;
237

238
  main_window = new_toplevel_window(g, 1200, 900, "eNB tracer");
239
240
241
242
243
  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
244
  logo = new_image(g, openair_logo_png, openair_logo_png_len);
Cedric Roux's avatar
Cedric Roux committed
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

  /* 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);

265
266
267
268
  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,
269
      "ENB_PHY_INPUT_SIGNAL", "subframe", "rxdata");
270
271
272
273
274
  /* 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,
Cedric Roux's avatar
Cedric Roux committed
275
      g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE);
276
  logger_add_view(input_signal_log, input_signal_view);
Cedric Roux's avatar
Cedric Roux committed
277

Cedric Roux's avatar
Cedric Roux committed
278
279
280
  /* UE x PUSCH IQ data */
  w = new_xy_plot(g, 55, 55, "", 50);
  e->pusch_iq_ue_xy_plot = w;
281
282
283
284
285
286
  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
287
  e->pusch_iq_ue_logger = l;
288

Cedric Roux's avatar
Cedric Roux committed
289
290
291
  /* UE x estimated UL channel */
  w = new_xy_plot(g, 280, 55, "", 50);
  e->ul_estimate_ue_xy_plot = w;
292
293
294
295
296
297
298
299
  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
300
  e->ul_estimate_ue_logger = l;
301

Cedric Roux's avatar
Cedric Roux committed
302
303
304
  /* 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
305
306
307
308
309
310
  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
311
  e->pucch1_energy_ue_threshold_logger = l;
Cedric Roux's avatar
Cedric Roux committed
312
313
314
315
  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
316
  e->pucch1_energy_ue_energy_logger = l;
Cedric Roux's avatar
Cedric Roux committed
317

Cedric Roux's avatar
Cedric Roux committed
318
319
320
  /* 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
321
  widget_add_child(g, line, w, -1);
Cedric Roux's avatar
Cedric Roux committed
322
  xy_plot_set_range(g, w, -2000, 2000, -2000, 2000);
Cedric Roux's avatar
Cedric Roux committed
323
324
325
  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
326
  e->pucch_iq_ue_logger = l;
Cedric Roux's avatar
Cedric Roux committed
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  /* UE x DL mcs */
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
  w = new_xy_plot(g, 128, 55, "", 20);
  xy_plot_set_range(g, w, 0, 1024*10, -1, 29);
  e->dl_mcs_xy_plot = w;
  widget_add_child(g, line, w, -1);
  l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
      "ENB_PHY_DLSCH_UE_DCI", "mcs", 0, -1);
  v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
  logger_add_view(l, v);
  e->dl_mcs_logger = l;

  /* UE x UL mcs */
  w = new_xy_plot(g, 128, 55, "", 20);
  xy_plot_set_range(g, w, 0, 1024*10, -1, 29);
  e->ul_mcs_xy_plot = w;
  widget_add_child(g, line, w, -1);
  l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
      "ENB_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
  v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
  logger_add_view(l, v);
  e->ul_mcs_logger = l;

352
  /* downlink/uplink UE DCIs */
Cedric Roux's avatar
Cedric Roux committed
353
  widget_add_child(g, top_container,
Cedric Roux's avatar
Cedric Roux committed
354
      new_label(g,"DL/UL TICK/DCI/ACK/NACK [all UEs]"), -1);
Cedric Roux's avatar
Cedric Roux committed
355
356
  line = new_container(g, HORIZONTAL);
  widget_add_child(g, top_container, line, -1);
Cedric Roux's avatar
Cedric Roux committed
357
  timeline_plot = new_timeline(g, 512, 8, 5);
Cedric Roux's avatar
Cedric Roux committed
358
359
  widget_add_child(g, line, timeline_plot, -1);
  container_set_child_growable(g, line, timeline_plot, 1);
Cedric Roux's avatar
Cedric Roux committed
360
  for (i = 0; i < 8; i++)
Cedric Roux's avatar
Cedric Roux committed
361
    timeline_set_subline_background_color(g, timeline_plot, i,
Cedric Roux's avatar
Cedric Roux committed
362
        new_color(g, i==0 || i==4 ? "#aaf" : "#eee"));
363
  timeview = new_view_time(3600, 10, g, timeline_plot);
364
  /* DL tick logging */
365
  timelog = new_timelog(h, database, "ENB_PHY_DL_TICK");
Cedric Roux's avatar
Cedric Roux committed
366
  subview = new_subview_time(timeview, 0, new_color(g, "#77c"), 3600*1000);
367
  logger_add_view(timelog, subview);
368
  /* DL DCI logging */
369
  timelog = new_timelog(h, database, "ENB_PHY_DLSCH_UE_DCI");
370
  subview = new_subview_time(timeview, 1, new_color(g, "#228"), 3600*1000);
Cedric Roux's avatar
Cedric Roux committed
371
  logger_add_view(timelog, subview);
372
  /* DL ACK */
373
  timelog = new_timelog(h, database, "ENB_PHY_DLSCH_UE_ACK");
374
  subview = new_subview_time(timeview, 2, new_color(g, "#282"), 3600*1000);
375
  logger_add_view(timelog, subview);
376
  /* DL NACK */
377
  timelog = new_timelog(h, database, "ENB_PHY_DLSCH_UE_NACK");
378
  subview = new_subview_time(timeview, 3, new_color(g, "#f22"), 3600*1000);
379
  logger_add_view(timelog, subview);
380

381
  /* UL tick logging */
382
  timelog = new_timelog(h, database, "ENB_PHY_UL_TICK");
Cedric Roux's avatar
Cedric Roux committed
383
  subview = new_subview_time(timeview, 4, new_color(g, "#77c"), 3600*1000);
384
  logger_add_view(timelog, subview);
385
  /* UL DCI logging */
386
  timelog = new_timelog(h, database, "ENB_PHY_ULSCH_UE_DCI");
387
388
389
  subview = new_subview_time(timeview, 5, new_color(g, "#228"), 3600*1000);
  logger_add_view(timelog, subview);
  /* UL retransmission without DCI logging */
390
  timelog = new_timelog(h,database,"ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION");
391
392
393
  subview = new_subview_time(timeview, 5, new_color(g, "#f22"), 3600*1000);
  logger_add_view(timelog, subview);
  /* UL ACK */
394
  timelog = new_timelog(h, database, "ENB_PHY_ULSCH_UE_ACK");
395
396
397
  subview = new_subview_time(timeview, 6, new_color(g, "#282"), 3600*1000);
  logger_add_view(timelog, subview);
  /* UL NACK */
398
  timelog = new_timelog(h, database, "ENB_PHY_ULSCH_UE_NACK");
399
400
  subview = new_subview_time(timeview, 7, new_color(g, "#f22"), 3600*1000);
  logger_add_view(timelog, subview);
Cedric Roux's avatar
Cedric Roux committed
401

402
  /* harq processes' ticktime view */
Cedric Roux's avatar
Cedric Roux committed
403
404
  e->dl_ul_harq_ue_label = new_label(g, "");
  widget_add_child(g, top_container, e->dl_ul_harq_ue_label, -1);
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  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
424
  /* DL DCI */
425
  for (i = 0; i < 8; i++) {
426
    timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_DCI",
427
428
429
430
        "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
431
    e->dl_dci_logger[i] = timelog;
432
433
434
  }
  /* DL ACK */
  for (i = 0; i < 8; i++) {
435
    timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_ACK",
436
437
438
439
        "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
440
    e->dl_ack_logger[i] = timelog;
441
442
443
  }
  /* DL NACK */
  for (i = 0; i < 8; i++) {
444
    timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_NACK",
445
446
447
448
        "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
449
    e->dl_nack_logger[i] = timelog;
450
  }
Cedric Roux's avatar
Cedric Roux committed
451
  /* UL DCI/retransmission without DCI */
452
453
  for (i = 0; i < 8; i++) {
    /* first transmission */
454
    timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_DCI",
455
456
457
458
        "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
459
    e->ul_dci_logger[i] = timelog;
460
    /* retransmission */
461
462
    timelog = new_ticklog(h, database,
        "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe");
463
464
465
    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
466
    e->ul_dci_retransmission_logger[i] = timelog;
467
468
469
  }
  /* UL ACK */
  for (i = 0; i < 8; i++) {
470
    timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_ACK",
471
472
473
474
        "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
475
    e->ul_ack_logger[i] = timelog;
476
477
478
  }
  /* UL NACK */
  for (i = 0; i < 8; i++) {
479
    timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_NACK",
480
481
482
483
        "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
484
    e->ul_nack_logger[i] = timelog;
485
486
  }

Cedric Roux's avatar
Cedric Roux committed
487
488
489
490
491
492
493
494
495
496
497
498
499
500
  /* 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);
501
  e->phyview = textview;
Cedric Roux's avatar
Cedric Roux committed
502
503
504
505
506
507
508
509
510
511

  /* 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
512
  e->macview = textview;
Cedric Roux's avatar
Cedric Roux committed
513

514
515
516
517
  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
518
519
520
521
522
523
524
525
526
  /* 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
527
  e->rlcview = textview;
Cedric Roux's avatar
Cedric Roux committed
528
529
530
531
532
533
534
535
536
537

  /* 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
538
  e->pdcpview = textview;
Cedric Roux's avatar
Cedric Roux committed
539

540
541
542
543
  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
544
545
546
547
548
549
550
551
552
553
  /* 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
554
555
556
557
558
559
560

  /* 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
561
562
563
564

  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
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
}

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);
581
582
583
584
585
586
587
}

int main(int n, char **v)
{
  extern int volatile gui_logd;
  char *database_filename = NULL;
  void *database;
588
  char *ip = DEFAULT_REMOTE_IP;
589
590
591
592
593
594
595
596
597
  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
598
  enb_gui eg;
599
  enb_data enb_data;
600

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

604
605
606
607
608
609
610
  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; }
611
    if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
    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);

633
  load_config_file(database_filename);
634

635
636
637
638
639
640
641
642
643
  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
644
645
646
647
648
  enb_data.ue = 0;
  enb_data.e = &eg;
  enb_data.database = database;

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

Cedric Roux's avatar
Cedric Roux committed
650
651
652
653
  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
654
655
656
657
    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
658
659
660
661
    free(name);
    free(desc);
  }

662
  on_off(database, "ENB_PHY_INPUT_SIGNAL", is_on, 1);
663
  on_off(database, "ENB_PHY_UL_CHANNEL_ESTIMATE", is_on, 1);
664
665
666
667
668
669
670
671
672
  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);
673
  on_off(database, "ENB_MASTER_TICK", is_on, 1);
674
  on_off(database, "ENB_PHY_PUSCH_IQ", is_on, 1);
Cedric Roux's avatar
Cedric Roux committed
675
676
  on_off(database, "ENB_PHY_PUCCH_1_ENERGY", is_on, 1);
  on_off(database, "ENB_PHY_PUCCH_1AB_IQ", is_on, 1);
677

678
679
680
  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);
681

682
683
684
685
686
  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",
687
      h, database, is_on);
688
689
  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);
690

Cedric Roux's avatar
Cedric Roux committed
691
692
693
694
695
  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);
696
  view_add_log(eg.macview, "ENB_MAC_UE_UL_PDU_WITH_DATA", h, database, is_on);
Cedric Roux's avatar
Cedric Roux committed
697
  view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU", h, database, is_on);
698
  view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU_WITH_DATA", h, database, is_on);
Cedric Roux's avatar
Cedric Roux committed
699
700
701
702
703
704
705
706
707
708
  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
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
  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);
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
  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
765

766
767
768
769
  /* 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);

770
771
772
  for (i = 0; i < on_off_n; i++)
    on_off(database, on_off_name[i], is_on, on_off_action[i]);

773
774
775
776
777
  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);
778

Cedric Roux's avatar
Cedric Roux committed
779
780
restart:
  clear_remote_config();
781
  enb_data.socket = connect_to(ip, port);
782

783
784
  /* send the first message - activate selected traces */
  is_on_changed(&enb_data);
785
786
787
788
789

  /* read messages */
  while (1) {
    char v[T_BUFFER_MAX];
    event e;
790
    e = get_event(enb_data.socket, v, database);
Cedric Roux's avatar
Cedric Roux committed
791
    if (e.type == -1) goto restart;
Cedric Roux's avatar
Cedric Roux committed
792
    if (pthread_mutex_lock(&enb_data.lock)) abort();
793
    handle_event(h, e);
Cedric Roux's avatar
Cedric Roux committed
794
    if (pthread_mutex_unlock(&enb_data.lock)) abort();
795
796
797
798
  }

  return 0;
}