Merge remote-tracking branch 'origin/ru_rau_enhancement-external-timing' into ru_rau_enhancement_L1_renaming
This commit is contained in:
@@ -19,7 +19,7 @@ T_IDs.h: $(GENIDS) T_messages.txt
|
||||
./$(GENIDS) T_messages.txt T_IDs.h
|
||||
|
||||
check_vcd:
|
||||
gcc -Wall -I. -I.. -I../itti -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
|
||||
gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
|
||||
./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false)
|
||||
rm -f ./_check_vcd
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
/* array used to activate/disactivate a log */
|
||||
static int T_IDs[T_NUMBER_OF_IDS];
|
||||
int *T_active = T_IDs;
|
||||
int T_stdout;
|
||||
int T_stdout = 1;
|
||||
|
||||
static int T_socket;
|
||||
|
||||
|
||||
@@ -75,8 +75,12 @@ ID = ENB_PHY_MSG3_ALLOCATION
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,first_transmission : int,Msg3_frame : int,Msg3_subframe
|
||||
ID = ENB_PHY_INITIATE_RA_PROCEDURE
|
||||
DESC = eNodeB initiates a random access procedure after detecting enough energy for one of the preambles
|
||||
GROUP = ALL:PHY:ENB
|
||||
GROUP = ALL:PHY:ENB:WIRESHARK
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,preamble : int,energy : int,delay
|
||||
ID = ENB_PHY_MIB
|
||||
DESC = MIB data
|
||||
GROUP = ALL:PHY:ENB:WIRESHARK
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : buffer,data
|
||||
|
||||
#MAC logs
|
||||
ID = ENB_MAC_UE_DL_SDU
|
||||
@@ -97,7 +101,7 @@ ID = ENB_MAC_UE_UL_PDU
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,sdu_length : int,num_ce : int,num_sdu
|
||||
ID = ENB_MAC_UE_UL_PDU_WITH_DATA
|
||||
DESC = MAC uplink UE received PDU
|
||||
GROUP = ALL:MAC:ENB
|
||||
GROUP = ALL:MAC:ENB:WIRESHARK
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,sdu_length : int,num_ce : int,num_sdu : buffer,data
|
||||
ID = ENB_MAC_UE_UL_SDU
|
||||
DESC = MAC uplink UE received SDU
|
||||
@@ -113,12 +117,16 @@ ID = ENB_MAC_UE_UL_CE
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,ce
|
||||
ID = ENB_MAC_UE_DL_PDU_WITH_DATA
|
||||
DESC = MAC downlink PDU for an UE
|
||||
GROUP = ALL:MAC:ENB
|
||||
GROUP = ALL:MAC:ENB:WIRESHARK
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data
|
||||
ID = ENB_MAC_SCHEDULING_REQUEST
|
||||
DESC = MAC scheduling request detected for an UE
|
||||
GROUP = ALL:MAC:ENB
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,rnti
|
||||
ID = ENB_MAC_UE_DL_RAR_PDU_WITH_DATA
|
||||
DESC = MAC downlink PDU for an UE
|
||||
GROUP = ALL:MAC:ENB:WIRESHARK
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data
|
||||
|
||||
#RLC logs
|
||||
ID = ENB_RLC_DL
|
||||
|
||||
+92
-35
@@ -8,27 +8,35 @@ char **unique_ids;
|
||||
int unique_ids_size;
|
||||
int unique_ids_maxsize;
|
||||
|
||||
int cmp(const void *p1, const void *p2)
|
||||
{
|
||||
return strcmp(*(char * const *)p1, *(char * const *)p2);
|
||||
int cmp(const void *p1, const void *p2) {
|
||||
return strcmp(*(char *const *)p1, *(char *const *)p2);
|
||||
}
|
||||
|
||||
/* return 1 if s was not already known, 0 if it was */
|
||||
int new_unique_id(char *s, char *input_file)
|
||||
{
|
||||
int new_unique_id(char *s, char *input_file) {
|
||||
if (unique_ids_size)
|
||||
if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) {
|
||||
printf("error: ID %s is not unique in %s\n", s, input_file);
|
||||
return 0;
|
||||
}
|
||||
if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) {
|
||||
printf("error: ID %s is not unique in %s\n", s, input_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (unique_ids_size == unique_ids_maxsize) {
|
||||
unique_ids_maxsize += 256;
|
||||
unique_ids = realloc(unique_ids, unique_ids_maxsize * sizeof(char *));
|
||||
if (unique_ids == NULL) { printf("erorr: out of memory\n"); abort(); }
|
||||
|
||||
if (unique_ids == NULL) {
|
||||
printf("error: out of memory\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
unique_ids[unique_ids_size] = strdup(s);
|
||||
if (unique_ids[unique_ids_size] == NULL)
|
||||
{ printf("erorr: out of memory\n"); abort(); }
|
||||
|
||||
if (unique_ids[unique_ids_size] == NULL) {
|
||||
printf("error: out of memory\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
unique_ids_size++;
|
||||
qsort(unique_ids, unique_ids_size, sizeof(char *), cmp);
|
||||
return 1;
|
||||
@@ -38,14 +46,17 @@ char *bufname;
|
||||
int bufname_size;
|
||||
int bufname_maxsize;
|
||||
|
||||
void putname(int c)
|
||||
{
|
||||
void putname(int c) {
|
||||
if (bufname_size == bufname_maxsize) {
|
||||
bufname_maxsize += 256;
|
||||
bufname = realloc(bufname, bufname_maxsize);
|
||||
if (bufname == NULL)
|
||||
{ printf("erorr: memory allocation error\n"); exit(1); }
|
||||
|
||||
if (bufname == NULL) {
|
||||
printf("error: memory allocation error\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bufname[bufname_size] = c;
|
||||
bufname_size++;
|
||||
}
|
||||
@@ -54,42 +65,54 @@ char *bufvalue;
|
||||
int bufvalue_size;
|
||||
int bufvalue_maxsize;
|
||||
|
||||
void putvalue(int c)
|
||||
{
|
||||
void putvalue(int c) {
|
||||
if (bufvalue_size == bufvalue_maxsize) {
|
||||
bufvalue_maxsize += 256;
|
||||
bufvalue = realloc(bufvalue, bufvalue_maxsize);
|
||||
if (bufvalue == NULL)
|
||||
{ printf("error: memory allocation error\n"); exit(1); }
|
||||
|
||||
if (bufvalue == NULL) {
|
||||
printf("error: memory allocation error\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bufvalue[bufvalue_size] = c;
|
||||
bufvalue_size++;
|
||||
}
|
||||
|
||||
void smash_spaces(FILE *f)
|
||||
{
|
||||
void smash_spaces(FILE *f) {
|
||||
int c;
|
||||
|
||||
while (1) {
|
||||
c = fgetc(f);
|
||||
|
||||
if (isspace(c)) continue;
|
||||
|
||||
if (c == ' ') continue;
|
||||
|
||||
if (c == '\t') continue;
|
||||
|
||||
if (c == '\n') continue;
|
||||
|
||||
if (c == 10 || c == 13) continue;
|
||||
|
||||
if (c == '#') {
|
||||
while (1) {
|
||||
c = fgetc(f);
|
||||
|
||||
if (c == '\n' || c == EOF) break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (c != EOF) ungetc(c, f);
|
||||
}
|
||||
|
||||
void get_line(FILE *f, char **name, char **value)
|
||||
{
|
||||
void get_line(FILE *f, char **name, char **value) {
|
||||
int c;
|
||||
bufname_size = 0;
|
||||
bufvalue_size = 0;
|
||||
@@ -97,23 +120,39 @@ void get_line(FILE *f, char **name, char **value)
|
||||
*value = NULL;
|
||||
smash_spaces(f);
|
||||
c = fgetc(f);
|
||||
while (!(c == '=' || isspace(c) || c == EOF)) { putname(c); c = fgetc(f); }
|
||||
|
||||
while (!(c == '=' || isspace(c) || c == EOF)) {
|
||||
putname(c);
|
||||
c = fgetc(f);
|
||||
}
|
||||
|
||||
if (c == EOF) return;
|
||||
|
||||
putname(0);
|
||||
|
||||
while (!(c == EOF || c == '=')) c = fgetc(f);
|
||||
|
||||
if (c == EOF) return;
|
||||
|
||||
smash_spaces(f);
|
||||
c = fgetc(f);
|
||||
while (!(c == 10 || c == 13 || c == EOF)) { putvalue(c); c = fgetc(f); }
|
||||
|
||||
while (!(c == 10 || c == 13 || c == EOF)) {
|
||||
putvalue(c);
|
||||
c = fgetc(f);
|
||||
}
|
||||
|
||||
putvalue(0);
|
||||
|
||||
if (bufname_size <= 1) return;
|
||||
|
||||
if (bufvalue_size <= 1) return;
|
||||
|
||||
*name = bufname;
|
||||
*value = bufvalue;
|
||||
}
|
||||
|
||||
int main(int n, char **v)
|
||||
{
|
||||
int main(int n, char **v) {
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
char *name;
|
||||
@@ -121,36 +160,54 @@ int main(int n, char **v)
|
||||
char *in_name;
|
||||
char *out_name;
|
||||
|
||||
if (n != 3) { printf("error: gimme <source> <dest>\n"); exit(1); }
|
||||
if (n != 3) {
|
||||
printf("error: gimme <source> <dest>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
in_name = v[1];
|
||||
out_name = v[2];
|
||||
in = fopen(in_name, "r");
|
||||
|
||||
in = fopen(in_name, "r"); if (in == NULL) { perror(in_name); exit(1); }
|
||||
out = fopen(out_name, "w"); if (out == NULL) { perror(out_name); exit(1); }
|
||||
if (in == NULL) {
|
||||
perror(in_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
out = fopen(out_name, "w");
|
||||
|
||||
if (out == NULL) {
|
||||
perror(out_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(out, "/* generated file, do not edit by hand */\n\n");
|
||||
|
||||
while (1) {
|
||||
get_line(in, &name, &value);
|
||||
|
||||
if (name == NULL) break;
|
||||
|
||||
if (isspace(value[strlen(value)-1])) {
|
||||
printf("error: bad value '%s' (no space at the end please!)\n", value);
|
||||
unlink(out_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strcmp(name, "ID")) {
|
||||
if (!new_unique_id(value, in_name)) { unlink(out_name); exit(1); }
|
||||
if (!new_unique_id(value, in_name)) {
|
||||
unlink(out_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(out, "#define T_%s T_ID(%d)\n", value, n);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
fprintf(out, "#define T_NUMBER_OF_IDS %d\n", n);
|
||||
|
||||
fprintf(out, "#define T_NUMBER_OF_IDS %d\n", n);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \
|
||||
multi: multi.o utils.o database.o config.o
|
||||
$(CC) $(CFLAGS) -o multi $^ $(LIBS)
|
||||
|
||||
multi.o: ../T_IDs.h
|
||||
|
||||
../T_IDs.h:
|
||||
cd .. && $(MAKE)
|
||||
|
||||
.PHONY: all gui/gui.a view/view.a logger/logger.a filter/filter.a
|
||||
|
||||
gui/gui.a:
|
||||
|
||||
@@ -16,6 +16,8 @@ void usage(void)
|
||||
" -f <name> <value> field 'name' of 'event' has to match 'value'\n"
|
||||
" type of 'name' must be int\n"
|
||||
" (you can use several -f options)\n"
|
||||
" -after <raw time> <nsec> 'event' time has to be greater than this\n"
|
||||
" -count <n> dump 'n' matching events (less if EOF reached)\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
@@ -51,6 +53,10 @@ int main(int n, char **v)
|
||||
int filter_count = 0;
|
||||
int buffer_arg;
|
||||
int found;
|
||||
int count = 1;
|
||||
int check_time = 0;
|
||||
time_t sec;
|
||||
long nsec;
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
||||
@@ -63,6 +69,14 @@ int main(int n, char **v)
|
||||
filter_value[filter_count++] = atoi(v[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(v[i], "-after")) { if (i>n-3) usage();
|
||||
check_time = 1;
|
||||
sec = atoll(v[++i]);
|
||||
nsec = atol(v[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(v[i], "-count"))
|
||||
{ if (i > n-2) usage(); count = atoi(v[++i]); continue; }
|
||||
if (file == NULL) { file = v[i]; continue; }
|
||||
if (event_name == NULL) { event_name = v[i]; continue; }
|
||||
if (buffer_name == NULL) { buffer_name = v[i]; continue; }
|
||||
@@ -111,13 +125,20 @@ int main(int n, char **v)
|
||||
break;
|
||||
if (i != filter_count)
|
||||
continue;
|
||||
if (check_time &&
|
||||
!(e.sending_time.tv_sec > sec ||
|
||||
(e.sending_time.tv_sec == sec && e.sending_time.tv_nsec >= nsec)))
|
||||
continue;
|
||||
if (fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, out) != 1)
|
||||
{ perror(output_file); exit(1); }
|
||||
found = 1;
|
||||
break;
|
||||
found++;
|
||||
if (found == count)
|
||||
break;
|
||||
}
|
||||
|
||||
if (found == 0) printf("ERROR: event not found\n");
|
||||
if (found != count)
|
||||
printf("WARNING: dumped %d events (wanted %d)\n", found, count);
|
||||
|
||||
fclose(out);
|
||||
|
||||
|
||||
+147
-136
@@ -7,21 +7,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int x_connection_fd(x_connection *_x)
|
||||
{
|
||||
int x_connection_fd(x_connection *_x) {
|
||||
struct x_connection *x = _x;
|
||||
return ConnectionNumber(x->d);
|
||||
}
|
||||
|
||||
static GC create_gc(Display *d, char *color)
|
||||
{
|
||||
static GC create_gc(Display *d, char *color) {
|
||||
GC ret = XCreateGC(d, DefaultRootWindow(d), 0, NULL);
|
||||
XGCValues gcv;
|
||||
XColor rcol, scol;
|
||||
|
||||
XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, ret);
|
||||
|
||||
if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)),
|
||||
color, &scol, &rcol)) {
|
||||
color, &scol, &rcol)) {
|
||||
gcv.foreground = scol.pixel;
|
||||
XChangeGC(d, ret, GCForeground, &gcv);
|
||||
} else ERR("X: could not allocate color '%s'\n", color);
|
||||
@@ -29,82 +27,81 @@ static GC create_gc(Display *d, char *color)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x_new_color(x_connection *_x, char *color)
|
||||
{
|
||||
int x_new_color(x_connection *_x, char *color) {
|
||||
struct x_connection *x = _x;
|
||||
x->ncolors++;
|
||||
|
||||
x->colors = realloc(x->colors, x->ncolors * sizeof(GC));
|
||||
if (x->colors == NULL) OOM;
|
||||
x->colors[x->ncolors-1] = create_gc(x->d, color);
|
||||
|
||||
if (x->colors == NULL) OOM;
|
||||
|
||||
x->colors[x->ncolors-1] = create_gc(x->d, color);
|
||||
x->xft_colors = realloc(x->xft_colors, x->ncolors * sizeof(XftColor));
|
||||
|
||||
if (x->xft_colors == NULL) OOM;
|
||||
|
||||
if (XftColorAllocName(x->d, DefaultVisual(x->d, DefaultScreen(x->d)),
|
||||
DefaultColormap(x->d, DefaultScreen(x->d)),
|
||||
color, &x->xft_colors[x->ncolors-1]) == False)
|
||||
DefaultColormap(x->d, DefaultScreen(x->d)),
|
||||
color, &x->xft_colors[x->ncolors-1]) == False)
|
||||
ERR("could not allocate color '%s'\n", color);
|
||||
|
||||
return x->ncolors - 1;
|
||||
}
|
||||
|
||||
int x_new_font(x_connection *_x, char *font)
|
||||
{
|
||||
int x_new_font(x_connection *_x, char *font) {
|
||||
struct x_connection *x = _x;
|
||||
/* TODO: allocate fonts only once */
|
||||
x->nfonts++;
|
||||
x->fonts = realloc(x->fonts, x->nfonts * sizeof(XftFont *));
|
||||
|
||||
if (x->fonts == NULL) OOM;
|
||||
|
||||
x->fonts[x->nfonts-1] = XftFontOpenName(x->d, DefaultScreen(x->d), font);
|
||||
|
||||
if (x->fonts[x->nfonts-1] == NULL)
|
||||
ERR("failed allocating font '%s'\n", font);
|
||||
|
||||
return x->nfonts - 1;
|
||||
}
|
||||
|
||||
x_connection *x_open(void)
|
||||
{
|
||||
x_connection *x_open(void) {
|
||||
struct x_connection *ret;
|
||||
|
||||
ret = calloc(1, sizeof(struct x_connection));
|
||||
|
||||
if (ret == NULL) OOM;
|
||||
|
||||
ret->d = XOpenDisplay(0);
|
||||
LOGD("XOpenDisplay display %p return x_connection %p\n", ret->d, ret);
|
||||
|
||||
if (ret->d == NULL) ERR("error calling XOpenDisplay: no X? you root?\n");
|
||||
|
||||
x_new_color(ret, "white"); /* background color */
|
||||
x_new_color(ret, "black"); /* foreground color */
|
||||
|
||||
x_new_font(ret, "sans-8");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
x_window *x_create_window(x_connection *_x, int width, int height,
|
||||
char *title)
|
||||
{
|
||||
char *title) {
|
||||
struct x_connection *x = _x;
|
||||
struct x_window *ret;
|
||||
|
||||
ret = calloc(1, sizeof(struct x_window));
|
||||
|
||||
if (ret == NULL) OOM;
|
||||
|
||||
ret->w = XCreateSimpleWindow(x->d, DefaultRootWindow(x->d), 0, 0,
|
||||
width, height, 0, WhitePixel(x->d, DefaultScreen(x->d)),
|
||||
WhitePixel(x->d, DefaultScreen(x->d)));
|
||||
width, height, 0, WhitePixel(x->d, DefaultScreen(x->d)),
|
||||
WhitePixel(x->d, DefaultScreen(x->d)));
|
||||
ret->width = width;
|
||||
ret->height = height;
|
||||
|
||||
XStoreName(x->d, ret->w, title);
|
||||
|
||||
ret->p = XCreatePixmap(x->d, ret->w, width, height,
|
||||
DefaultDepth(x->d, DefaultScreen(x->d)));
|
||||
DefaultDepth(x->d, DefaultScreen(x->d)));
|
||||
XFillRectangle(x->d, ret->p, x->colors[BACKGROUND_COLOR],
|
||||
0, 0, width, height);
|
||||
|
||||
0, 0, width, height);
|
||||
ret->xft = XftDrawCreate(x->d, ret->p,
|
||||
DefaultVisual(x->d, DefaultScreen(x->d)),
|
||||
DefaultColormap(x->d, DefaultScreen(x->d)));
|
||||
DefaultVisual(x->d, DefaultScreen(x->d)),
|
||||
DefaultColormap(x->d, DefaultScreen(x->d)));
|
||||
|
||||
if (ret->xft == NULL) ERR("XftDrawCreate failed\n");
|
||||
|
||||
/* enable backing store */
|
||||
@@ -113,23 +110,19 @@ x_window *x_create_window(x_connection *_x, int width, int height,
|
||||
att.backing_store = Always;
|
||||
XChangeWindowAttributes(x->d, ret->w, CWBackingStore, &att);
|
||||
}
|
||||
|
||||
XSelectInput(x->d, ret->w,
|
||||
KeyPressMask |
|
||||
ButtonPressMask |
|
||||
ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
ExposureMask |
|
||||
StructureNotifyMask);
|
||||
|
||||
KeyPressMask |
|
||||
ButtonPressMask |
|
||||
ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
ExposureMask |
|
||||
StructureNotifyMask);
|
||||
XMapWindow(x->d, ret->w);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
x_image *x_create_image(x_connection *_x, unsigned char *data,
|
||||
int width, int height)
|
||||
{
|
||||
int width, int height) {
|
||||
struct x_connection *x = _x;
|
||||
struct x_image *ret;
|
||||
XImage *ximage;
|
||||
@@ -137,8 +130,9 @@ x_image *x_create_image(x_connection *_x, unsigned char *data,
|
||||
XVisualInfo template;
|
||||
int nvs;
|
||||
Visual *v;
|
||||
ret = calloc(1, sizeof(struct x_image));
|
||||
|
||||
ret = calloc(1, sizeof(struct x_image)); if (ret == NULL) OOM;
|
||||
if (ret == NULL) OOM;
|
||||
|
||||
template.class = TrueColor;
|
||||
template.depth = 24;
|
||||
@@ -146,68 +140,65 @@ x_image *x_create_image(x_connection *_x, unsigned char *data,
|
||||
template.green_mask = 0x00ff00;
|
||||
template.blue_mask = 0x0000ff;
|
||||
template.bits_per_rgb = 8;
|
||||
|
||||
vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask |
|
||||
VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
|
||||
VisualBitsPerRGBMask, &template, &nvs);
|
||||
VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
|
||||
VisualBitsPerRGBMask, &template, &nvs);
|
||||
|
||||
if (vs == NULL) {
|
||||
/* try again with 32 bpp */
|
||||
template.depth = 32;
|
||||
vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask |
|
||||
VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
|
||||
VisualBitsPerRGBMask, &template, &nvs);
|
||||
VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
|
||||
VisualBitsPerRGBMask, &template, &nvs);
|
||||
}
|
||||
|
||||
if (vs == NULL) ERR("no good visual found\n");
|
||||
|
||||
v = vs[0].visual;
|
||||
XFree(vs);
|
||||
|
||||
ximage = XCreateImage(x->d, v, 24, ZPixmap, 0,
|
||||
(char*)data, width, height, 32, 0);
|
||||
(char *)data, width, height, 32, 0);
|
||||
|
||||
if (ximage == NULL) ERR("image creation failed\n");
|
||||
|
||||
ret->p = XCreatePixmap(x->d, DefaultRootWindow(x->d), width, height, 24);
|
||||
|
||||
XPutImage(x->d, ret->p, DefaultGC(x->d, DefaultScreen(x->d)),
|
||||
ximage, 0, 0, 0, 0, width, height);
|
||||
|
||||
ximage, 0, 0, 0, 0, width, height);
|
||||
/* TODO: be sure it's fine to set data to NULL */
|
||||
ximage->data = NULL;
|
||||
XDestroyImage(ximage);
|
||||
|
||||
ret->width = width;
|
||||
ret->height = height;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct toplevel_window_widget *find_x_window(struct gui *g, Window id)
|
||||
{
|
||||
static struct toplevel_window_widget *find_x_window(struct gui *g, Window id) {
|
||||
struct widget_list *cur;
|
||||
struct toplevel_window_widget *w;
|
||||
struct x_window *xw;
|
||||
cur = g->toplevel;
|
||||
|
||||
while (cur) {
|
||||
w = (struct toplevel_window_widget *)cur->item;
|
||||
xw = w->x;
|
||||
|
||||
if (xw->w == id) return w;
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void x_events(gui *_gui)
|
||||
{
|
||||
void x_events(gui *_gui) {
|
||||
struct gui *g = _gui;
|
||||
struct widget_list *cur;
|
||||
struct x_connection *x = g->x;
|
||||
struct toplevel_window_widget *w;
|
||||
|
||||
LOGD("x_events START\n");
|
||||
/* preprocessing (to "compress" events) */
|
||||
cur = g->toplevel;
|
||||
|
||||
while (cur) {
|
||||
struct x_window *xw;
|
||||
w = (struct toplevel_window_widget *)cur->item;
|
||||
@@ -222,58 +213,84 @@ void x_events(gui *_gui)
|
||||
XEvent ev;
|
||||
XNextEvent(x->d, &ev);
|
||||
LOGD("XEV %d\n", ev.type);
|
||||
|
||||
switch (ev.type) {
|
||||
case MapNotify:
|
||||
case Expose:
|
||||
if ((w = find_x_window(g, ev.xexpose.window)) != NULL) {
|
||||
struct x_window *xw = w->x;
|
||||
xw->redraw = 1;
|
||||
}
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
if ((w = find_x_window(g, ev.xconfigure.window)) != NULL) {
|
||||
struct x_window *xw = w->x;
|
||||
xw->resize = 1;
|
||||
xw->new_width = ev.xconfigure.width;
|
||||
xw->new_height = ev.xconfigure.height;
|
||||
if (xw->new_width < 10) xw->new_width = 10;
|
||||
if (xw->new_height < 10) xw->new_height = 10;
|
||||
LOGD("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height);
|
||||
}
|
||||
break;
|
||||
case ButtonPress:
|
||||
if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
|
||||
int key_modifiers = 0;
|
||||
if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT;
|
||||
if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT;
|
||||
if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL;
|
||||
w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers,
|
||||
ev.xbutton.button, 0);
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
|
||||
int key_modifiers = 0;
|
||||
if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT;
|
||||
if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT;
|
||||
if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL;
|
||||
w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers,
|
||||
ev.xbutton.button, 1);
|
||||
}
|
||||
break;
|
||||
default: if (gui_logd) WARN("TODO: X event type %d\n", ev.type); break;
|
||||
case MapNotify:
|
||||
case Expose:
|
||||
if ((w = find_x_window(g, ev.xexpose.window)) != NULL) {
|
||||
struct x_window *xw = w->x;
|
||||
xw->redraw = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ConfigureNotify:
|
||||
if ((w = find_x_window(g, ev.xconfigure.window)) != NULL) {
|
||||
struct x_window *xw = w->x;
|
||||
xw->resize = 1;
|
||||
xw->new_width = ev.xconfigure.width;
|
||||
xw->new_height = ev.xconfigure.height;
|
||||
|
||||
if (xw->new_width < 10) xw->new_width = 10;
|
||||
|
||||
if (xw->new_height < 10) xw->new_height = 10;
|
||||
|
||||
LOGD("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
|
||||
int key_modifiers = 0;
|
||||
|
||||
if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT;
|
||||
|
||||
if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT;
|
||||
|
||||
if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL;
|
||||
|
||||
w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers,
|
||||
ev.xbutton.button, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
|
||||
int key_modifiers = 0;
|
||||
|
||||
if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT;
|
||||
|
||||
if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT;
|
||||
|
||||
if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL;
|
||||
|
||||
w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers,
|
||||
ev.xbutton.button, 1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (gui_logd) WARN("TODO: X event type %d\n", ev.type);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* postprocessing */
|
||||
LOGD("post processing\n");
|
||||
cur = g->toplevel;
|
||||
|
||||
while (cur) {
|
||||
struct toplevel_window_widget *w =
|
||||
(struct toplevel_window_widget *)cur->item;
|
||||
(struct toplevel_window_widget *)cur->item;
|
||||
struct x_window *xw = w->x;
|
||||
|
||||
if (xw->resize) {
|
||||
LOGD("resize old %d %d new %d %d\n", xw->width, xw->height, xw->new_width, xw->new_height);
|
||||
|
||||
if (xw->width != xw->new_width || xw->height != xw->new_height) {
|
||||
w->common.allocate(g, w, 0, 0, xw->new_width, xw->new_height);
|
||||
xw->width = xw->new_width;
|
||||
@@ -281,46 +298,47 @@ void x_events(gui *_gui)
|
||||
XftDrawDestroy(xw->xft);
|
||||
XFreePixmap(x->d, xw->p);
|
||||
xw->p = XCreatePixmap(x->d, xw->w, xw->width, xw->height,
|
||||
DefaultDepth(x->d, DefaultScreen(x->d)));
|
||||
DefaultDepth(x->d, DefaultScreen(x->d)));
|
||||
XFillRectangle(x->d, xw->p, x->colors[BACKGROUND_COLOR],
|
||||
0, 0, xw->width, xw->height);
|
||||
0, 0, xw->width, xw->height);
|
||||
xw->xft = XftDrawCreate(x->d, xw->p,
|
||||
DefaultVisual(x->d, DefaultScreen(x->d)),
|
||||
DefaultColormap(x->d, DefaultScreen(x->d)));
|
||||
DefaultVisual(x->d, DefaultScreen(x->d)),
|
||||
DefaultColormap(x->d, DefaultScreen(x->d)));
|
||||
|
||||
if (xw->xft == NULL) ERR("XftDrawCreate failed\n");
|
||||
|
||||
//xw->repaint = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (xw->repaint) {
|
||||
w->common.paint(g, w);
|
||||
xw->redraw = 1;
|
||||
}
|
||||
|
||||
if (xw->redraw) {
|
||||
struct x_connection *x = g->x;
|
||||
LOGD("XCopyArea w h %d %d\n", xw->width, xw->height);
|
||||
XCopyArea(x->d, xw->p, xw->w, x->colors[1],
|
||||
0, 0, xw->width, xw->height, 0, 0);
|
||||
0, 0, xw->width, xw->height, 0, 0);
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
LOGD("x_events DONE\n");
|
||||
}
|
||||
|
||||
void x_flush(x_connection *_x)
|
||||
{
|
||||
void x_flush(x_connection *_x) {
|
||||
struct x_connection *x = _x;
|
||||
XFlush(x->d);
|
||||
}
|
||||
|
||||
void x_text_get_dimensions(x_connection *_c, int font, const char *t,
|
||||
int *width, int *height, int *baseline)
|
||||
{
|
||||
int *width, int *height, int *baseline) {
|
||||
struct x_connection *c = _c;
|
||||
XGlyphInfo ext;
|
||||
|
||||
XftTextExtentsUtf8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext);
|
||||
|
||||
*width = ext.width;
|
||||
*height = c->fonts[font]->height;
|
||||
*baseline = c->fonts[font]->ascent;
|
||||
@@ -331,63 +349,57 @@ void x_text_get_dimensions(x_connection *_c, int font, const char *t,
|
||||
/***********************************************************************/
|
||||
|
||||
void x_draw_line(x_connection *_c, x_window *_w, int color,
|
||||
int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int x1, int y1, int x2, int y2) {
|
||||
struct x_connection *c = _c;
|
||||
struct x_window *w = _w;
|
||||
XDrawLine(c->d, w->p, c->colors[color], x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void x_draw_rectangle(x_connection *_c, x_window *_w, int color,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
int x, int y, int width, int height) {
|
||||
struct x_connection *c = _c;
|
||||
struct x_window *w = _w;
|
||||
XDrawRectangle(c->d, w->p, c->colors[color], x, y, width, height);
|
||||
}
|
||||
|
||||
void x_fill_rectangle(x_connection *_c, x_window *_w, int color,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
int x, int y, int width, int height) {
|
||||
struct x_connection *c = _c;
|
||||
struct x_window *w = _w;
|
||||
XFillRectangle(c->d, w->p, c->colors[color], x, y, width, height);
|
||||
}
|
||||
|
||||
void x_draw_string(x_connection *_c, x_window *_w, int font, int color,
|
||||
int x, int y, const char *t)
|
||||
{
|
||||
int x, int y, const char *t) {
|
||||
struct x_connection *c = _c;
|
||||
struct x_window *w = _w;
|
||||
int tlen = strlen(t);
|
||||
XftDrawStringUtf8(w->xft, &c->xft_colors[color], c->fonts[font],
|
||||
x, y, (const unsigned char *)t, tlen);
|
||||
x, y, (const unsigned char *)t, tlen);
|
||||
}
|
||||
|
||||
void x_draw_clipped_string(x_connection *_c, x_window *_w, int font,
|
||||
int color, int x, int y, const char *t,
|
||||
int clipx, int clipy, int clipwidth, int clipheight)
|
||||
{
|
||||
int color, int x, int y, const char *t,
|
||||
int clipx, int clipy, int clipwidth, int clipheight) {
|
||||
struct x_window *w = _w;
|
||||
|
||||
XRectangle clip = { clipx, clipy, clipwidth, clipheight };
|
||||
|
||||
if (XftDrawSetClipRectangles(w->xft, 0, 0, &clip, 1) == False) abort();
|
||||
|
||||
x_draw_string(_c, _w, font, color, x, y, t);
|
||||
|
||||
if (XftDrawSetClip(w->xft, NULL) == False) abort();
|
||||
}
|
||||
|
||||
void x_draw_image(x_connection *_c, x_window *_w, x_image *_img, int x, int y)
|
||||
{
|
||||
void x_draw_image(x_connection *_c, x_window *_w, x_image *_img, int x, int y) {
|
||||
struct x_connection *c = _c;
|
||||
struct x_window *w = _w;
|
||||
struct x_image *img = _img;
|
||||
|
||||
XCopyArea(c->d, img->p, w->p, DefaultGC(c->d, DefaultScreen(c->d)),
|
||||
0, 0, img->width, img->height, x, y);
|
||||
0, 0, img->width, img->height, x, y);
|
||||
}
|
||||
|
||||
void x_draw(x_connection *_c, x_window *_w)
|
||||
{
|
||||
void x_draw(x_connection *_c, x_window *_w) {
|
||||
struct x_connection *c = _c;
|
||||
struct x_window *w = _w;
|
||||
LOGD("x_draw XCopyArea w h %d %d display %p window %d pixmap %d\n", w->width, w->height, c->d, (int)w->w, (int)w->p);
|
||||
@@ -397,13 +409,13 @@ void x_draw(x_connection *_c, x_window *_w)
|
||||
/* those two special functions are to plot many points
|
||||
* first call x_add_point many times then x_plot_points once
|
||||
*/
|
||||
void x_add_point(x_connection *_c, int x, int y)
|
||||
{
|
||||
void x_add_point(x_connection *_c, int x, int y) {
|
||||
struct x_connection *c = _c;
|
||||
|
||||
if (c->pts_size == c->pts_maxsize) {
|
||||
c->pts_maxsize += 65536;
|
||||
c->pts = realloc(c->pts, c->pts_maxsize * sizeof(XPoint));
|
||||
|
||||
if (c->pts == NULL) OOM;
|
||||
}
|
||||
|
||||
@@ -412,12 +424,11 @@ void x_add_point(x_connection *_c, int x, int y)
|
||||
c->pts_size++;
|
||||
}
|
||||
|
||||
void x_plot_points(x_connection *_c, x_window *_w, int color)
|
||||
{
|
||||
void x_plot_points(x_connection *_c, x_window *_w, int color) {
|
||||
struct x_connection *c = _c;
|
||||
LOGD("x_plot_points %d points\n", c->pts_size);
|
||||
struct x_window *w = _w;
|
||||
XDrawPoints(c->d, w->p, c->colors[color], c->pts, c->pts_size,
|
||||
CoordModeOrigin);
|
||||
CoordModeOrigin);
|
||||
c->pts_size = 0;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ void framelog_set_skip(logger *_this, int skip_delay);
|
||||
void framelog_set_update_only_at_sf9(logger *_this, int update_only_at_sf9);
|
||||
|
||||
void textlog_dump_buffer(logger *_this, int dump_buffer);
|
||||
void textlog_raw_time(logger *_this, int raw_time);
|
||||
|
||||
#include "view/view.h"
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ struct textlog {
|
||||
/* local output buffer */
|
||||
OBUF o;
|
||||
int dump_buffer;
|
||||
int raw_time;
|
||||
};
|
||||
|
||||
static void _event(void *p, event e)
|
||||
@@ -51,9 +52,13 @@ static void _event(void *p, event e)
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
t = localtime(&e.sending_time.tv_sec);
|
||||
/* round tv_nsec to nearest millisecond */
|
||||
sprintf(tt, "%2.2d:%2.2d:%2.2d.%9.9ld: ", t->tm_hour, t->tm_min, t->tm_sec,
|
||||
e.sending_time.tv_nsec);
|
||||
if (l->raw_time)
|
||||
sprintf(tt, "%2.2d:%2.2d:%2.2d.%9.9ld [%ld]: ",
|
||||
t->tm_hour, t->tm_min, t->tm_sec,
|
||||
e.sending_time.tv_nsec, e.sending_time.tv_sec);
|
||||
else
|
||||
sprintf(tt, "%2.2d:%2.2d:%2.2d.%9.9ld: ", t->tm_hour, t->tm_min, t->tm_sec,
|
||||
e.sending_time.tv_nsec);
|
||||
PUTS(&l->o, tt);
|
||||
#endif
|
||||
|
||||
@@ -215,3 +220,9 @@ void textlog_dump_buffer(logger *_this, int dump_buffer)
|
||||
struct textlog *l = _this;
|
||||
l->dump_buffer = dump_buffer;
|
||||
}
|
||||
|
||||
void textlog_raw_time(logger *_this, int raw_time)
|
||||
{
|
||||
struct textlog *l = _this;
|
||||
l->raw_time = raw_time;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#define DEFAULT_IP "127.0.0.1"
|
||||
#define DEFAULT_PORT 9999
|
||||
|
||||
#define DEFAULT_LIVE_IP "127.0.0.1"
|
||||
#define DEFAULT_LIVE_PORT 2021
|
||||
|
||||
#define NO_PREAMBLE -1
|
||||
|
||||
typedef struct {
|
||||
int socket;
|
||||
struct sockaddr_in to;
|
||||
@@ -28,11 +33,33 @@ typedef struct {
|
||||
int dl_frame;
|
||||
int dl_subframe;
|
||||
int dl_data;
|
||||
/* mib */
|
||||
int mib_frame;
|
||||
int mib_subframe;
|
||||
int mib_data;
|
||||
/* RA preamble */
|
||||
int preamble_frame;
|
||||
int preamble_subframe;
|
||||
int preamble_preamble;
|
||||
/* RAR */
|
||||
int rar_rnti;
|
||||
int rar_frame;
|
||||
int rar_subframe;
|
||||
int rar_data;
|
||||
/* config */
|
||||
int no_mib;
|
||||
int no_sib;
|
||||
int max_mib;
|
||||
int max_sib;
|
||||
int live;
|
||||
/* runtime vars */
|
||||
int cur_mib;
|
||||
int cur_sib;
|
||||
} ev_data;
|
||||
|
||||
void ul(void *_d, event e)
|
||||
void trace(ev_data *d, int direction, int rnti_type, int rnti,
|
||||
int frame, int subframe, void *buf, int bufsize, int preamble)
|
||||
{
|
||||
ev_data *d = _d;
|
||||
ssize_t ret;
|
||||
int fsf;
|
||||
int i;
|
||||
@@ -41,79 +68,124 @@ void ul(void *_d, event e)
|
||||
|
||||
PUTS(&d->buf, MAC_LTE_START_STRING);
|
||||
PUTC(&d->buf, FDD_RADIO);
|
||||
PUTC(&d->buf, DIRECTION_UPLINK);
|
||||
PUTC(&d->buf, C_RNTI);
|
||||
PUTC(&d->buf, direction);
|
||||
PUTC(&d->buf, rnti_type);
|
||||
|
||||
PUTC(&d->buf, MAC_LTE_RNTI_TAG);
|
||||
PUTC(&d->buf, (e.e[d->ul_rnti].i>>8) & 255);
|
||||
PUTC(&d->buf, e.e[d->ul_rnti].i & 255);
|
||||
if (rnti_type == C_RNTI || rnti_type == RA_RNTI) {
|
||||
PUTC(&d->buf, MAC_LTE_RNTI_TAG);
|
||||
PUTC(&d->buf, (rnti>>8) & 255);
|
||||
PUTC(&d->buf, rnti & 255);
|
||||
}
|
||||
|
||||
/* for newer version of wireshark? */
|
||||
fsf = (e.e[d->ul_frame].i << 4) + e.e[d->ul_subframe].i;
|
||||
fsf = (frame << 4) + subframe;
|
||||
/* for older version? */
|
||||
fsf = e.e[d->ul_subframe].i;
|
||||
//fsf = subframe;
|
||||
PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG);
|
||||
PUTC(&d->buf, (fsf>>8) & 255);
|
||||
PUTC(&d->buf, fsf & 255);
|
||||
|
||||
if (preamble != NO_PREAMBLE) {
|
||||
PUTC(&d->buf, MAC_LTE_SEND_PREAMBLE_TAG);
|
||||
PUTC(&d->buf, preamble);
|
||||
PUTC(&d->buf, 0); /* rach attempt - always 0 for us (not sure of this) */
|
||||
}
|
||||
|
||||
PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG);
|
||||
for (i = 0; i < e.e[d->ul_data].bsize; i++)
|
||||
PUTC(&d->buf, ((char*)e.e[d->ul_data].b)[i]);
|
||||
for (i = 0; i < bufsize; i++)
|
||||
PUTC(&d->buf, ((char*)buf)[i]);
|
||||
|
||||
ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0,
|
||||
(struct sockaddr *)&d->to, sizeof(struct sockaddr_in));
|
||||
if (ret != d->buf.osize) abort();
|
||||
}
|
||||
|
||||
void ul(void *_d, event e)
|
||||
{
|
||||
ev_data *d = _d;
|
||||
trace(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i,
|
||||
e.e[d->ul_frame].i, e.e[d->ul_subframe].i,
|
||||
e.e[d->ul_data].b, e.e[d->ul_data].bsize,
|
||||
NO_PREAMBLE);
|
||||
}
|
||||
|
||||
void dl(void *_d, event e)
|
||||
{
|
||||
ev_data *d = _d;
|
||||
ssize_t ret;
|
||||
int fsf;
|
||||
int i;
|
||||
|
||||
d->buf.osize = 0;
|
||||
if (e.e[d->dl_rnti].i == 0xffff) {
|
||||
if (d->no_sib) return;
|
||||
if (d->max_sib && d->cur_sib == d->max_sib) return;
|
||||
d->cur_sib++;
|
||||
}
|
||||
|
||||
PUTS(&d->buf, MAC_LTE_START_STRING);
|
||||
PUTC(&d->buf, FDD_RADIO);
|
||||
PUTC(&d->buf, DIRECTION_DOWNLINK);
|
||||
PUTC(&d->buf, C_RNTI);
|
||||
|
||||
PUTC(&d->buf, MAC_LTE_RNTI_TAG);
|
||||
PUTC(&d->buf, (e.e[d->dl_rnti].i>>8) & 255);
|
||||
PUTC(&d->buf, e.e[d->dl_rnti].i & 255);
|
||||
|
||||
/* for newer version of wireshark? */
|
||||
fsf = (e.e[d->dl_frame].i << 4) + e.e[d->dl_subframe].i;
|
||||
/* for older version? */
|
||||
fsf = e.e[d->dl_subframe].i;
|
||||
PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG);
|
||||
PUTC(&d->buf, (fsf>>8) & 255);
|
||||
PUTC(&d->buf, fsf & 255);
|
||||
|
||||
PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG);
|
||||
for (i = 0; i < e.e[d->dl_data].bsize; i++)
|
||||
PUTC(&d->buf, ((char*)e.e[d->dl_data].b)[i]);
|
||||
|
||||
ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0,
|
||||
(struct sockaddr *)&d->to, sizeof(struct sockaddr_in));
|
||||
if (ret != d->buf.osize) abort();
|
||||
trace(d, DIRECTION_DOWNLINK,
|
||||
e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i,
|
||||
e.e[d->dl_frame].i, e.e[d->dl_subframe].i,
|
||||
e.e[d->dl_data].b, e.e[d->dl_data].bsize,
|
||||
NO_PREAMBLE);
|
||||
}
|
||||
|
||||
void setup_data(ev_data *d, void *database, int ul_id, int dl_id)
|
||||
void mib(void *_d, event e)
|
||||
{
|
||||
ev_data *d = _d;
|
||||
|
||||
if (d->no_mib) return;
|
||||
if (d->max_mib && d->cur_mib == d->max_mib) return;
|
||||
d->cur_mib++;
|
||||
|
||||
trace(d, DIRECTION_DOWNLINK, NO_RNTI, 0,
|
||||
e.e[d->mib_frame].i, e.e[d->mib_subframe].i,
|
||||
e.e[d->mib_data].b, e.e[d->mib_data].bsize,
|
||||
NO_PREAMBLE);
|
||||
}
|
||||
|
||||
void preamble(void *_d, event e)
|
||||
{
|
||||
ev_data *d = _d;
|
||||
trace(d, DIRECTION_UPLINK, NO_RNTI, 0,
|
||||
e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i,
|
||||
NULL, 0,
|
||||
e.e[d->preamble_preamble].i);
|
||||
}
|
||||
|
||||
void rar(void *_d, event e)
|
||||
{
|
||||
ev_data *d = _d;
|
||||
trace(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i,
|
||||
e.e[d->rar_frame].i, e.e[d->rar_subframe].i,
|
||||
e.e[d->rar_data].b, e.e[d->rar_data].bsize,
|
||||
NO_PREAMBLE);
|
||||
}
|
||||
|
||||
void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id,
|
||||
int preamble_id, int rar_id)
|
||||
{
|
||||
database_event_format f;
|
||||
int i;
|
||||
|
||||
d->ul_rnti = -1;
|
||||
d->ul_frame = -1;
|
||||
d->ul_subframe = -1;
|
||||
d->ul_data = -1;
|
||||
d->ul_rnti = -1;
|
||||
d->ul_frame = -1;
|
||||
d->ul_subframe = -1;
|
||||
d->ul_data = -1;
|
||||
|
||||
d->dl_rnti = -1;
|
||||
d->dl_frame = -1;
|
||||
d->dl_subframe = -1;
|
||||
d->dl_data = -1;
|
||||
d->dl_rnti = -1;
|
||||
d->dl_frame = -1;
|
||||
d->dl_subframe = -1;
|
||||
d->dl_data = -1;
|
||||
|
||||
d->mib_frame = -1;
|
||||
d->mib_subframe = -1;
|
||||
d->mib_data = -1;
|
||||
|
||||
d->preamble_frame = -1;
|
||||
d->preamble_subframe = -1;
|
||||
d->preamble_preamble = -1;
|
||||
|
||||
d->rar_rnti = -1;
|
||||
d->rar_frame = -1;
|
||||
d->rar_subframe = -1;
|
||||
d->rar_data = -1;
|
||||
|
||||
#define G(var_name, var_type, var) \
|
||||
if (!strcmp(f.name[i], var_name)) { \
|
||||
@@ -144,6 +216,37 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id)
|
||||
if (d->dl_rnti == -1 || d->dl_frame == -1 || d->dl_subframe == -1 ||
|
||||
d->dl_data == -1) goto error;
|
||||
|
||||
/* MIB: frame, subframe, data */
|
||||
f = get_format(database, mib_id);
|
||||
for (i = 0; i < f.count; i++) {
|
||||
G("frame", "int", d->mib_frame);
|
||||
G("subframe", "int", d->mib_subframe);
|
||||
G("data", "buffer", d->mib_data);
|
||||
}
|
||||
if (d->mib_frame == -1 || d->mib_subframe == -1 || d->mib_data == -1)
|
||||
goto error;
|
||||
|
||||
/* preamble: frame, subframe, preamble */
|
||||
f = get_format(database, preamble_id);
|
||||
for (i = 0; i < f.count; i++) {
|
||||
G("frame", "int", d->preamble_frame);
|
||||
G("subframe", "int", d->preamble_subframe);
|
||||
G("preamble", "int", d->preamble_preamble);
|
||||
}
|
||||
if (d->preamble_frame == -1 || d->preamble_subframe == -1 ||
|
||||
d->preamble_preamble == -1) goto error;
|
||||
|
||||
/* rar: rnti, frame, subframe, data */
|
||||
f = get_format(database, rar_id);
|
||||
for (i = 0; i < f.count; i++) {
|
||||
G("rnti", "int", d->rar_rnti);
|
||||
G("frame", "int", d->rar_frame);
|
||||
G("subframe", "int", d->rar_subframe);
|
||||
G("data", "buffer", d->rar_data);
|
||||
}
|
||||
if (d->rar_rnti == -1 || d->rar_frame == -1 || d->rar_subframe == -1 ||
|
||||
d->rar_data == -1) goto error;
|
||||
|
||||
#undef G
|
||||
|
||||
return;
|
||||
@@ -179,9 +282,20 @@ void usage(void)
|
||||
" -d <database file> this option is mandatory\n"
|
||||
" -i <dump file> read events from this dump file\n"
|
||||
" -ip <IP address> send packets to this IP address (default %s)\n"
|
||||
" -p <port> send packets to this port (default %d)\n",
|
||||
" -p <port> send packets to this port (default %d)\n"
|
||||
" -no-mib do not report MIB\n"
|
||||
" -no-sib do not report SIBs\n"
|
||||
" -max-mib <n> report at maximum n MIB\n"
|
||||
" -max-sib <n> report at maximum n SIBs\n"
|
||||
" -live run live\n"
|
||||
" -live-ip <IP address> tracee's IP address (default %p)\n"
|
||||
" -live-port <por> tracee's port (default %d)\n"
|
||||
"-i and -live are mutually exclusive options. One of them must be provided\n"
|
||||
"but not both.\n",
|
||||
DEFAULT_IP,
|
||||
DEFAULT_PORT
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_LIVE_IP,
|
||||
DEFAULT_LIVE_PORT
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
@@ -194,10 +308,13 @@ int main(int n, char **v)
|
||||
event_handler *h;
|
||||
int in;
|
||||
int i;
|
||||
int ul_id, dl_id;
|
||||
int ul_id, dl_id, mib_id = -1, preamble_id, rar_id;
|
||||
ev_data d;
|
||||
char *ip = DEFAULT_IP;
|
||||
int port = DEFAULT_PORT;
|
||||
char *live_ip = DEFAULT_LIVE_IP;
|
||||
int live_port = DEFAULT_LIVE_PORT;
|
||||
int live = 0;
|
||||
|
||||
memset(&d, 0, sizeof(ev_data));
|
||||
|
||||
@@ -209,6 +326,17 @@ int main(int n, char **v)
|
||||
{ if (i > n-2) usage(); input_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; }
|
||||
if (!strcmp(v[i], "-no-mib")) { d.no_mib = 1; continue; }
|
||||
if (!strcmp(v[i], "-no-sib")) { d.no_sib = 1; continue; }
|
||||
if (!strcmp(v[i], "-max-mib"))
|
||||
{ if (i > n-2) usage(); d.max_mib = atoi(v[++i]); continue; }
|
||||
if (!strcmp(v[i], "-max-sib"))
|
||||
{ if (i > n-2) usage(); d.max_sib = atoi(v[++i]); continue; }
|
||||
if (!strcmp(v[i], "-live")) { live = 1; continue; }
|
||||
if (!strcmp(v[i], "-live-ip"))
|
||||
{ if (i > n-2) usage(); live_ip = v[++i]; continue; }
|
||||
if (!strcmp(v[i], "-live-port"))
|
||||
{ if (i > n-2) usage(); live_port = atoi(v[++i]); continue; }
|
||||
usage();
|
||||
}
|
||||
|
||||
@@ -217,25 +345,59 @@ int main(int n, char **v)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (input_filename == NULL) {
|
||||
printf("ERROR: provide an input file (-i)\n");
|
||||
if (input_filename == NULL && live == 0) {
|
||||
printf("ERROR: provide an input file (-i) or run live (-live)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
in = open(input_filename, O_RDONLY);
|
||||
if (in == -1) { perror(input_filename); return 1; }
|
||||
if (input_filename != NULL && live != 0) {
|
||||
printf("ERROR: cannot use both -i and -live\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (live == 0) {
|
||||
in = open(input_filename, O_RDONLY);
|
||||
if (in == -1) { perror(input_filename); return 1; }
|
||||
} else
|
||||
in = connect_to(live_ip, live_port);
|
||||
|
||||
database = parse_database(database_filename);
|
||||
load_config_file(database_filename);
|
||||
|
||||
h = new_handler(database);
|
||||
|
||||
if (live) {
|
||||
char mt = 1;
|
||||
int number_of_events = number_of_ids(database);
|
||||
int *is_on = calloc(number_of_events, sizeof(int));
|
||||
if (is_on == NULL) { printf("ERROR: out of memory\n"); exit(1); }
|
||||
on_off(database, "ENB_MAC_UE_UL_PDU_WITH_DATA", is_on, 1);
|
||||
on_off(database, "ENB_MAC_UE_DL_PDU_WITH_DATA", is_on, 1);
|
||||
on_off(database, "ENB_PHY_MIB", is_on, 1);
|
||||
on_off(database, "ENB_PHY_INITIATE_RA_PROCEDURE", is_on, 1);
|
||||
on_off(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA", is_on, 1);
|
||||
/* activate selected traces */
|
||||
if (socket_send(in, &mt, 1) == -1 ||
|
||||
socket_send(in, &number_of_events, sizeof(int)) == -1 ||
|
||||
socket_send(in, is_on, number_of_events * sizeof(int)) == -1) {
|
||||
printf("ERROR: socket_send failed\n");
|
||||
exit(1);
|
||||
}
|
||||
free(is_on);
|
||||
}
|
||||
|
||||
ul_id = event_id_from_name(database, "ENB_MAC_UE_UL_PDU_WITH_DATA");
|
||||
dl_id = event_id_from_name(database, "ENB_MAC_UE_DL_PDU_WITH_DATA");
|
||||
setup_data(&d, database, ul_id, dl_id);
|
||||
mib_id = event_id_from_name(database, "ENB_PHY_MIB");
|
||||
preamble_id = event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE");
|
||||
rar_id = event_id_from_name(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA");
|
||||
setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id);
|
||||
|
||||
register_handler_function(h, ul_id, ul, &d);
|
||||
register_handler_function(h, dl_id, dl, &d);
|
||||
register_handler_function(h, mib_id, mib, &d);
|
||||
register_handler_function(h, preamble_id, preamble, &d);
|
||||
register_handler_function(h, rar_id, rar, &d);
|
||||
|
||||
d.socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (d.socket == -1) { perror("socket"); exit(1); }
|
||||
@@ -253,7 +415,8 @@ int main(int n, char **v)
|
||||
event e;
|
||||
e = get_event(in, &ebuf, database);
|
||||
if (e.type == -1) break;
|
||||
if (!(e.type == ul_id || e.type == dl_id)) continue;
|
||||
if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id ||
|
||||
e.type == preamble_id || e.type == rar_id)) continue;
|
||||
handle_event(h, e);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ void usage(void)
|
||||
" they will be processed in order\n"
|
||||
" by default, all is off\n"
|
||||
" -full also dump buffers' content\n"
|
||||
" -raw-time also prints 'raw time'\n"
|
||||
" -ip <host> connect to given IP address (default %s)\n"
|
||||
" -p <port> connect to given port (default %d)\n"
|
||||
" -x GUI output\n"
|
||||
@@ -91,6 +92,7 @@ int main(int n, char **v)
|
||||
int gui_active = 1;
|
||||
textlog_data textlog_data;
|
||||
int full = 0;
|
||||
int raw_time = 0;
|
||||
|
||||
/* write on a socket fails if the other end is closed and we get SIGPIPE */
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
|
||||
@@ -117,6 +119,7 @@ int main(int n, char **v)
|
||||
if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; }
|
||||
if (!strcmp(v[i], "-no-gui")) { gui_active = 0; continue; }
|
||||
if (!strcmp(v[i], "-full")) { full = 1; continue; }
|
||||
if (!strcmp(v[i], "-raw-time")) { raw_time = 1; continue; }
|
||||
usage();
|
||||
}
|
||||
|
||||
@@ -162,6 +165,7 @@ int main(int n, char **v)
|
||||
// "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]");
|
||||
logger_add_view(textlog, out);
|
||||
if (full) textlog_dump_buffer(textlog, 1);
|
||||
if (raw_time) textlog_raw_time(textlog, 1);
|
||||
free(name);
|
||||
free(desc);
|
||||
}
|
||||
@@ -187,7 +191,7 @@ int main(int n, char **v)
|
||||
while (1) {
|
||||
event e;
|
||||
e = get_event(textlog_data.socket, &ebuf, database);
|
||||
if (e.type == -1) abort();
|
||||
if (e.type == -1) break;
|
||||
handle_event(h, e);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user