Merge remote-tracking branch 'origin/t-gnb-tracer' into integration_2021_wk10
This commit is contained in:
@@ -4,6 +4,7 @@ T_IDs.h
|
|||||||
T_messages.txt.h
|
T_messages.txt.h
|
||||||
genids
|
genids
|
||||||
tracer/enb
|
tracer/enb
|
||||||
|
tracer/gnb
|
||||||
tracer/extract_config
|
tracer/extract_config
|
||||||
tracer/record
|
tracer/record
|
||||||
tracer/replay
|
tracer/replay
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
ID = BENETEL
|
|
||||||
GROUP = ALL
|
|
||||||
FORMAT = int,frame : int,slot : buffer,rxdataF
|
|
||||||
|
|
||||||
#general logs
|
#general logs
|
||||||
ID = ENB_MASTER_TICK
|
ID = ENB_MASTER_TICK
|
||||||
DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view
|
DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view
|
||||||
@@ -93,6 +89,10 @@ ID = GNB_PHY_MIB
|
|||||||
DESC = NR MIB data
|
DESC = NR MIB data
|
||||||
GROUP = ALL:PHY:GNB:WIRESHARK
|
GROUP = ALL:PHY:GNB:WIRESHARK
|
||||||
FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data
|
FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data
|
||||||
|
ID = GNB_PHY_PUCCH_PUSCH_IQ
|
||||||
|
DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done
|
||||||
|
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
|
||||||
|
FORMAT = int,frame : int,slot : buffer,rxdataF
|
||||||
|
|
||||||
#MAC logs
|
#MAC logs
|
||||||
ID = ENB_MAC_UE_DL_SDU
|
ID = ENB_MAC_UE_DL_SDU
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ LIBS=-lm
|
|||||||
XLIBS=-lX11 -lpng -lXft
|
XLIBS=-lX11 -lpng -lXft
|
||||||
|
|
||||||
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
|
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
|
||||||
extract_input_subframe extract_output_subframe to_vcd extract multi
|
extract_input_subframe extract_output_subframe to_vcd extract multi \
|
||||||
|
gnb
|
||||||
|
|
||||||
record: utils.o record.o database.o config.o
|
record: utils.o record.o database.o config.o
|
||||||
$(CC) $(CFLAGS) -o record $^ $(LIBS)
|
$(CC) $(CFLAGS) -o record $^ $(LIBS)
|
||||||
@@ -60,6 +61,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \
|
|||||||
multi: multi.o utils.o database.o config.o
|
multi: multi.o utils.o database.o config.o
|
||||||
$(CC) $(CFLAGS) -o multi $^ $(LIBS)
|
$(CC) $(CFLAGS) -o multi $^ $(LIBS)
|
||||||
|
|
||||||
|
gnb: utils.o gnb.o database.o event.o handler.o config.o \
|
||||||
|
view/view.a gui/gui.a logger/logger.a \
|
||||||
|
filter/filter.a
|
||||||
|
$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
|
||||||
|
|
||||||
multi.o: ../T_IDs.h
|
multi.o: ../T_IDs.h
|
||||||
|
|
||||||
../T_IDs.h:
|
../T_IDs.h:
|
||||||
@@ -85,7 +91,7 @@ filter/filter.a:
|
|||||||
clean:
|
clean:
|
||||||
rm -f *.o core tracer_remote textlog enb ue vcd record replay
|
rm -f *.o core tracer_remote textlog enb ue vcd record replay
|
||||||
rm -f extract_config macpdu2wireshark extract_input_subframe
|
rm -f extract_config macpdu2wireshark extract_input_subframe
|
||||||
rm -f extract_output_subframe to_vcd extract multi
|
rm -f extract_output_subframe to_vcd extract multi gnb
|
||||||
cd gui && $(MAKE) clean
|
cd gui && $(MAKE) clean
|
||||||
cd view && $(MAKE) clean
|
cd view && $(MAKE) clean
|
||||||
cd logger && $(MAKE) clean
|
cd logger && $(MAKE) clean
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "database.h"
|
||||||
|
#include "handler.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "logger/logger.h"
|
||||||
|
#include "view/view.h"
|
||||||
|
#include "gui/gui.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
widget *pucch_pusch_iq_plot;
|
||||||
|
logger *pucch_pusch_iq_logger;
|
||||||
|
} gnb_gui;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int socket;
|
||||||
|
int *is_on;
|
||||||
|
int nevents;
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
gnb_gui *e;
|
||||||
|
void *database;
|
||||||
|
} gnb_data;
|
||||||
|
|
||||||
|
void is_on_changed(void *_d)
|
||||||
|
{
|
||||||
|
gnb_data *d = _d;
|
||||||
|
char t;
|
||||||
|
|
||||||
|
if (pthread_mutex_lock(&d->lock)) abort();
|
||||||
|
|
||||||
|
if (d->socket == -1) goto no_connection;
|
||||||
|
|
||||||
|
t = 1;
|
||||||
|
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)
|
||||||
|
goto connection_dies;
|
||||||
|
|
||||||
|
no_connection:
|
||||||
|
if (pthread_mutex_unlock(&d->lock)) abort();
|
||||||
|
return;
|
||||||
|
|
||||||
|
connection_dies:
|
||||||
|
close(d->socket);
|
||||||
|
d->socket = -1;
|
||||||
|
if (pthread_mutex_unlock(&d->lock)) abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"options:\n"
|
||||||
|
" -d <database file> this option is mandatory\n"
|
||||||
|
" -ip <host> connect to given IP address (default %s)\n"
|
||||||
|
" -p <port> connect to given port (default %d)\n",
|
||||||
|
DEFAULT_REMOTE_IP,
|
||||||
|
DEFAULT_REMOTE_PORT
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *gui_thread(void *_g)
|
||||||
|
{
|
||||||
|
gui *g = _g;
|
||||||
|
gui_loop(g);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database,
|
||||||
|
gnb_data *ed)
|
||||||
|
{
|
||||||
|
widget *main_window;
|
||||||
|
widget *top_container;
|
||||||
|
widget *line;
|
||||||
|
widget *w;
|
||||||
|
logger *l;
|
||||||
|
view *v;
|
||||||
|
|
||||||
|
main_window = new_toplevel_window(g, 500, 300, "gNB tracer");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* PUCCH/PUSCH IQ data */
|
||||||
|
w = new_xy_plot(g, 55, 55, "", 50);
|
||||||
|
e->pucch_pusch_iq_plot = w;
|
||||||
|
widget_add_child(g, line, w, -1);
|
||||||
|
xy_plot_set_range(g, w, -1000, 1000, -1000, 1000);
|
||||||
|
xy_plot_set_title(g, w, "rxdataF");
|
||||||
|
l = new_iqlog_full(h, database, "GNB_PHY_PUCCH_PUSCH_IQ", "rxdataF");
|
||||||
|
v = new_view_xy(300*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
|
||||||
|
logger_add_view(l, v);
|
||||||
|
e->pucch_pusch_iq_logger = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int n, char **v)
|
||||||
|
{
|
||||||
|
char *database_filename = NULL;
|
||||||
|
void *database;
|
||||||
|
char *ip = DEFAULT_REMOTE_IP;
|
||||||
|
int port = DEFAULT_REMOTE_PORT;
|
||||||
|
int *is_on;
|
||||||
|
int number_of_events;
|
||||||
|
int i;
|
||||||
|
event_handler *h;
|
||||||
|
gnb_data gnb_data;
|
||||||
|
gui *g;
|
||||||
|
gnb_gui eg;
|
||||||
|
|
||||||
|
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; }
|
||||||
|
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();
|
||||||
|
|
||||||
|
h = new_handler(database);
|
||||||
|
|
||||||
|
on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1);
|
||||||
|
|
||||||
|
gnb_data.database = database;
|
||||||
|
gnb_data.socket = -1;
|
||||||
|
gnb_data.is_on = is_on;
|
||||||
|
gnb_data.nevents = number_of_events;
|
||||||
|
if (pthread_mutex_init(&gnb_data.lock, NULL)) abort();
|
||||||
|
|
||||||
|
g = gui_init();
|
||||||
|
new_thread(gui_thread, g);
|
||||||
|
|
||||||
|
gnb_main_gui(&eg, g, h, database, &gnb_data);
|
||||||
|
|
||||||
|
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||||
|
|
||||||
|
restart:
|
||||||
|
clear_remote_config();
|
||||||
|
if (gnb_data.socket != -1) close(gnb_data.socket);
|
||||||
|
gnb_data.socket = connect_to(ip, port);
|
||||||
|
|
||||||
|
/* send the first message - activate selected traces */
|
||||||
|
is_on_changed(&gnb_data);
|
||||||
|
|
||||||
|
/* read messages */
|
||||||
|
while (1) {
|
||||||
|
event e;
|
||||||
|
e = get_event(gnb_data.socket, &ebuf, database);
|
||||||
|
if (e.type == -1) goto restart;
|
||||||
|
if (pthread_mutex_lock(&gnb_data.lock)) abort();
|
||||||
|
handle_event(h, e);
|
||||||
|
if (pthread_mutex_unlock(&gnb_data.lock)) abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -74,6 +74,44 @@ static void _event(void *p, event e)
|
|||||||
l->common.v[i]->append(l->common.v[i], l->i, l->q, count);
|
l->common.v[i]->append(l->common.v[i], l->i, l->q, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _event_full(void *p, event e)
|
||||||
|
{
|
||||||
|
struct iqlog *l = p;
|
||||||
|
int i;
|
||||||
|
void *buffer;
|
||||||
|
int bsize;
|
||||||
|
int nsamples;
|
||||||
|
float *idst, *qdst;
|
||||||
|
|
||||||
|
if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
buffer = e.e[l->buffer_arg].b;
|
||||||
|
bsize = e.e[l->buffer_arg].bsize;
|
||||||
|
|
||||||
|
nsamples = bsize / 4;
|
||||||
|
|
||||||
|
if (nsamples > l->max_length) {
|
||||||
|
l->i = realloc(l->i, nsamples * sizeof(float));
|
||||||
|
if (l->i == NULL) abort();
|
||||||
|
l->q = realloc(l->q, nsamples * sizeof(float));
|
||||||
|
if (l->q == NULL) abort();
|
||||||
|
l->max_length = nsamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
idst = l->i;
|
||||||
|
qdst = l->q;
|
||||||
|
for (i = 0; i < nsamples; i++) {
|
||||||
|
*idst = ((int16_t *)buffer)[i * 2];
|
||||||
|
*qdst = ((int16_t *)buffer)[i * 2 + 1];
|
||||||
|
idst++;
|
||||||
|
qdst++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < l->common.vsize; i++)
|
||||||
|
l->common.v[i]->append(l->common.v[i], l->i, l->q, nsamples);
|
||||||
|
}
|
||||||
|
|
||||||
logger *new_iqlog(event_handler *h, void *database,
|
logger *new_iqlog(event_handler *h, void *database,
|
||||||
char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
|
char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
|
||||||
char *buffer_varname)
|
char *buffer_varname)
|
||||||
@@ -149,3 +187,43 @@ logger *new_iqlog(event_handler *h, void *database,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger *new_iqlog_full(event_handler *h, void *database, char *event_name,
|
||||||
|
char *buffer_varname)
|
||||||
|
{
|
||||||
|
struct iqlog *ret;
|
||||||
|
int event_id;
|
||||||
|
database_event_format f;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ret = calloc(1, sizeof(struct iqlog)); if (ret == NULL) abort();
|
||||||
|
|
||||||
|
ret->common.event_name = strdup(event_name);
|
||||||
|
if (ret->common.event_name == NULL) abort();
|
||||||
|
ret->database = database;
|
||||||
|
|
||||||
|
event_id = event_id_from_name(database, event_name);
|
||||||
|
|
||||||
|
ret->common.handler_id = register_handler_function(h, event_id, _event_full,
|
||||||
|
ret);
|
||||||
|
|
||||||
|
f = get_format(database, event_id);
|
||||||
|
|
||||||
|
/* look for args */
|
||||||
|
ret->buffer_arg = -1;
|
||||||
|
for (i = 0; i < f.count; i++) {
|
||||||
|
if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i;
|
||||||
|
}
|
||||||
|
if (ret->buffer_arg == -1) {
|
||||||
|
printf("%s:%d: buffer argument '%s' not found in event '%s'\n",
|
||||||
|
__FILE__, __LINE__, buffer_varname, event_name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (strcmp(f.type[ret->buffer_arg], "buffer") != 0) {
|
||||||
|
printf("%s:%d: argument '%s' has wrong type (should be 'buffer')\n",
|
||||||
|
__FILE__, __LINE__, buffer_varname);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ logger *new_ticklog(void *event_handler, void *database,
|
|||||||
logger *new_iqlog(void *event_handler, void *database,
|
logger *new_iqlog(void *event_handler, void *database,
|
||||||
char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
|
char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
|
||||||
char *buffer_varname);
|
char *buffer_varname);
|
||||||
|
logger *new_iqlog_full(void *event_handler, void *database, char *event_name,
|
||||||
|
char *buffer_varname);
|
||||||
logger *new_iqdotlog(void *event_handler, void *database,
|
logger *new_iqdotlog(void *event_handler, void *database,
|
||||||
char *event_name, char *I, char *Q);
|
char *event_name, char *I, char *Q);
|
||||||
|
|
||||||
|
|||||||
@@ -542,6 +542,9 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||||
|
/* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */
|
||||||
|
int pucch_decode_done = 0;
|
||||||
|
int pusch_decode_done = 0;
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
|
||||||
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
|
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
|
||||||
@@ -563,6 +566,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
|||||||
(pucch->frame == frame_rx) &&
|
(pucch->frame == frame_rx) &&
|
||||||
(pucch->slot == slot_rx) ) {
|
(pucch->slot == slot_rx) ) {
|
||||||
|
|
||||||
|
pucch_decode_done = 1;
|
||||||
|
|
||||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
||||||
uint16_t num_ucis;
|
uint16_t num_ucis;
|
||||||
switch (pucch_pdu->format_type) {
|
switch (pucch_pdu->format_type) {
|
||||||
@@ -651,7 +656,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14));
|
pusch_decode_done = 1;
|
||||||
|
|
||||||
uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
|
uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
|
||||||
uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
|
uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
|
||||||
@@ -680,5 +685,9 @@ T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF
|
|||||||
// figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
|
// figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
|
||||||
if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB);
|
if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB);
|
||||||
|
|
||||||
|
if (pucch_decode_done || pusch_decode_done) {
|
||||||
|
T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
|
||||||
|
}
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user