diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore index 60264a9c4a..7ac6cc75bd 100644 --- a/common/utils/T/.gitignore +++ b/common/utils/T/.gitignore @@ -3,6 +3,7 @@ genids tracer/enb tracer/gnb +tracer/gnb_mac tracer/extract_config tracer/record tracer/replay diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 813226ec14..8dd5052714 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -92,9 +92,13 @@ ID = UE_PHY_INITIATE_RA_PROCEDURE GROUP = ALL:PHY:UE:WIRESHARK FORMAT = int,frame : int,subframe_or_slot : int,preamble : int,power ID = GNB_PHY_DL_TICK - DESC = gNodeB downlink tick - one tick per ms at start of downlink processing + DESC = gNodeB downlink tick - one tick per slot at start of downlink processing GROUP = ALL:PHY:GRAPHIC:GNB - FORMAT = int,gNB_ID : int,frame : int,subframe + FORMAT = int,gNB_ID : int,frame : int,slot +ID = GNB_PHY_UL_TICK + DESC = gNodeB uplink tick - one tick per slot at start of uplink processing + GROUP = ALL:PHY:GRAPHIC:GNB + FORMAT = int,gNB_ID : int,frame : int,slot ID = ENB_PHY_MIB DESC = MIB data GROUP = ALL:PHY:ENB:WIRESHARK @@ -221,6 +225,22 @@ ID = NRUE_MAC_DL_RAR_PDU_WITH_DATA DESC = NR MAC downlink PDU for RAR GROUP = ALL:MAC:UE:WIRESHARK FORMAT = int,rnti : int,frame : int,slot : buffer,data +ID = GNB_MAC_DL + DESC = NR MAC downlink scheduler decision for an UE + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs +ID = GNB_MAC_LCID_DL + DESC = NR MAC downlink scheduler decision for an UE for a specific LCID + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size : int,tx_list_occupancy +ID = GNB_MAC_UL + DESC = NR MAC uplink scheduler decision for an UE + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs +ID = GNB_MAC_LCID_UL + DESC = NR MAC uplink traffic received for an UE for a specific LCID + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size #RLC logs ID = ENB_RLC_DL diff --git a/common/utils/T/tracer/CMakeLists.txt b/common/utils/T/tracer/CMakeLists.txt index e1c79ffdf6..56568c905e 100644 --- a/common/utils/T/tracer/CMakeLists.txt +++ b/common/utils/T/tracer/CMakeLists.txt @@ -62,9 +62,13 @@ if(T_TRACER_GUI) tracer_logger tracer_view tracer_events) target_link_libraries(gnb PRIVATE png) - add_executable(ue ue.c) - target_link_libraries(ue PRIVATE tracer_utils tracer_filter tracer_gui + add_executable(gnb_mac gnb_mac.c) + target_link_libraries(gnb_mac PRIVATE tracer_utils tracer_filter tracer_gui tracer_logger tracer_view tracer_events) + + add_executable(ue ue.c) + target_link_libraries(ue PRIVATE tracer_utils tracer_view tracer_gui + tracer_logger tracer_filter tracer_events) target_link_libraries(ue PRIVATE png) add_executable(vcd vcd.c) @@ -77,5 +81,5 @@ if(T_TRACER_GUI) add_subdirectory(gui) - add_dependencies(T_tools enb gnb ue vcd to_vcd) + add_dependencies(T_tools enb gnb gnb_mac ue vcd to_vcd) endif() diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 6777be7152..ce99eabbe8 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -8,7 +8,7 @@ XLIBS=-lX11 -lpng -lXft all: record replay extract_config textlog enb ue vcd macpdu2wireshark \ extract_input_subframe extract_output_subframe to_vcd extract multi \ - gnb t_tracer_app_gnb t_tracer_app_ue + gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac record: utils.o record.o database.o configuration.o $(CC) $(CFLAGS) -o record $^ $(LIBS) @@ -65,14 +65,18 @@ gnb: utils.o gnb.o database.o event.o handler.o configuration.o \ filter/filter.a $(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS) -t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o configuration.o \ - logger/logger.a filter/filter.a +t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o \ + configuration.o logger/logger.a filter/filter.a $(CC) $(CFLAGS) -o t_tracer_app_gnb $^ $(LIBS) $(XLIBS) -t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o configuration.o \ - logger/logger.a filter/filter.a +t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o \ + configuration.o logger/logger.a filter/filter.a $(CC) $(CFLAGS) -o t_tracer_app_ue $^ $(LIBS) $(XLIBS) +gnb_mac: gnb_mac.o gui/gui.a view/view.a logger/logger.a filter/filter.a \ + utils.o database.o configuration.o handler.o event.o + $(CC) $(CFLAGS) -o gnb_mac $^ $(LIBS) $(XLIBS) + multi.o: ../incgen/T_IDs.h ../incgen/T_IDs.h: ../T_messages.txt @@ -98,7 +102,8 @@ filter/filter.a: clean: rm -f *.o core tracer_remote textlog enb ue vcd record replay rm -f extract_config macpdu2wireshark extract_input_subframe - rm -f extract_output_subframe to_vcd extract multi gnb t_tracer_app_gnb t_tracer_app_ue + rm -f extract_output_subframe to_vcd extract multi gnb + rm -f t_tracer_app_gnb t_tracer_app_ue gnb_mac cd gui && $(MAKE) clean cd view && $(MAKE) clean cd logger && $(MAKE) clean diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 5bb1cb87e2..f48f8e7dd7 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -340,12 +340,12 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, 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")); + v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10); logger_add_view(l, v); e->pucch1_energy_ue_threshold_logger = l; 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")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->pucch1_energy_ue_energy_logger = l; @@ -368,7 +368,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, 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")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->dl_mcs_logger = l; @@ -379,7 +379,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, 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")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->ul_mcs_logger = l; @@ -394,8 +394,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, col, w, -1); container_set_child_growable(g, col, w, 1); l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe", - "ENB_PHY_DLSCH_UE_DCI", "TBS"); - v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2); + "ENB_PHY_DLSCH_UE_DCI", "TBS", 10); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10); logger_add_view(l, v); /* UE x UL PHY (truly: DCI) throughput */ @@ -409,8 +409,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, col, w, -1); container_set_child_growable(g, col, w, 1); l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe", - "ENB_PHY_ULSCH_UE_DCI", "TBS"); - v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2); + "ENB_PHY_ULSCH_UE_DCI", "TBS", 10); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10); logger_add_view(l, v); /* downlink/uplink UE DCIs */ diff --git a/common/utils/T/tracer/gnb_mac.c b/common/utils/T/tracer/gnb_mac.c new file mode 100644 index 0000000000..84f29b8f82 --- /dev/null +++ b/common/utils/T/tracer/gnb_mac.c @@ -0,0 +1,332 @@ +#include +#include +#include +#include + +#include "utils.h" +#include "gui/gui.h" +#include "view/view.h" +#include "logger/logger.h" +#include "filter/filter.h" +#include "database.h" +#include "configuration.h" +#include "handler.h" + +typedef struct { + int used; +} ue_list_item; + +typedef struct { + widget *container; +} gnb_gui; + +typedef struct { + int socket; + gui *g; + gnb_gui *gg; + event_handler *h; + void *database; + ue_list_item ues[65536]; + int rnti_arg; +} gnb_data; + +void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return 0; +} + +void add_ue(gnb_data *gd, int rnti, int lcid) +{ + event_handler *h = gd->h; + void *database = gd->database; + gnb_gui *gg = gd->gg; + gui *g = gd->g; + widget *line; + widget *w, *w2, *col; + view *v; + logger *l; + + gd->ues[rnti].used = 1; + + line = new_container(g, HORIZONTAL); + widget_add_child(g, gg->container, line, -1); + + /* label */ + char s[512]; + sprintf(s, "UE %d", rnti); + widget *label = new_label(g, s); + widget_add_child(g, line, label, -1); + + /* DL MCS */ + w = new_xy_plot(g, 128, 55, "DL mcs", 20); + xy_plot_set_range(g, w, 0, 1024*20, -2, 30); + widget_add_child(g, line, w, -1); + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_DL", "mcs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_DL", "rnti"), + filter_int(rnti))); + + /* DL TBS */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + w = new_xy_plot(g, 70, 10, "DL tbs", 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1024*20, 0, 1000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_DL", "tbs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + view_tti_enable_automax(v, w2); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_DL", "rnti"), + filter_int(rnti))); + + /* DL lcid throughput */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + sprintf(s, "DL lcid %d", lcid); + w = new_xy_plot(g, 70, 10, s, 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1000, 0, 100000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_throughputlog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_LCID_DL", "data_size", 20); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_and( + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"), + filter_int(rnti)), + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"), + filter_int(lcid)))); + + /* UL MCS */ + w = new_xy_plot(g, 128, 55, "UL mcs", 20); + xy_plot_set_range(g, w, 0, 1024*20, -2, 30); + widget_add_child(g, line, w, -1); + /* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */ + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_UL", "mcs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_UL", "rnti"), + filter_int(rnti))); + + /* UL TBS */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + w = new_xy_plot(g, 70, 10, "UL tbs", 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1024*20, 0, 1000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + /* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */ + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_UL", "tbs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + view_tti_enable_automax(v, w2); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_UL", "rnti"), + filter_int(rnti))); + + /* UL lcid throughput */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + sprintf(s, "UL lcid %d", lcid); + w = new_xy_plot(g, 70, 10, s, 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1000, 0, 100000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_throughputlog(h, database, "GNB_PHY_UL_TICK", "frame", "slot", + "GNB_MAC_LCID_UL", "data_size", 20); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_and( + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_UL", "rnti"), + filter_int(rnti)), + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_UL", "lcid"), + filter_int(lcid)))); + + /* lcid RLC tx buffer occupancy */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + sprintf(s, "rlc tx %d", lcid); + w = new_xy_plot(g, 70, 10, s, 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1024*20, 0, 1000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_LCID_DL", "tx_list_occupancy", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + view_tti_enable_automax(v, w2); + logger_add_view(l, v); + logger_set_filter(l, + filter_and( + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"), + filter_int(rnti)), + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"), + filter_int(lcid)))); +} + +void build_gui(gnb_gui *gg, gui *g) +{ + widget *main_window; + + main_window = new_toplevel_window(g, 900, 1000, "gNB MAC tracer"); + gg->container = new_container(g, VERTICAL); + widget_add_child(g, main_window, gg->container, -1); +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +void check_new_ue(void *_gd, event e) +{ + gnb_data *gd = _gd; + int rnti = e.e[gd->rnti_arg].i; + if (!gd->ues[rnti].used) + add_ue(gd, rnti, 4); +} + +int main(int n, char **v) +{ + gui *g; + gnb_gui gg; + gnb_data *gd; + char *database_filename = NULL; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + event_handler *h; + int *is_on; + int number_of_events; + int i; + + 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; } + if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } + if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + on_off(database, "GNB_PHY_DL_TICK", is_on, 1); + on_off(database, "GNB_MAC_DL", is_on, 1); + on_off(database, "GNB_MAC_LCID_DL", is_on, 1); + on_off(database, "GNB_PHY_UL_TICK", is_on, 1); + on_off(database, "GNB_MAC_UL", is_on, 1); + on_off(database, "GNB_MAC_LCID_UL", is_on, 1); + + gd = calloc(1, sizeof(*gd)); if (!gd) abort(); + + h = new_handler(database); + + g = gui_init(); + new_thread(gui_thread, g); + + build_gui(&gg, g); + + gd->g = g; + gd->gg = ≫ + gd->h = h; + gd->database = database; + + /* get rnti_arg from event GNB_MAC_DL */ + int event_id = event_id_from_name(database, "GNB_MAC_DL"); + database_event_format f = get_format(database, event_id); + gd->rnti_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], "rnti")) gd->rnti_arg = i; + } + if (gd->rnti_arg == -1) { + printf("fatal: event 'GNB_MAC_DL' does not have argument 'rnti'\n"); + exit(1); + } + if (strcmp(f.type[gd->rnti_arg], "int") != 0) { + printf("fatal: argument 'rnti' of event 'GNB_MAC_DL' is not 'int'\n"); + exit(1); + } + + register_handler_function(h, event_id, check_new_ue, gd); + + OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL}; + + gd->socket = -1; + +restart: + clear_remote_config(); + if (gd->socket != -1) close(gd->socket); + gd->socket = connect_to(ip, port); + + /* send the first message - activate selected traces */ + int t = 1; + if (socket_send(gd->socket, &t, 1) == -1 || + socket_send(gd->socket, &number_of_events, sizeof(int)) == -1 || + socket_send(gd->socket, is_on, number_of_events * sizeof(int)) == -1) + goto restart; + + while (1) { + event e; + e = get_event(gd->socket, &ebuf, database); + if (e.type == -1) goto restart; + handle_event(h, e); + } + + return 0; +} diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 0fb96db325..b2fce32cff 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -54,6 +54,8 @@ void container_set_child_growable(gui *_gui, widget *_this, int xy_plot_new_plot(gui *gui, widget *this, int color); void xy_plot_set_range(gui *gui, widget *this, float xmin, float xmax, float ymin, float ymax); +void xy_plot_get_range(gui *gui, widget *this, + float *xmin, float *xmax, float *ymin, float *ymax); void xy_plot_set_points(gui *gui, widget *this, int plot, int npoints, float *x, float *y); void xy_plot_get_dimensions(gui *gui, widget *this, int *width, int *height); diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index c10b76c6ee..cc198475c2 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -280,6 +280,22 @@ void xy_plot_set_range(gui *_gui, widget *_this, gunlock(g); } +void xy_plot_get_range(gui *_gui, widget *_this, + float *xmin, float *xmax, float *ymin, float *ymax) +{ + struct gui *g = _gui; + struct xy_plot_widget *this = _this; + + glock(g); + + *xmin = this->xmin; + *xmax = this->xmax; + *ymin = this->ymin; + *ymax = this->ymax; + + gunlock(g); +} + void xy_plot_set_points(gui *_gui, widget *_this, int plot, int npoints, float *x, float *y) { diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index d746161e70..b78fa1b359 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -15,8 +15,8 @@ logger *new_ticked_ttilog(void *event_handler, void *database, char *event_name, char *data_varname, int convert_to_dB, float empty_value); logger *new_throughputlog(void *event_handler, void *database, - char *tick_event_name, char *frame_varname, char *subframe_varname, - char *event_name, char *data_varname); + char *tick_event_name, char *frame_varname, char *tick_varname, + char *event_name, char *data_varname, int ticks_per_frame); logger *new_timelog(void *event_handler, void *database, char *event_name); logger *new_ticklog(void *event_handler, void *database, char *event_name, char *frame_name, char *subframe_name); diff --git a/common/utils/T/tracer/logger/throughputlog.c b/common/utils/T/tracer/logger/throughputlog.c index 8a2d46da91..5f066df343 100644 --- a/common/utils/T/tracer/logger/throughputlog.c +++ b/common/utils/T/tracer/logger/throughputlog.c @@ -13,13 +13,14 @@ struct throughputlog { struct logger common; void *database; int tick_frame_arg; - int tick_subframe_arg; + int tick_tick_arg; int data_frame_arg; - int data_subframe_arg; + int data_tick_arg; int data_arg; int last_tick_frame; - int last_tick_subframe; - unsigned long bits[1000]; + int last_tick_tick; + int ticks_per_frame; + unsigned long *bits; unsigned long total; int insert_point; char *tick_event_name; @@ -32,16 +33,16 @@ static void _event(void *p, event e) { struct throughputlog *l = p; int frame; - int subframe; + int tick; unsigned long value; if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) return; frame = e.e[l->data_frame_arg].i; - subframe = e.e[l->data_subframe_arg].i; + tick = e.e[l->data_tick_arg].i; - if (frame != l->last_tick_frame || subframe != l->last_tick_subframe) { + if (frame != l->last_tick_frame || tick != l->last_tick_tick) { printf("WARNING: %s:%d: data comes without previous tick!\n", __FILE__, __LINE__); return; @@ -62,28 +63,34 @@ static void _tick_event(void *p, event e) struct throughputlog *l = p; int i; int frame; - int subframe; + int tick; if (l->tick_filter != NULL && filter_eval(l->tick_filter, e) == 0) return; frame = e.e[l->tick_frame_arg].i; - subframe = e.e[l->tick_subframe_arg].i; + tick = e.e[l->tick_tick_arg].i; for (i = 0; i < l->common.vsize; i++) - l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total); + l->common.v[i]->append(l->common.v[i], frame, tick, (double)l->total); - l->insert_point = (l->insert_point + 1) % 1000; - l->total -= l->bits[l->insert_point]; - l->bits[l->insert_point] = 0; + while (l->last_tick_frame != frame || l->last_tick_tick != tick) { + l->insert_point = (l->insert_point + 1) % (100 * l->ticks_per_frame); + l->total -= l->bits[l->insert_point]; + l->bits[l->insert_point] = 0; + l->last_tick_tick++; + if (l->last_tick_tick == l->ticks_per_frame) { + l->last_tick_tick = 0; + l->last_tick_frame++; + l->last_tick_frame %= 1024; + } + } - l->last_tick_frame = frame; - l->last_tick_subframe = subframe; } logger *new_throughputlog(event_handler *h, void *database, - char *tick_event_name, char *frame_varname, char *subframe_varname, - char *event_name, char *data_varname) + char *tick_event_name, char *frame_varname, char *tick_varname, + char *event_name, char *data_varname, int ticks_per_frame) { struct throughputlog *ret; int event_id; @@ -106,21 +113,21 @@ logger *new_throughputlog(event_handler *h, void *database, f = get_format(database, event_id); - /* look for frame and subframe */ + /* look for frame and tick */ ret->tick_frame_arg = -1; - ret->tick_subframe_arg = -1; + ret->tick_tick_arg = -1; for (i = 0; i < f.count; i++) { if (!strcmp(f.name[i], frame_varname)) ret->tick_frame_arg = i; - if (!strcmp(f.name[i], subframe_varname)) ret->tick_subframe_arg = i; + if (!strcmp(f.name[i], tick_varname)) ret->tick_tick_arg = i; } if (ret->tick_frame_arg == -1) { printf("%s:%d: frame argument '%s' not found in event '%s'\n", __FILE__, __LINE__, frame_varname, event_name); abort(); } - if (ret->tick_subframe_arg == -1) { - printf("%s:%d: subframe argument '%s' not found in event '%s'\n", - __FILE__, __LINE__, subframe_varname, event_name); + if (ret->tick_tick_arg == -1) { + printf("%s:%d: tick argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, tick_varname, event_name); abort(); } if (strcmp(f.type[ret->tick_frame_arg], "int") != 0) { @@ -128,9 +135,9 @@ logger *new_throughputlog(event_handler *h, void *database, __FILE__, __LINE__, frame_varname); abort(); } - if (strcmp(f.type[ret->tick_subframe_arg], "int") != 0) { + if (strcmp(f.type[ret->tick_tick_arg], "int") != 0) { printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", - __FILE__, __LINE__, subframe_varname); + __FILE__, __LINE__, tick_varname); abort(); } @@ -141,13 +148,13 @@ logger *new_throughputlog(event_handler *h, void *database, f = get_format(database, event_id); - /* look for frame, subframe and data args */ + /* look for frame, tick and data args */ ret->data_frame_arg = -1; - ret->data_subframe_arg = -1; + ret->data_tick_arg = -1; ret->data_arg = -1; for (i = 0; i < f.count; i++) { if (!strcmp(f.name[i], frame_varname)) ret->data_frame_arg = i; - if (!strcmp(f.name[i], subframe_varname)) ret->data_subframe_arg = i; + if (!strcmp(f.name[i], tick_varname)) ret->data_tick_arg = i; if (!strcmp(f.name[i], data_varname)) ret->data_arg = i; } if (ret->data_frame_arg == -1) { @@ -155,9 +162,9 @@ logger *new_throughputlog(event_handler *h, void *database, __FILE__, __LINE__, frame_varname, event_name); abort(); } - if (ret->data_subframe_arg == -1) { - printf("%s:%d: subframe argument '%s' not found in event '%s'\n", - __FILE__, __LINE__, subframe_varname, event_name); + if (ret->data_tick_arg == -1) { + printf("%s:%d: tick argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, tick_varname, event_name); abort(); } if (ret->data_arg == -1) { @@ -170,9 +177,9 @@ logger *new_throughputlog(event_handler *h, void *database, __FILE__, __LINE__, frame_varname); abort(); } - if (strcmp(f.type[ret->data_subframe_arg], "int") != 0) { + if (strcmp(f.type[ret->data_tick_arg], "int") != 0) { printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", - __FILE__, __LINE__, subframe_varname); + __FILE__, __LINE__, tick_varname); abort(); } if (strcmp(f.type[ret->data_arg], "int") != 0 && @@ -183,6 +190,10 @@ logger *new_throughputlog(event_handler *h, void *database, abort(); } + ret->ticks_per_frame = ticks_per_frame; + ret->bits = calloc(100 * ticks_per_frame, sizeof(unsigned long)); + if (ret->bits == NULL) abort(); + return ret; } diff --git a/common/utils/T/tracer/ue.c b/common/utils/T/tracer/ue.c index b28f83b0f2..f4ea38f980 100644 --- a/common/utils/T/tracer/ue.c +++ b/common/utils/T/tracer/ue.c @@ -250,15 +250,15 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -130, 35); /*l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rssi", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10); logger_add_view(l, v); e->phy_meas_logger = l;*/ l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rsrp", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->phy_meas_logger = l; l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "snr", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c720c")); + v = new_view_tti(10, g, w, new_color(g, "#0c720c"), 10); logger_add_view(l, v); e->phy_meas_logger = l; @@ -277,7 +277,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", "UE_PHY_DLSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->dl_mcs_logger = l; @@ -288,7 +288,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", "UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->ul_mcs_logger = l; @@ -301,12 +301,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -30, 50); l = new_ttilog(h, database, "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->pusch_power_logger = l; l = new_ttilog(h, database, "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10); logger_add_view(l, v); e->pusch_ampl_logger = l; @@ -319,12 +319,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -30, 50); l = new_ttilog(h, database, "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->pucch_power_logger = l; l = new_ttilog(h, database, "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10); logger_add_view(l, v); e->pucch_ampl_logger = l; @@ -335,22 +335,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -10, 80); l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level00", 1); - v = new_view_tti(10, g, w, new_color(g, "#ff0000")); + v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level01", 1); - v = new_view_tti(10, g, w, new_color(g, "#00ff00")); + v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level10", 1); - v = new_view_tti(10, g, w, new_color(g, "#0f0f0f")); + v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level11", 1); - v = new_view_tti(10, g, w, new_color(g, "#0000ff")); + v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; @@ -361,22 +361,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -10, 80); l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level00", 1); - v = new_view_tti(10, g, w, new_color(g, "#ff0000")); + v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level01", 1); - v = new_view_tti(10, g, w, new_color(g, "#00ff00")); + v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level10", 1); - v = new_view_tti(10, g, w, new_color(g, "#0f0f0f")); + v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level11", 1); - v = new_view_tti(10, g, w, new_color(g, "#0000ff")); + v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; diff --git a/common/utils/T/tracer/view/scrolltti.c b/common/utils/T/tracer/view/scrolltti.c index ad83cbc756..3bf1c93bd2 100644 --- a/common/utils/T/tracer/view/scrolltti.c +++ b/common/utils/T/tracer/view/scrolltti.c @@ -15,11 +15,14 @@ struct scrolltti { int plot; float refresh_rate; pthread_mutex_t lock; - unsigned long data[1000]; - unsigned long total; /* sum data[0..999] to have smoother value printed */ - float xout[1000]; - float yout[1000]; + int ticks_per_frame; + unsigned long *data; + unsigned long total; /* sum data[0..n] to have smoother value printed */ + float *xout; + float *yout; int insert_point; + int next_tick_frame; + int next_tick_tick; }; /* this array is used to get Y range 1000, 2000, 5000, 10000, ... */ @@ -38,21 +41,21 @@ static void *scrolltti_thread(void *_this) /* TODO: optimize */ p = this->insert_point; max = 0; - for (i = 0; i < 1000; i++) { + for (i = 0; i < this->ticks_per_frame * 100; i++) { this->xout[i] = i; this->yout[i] = this->data[p]; if (this->data[p] > max) max = this->data[p]; - p = (p + 1) % 1000; + p = (p + 1) % (this->ticks_per_frame * 100); } - bps(o, this->total/1000., "b/s"); + bps(o, this->total/(this->ticks_per_frame * 100.), "b/s"); textarea_set_text(this->g, this->throughput_textarea, o); /* for Y range we want 1000, 2000, 5000, 10000, 20000, 50000, etc. */ if (max < 1000) max = 1000; mlog = pow(10, floor(log10(max))); max = tolog[(int)ceil(max/mlog)] * mlog; - xy_plot_set_range(this->g, this->w, 0, 1000, 0, max); + xy_plot_set_range(this->g, this->w, 0, this->ticks_per_frame * 100, 0, max); xy_plot_set_points(this->g, this->w, this->plot, - 1000, this->xout, this->yout); + this->ticks_per_frame * 100, this->xout, this->yout); if (pthread_mutex_unlock(&this->lock)) abort(); sleepms(1000/this->refresh_rate); } @@ -65,20 +68,40 @@ static void clear(view *this) /* TODO */ } -static void append(view *_this, int frame, int subframe, double value) +static void insert(struct scrolltti *this, double value) +{ + this->total -= this->data[this->insert_point]; + this->data[this->insert_point] = value; + this->total += this->data[this->insert_point]; + this->insert_point = (this->insert_point + 1) % (this->ticks_per_frame * 100); +} + +static void next_tick(struct scrolltti *this) +{ + this->next_tick_tick++; + if (this->next_tick_tick == this->ticks_per_frame) { + this->next_tick_tick = 0; + this->next_tick_frame++; + this->next_tick_frame %= 1024; + } +} + +static void append(view *_this, int frame, int tick, double value) { struct scrolltti *this = (struct scrolltti *)_this; if (pthread_mutex_lock(&this->lock)) abort(); - this->total -= this->data[this->insert_point]; - this->data[this->insert_point] = value; - this->total += this->data[this->insert_point]; - this->insert_point = (this->insert_point + 1) % 1000; + while (this->next_tick_frame != frame || this->next_tick_tick != tick) { + insert(this, 0); + next_tick(this); + } + insert(this, value); + next_tick(this); if (pthread_mutex_unlock(&this->lock)) abort(); } view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color, - widget *throughput_textarea) + widget *throughput_textarea, int ticks_per_frame) { struct scrolltti *ret = calloc(1, sizeof(struct scrolltti)); if (ret == NULL) abort(); @@ -92,6 +115,14 @@ view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color, ret->throughput_textarea = throughput_textarea; ret->plot = xy_plot_new_plot(g, w, color); + ret->ticks_per_frame = ticks_per_frame; + ret->data = calloc(ticks_per_frame * 100, sizeof(unsigned long)); + if (ret->data == NULL) abort(); + ret->xout = calloc(ticks_per_frame * 100, sizeof(float)); + if (ret->xout == NULL) abort(); + ret->yout = calloc(ticks_per_frame * 100, sizeof(float)); + if (ret->yout == NULL) abort(); + if (pthread_mutex_init(&ret->lock, NULL)) abort(); new_thread(scrolltti_thread, ret); diff --git a/common/utils/T/tracer/view/tti.c b/common/utils/T/tracer/view/tti.c index ebf9fc657c..73d43b539b 100644 --- a/common/utils/T/tracer/view/tti.c +++ b/common/utils/T/tracer/view/tti.c @@ -5,31 +5,36 @@ #include #include #include +#include struct tti { view common; gui *g; widget *w; + int automax; + widget *w2; int plot; float refresh_rate; pthread_mutex_t lock; - float data[1024*10]; - int valid[1024*10]; - float xout[1024*10]; - float yout[1024*10]; + float *data; + int *valid; + float *xout; + float *yout; int last_insert_point; + int ticks_per_frame; }; -static int far_enough(int i, int last_insert, int plot_width) +static int far_enough(int i, int last_insert, int plot_width, + int ticks_per_frame) { int p1; int p2; int hole_size_px; int hole_size_tti; hole_size_px = 10; - hole_size_tti = 10240 * hole_size_px / plot_width; + hole_size_tti = 1024 * ticks_per_frame * hole_size_px / plot_width; p1 = last_insert; - p2 = (last_insert + hole_size_tti) % (1024*10); + p2 = (last_insert + hole_size_tti) % (1024 * ticks_per_frame); if (p1 < p2) { return !(i > p1 && i < p2); } @@ -48,15 +53,31 @@ static void *tti_thread(void *_this) if (pthread_mutex_lock(&this->lock)) abort(); xy_plot_get_dimensions(this->g, this->w, &plot_width, &plot_height); length = 0; + double max = 0; /* TODO: optimize */ - for (i = 0; i < 1024*10; i++) + for (i = 0; i < 1024 * this->ticks_per_frame; i++) /* do not take points too close after last insertion point */ if (this->valid[i] && - far_enough(i, this->last_insert_point, plot_width)) { + far_enough(i, this->last_insert_point, plot_width, + this->ticks_per_frame)) { this->xout[length] = i; this->yout[length] = this->data[i]; + if (this->data[i] > max) max = this->data[i]; length++; } + if (this->automax) { + char o[128]; + sprintf(o, "%d", (int)max); + textarea_set_text(this->g, this->w2, o); + /* for Y range we want 10, 20, 50, 100, 200, 500, etc. */ + if (max < 10) max = 10; + double mlog = pow(10, floor(log10(max))); + static int tolog[11] = { -1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10 }; + max = tolog[(int)ceil(max/mlog)] * mlog; + float xmin, xmax, ymin, ymax; + xy_plot_get_range(this->g, this->w, &xmin, &xmax, &ymin, &ymax); + xy_plot_set_range(this->g, this->w, xmin, xmax, 0, max); + } xy_plot_set_points(this->g, this->w, this->plot, length, this->xout, this->yout); if (pthread_mutex_unlock(&this->lock)) abort(); @@ -71,11 +92,11 @@ static void clear(view *this) /* TODO */ } -static void append(view *_this, int frame, int subframe, double value) +static void append(view *_this, int frame, int tick, double value) { struct tti *this = (struct tti *)_this; int i; - int index = frame * 10 + subframe; + int index = frame * this->ticks_per_frame + tick; if (pthread_mutex_lock(&this->lock)) abort(); @@ -84,10 +105,10 @@ static void append(view *_this, int frame, int subframe, double value) * this may be wrong if delay between two append is * greater than 1024 frames (something like that) */ - i = (this->last_insert_point + 1) % (1024*10); + i = (this->last_insert_point + 1) % (1024 * this->ticks_per_frame); while (i != index) { this->valid[i] = 0; - i = (i + 1) % (1024*10); + i = (i + 1) % (1024 * this->ticks_per_frame); } this->data[index] = value; @@ -98,7 +119,8 @@ static void append(view *_this, int frame, int subframe, double value) if (pthread_mutex_unlock(&this->lock)) abort(); } -view *new_view_tti(float refresh_rate, gui *g, widget *w, int color) +view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, + int ticks_per_frame) { struct tti *ret = calloc(1, sizeof(struct tti)); if (ret == NULL) abort(); @@ -115,7 +137,24 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color) if (pthread_mutex_init(&ret->lock, NULL)) abort(); + ret->ticks_per_frame = ticks_per_frame; + ret->data = calloc(ticks_per_frame * 1024, sizeof(float)); + if (ret->data == NULL) abort(); + ret->valid = calloc(ticks_per_frame * 1024, sizeof(int)); + if (ret->valid == NULL) abort(); + ret->xout = calloc(ticks_per_frame * 1024, sizeof(float)); + if (ret->xout == NULL) abort(); + ret->yout = calloc(ticks_per_frame * 1024, sizeof(float)); + if (ret->yout == NULL) abort(); + new_thread(tti_thread, ret); return (view *)ret; } + +void view_tti_enable_automax(view *_tti, widget *w2) +{ + struct tti *tti = (struct tti *)_tti; + tti->automax = 1; + tti->w2 = w2; +} diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 8167a00ccd..bc37e654d1 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -17,15 +17,16 @@ view *new_view_stdout(void); view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w); view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, int color, enum xy_mode mode); -view *new_view_tti(float refresh_rate, gui *g, widget *w, - int color); +view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, + int ticks_per_frame); view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, - int color, widget *throughput_label); + int color, widget *throughput_label, int ticks_per_frame); view *new_view_time(int number_of_seconds, float refresh_rate, gui *g, widget *w); view *new_subview_time(view *time, int line, int color, int size); view *new_view_ticktime(float refresh_rate, gui *g, widget *w); view *new_subview_ticktime(view *ticktime, int line, int color, int size); void ticktime_set_tick(view *ticktime, void *logger); +void view_tti_enable_automax(view *tti, widget *w2); #endif /* _VIEW_H_ */ diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 24870544b8..1021aba1ce 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -174,6 +174,8 @@ static void rx_func(processingData_L1_t *info) int slot_rx = info->slot_rx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + T(T_GNB_PHY_UL_TICK, T_INT(gNB->Mod_id), T_INT(frame_rx), T_INT(slot_rx)); + // RX processing int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx); if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index c88ad3bd96..8befbe4833 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1314,6 +1314,7 @@ void nr_schedule_ue_spec(module_id_t module_id, if (len == 0) break; + T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid))); header->R = 0; header->F = 1; header->LCID = lcid; @@ -1387,6 +1388,7 @@ void nr_schedule_ue_spec(module_id_t module_id, T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS)); + T(T_GNB_MAC_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(sched_pdsch->mcs), T_INT(TBS)); } const int ntx_req = TX_req->Number_of_PDUs; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b4ab184deb..09044e9170 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -485,6 +485,7 @@ static int nr_process_mac_pdu(instance_t module_idP, UE->mac_stats.ul.total_sdu_bytes += mac_len; UE->mac_stats.ul.lc_bytes[lcid] += mac_len; } + T(T_GNB_MAC_LCID_UL, T_INT(UE->rnti), T_INT(frameP), T_INT(slot), T_INT(lcid), T_INT(mac_len * 8)); break; case UL_SCH_LCID_DTCH ...(UL_SCH_LCID_DTCH + 28): @@ -512,6 +513,7 @@ static int nr_process_mac_pdu(instance_t module_idP, else sched_ctrl->estimated_ul_buffer = 0; } + T(T_GNB_MAC_LCID_UL, T_INT(UE->rnti), T_INT(frameP), T_INT(slot), T_INT(lcid), T_INT(mac_len * 8)); break; case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: @@ -2470,6 +2472,8 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, sched_ctrl->tpc0); + T(T_GNB_MAC_UL, T_INT(UE->rnti), T_INT(frame), T_INT(slot), T_INT(sched_pusch->mcs), T_INT(sched_pusch->tb_size)); + /* PUSCH in a later slot, but corresponding DCI now! */ const int index = ul_buffer_index(sched_pusch->frame, sched_pusch->slot, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index 6103a7011a..e452981357 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -125,6 +125,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ret->common.reestablishment = nr_rlc_entity_am_reestablishment; ret->common.delete_entity = nr_rlc_entity_am_delete; ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space; + ret->common.tx_list_occupancy = nr_rlc_entity_am_tx_list_occupancy; ret->common.get_stats = nr_rlc_entity_get_stats; ret->common.deliver_sdu = deliver_sdu; @@ -186,6 +187,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( ret->common.reestablishment = nr_rlc_entity_um_reestablishment; ret->common.delete_entity = nr_rlc_entity_um_delete; ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space; + ret->common.tx_list_occupancy = nr_rlc_entity_um_tx_list_occupancy; ret->common.get_stats = nr_rlc_entity_get_stats; ret->common.deliver_sdu = deliver_sdu; @@ -226,6 +228,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; ret->common.delete_entity = nr_rlc_entity_tm_delete; ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space; + ret->common.tx_list_occupancy = nr_rlc_entity_tm_tx_list_occupancy; ret->common.get_stats = nr_rlc_entity_get_stats; ret->common.deliver_sdu = deliver_sdu; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index dc0bf4907c..459e9f59a5 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -116,6 +116,7 @@ typedef struct nr_rlc_entity_t { void (*delete_entity)(struct nr_rlc_entity_t *entity); int (*available_tx_space)(struct nr_rlc_entity_t *entity); + int (*tx_list_occupancy)(struct nr_rlc_entity_t *entity); void (*get_stats)(struct nr_rlc_entity_t *entity, nr_rlc_statistics_t *out); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index a66ebe82e5..b1f87a7a05 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -2116,3 +2116,8 @@ int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity) return entity->tx_maxsize - entity->tx_size; } +int nr_rlc_entity_am_tx_list_occupancy(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + return entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h index 6b61e84a2f..3ffcab6176 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -101,5 +101,6 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity); +int nr_rlc_entity_am_tx_list_occupancy(nr_rlc_entity_t *_entity); #endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c index 7b541c02ff..be20d574c1 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -221,3 +221,9 @@ int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity) nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; return entity->tx_maxsize - entity->tx_size; } + +int nr_rlc_entity_tm_tx_list_occupancy(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + return entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h index 716b35d14d..2792017c34 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -56,5 +56,6 @@ void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity); +int nr_rlc_entity_tm_tx_list_occupancy(nr_rlc_entity_t *_entity); #endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c index 75e407328b..4edee0ddab 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -765,3 +765,9 @@ int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity) nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; return entity->tx_maxsize - entity->tx_size; } + +int nr_rlc_entity_um_tx_list_occupancy(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + return entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h index 6395bfd47e..c32c5aaedf 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -80,5 +80,6 @@ void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity); +int nr_rlc_entity_um_tx_list_occupancy(nr_rlc_entity_t *_entity); #endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 88c8d5d377..e187541fd5 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -320,6 +320,25 @@ int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t chann return ret; } +int nr_rlc_tx_list_occupancy(int ue_id, logical_chan_id_t lcid) +{ + int ret; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lcid); + + if (rb != NULL) { + ret = rb->tx_list_occupancy(rb); + } else { + ret = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return ret; +} + int nr_rlc_module_init(nr_rlc_op_mode_t mode) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index fec65796d9..454a59b928 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -80,6 +80,8 @@ void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t channel_idP); +int nr_rlc_tx_list_occupancy(int ue_id, logical_chan_id_t lcid); + void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t channel_id, const bool is_on); void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size);