diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 8dd9d9a7e2a6a88c288e6bba04e8e5d37f7c4e22..08b79f2aa1645206977accfaff1920f2ad0b185d 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -6,7 +6,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. LIBS=-lX11 -lm PROG=tracer_remote -OBJS=remote_old.o plot.o database.o gui.o +OBJS=remote_old.o plot.o database.o gui.o utils.o $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index c0224af5d06d098b38190afb4b949c7cadc1b19a..62796149b3af38c4105077fe023ad0d0d4097e9f 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -1,4 +1,5 @@ #include "database.h" +#include "utils.h" #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -453,3 +454,48 @@ int number_of_ids(void *_d) database *d = _d; return d->isize; } + +int database_get_ids(void *_d, char ***ids) +{ + database *d = _d; + int i; + *ids = malloc(d->isize * sizeof(char **)); + for (i = 0; i < d->isize; i++) (*ids)[i] = d->i[i].name; + return d->isize; +} + +int database_get_groups(void *_d, char ***groups) +{ + database *d = _d; + int i; + *groups = malloc(d->gsize * sizeof(char **)); + for (i = 0; i < d->gsize; i++) (*groups)[i] = d->g[i].name; + return d->gsize; +} + +int database_pos_to_id(void *_d, int pos) +{ + database *d = _d; + return d->i[pos].id; +} + +void database_get_generic_description(void *_d, int id, + char **name, char **desc) +{ + database *d = _d; + OBUF o; + int i; + *name = strdup(d->i[id].name); + o.osize = o.omaxsize = 0; + o.obuf = NULL; + PUTS(&o, *name); + for (i = 0; i < d->i[id].asize; i++) { + PUTC(&o, ' '); + PUTS(&o, d->i[id].arg_name[i]); + PUTS(&o, " ["); + PUTS(&o, d->i[id].arg_name[i]); + PUTS(&o, "]"); + } + PUTC(&o, 0); + *desc = o.obuf; +} diff --git a/common/utils/T/tracer/database.h b/common/utils/T/tracer/database.h index e2f8aee8b7924365eef6b857140bd16d73bee2fa..c5cab05d9f7be0da0cc8d50fcf3fda243aec556a 100644 --- a/common/utils/T/tracer/database.h +++ b/common/utils/T/tracer/database.h @@ -10,6 +10,11 @@ void on_off(void *d, char *item, int *a, int onoff); char *event_name_from_id(void *database, int id); int event_id_from_name(void *database, char *name); int number_of_ids(void *database); +int database_get_ids(void *database, char ***ids); +int database_get_groups(void *database, char ***groups); +int database_pos_to_id(void *database, int pos); +void database_get_generic_description(void *database, int id, + char **name, char **desc); /****************************************************************************/ /* get format of an event */ diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index f632efb8daef9c9817978f1a64b00ac3099a5b44..650a6af59a4038f4fceeb070b477a816d731d1b0 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -1,13 +1,106 @@ #include "event_selector.h" #include "gui/gui.h" +#include "database.h" +#include "utils.h" +#include <stdlib.h> +#include <string.h> -void setup_event_selector(gui *g, void *database, int socket, int *is_on) +struct event_selector { + int *is_on; + int red; + int green; + gui *g; + widget *events; + widget *groups; + void *database; + int nevents; + int ngroups; + int socket; +}; + +static void scroll(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + int visible_lines; + int start_line; + int number_of_lines; + int new_line; + int inc; + + text_list_state(g, w, &visible_lines, &start_line, &number_of_lines); + inc = 10; + if (inc > visible_lines - 2) inc = visible_lines - 2; + if (inc < 1) inc = 1; + if (!strcmp(notification, "scrollup")) inc = -inc; + + new_line = start_line + inc; + if (new_line > number_of_lines - visible_lines) + new_line = number_of_lines - visible_lines; + if (new_line < 0) new_line = 0; + + text_list_set_start_line(g, w, new_line); +} + +static void click(void *private, gui *g, + char *notification, widget *w, void *notification_data) { + int *d = notification_data; + struct event_selector *this = private; + int set_on; + int line = d[0]; + int button = d[1]; + char *text; + int color; + int i; + char t; + + if (button != 1 && button != 3) return; + + if (button == 1) set_on = 1; else set_on = 0; + + if (w == this->events) + text_list_get_line(this->g, this->events, line, &text, &color); + else + text_list_get_line(this->g, this->groups, line, &text, &color); + + on_off(this->database, text, this->is_on, set_on); + + for (i = 0; i < this->nevents; i++) + text_list_set_color(this->g, this->events, i, + this->is_on[database_pos_to_id(this->database, i)] ? + this->green : this->red); + + for (i = 0; i < this->ngroups; i++) + text_list_set_color(this->g, this->groups, i, FOREGROUND_COLOR); + if (w == this->groups) + text_list_set_color(this->g, this->groups, line, + set_on ? this->green : this->red); + + t = 1; + socket_send(this->socket, &t, 1); + socket_send(this->socket, &this->nevents, sizeof(int)); + socket_send(this->socket, this->is_on, this->nevents * sizeof(int)); +} + +event_selector *setup_event_selector(gui *g, void *database, int socket, + int *is_on) +{ + struct event_selector *ret; widget *win; widget *main_container; widget *container; widget *left, *right; widget *events, *groups; + char **ids; + char **gps; + int n; + int i; + int red, green; + + ret = calloc(1, sizeof(struct event_selector)); if (ret == NULL) abort(); + + red = new_color(g, "#944"); + green = new_color(g, "#272"); win = new_toplevel_window(g, 610, 800, "event selector"); main_container = new_container(g, VERTICAL); @@ -38,4 +131,40 @@ void setup_event_selector(gui *g, void *database, int socket, int *is_on) widget_add_child(g, right, groups, -1); container_set_child_growable(g, left, events, 1); container_set_child_growable(g, right, groups, 1); + + n = database_get_ids(database, &ids); + for (i = 0; i < n; i++) { + text_list_add(g, events, ids[i], -1, + is_on[database_pos_to_id(database, i)] ? green : red); + } + free(ids); + + ret->nevents = n; + + n = database_get_groups(database, &gps); + for (i = 0; i < n; i++) { + text_list_add(g, groups, gps[i], -1, FOREGROUND_COLOR); + } + free(gps); + + ret->ngroups = n; + + ret->g = g; + ret->is_on = is_on; + ret->red = red; + ret->green = green; + ret->events = events; + ret->groups = groups; + ret->database = database; + ret->socket = socket; + + register_notifier(g, "scrollup", events, scroll, ret); + register_notifier(g, "scrolldown", events, scroll, ret); + register_notifier(g, "click", events, click, ret); + + register_notifier(g, "scrollup", groups, scroll, ret); + register_notifier(g, "scrolldown", groups, scroll, ret); + register_notifier(g, "click", groups, click, ret); + + return ret; } diff --git a/common/utils/T/tracer/event_selector.h b/common/utils/T/tracer/event_selector.h index 11e977b4f641772e3f9380fd9baecdd04d517059..60da0a07e5c33d1ef3427fb2cfe2d752143d1786 100644 --- a/common/utils/T/tracer/event_selector.h +++ b/common/utils/T/tracer/event_selector.h @@ -3,6 +3,9 @@ #include "gui/gui.h" -void setup_event_selector(gui *g, void *database, int socket, int *is_on); +typedef void event_selector; + +event_selector *setup_event_selector(gui *g, void *database, int socket, + int *is_on); #endif /* _EVENT_SELECTOR_H_ */ diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 9d1d2b0968bc88a9686289cdbff726b8aa2b6554..e99bcf2c36d72a4dc9e70054c22b5a16df5578b2 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -118,6 +118,7 @@ int main(int n, char **v) textlog *textlog; gui *g; int gui_mode = 0; + view *out; 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(); @@ -153,26 +154,30 @@ int main(int n, char **v) h = new_handler(database); - textlog = new_textlog(h, database, - "ENB_UL_CHANNEL_ESTIMATE", - "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); - g = gui_init(); new_thread(gui_thread, g); if (gui_mode) { - view *tout; widget *w, *win; // w = new_text_list(g, 600, 20, 0); w = new_text_list(g, 600, 20, new_color(g, "#ffabab")); win = new_toplevel_window(g, 600, 20*12, "textlog"); widget_add_child(g, win, w, -1); - tout = new_textlist(1000, 10, g, w); + out = new_textlist(1000, 10, g, w); //tout = new_textlist(7, 4, g, w); - textlog_add_view(textlog, tout); } else { - view *sout = new_stdout(); - textlog_add_view(textlog, sout); + out = new_stdout(); + } + + for (i = 0; i < number_of_events; i++) { + char *name, *desc; + database_get_generic_description(database, i, &name, &desc); + textlog = new_textlog(h, database, name, desc); +// "ENB_UL_CHANNEL_ESTIMATE", +// "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); + textlog_add_view(textlog, out); + free(name); + free(desc); } for (i = 0; i < on_off_n; i++) diff --git a/common/utils/T/tracer/remote_old.c b/common/utils/T/tracer/remote_old.c index 4988bd336ebfa01cce0f4296037bdd405789bf34..5c3a751bafc50e5011312c9cfbe06676798d079d 100644 --- a/common/utils/T/tracer/remote_old.c +++ b/common/utils/T/tracer/remote_old.c @@ -327,23 +327,6 @@ void get_message(int s) } } -void new_thread(void *(*f)(void *), void *data) -{ - pthread_t t; - pthread_attr_t att; - - if (pthread_attr_init(&att)) - { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } - if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) - { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } - if (pthread_attr_setstacksize(&att, 10000000)) - { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } - if (pthread_create(&t, &att, f, data)) - { fprintf(stderr, "pthread_create err\n"); exit(1); } - if (pthread_attr_destroy(&att)) - { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } -} - void usage(void) { printf( diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 0cb5bd855a7c6f82cdb677929ae0eaa66c893317..2b02fb144107528eb815d38fe2e89776d24c0986 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -2,6 +2,7 @@ #include "handler.h" #include "database.h" #include "view/view.h" +#include "utils.h" #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -32,55 +33,30 @@ struct textlog { view **v; int vsize; /* local output buffer */ - int osize; - int omaxsize; - char *obuf; + OBUF o; }; -static void PUTC(struct textlog *l, char c) -{ - if (l->osize == l->omaxsize) { - l->omaxsize += 512; - l->obuf = realloc(l->obuf, l->omaxsize); - if (l->obuf == NULL) abort(); - } - l->obuf[l->osize] = c; - l->osize++; -} - -static void PUTS(struct textlog *l, char *s) -{ - while (*s) PUTC(l, *s++); -} - -static void PUTI(struct textlog *l, int i) -{ - char s[64]; - sprintf(s, "%d", i); - PUTS(l, s); -} - static void _event(void *p, event e) { struct textlog *l = p; int i; - l->osize = 0; + l->o.osize = 0; for (i = 0; i < l->fsize; i++) switch(l->f[i].type) { - case INSTRING: PUTS(l, l->f[i].s); break; - case INT: PUTI(l, e.e[l->f[i].event_arg].i); break; - case STRING: PUTS(l, e.e[l->f[i].event_arg].s); break; + case INSTRING: PUTS(&l->o, l->f[i].s); break; + case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; + case STRING: PUTS(&l->o, e.e[l->f[i].event_arg].s); break; case BUFFER: - PUTS(l, "{buffer size:"); - PUTI(l, e.e[l->f[i].event_arg].bsize); - PUTS(l, "}"); + PUTS(&l->o, "{buffer size:"); + PUTI(&l->o, e.e[l->f[i].event_arg].bsize); + PUTS(&l->o, "}"); break; } - PUTC(l, 0); + PUTC(&l->o, 0); - for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->obuf); + for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->o.obuf); } enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index 2e18ccb60e3f35cf0f5dd38544aaccebe53dfd02..f00097160ffc386965fe0e6802a3d8d2aa240fd7 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -3,6 +3,7 @@ #include <stdlib.h> #include <pthread.h> #include <time.h> +#include <unistd.h> void new_thread(void *(*f)(void *), void *data) { @@ -59,3 +60,46 @@ list *list_append(list *l, void *data) l->last = new; return l; } + +/****************************************************************************/ +/* socket */ +/****************************************************************************/ + +void socket_send(int socket, void *buffer, int size) +{ + char *x = buffer; + int ret; + while (size) { + ret = write(socket, x, size); + if (ret <= 0) abort(); + size -= ret; + x += ret; + } +} + +/****************************************************************************/ +/* buffer */ +/****************************************************************************/ + +void PUTC(OBUF *o, char c) +{ + if (o->osize == o->omaxsize) { + o->omaxsize += 512; + o->obuf = realloc(o->obuf, o->omaxsize); + if (o->obuf == NULL) abort(); + } + o->obuf[o->osize] = c; + o->osize++; +} + +void PUTS(OBUF *o, char *s) +{ + while (*s) PUTC(o, *s++); +} + +void PUTI(OBUF *o, int i) +{ + char s[64]; + sprintf(s, "%d", i); + PUTS(o, s); +} diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index 5a37aa34c3485b40f260e39685091ca4fe094a38..eb9aa15506547bea4f018962f2407e9251aebc94 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -16,4 +16,24 @@ typedef struct list { list *list_remove_head(list *l); list *list_append(list *l, void *data); +/****************************************************************************/ +/* socket */ +/****************************************************************************/ + +void socket_send(int socket, void *buffer, int size); + +/****************************************************************************/ +/* buffer */ +/****************************************************************************/ + +typedef struct { + int osize; + int omaxsize; + char *obuf; +} OBUF; + +void PUTC(OBUF *o, char c); +void PUTS(OBUF *o, char *s); +void PUTI(OBUF *o, int i); + #endif /* _UTILS_H_ */