From 1e20abdd9e025312024b3d1d6987f923ce23b0a9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 14 Mar 2016 18:02:12 +0100 Subject: [PATCH 001/217] Initial commit of the T! --- Makefile | 33 ++++ T.c | 140 ++++++++++++++ T.h | 506 ++++++++++++++++++++++++++++++++++++++++++++++++ T_defs.h | 18 ++ T_messages.txt | 140 ++++++++++++++ generate_Txx.c | 25 +++ genids.c | 150 ++++++++++++++ main.c | 19 ++ tracer/Makefile | 20 ++ tracer/main.c | 254 ++++++++++++++++++++++++ 10 files changed, 1305 insertions(+) create mode 100644 Makefile create mode 100644 T.c create mode 100644 T.h create mode 100644 T_defs.h create mode 100644 T_messages.txt create mode 100644 generate_Txx.c create mode 100644 genids.c create mode 100644 main.c create mode 100644 tracer/Makefile create mode 100644 tracer/main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..06315e4585 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +CC=gcc +CFLAGS=-Wall -g -pthread + +#comment those two lines to NOT use shared memory +CFLAGS += -DT_USE_SHARED_MEMORY +LIBS += -lrt + +PROG=t +OBJS=main.o T.o + +GENIDS=genids +GENIDS_OBJS=genids.o + +ALL=$(PROG) $(GENIDS) + +all : $(ALL) + +$(GENIDS): $(GENIDS_OBJS) + $(CC) $(CFLAGS) -o $(GENIDS) $(GENIDS_OBJS) + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +T_IDs.h: $(GENIDS) T_messages.txt + ./$(GENIDS) T_messages.txt T_IDs.h + +main.o: T.h T_IDs.h + +clean: + rm -f *.o $(PROG) $(GENIDS) core T_IDs.h diff --git a/T.c b/T.c new file mode 100644 index 0000000000..a33d1e90b6 --- /dev/null +++ b/T.c @@ -0,0 +1,140 @@ +#include "T.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* array used to activate/disactivate a log */ +static int T_IDs[T_NUMBER_OF_IDS]; +int *T_active = T_IDs; + +static int T_socket; + +/* T_cache + * - the T macro picks up the head of freelist and marks it busy + * - the T sender thread periodically wakes up and sends what's to be sent + */ +volatile int _T_freelist_head; +volatile int *T_freelist_head = &_T_freelist_head; +int T_busylist_head; +T_cache_t _T_cache[T_CACHE_SIZE]; +T_cache_t *T_cache = _T_cache; + +static void get_message(int s) +{ + char t; + int l; + int id; + + if (read(s, &t, 1) != 1) abort(); +printf("got mess %d\n", t); + switch (t) { + case 0: + /* toggle all those IDs */ + /* optimze? (too much syscalls) */ + if (read(s, &l, sizeof(int)) != sizeof(int)) abort(); + while (l) { + if (read(s, &id, sizeof(int)) != sizeof(int)) abort(); + T_IDs[id] = 1 - T_IDs[id]; + l--; + } + break; + } +} + +#ifndef T_USE_SHARED_MEMORY + +static void *T_send_thread(void *_) +{ + while (1) { + usleep(5000); + while (T_cache[T_busylist_head].busy) { + char *b = T_cache[T_busylist_head].buffer; + int l = T_cache[T_busylist_head].length; + while (l) { + int done = write(T_socket, b, l); + if (done <= 0) { + printf("%s:%d:%s: error sending to socket\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } + b += done; + l -= done; + } + T_cache[T_busylist_head].busy = 0; + T_busylist_head++; + T_busylist_head &= T_CACHE_SIZE - 1; + } + } + return NULL; +} + +#endif /* T_USE_SHARED_MEMORY */ + +static void *T_receive_thread(void *_) +{ + while (1) get_message(T_socket); + return NULL; +} + +static void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + +void T_connect_to_tracer(char *addr, int port) +{ + struct sockaddr_in a; + int s; +#ifdef T_USE_SHARED_MEMORY + int T_shm_fd; +#endif + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) + { perror("connect"); exit(1); } + + /* wait for first message - initial list of active T events */ + get_message(s); + + T_socket = s; + +#ifdef T_USE_SHARED_MEMORY + /* setup shared memory */ + T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR, 0666); + shm_unlink(T_SHM_FILENAME); + if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); } + T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), + PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0); + if (T_cache == NULL) + { perror(T_SHM_FILENAME); abort(); } + close(T_shm_fd); +#endif + +#ifndef T_USE_SHARED_MEMORY + new_thread(T_send_thread, NULL); +#endif + new_thread(T_receive_thread, NULL); +} diff --git a/T.h b/T.h new file mode 100644 index 0000000000..884a9b6f89 --- /dev/null +++ b/T.h @@ -0,0 +1,506 @@ +#ifndef _T_T_T_ +#define _T_T_T_ + +#include + +#include "T_defs.h" + +/* T message IDs */ +#include "T_IDs.h" + +/* known type - this is where you add new types */ + +#define T_INT(x) int, (x) +#define T_FLOAT(x) float, (x) +#define T_BUFFER(x, len) buffer, ((T_buffer){addr:(x), length:(len)}) +#define T_STRING(x) string, (x) +#define T_PRINTF(...) printf, (__VA_ARGS__) + +/* for each known type a T_PUT_XX macro is defined */ + +#define T_PUT_int(argnum, val) \ + do { \ + int T_PUT_var = (val); \ + T_CHECK_SIZE(sizeof(int), argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(int)); \ + T_LOCAL_size += sizeof(int); \ + } while (0) + +#define T_PUT_float(argnum, val) \ + do { \ + float T_PUT_var = (val); \ + T_CHECK_SIZE(sizeof(float), argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(float)); \ + T_LOCAL_size += sizeof(float); \ + } while (0) + +#define T_PUT_buffer(argnum, val) \ + do { \ + T_buffer T_PUT_var = (val); \ + T_CHECK_SIZE(T_PUT_var.length, argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_var.addr, T_PUT_var.length); \ + T_LOCAL_size += T_PUT_var.length; \ + } while (0) + +#define T_PUT_string(argnum, val) \ + do { \ + char *T_PUT_var = (val); \ + int T_PUT_len = strlen(T_PUT_var) + 1; \ + T_CHECK_SIZE(T_PUT_len, argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_var, T_PUT_len); \ + T_LOCAL_size += T_PUT_len; \ + } while (0) + +#define T_PUT_printf_deref(...) __VA_ARGS__ + +#define T_PUT_printf(argnum, x) \ + do { \ + int T_PUT_len = snprintf(T_LOCAL_buf + T_LOCAL_size, \ + T_BUFFER_MAX - T_LOCAL_size, T_PUT_printf_deref x); \ + if (T_PUT_len < 0) { \ + printf("%s:%d:%s: you can't read this, or can you?", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + if (T_PUT_len >= T_BUFFER_MAX - T_LOCAL_size) { \ + printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ + ", consider increasing T_BUFFER_MAX (%d)\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ + abort(); \ + } \ + T_LOCAL_size += T_PUT_len + 1; \ + } while (0) + +/* structure type to detect that you pass a known type as first arg of T */ +struct T_header; + +/* to define message ID */ +#define T_ID(x) ((struct T_header *)(uintptr_t)(x)) + +/* T macro tricks */ + +#define TN(...) TN_N(__VA_ARGS__,33,32,31,30,29,28,27,26,25,24,23,22,21,\ + 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) +#define TN_N(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,\ + n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n,...) T##n +#define T(...) TN(__VA_ARGS__) + +/* type used to send arbitrary buffer data */ +typedef struct { + void *addr; + int length; +} T_buffer; + +extern volatile int *T_freelist_head; +extern T_cache_t *T_cache; + +/* used at header of Tn, allocates buffer */ +#define T_LOCAL_DATA \ + char *T_LOCAL_buf; \ + int T_LOCAL_size = 0; \ + int T_LOCAL_slot; \ + T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \ + & (T_CACHE_SIZE - 1); \ + (void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \ + if (T_cache[T_LOCAL_slot].busy) { \ + printf("%s:%d:%s: T cache is full - consider increasing its size\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + T_LOCAL_buf = T_cache[T_LOCAL_slot].buffer; + +#define T_ACTIVE(x) T_active[(intptr_t)x] + +#define T_SEND() \ + T_cache[T_LOCAL_slot].busy = 1; \ + T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ + T_send(T_LOCAL_buf, T_LOCAL_size) + +#define T_CHECK_SIZE(len, argnum) \ + if (T_LOCAL_size + len > T_BUFFER_MAX) { \ + printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ + ", consider increasing T_BUFFER_MAX (%d)\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ + abort(); \ + } + +#if 0 +#define T_PUT(type, var, argnum) \ + do { \ + if (T_LOCAL_size + sizeof(var) > T_BUFFER_MAX) { \ + printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ + ", consider increasing T_BUFFER_MAX (%d)\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ + abort(); \ + } \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &var, sizeof(var)); \ + T_LOCAL_size += sizeof(var); \ + } while (0) +#endif + +#if 0 +#define T_PROCESS(x, argnum) \ + do { \ + T_PUT(typeof(x), x, argnum); \ + } while (0) +#endif + +#if 0 +#define T_PROCESS(x, argnum) \ + do { \ + if (__builtin_types_compatible_p(typeof(x), int)) \ + { T_PUT(int, (intptr_t)(x), argnum); printf("int\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), short)) \ + { T_PUT(short, (intptr_t)(x), argnum); printf("short\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), float)) \ + { T_PUT(float, (x), argnum); printf("float\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), char *)) \ + { T_PUT(char *, (char *)(intptr_t)(x), argnum); printf("char *\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), float *)) \ + { T_PUT(float *, (float *)(intptr_t)(x), argnum); printf("float *\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), void *)) \ + { T_PUT(void *, (void *)(intptr_t)(x), argnum); printf("void *\n"); } \ + else { \ + printf("%s:%d:%s: unsupported type for argument %d in T macro\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum); \ + abort(); \ + } \ + } while (0) +#endif + +#define T_HEADER(x) \ + do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + T_PUT_int(1, (int)(uintptr_t)(x)); \ + } while (0) + +#define T1(t) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_SEND(); \ + } \ + } while (0) + +#define T3(t,t0,x0) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_SEND(); \ + } \ + } while (0) + +#define T5(t,t0,x0,t1,x1) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_SEND(); \ + } \ + } while (0) + +#define T7(t,t0,x0,t1,x1,t2,x2) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_SEND(); \ + } \ + } while (0) + +#define T9(t,t0,x0,t1,x1,t2,x2,t3,x3) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_SEND(); \ + } \ + } while (0) + +#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_SEND(); \ + } \ + } while (0) + +#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_SEND(); \ + } \ + } while (0) + +#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_SEND(); \ + } \ + } while (0) + +#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_SEND(); \ + } \ + } while (0) + +#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_SEND(); \ + } \ + } while (0) + +#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_SEND(); \ + } \ + } while (0) + +#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_SEND(); \ + } \ + } while (0) + +#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_SEND(); \ + } \ + } while (0) + +#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_SEND(); \ + } \ + } while (0) + +#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_SEND(); \ + } \ + } while (0) + +#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_PUT_##t13(15, x13); \ + T_SEND(); \ + } \ + } while (0) + +#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_PUT_##t13(15, x13); \ + T_PUT_##t14(16, x14); \ + T_SEND(); \ + } \ + } while (0) + +#define T_CALL_ERROR \ + do { \ + printf("%s:%d:%s: error calling T, you have to use T_INT() or T_XX()\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + } while (0) + +#define T2(...) T_CALL_ERROR +#define T4(...) T_CALL_ERROR +#define T6(...) T_CALL_ERROR +#define T8(...) T_CALL_ERROR +#define T10(...) T_CALL_ERROR +#define T12(...) T_CALL_ERROR +#define T14(...) T_CALL_ERROR +#define T16(...) T_CALL_ERROR +#define T18(...) T_CALL_ERROR +#define T20(...) T_CALL_ERROR +#define T22(...) T_CALL_ERROR +#define T24(...) T_CALL_ERROR +#define T26(...) T_CALL_ERROR +#define T28(...) T_CALL_ERROR +#define T30(...) T_CALL_ERROR +#define T32(...) T_CALL_ERROR + +#ifndef T_USE_SHARED_MEMORY + +#include + +static inline void T_send(char *buf, int size) +{ + int i; +return; + printf("sending %d bytes", size); + for (i = 0; i < size; i++) + printf("%s%2.2x", i?" ":"\n", (unsigned char)buf[i]); + printf("\n"); +} + +#else /* T_USE_SHARED_MEMORY */ + +#define T_send(...) /**/ + +#endif /* T_USE_SHARED_MEMORY */ + +extern int *T_active; + +void T_connect_to_tracer(char *addr, int port); + +#endif /* _T_T_T_ */ diff --git a/T_defs.h b/T_defs.h new file mode 100644 index 0000000000..1d01ea7415 --- /dev/null +++ b/T_defs.h @@ -0,0 +1,18 @@ +#ifndef _T_defs_H_ +#define _T_defs_H_ + +/* maximum size of a message - increase if needed */ +#define T_BUFFER_MAX 1024 + +/* size of the local cache for messages (must be pow(2,something)) */ +#define T_CACHE_SIZE (65536 * 2) + +typedef struct { + volatile int busy; + char buffer[T_BUFFER_MAX]; + int length; +} T_cache_t; + +#define T_SHM_FILENAME "/T_shm_segment" + +#endif /* _T_defs_H_ */ diff --git a/T_messages.txt b/T_messages.txt new file mode 100644 index 0000000000..b0e6cb00ed --- /dev/null +++ b/T_messages.txt @@ -0,0 +1,140 @@ +#legacy logs +ID = LEGACY_MAC_INFO + DESC = MAC legacy logs + GROUP = MAC:INFO:LEGACY +ID = LEGACY_MAC_ERROR +ID = LEGACY_MAC_WARNING +ID = LEGACY_MAC_DEBUG +ID = LEGACY_MAC_TRACE + +ID = LEGACY_PHY_INFO +ID = LEGACY_PHY_ERROR +ID = LEGACY_PHY_WARNING +ID = LEGACY_PHY_DEBUG +ID = LEGACY_PHY_TRACE + +ID = LEGACY_S1AP_INFO +ID = LEGACY_S1AP_ERROR +ID = LEGACY_S1AP_WARNING +ID = LEGACY_S1AP_DEBUG +ID = LEGACY_S1AP_TRACE + +ID = LEGACY_RRC_INFO +ID = LEGACY_RRC_ERROR +ID = LEGACY_RRC_WARNING +ID = LEGACY_RRC_DEBUG +ID = LEGACY_RRC_TRACE + +ID = LEGACY_RLC_INFO +ID = LEGACY_RLC_ERROR +ID = LEGACY_RLC_WARNING +ID = LEGACY_RLC_DEBUG +ID = LEGACY_RLC_TRACE + +ID = LEGACY_PDCP_INFO +ID = LEGACY_PDCP_ERROR +ID = LEGACY_PDCP_WARNING +ID = LEGACY_PDCP_DEBUG +ID = LEGACY_PDCP_TRACE + +ID = LEGACY_ENB_APP_INFO +ID = LEGACY_ENB_APP_ERROR +ID = LEGACY_ENB_APP_WARNING +ID = LEGACY_ENB_APP_DEBUG +ID = LEGACY_ENB_APP_TRACE + +ID = LEGACY_SCTP_INFO +ID = LEGACY_SCTP_ERROR +ID = LEGACY_SCTP_WARNING +ID = LEGACY_SCTP_DEBUG +ID = LEGACY_SCTP_TRACE + +ID = LEGACY_UDP__INFO +ID = LEGACY_UDP__ERROR +ID = LEGACY_UDP__WARNING +ID = LEGACY_UDP__DEBUG +ID = LEGACY_UDP__TRACE + +ID = LEGACY_NAS_INFO +ID = LEGACY_NAS_ERROR +ID = LEGACY_NAS_WARNING +ID = LEGACY_NAS_DEBUG +ID = LEGACY_NAS_TRACE + +ID = LEGACY_HW_INFO +ID = LEGACY_HW_ERROR +ID = LEGACY_HW_WARNING +ID = LEGACY_HW_DEBUG +ID = LEGACY_HW_TRACE + +ID = LEGACY_EMU_INFO +ID = LEGACY_EMU_ERROR +ID = LEGACY_EMU_WARNING +ID = LEGACY_EMU_DEBUG +ID = LEGACY_EMU_TRACE + +ID = LEGACY_OTG_INFO +ID = LEGACY_OTG_ERROR +ID = LEGACY_OTG_WARNING +ID = LEGACY_OTG_DEBUG +ID = LEGACY_OTG_TRACE + +ID = LEGACY_OCG_INFO +ID = LEGACY_OCG_ERROR +ID = LEGACY_OCG_WARNING +ID = LEGACY_OCG_DEBUG +ID = LEGACY_OCG_TRACE + +ID = LEGACY_OMG_INFO +ID = LEGACY_OMG_ERROR +ID = LEGACY_OMG_WARNING +ID = LEGACY_OMG_DEBUG +ID = LEGACY_OMG_TRACE + +ID = LEGACY_OPT_INFO +ID = LEGACY_OPT_ERROR +ID = LEGACY_OPT_WARNING +ID = LEGACY_OPT_DEBUG +ID = LEGACY_OPT_TRACE + +ID = LEGACY_GTPU_INFO +ID = LEGACY_GTPU_ERROR +ID = LEGACY_GTPU_WARNING +ID = LEGACY_GTPU_DEBUG +ID = LEGACY_GTPU_TRACE + +ID = LEGACY_TMR_INFO +ID = LEGACY_TMR_ERROR +ID = LEGACY_TMR_WARNING +ID = LEGACY_TMR_DEBUG +ID = LEGACY_TMR_TRACE + +ID = LEGACY_OSA_INFO +ID = LEGACY_OSA_ERROR +ID = LEGACY_OSA_WARNING +ID = LEGACY_OSA_DEBUG +ID = LEGACY_OSA_TRACE + +# this is a bad hack but I won't fix (function util_print_hex_octets +# in openairinterface5g/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c +# does funky things with the LOG_x macros but we work on the C pre-processor +# level and this funkyness is not easily dealable with, so be it...) +ID = LEGACY_component_INFO +ID = LEGACY_component_ERROR +ID = LEGACY_component_WARNING +ID = LEGACY_component_DEBUG +ID = LEGACY_component_TRACE +ID = LEGACY_componentP_INFO +ID = LEGACY_componentP_ERROR +ID = LEGACY_componentP_WARNING +ID = LEGACY_componentP_DEBUG +ID = LEGACY_componentP_TRACE + +#needed? +ID = LEGACY_CLI_INFO +ID = LEGACY_CLI_ERROR +ID = LEGACY_CLI_WARNING +ID = LEGACY_CLI_DEBUG +ID = LEGACY_CLI_TRACE + +ID = first diff --git a/generate_Txx.c b/generate_Txx.c new file mode 100644 index 0000000000..6e803aac50 --- /dev/null +++ b/generate_Txx.c @@ -0,0 +1,25 @@ +#include + +void print(int n) +{ + int i; + printf("#define T%d(t", n); + for(i=0; i<(n-3)/2; i++) printf(",t%d,x%d", i, i); + printf(") \\\n"); + printf(" do { \\\n"); + printf(" if (T_ACTIVE(t)) { \\\n"); + printf(" T_LOCAL_DATA \\\n"); + printf(" T_HEADER(t); \\\n"); + for(i=0; i<(n-3)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i); + printf(" T_SEND(); \\\n"); + printf(" } \\\n"); + printf(" } while (0)\n"); + printf("\n"); +} + +int main(void) +{ + int i; + for (i = 11; i <= 33; i+=2) print(i); + return 0; +} diff --git a/genids.c b/genids.c new file mode 100644 index 0000000000..47383eccf3 --- /dev/null +++ b/genids.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include + +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); +} + +/* return 1 if s was not already known, 0 if it was */ +int new_unique_id(char *s) +{ + if (unique_ids_size) + if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) { + printf("FATAL: ID %s is not unique\n", s); + 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("out of memory\n"); abort(); } + } + unique_ids[unique_ids_size] = strdup(s); + if (unique_ids[unique_ids_size] == NULL) + { printf("out of memory\n"); abort(); } + unique_ids_size++; + qsort(unique_ids, unique_ids_size, sizeof(char *), cmp); + return 1; +} + +char *bufname; +int bufname_size; +int bufname_maxsize; + +void putname(int c) +{ + if (bufname_size == bufname_maxsize) { + bufname_maxsize += 256; + bufname = realloc(bufname, bufname_maxsize); + if (bufname == NULL) { printf("memory allocation error\n"); exit(1); } + } + bufname[bufname_size] = c; + bufname_size++; +} + +char *bufvalue; +int bufvalue_size; +int bufvalue_maxsize; + +void putvalue(int c) +{ + if (bufvalue_size == bufvalue_maxsize) { + bufvalue_maxsize += 256; + bufvalue = realloc(bufvalue, bufvalue_maxsize); + if (bufvalue == NULL) { printf("memory allocation error\n"); exit(1); } + } + bufvalue[bufvalue_size] = c; + bufvalue_size++; +} + +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) +{ + int c; + bufname_size = 0; + bufvalue_size = 0; + *name = NULL; + *value = NULL; + smash_spaces(f); + 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); } + putvalue(0); + if (bufname_size <= 1) return; + if (bufvalue_size <= 1) return; + *name = bufname; + *value = bufvalue; +} + +int main(int n, char **v) +{ + FILE *in; + FILE *out; + char *name; + char *value; + char *in_name; + char *out_name; + + if (n != 3) { printf("gimme \n"); exit(1); } + + n = 0; + + in_name = v[1]; + out_name = v[2]; + + 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); } + + fprintf(out, "/* generated file, do not edit by hand */\n\n"); + + while (1) { + get_line(in, &name, &value); + if (name == NULL) break; + printf("name '%s' value '%s'\n", name, value); + if (!strcmp(name, "ID")) { + if (!new_unique_id(value)) { 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); + + fclose(in); + fclose(out); + + return 0; +} diff --git a/main.c b/main.c new file mode 100644 index 0000000000..50b1d9339c --- /dev/null +++ b/main.c @@ -0,0 +1,19 @@ +#include "T.h" +#include +#include +#include +#include +#include + +int main(void) +{ + T_connect_to_tracer("127.0.0.1", 2020); + printf("after connect\n"); + while (1) { + T(T_first, T_PRINTF("hello world %s!\n", "yo")); + //usleep(1); + } + while (1) pause(); + + return 0; +} diff --git a/tracer/Makefile b/tracer/Makefile new file mode 100644 index 0000000000..156700812e --- /dev/null +++ b/tracer/Makefile @@ -0,0 +1,20 @@ +CC=gcc +CFLAGS=-Wall -g -O3 + +#comment those two lines to NOT use shared memory +CFLAGS += -DT_USE_SHARED_MEMORY +LIBS += -lrt + +PROG=tracer +OBJS=main.o + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +main.o: ../T_IDs.h ../T_defs.h + +clean: + rm -f *.o $(PROG) core diff --git a/tracer/main.c b/tracer/main.c new file mode 100644 index 0000000000..fa19a6237b --- /dev/null +++ b/tracer/main.c @@ -0,0 +1,254 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define T_ID(x) x +#include "../T_IDs.h" +#include "../T_defs.h" + +#ifdef T_USE_SHARED_MEMORY + +T_cache_t *T_cache; +int T_busylist_head; +int T_pos; + +static inline int GET(int s, void *out, int count) +{ + if (count == 1) { + *(char *)out = T_cache[T_busylist_head].buffer[T_pos]; + T_pos++; + return 1; + } + memcpy(out, T_cache[T_busylist_head].buffer + T_pos, count); + T_pos += count; + return count; +} + +#else /* T_USE_SHARED_MEMORY */ + +#define GET read + +#endif /* T_USE_SHARED_MEMORY */ + +int get_connection(char *addr, int port) +{ + struct sockaddr_in a; + socklen_t alen; + int s, t; + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + return t; +} + +void get_string(int s, char *out) +{ + while (1) { + if (GET(s, out, 1) != 1) abort(); + if (*out == 0) break; + out++; + } +} + +void get_message(int s) +{ +#define S(x, y) do { \ + char str[1024]; \ + get_string(s, str); \ + printf("["x"]["y"] %s", str); \ + } while (0) + + int m; +#ifdef T_USE_SHARED_MEMORY + T_pos = 0; +#endif + if (GET(s, &m, sizeof(int)) != sizeof(int)) abort(); + switch (m) { + case T_first: { + char str[1024]; + get_string(s, str); + printf("%s", str); + break; + } + case T_LEGACY_MAC_INFO: S("MAC", "INFO"); break; + case T_LEGACY_MAC_ERROR: S("MAC", "ERROR"); break; + case T_LEGACY_MAC_WARNING: S("MAC", "WARNING"); break; + case T_LEGACY_MAC_DEBUG: S("MAC", "DEBUG"); break; + case T_LEGACY_MAC_TRACE: S("MAC", "TRACE"); break; + case T_LEGACY_PHY_INFO: S("PHY", "INFO"); break; + case T_LEGACY_PHY_ERROR: S("PHY", "ERROR"); break; + case T_LEGACY_PHY_WARNING: S("PHY", "WARNING"); break; + case T_LEGACY_PHY_DEBUG: S("PHY", "DEBUG"); break; + case T_LEGACY_PHY_TRACE: S("PHY", "TRACE"); break; + case T_LEGACY_S1AP_INFO: S("S1AP", "INFO"); break; + case T_LEGACY_S1AP_ERROR: S("S1AP", "ERROR"); break; + case T_LEGACY_S1AP_WARNING: S("S1AP", "WARNING"); break; + case T_LEGACY_S1AP_DEBUG: S("S1AP", "DEBUG"); break; + case T_LEGACY_S1AP_TRACE: S("S1AP", "TRACE"); break; + case T_LEGACY_RRC_INFO: S("RRC", "INFO"); break; + case T_LEGACY_RRC_ERROR: S("RRC", "ERROR"); break; + case T_LEGACY_RRC_WARNING: S("RRC", "WARNING"); break; + case T_LEGACY_RRC_DEBUG: S("RRC", "DEBUG"); break; + case T_LEGACY_RRC_TRACE: S("RRC", "TRACE"); break; + case T_LEGACY_RLC_INFO: S("RLC", "INFO"); break; + case T_LEGACY_RLC_ERROR: S("RLC", "ERROR"); break; + case T_LEGACY_RLC_WARNING: S("RLC", "WARNING"); break; + case T_LEGACY_RLC_DEBUG: S("RLC", "DEBUG"); break; + case T_LEGACY_RLC_TRACE: S("RLC", "TRACE"); break; + case T_LEGACY_PDCP_INFO: S("PDCP", "INFO"); break; + case T_LEGACY_PDCP_ERROR: S("PDCP", "ERROR"); break; + case T_LEGACY_PDCP_WARNING: S("PDCP", "WARNING"); break; + case T_LEGACY_PDCP_DEBUG: S("PDCP", "DEBUG"); break; + case T_LEGACY_PDCP_TRACE: S("PDCP", "TRACE"); break; + case T_LEGACY_ENB_APP_INFO: S("ENB_APP", "INFO"); break; + case T_LEGACY_ENB_APP_ERROR: S("ENB_APP", "ERROR"); break; + case T_LEGACY_ENB_APP_WARNING: S("ENB_APP", "WARNING"); break; + case T_LEGACY_ENB_APP_DEBUG: S("ENB_APP", "DEBUG"); break; + case T_LEGACY_ENB_APP_TRACE: S("ENB_APP", "TRACE"); break; + case T_LEGACY_SCTP_INFO: S("SCTP", "INFO"); break; + case T_LEGACY_SCTP_ERROR: S("SCTP", "ERROR"); break; + case T_LEGACY_SCTP_WARNING: S("SCTP", "WARNING"); break; + case T_LEGACY_SCTP_DEBUG: S("SCTP", "DEBUG"); break; + case T_LEGACY_SCTP_TRACE: S("SCTP", "TRACE"); break; + case T_LEGACY_UDP__INFO: S("UDP", "INFO"); break; + case T_LEGACY_UDP__ERROR: S("UDP", "ERROR"); break; + case T_LEGACY_UDP__WARNING: S("UDP", "WARNING"); break; + case T_LEGACY_UDP__DEBUG: S("UDP", "DEBUG"); break; + case T_LEGACY_UDP__TRACE: S("UDP", "TRACE"); break; + case T_LEGACY_NAS_INFO: S("NAS", "INFO"); break; + case T_LEGACY_NAS_ERROR: S("NAS", "ERROR"); break; + case T_LEGACY_NAS_WARNING: S("NAS", "WARNING"); break; + case T_LEGACY_NAS_DEBUG: S("NAS", "DEBUG"); break; + case T_LEGACY_NAS_TRACE: S("NAS", "TRACE"); break; + case T_LEGACY_HW_INFO: S("HW", "INFO"); break; + case T_LEGACY_HW_ERROR: S("HW", "ERROR"); break; + case T_LEGACY_HW_WARNING: S("HW", "WARNING"); break; + case T_LEGACY_HW_DEBUG: S("HW", "DEBUG"); break; + case T_LEGACY_HW_TRACE: S("HW", "TRACE"); break; + case T_LEGACY_EMU_INFO: S("EMU", "INFO"); break; + case T_LEGACY_EMU_ERROR: S("EMU", "ERROR"); break; + case T_LEGACY_EMU_WARNING: S("EMU", "WARNING"); break; + case T_LEGACY_EMU_DEBUG: S("EMU", "DEBUG"); break; + case T_LEGACY_EMU_TRACE: S("EMU", "TRACE"); break; + case T_LEGACY_OTG_INFO: S("OTG", "INFO"); break; + case T_LEGACY_OTG_ERROR: S("OTG", "ERROR"); break; + case T_LEGACY_OTG_WARNING: S("OTG", "WARNING"); break; + case T_LEGACY_OTG_DEBUG: S("OTG", "DEBUG"); break; + case T_LEGACY_OTG_TRACE: S("OTG", "TRACE"); break; + case T_LEGACY_OCG_INFO: S("OCG", "INFO"); break; + case T_LEGACY_OCG_ERROR: S("OCG", "ERROR"); break; + case T_LEGACY_OCG_WARNING: S("OCG", "WARNING"); break; + case T_LEGACY_OCG_DEBUG: S("OCG", "DEBUG"); break; + case T_LEGACY_OCG_TRACE: S("OCG", "TRACE"); break; + case T_LEGACY_OMG_INFO: S("OMG", "INFO"); break; + case T_LEGACY_OMG_ERROR: S("OMG", "ERROR"); break; + case T_LEGACY_OMG_WARNING: S("OMG", "WARNING"); break; + case T_LEGACY_OMG_DEBUG: S("OMG", "DEBUG"); break; + case T_LEGACY_OMG_TRACE: S("OMG", "TRACE"); break; + case T_LEGACY_GTPU_INFO: S("GTPU", "INFO"); break; + case T_LEGACY_GTPU_ERROR: S("GTPU", "ERROR"); break; + case T_LEGACY_GTPU_WARNING: S("GTPU", "WARNING"); break; + case T_LEGACY_GTPU_DEBUG: S("GTPU", "DEBUG"); break; + case T_LEGACY_GTPU_TRACE: S("GTPU", "TRACE"); break; + case T_LEGACY_TMR_INFO: S("TMR", "INFO"); break; + case T_LEGACY_TMR_ERROR: S("TMR", "ERROR"); break; + case T_LEGACY_TMR_WARNING: S("TMR", "WARNING"); break; + case T_LEGACY_TMR_DEBUG: S("TMR", "DEBUG"); break; + case T_LEGACY_TMR_TRACE: S("TMR", "TRACE"); break; + case T_LEGACY_OSA_INFO: S("OSA", "INFO"); break; + case T_LEGACY_OSA_ERROR: S("OSA", "ERROR"); break; + case T_LEGACY_OSA_WARNING: S("OSA", "WARNING"); break; + case T_LEGACY_OSA_DEBUG: S("OSA", "DEBUG"); break; + case T_LEGACY_OSA_TRACE: S("OSA", "TRACE"); break; + case T_LEGACY_component_INFO: S("XXX", "INFO"); break; + case T_LEGACY_component_ERROR: S("XXX", "ERROR"); break; + case T_LEGACY_component_WARNING: S("XXX", "WARNING"); break; + case T_LEGACY_component_DEBUG: S("XXX", "DEBUG"); break; + case T_LEGACY_component_TRACE: S("XXX", "TRACE"); break; + case T_LEGACY_componentP_INFO: S("XXX", "INFO"); break; + case T_LEGACY_componentP_ERROR: S("XXX", "ERROR"); break; + case T_LEGACY_componentP_WARNING: S("XXX", "WARNING"); break; + case T_LEGACY_componentP_DEBUG: S("XXX", "DEBUG"); break; + case T_LEGACY_componentP_TRACE: S("XXX", "TRACE"); break; + case T_LEGACY_CLI_INFO: S("CLI", "INFO"); break; + case T_LEGACY_CLI_ERROR: S("CLI", "ERROR"); break; + case T_LEGACY_CLI_WARNING: S("CLI", "WARNING"); break; + case T_LEGACY_CLI_DEBUG: S("CLI", "DEBUG"); break; + case T_LEGACY_CLI_TRACE: S("CLI", "TRACE"); break; + default: printf("unkown message type %d\n", m); abort(); + } + +#ifdef T_USE_SHARED_MEMORY + T_cache[T_busylist_head].busy = 0; + T_busylist_head++; + T_busylist_head &= T_CACHE_SIZE - 1; +#endif +} + +#ifdef T_USE_SHARED_MEMORY + +void wait_message(void) +{ + while (T_cache[T_busylist_head].busy == 0) usleep(1000); +} + +void init_shm(void) +{ + int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT, 0666); + if (s == -1) { perror(T_SHM_FILENAME); abort(); } + if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) + { perror(T_SHM_FILENAME); abort(); } + T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), + PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); + if (T_cache == NULL) + { perror(T_SHM_FILENAME); abort(); } + close(s); +} + +#endif /* T_USE_SHARED_MEMORY */ + +int main(void) +{ + int s; + int l; + char t; +#ifdef T_USE_SHARED_MEMORY + init_shm(); +#endif + s = get_connection("127.0.0.1", 2020); + /* send the first message - activate all traces */ + t = 0; + if (write(s, &t, 1) != 1) abort(); + l = T_NUMBER_OF_IDS; + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + for (l = 0; l < T_NUMBER_OF_IDS; l++) + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + /* read messages */ + while (1) { +#ifdef T_USE_SHARED_MEMORY + wait_message(); +#endif + get_message(s); + } + return 0; +} From 4b68033b2dc24df6800097f5f16b0352d4f4b9e3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 15 Mar 2016 10:43:10 +0100 Subject: [PATCH 002/217] some work for buffer handling --- T.h | 12 +++++++----- T_messages.txt | 1 + main.c | 6 ++++-- tracer/main.c | 13 +++++++++++-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/T.h b/T.h index 884a9b6f89..ec7b1d2a0c 100644 --- a/T.h +++ b/T.h @@ -36,10 +36,12 @@ #define T_PUT_buffer(argnum, val) \ do { \ - T_buffer T_PUT_var = (val); \ - T_CHECK_SIZE(T_PUT_var.length, argnum); \ - memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_var.addr, T_PUT_var.length); \ - T_LOCAL_size += T_PUT_var.length; \ + T_buffer T_PUT_buffer_var = (val); \ + T_PUT_int(argnum, T_PUT_buffer_var.length); \ + T_CHECK_SIZE(T_PUT_buffer_var.length, argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_buffer_var.addr, \ + T_PUT_buffer_var.length); \ + T_LOCAL_size += T_PUT_buffer_var.length; \ } while (0) #define T_PUT_string(argnum, val) \ @@ -117,7 +119,7 @@ extern T_cache_t *T_cache; T_send(T_LOCAL_buf, T_LOCAL_size) #define T_CHECK_SIZE(len, argnum) \ - if (T_LOCAL_size + len > T_BUFFER_MAX) { \ + if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \ printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ ", consider increasing T_BUFFER_MAX (%d)\n", \ __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ diff --git a/T_messages.txt b/T_messages.txt index b0e6cb00ed..8cca071ae8 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -138,3 +138,4 @@ ID = LEGACY_CLI_DEBUG ID = LEGACY_CLI_TRACE ID = first +ID = buf_test diff --git a/main.c b/main.c index 50b1d9339c..3552f19df5 100644 --- a/main.c +++ b/main.c @@ -10,8 +10,10 @@ int main(void) T_connect_to_tracer("127.0.0.1", 2020); printf("after connect\n"); while (1) { - T(T_first, T_PRINTF("hello world %s!\n", "yo")); - //usleep(1); + char *buf = "hello world %s!\n"; + //T(T_first, T_PRINTF("hello world %s!\n", "yo")); + T(T_buf_test, T_BUFFER("hello world %s!\n", strlen(buf)+1)); + usleep(1); } while (1) pause(); diff --git a/tracer/main.c b/tracer/main.c index fa19a6237b..f9da2085bf 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -73,7 +73,7 @@ void get_string(int s, char *out) void get_message(int s) { #define S(x, y) do { \ - char str[1024]; \ + char str[T_BUFFER_MAX]; \ get_string(s, str); \ printf("["x"]["y"] %s", str); \ } while (0) @@ -85,7 +85,7 @@ void get_message(int s) if (GET(s, &m, sizeof(int)) != sizeof(int)) abort(); switch (m) { case T_first: { - char str[1024]; + char str[T_BUFFER_MAX]; get_string(s, str); printf("%s", str); break; @@ -195,6 +195,15 @@ void get_message(int s) case T_LEGACY_CLI_WARNING: S("CLI", "WARNING"); break; case T_LEGACY_CLI_DEBUG: S("CLI", "DEBUG"); break; case T_LEGACY_CLI_TRACE: S("CLI", "TRACE"); break; + case T_buf_test: { + unsigned char buf[T_BUFFER_MAX]; + int size; + GET(s, &size, sizeof(int)); + GET(s, buf, size); + printf("got buffer size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); + break; + } default: printf("unkown message type %d\n", m); abort(); } From 6fa2737027914bce7b409460b973bd7636ab094d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 15 Mar 2016 17:01:05 +0100 Subject: [PATCH 003/217] add a plotter for raw IQ samples from eNB uplink received data only works for 5MHz (7680 samples per TTI), one transport block (basic FDD thing) --- Makefile | 2 +- T.h | 60 +++++++++++++---------- T_defs.h | 4 +- T_messages.txt | 27 ++++++++++- generate_Txx.c | 4 +- tracer/Makefile | 6 ++- tracer/defs.h | 8 ++++ tracer/main.c | 24 ++++++++++ tracer/plot.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 226 insertions(+), 32 deletions(-) create mode 100644 tracer/defs.h create mode 100644 tracer/plot.c diff --git a/Makefile b/Makefile index 06315e4585..c65ed27b8e 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ $(PROG): $(OBJS) T_IDs.h: $(GENIDS) T_messages.txt ./$(GENIDS) T_messages.txt T_IDs.h -main.o: T.h T_IDs.h +main.o: T.h T_IDs.h T_defs.h clean: rm -f *.o $(PROG) $(GENIDS) core T_IDs.h diff --git a/T.h b/T.h index ec7b1d2a0c..46c5bdc180 100644 --- a/T.h +++ b/T.h @@ -236,20 +236,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3) \ - do { \ - if (T_ACTIVE(t)) { \ - T_LOCAL_DATA \ - T_HEADER(t); \ - T_PUT_##t0(2, x0); \ - T_PUT_##t1(3, x1); \ - T_PUT_##t2(4, x2); \ - T_PUT_##t3(5, x3); \ - T_SEND(); \ - } \ - } while (0) - -#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \ +#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -263,7 +250,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \ +#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -278,7 +265,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \ +#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -294,7 +281,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \ +#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -311,7 +298,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \ +#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -329,7 +316,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \ +#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -348,7 +335,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \ +#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -368,7 +355,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \ +#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -389,7 +376,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \ +#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -411,7 +398,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \ +#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -434,7 +421,7 @@ extern T_cache_t *T_cache; } \ } while (0) -#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \ +#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \ do { \ if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ @@ -458,6 +445,31 @@ extern T_cache_t *T_cache; } \ } while (0) +#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_PUT_##t13(15, x13); \ + T_PUT_##t14(16, x14); \ + T_PUT_##t15(17, x15); \ + T_SEND(); \ + } \ + } while (0) + #define T_CALL_ERROR \ do { \ printf("%s:%d:%s: error calling T, you have to use T_INT() or T_XX()\n", \ diff --git a/T_defs.h b/T_defs.h index 1d01ea7415..5aca54e8d6 100644 --- a/T_defs.h +++ b/T_defs.h @@ -2,10 +2,10 @@ #define _T_defs_H_ /* maximum size of a message - increase if needed */ -#define T_BUFFER_MAX 1024 +#define T_BUFFER_MAX (1024*64) /* size of the local cache for messages (must be pow(2,something)) */ -#define T_CACHE_SIZE (65536 * 2) +#define T_CACHE_SIZE (8192 * 2) typedef struct { volatile int busy; diff --git a/T_messages.txt b/T_messages.txt index 8cca071ae8..e5f0c916a3 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -1,17 +1,41 @@ +#PHY logs +ID = ENB_INPUT_SIGNAL + DESC = eNodeB received signal in the time domain for a duration of 1ms + GROUP = PHY:GRAPHIC:HEAVY + FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata + #legacy logs ID = LEGACY_MAC_INFO - DESC = MAC legacy logs + DESC = MAC legacy logs - info level GROUP = MAC:INFO:LEGACY ID = LEGACY_MAC_ERROR + DESC = MAC legacy logs - error level + GROUP = MAC:ERROR:LEGACY ID = LEGACY_MAC_WARNING + DESC = MAC legacy logs - warning level + GROUP = MAC:WARNING:LEGACY ID = LEGACY_MAC_DEBUG + DESC = MAC legacy logs - debug level + GROUP = MAC:DEBUG:LEGACY ID = LEGACY_MAC_TRACE + DESC = MAC legacy logs - trace level + GROUP = MAC:TRACE:LEGACY ID = LEGACY_PHY_INFO + DESC = PHY legacy logs - info level + GROUP = PHY:INFO:LEGACY ID = LEGACY_PHY_ERROR + DESC = PHY legacy logs - error level + GROUP = PHY:ERROR:LEGACY ID = LEGACY_PHY_WARNING + DESC = PHY legacy logs - warning level + GROUP = PHY:WARNING:LEGACY ID = LEGACY_PHY_DEBUG + DESC = PHY legacy logs - debug level + GROUP = PHY:DEBUG:LEGACY ID = LEGACY_PHY_TRACE + DESC = PHY legacy logs - trace level + GROUP = PHY:TRACE:LEGACY ID = LEGACY_S1AP_INFO ID = LEGACY_S1AP_ERROR @@ -137,5 +161,6 @@ ID = LEGACY_CLI_WARNING ID = LEGACY_CLI_DEBUG ID = LEGACY_CLI_TRACE +#for debug/test - not used ID = first ID = buf_test diff --git a/generate_Txx.c b/generate_Txx.c index 6e803aac50..da6282adc1 100644 --- a/generate_Txx.c +++ b/generate_Txx.c @@ -4,13 +4,13 @@ void print(int n) { int i; printf("#define T%d(t", n); - for(i=0; i<(n-3)/2; i++) printf(",t%d,x%d", i, i); + for(i=0; i<(n-1)/2; i++) printf(",t%d,x%d", i, i); printf(") \\\n"); printf(" do { \\\n"); printf(" if (T_ACTIVE(t)) { \\\n"); printf(" T_LOCAL_DATA \\\n"); printf(" T_HEADER(t); \\\n"); - for(i=0; i<(n-3)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i); + for(i=0; i<(n-1)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i); printf(" T_SEND(); \\\n"); printf(" } \\\n"); printf(" } while (0)\n"); diff --git a/tracer/Makefile b/tracer/Makefile index 156700812e..047e1a5c38 100644 --- a/tracer/Makefile +++ b/tracer/Makefile @@ -1,12 +1,14 @@ CC=gcc -CFLAGS=-Wall -g -O3 +CFLAGS=-Wall -g -pthread + +LIBS=-lX11 -lm #comment those two lines to NOT use shared memory CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer -OBJS=main.o +OBJS=main.o plot.o $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) diff --git a/tracer/defs.h b/tracer/defs.h new file mode 100644 index 0000000000..73e11a0c7d --- /dev/null +++ b/tracer/defs.h @@ -0,0 +1,8 @@ +#ifndef _TRACER_DEFS_H_ +#define _TRACER_DEFS_H_ + +void *make_plot(int width, int height, int bufsize); +void plot_set(void *plot, float *data, int len, int pos); +void iq_plot_set(void *plot, short *data, int len, int pos); + +#endif /* _TRACER_DEFS_H_ */ diff --git a/tracer/main.c b/tracer/main.c index f9da2085bf..e80c5691a1 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -8,10 +8,14 @@ #include #include +#include "defs.h" + #define T_ID(x) x #include "../T_IDs.h" #include "../T_defs.h" +void *ul_plot; + #ifdef T_USE_SHARED_MEMORY T_cache_t *T_cache; @@ -195,6 +199,23 @@ void get_message(int s) case T_LEGACY_CLI_WARNING: S("CLI", "WARNING"); break; case T_LEGACY_CLI_DEBUG: S("CLI", "DEBUG"); break; case T_LEGACY_CLI_TRACE: S("CLI", "TRACE"); break; + case T_ENB_INPUT_SIGNAL: { + unsigned char buf[T_BUFFER_MAX]; + int size; + int eNB, frame, subframe, antenna; + GET(s, &eNB, sizeof(int)); + GET(s, &frame, sizeof(int)); + GET(s, &subframe, sizeof(int)); + GET(s, &antenna, sizeof(int)); + GET(s, &size, sizeof(int)); + GET(s, buf, size); + printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna %d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); + if (size != 4 * 7680) + {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();} + iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680); + break; + } case T_buf_test: { unsigned char buf[T_BUFFER_MAX]; int size; @@ -252,6 +273,9 @@ int main(void) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); for (l = 0; l < T_NUMBER_OF_IDS; l++) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + + ul_plot = make_plot(512, 100, 7680*2*10); + /* read messages */ while (1) { #ifdef T_USE_SHARED_MEMORY diff --git a/tracer/plot.c b/tracer/plot.c new file mode 100644 index 0000000000..ba203b0886 --- /dev/null +++ b/tracer/plot.c @@ -0,0 +1,123 @@ +#include "defs.h" +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + Display *d; + Window w; + Pixmap p; + int width; + int height; + float *buf; + short *iqbuf; + int bufsize; +} plot; + +static void *plot_thread(void *_p) +{ + float v; + float *s; + int i, j; + plot *p = _p; + while (1) { + while (XPending(p->d)) { + XEvent e; + XNextEvent(p->d, &e); + } + + { + /* TODO: get white & black GCs at startup */ + GC gc; + XGCValues v; + gc = DefaultGC(p->d, DefaultScreen(p->d)); + v.foreground = WhitePixel(p->d, DefaultScreen(p->d)); + XChangeGC(p->d, gc, GCForeground, &v); + XFillRectangle(p->d, p->p, gc, 0, 0, p->width, p->height); + v.foreground = BlackPixel(p->d, DefaultScreen(p->d)); + XChangeGC(p->d, gc, GCForeground, &v); + } + + { + int i; + for (i = 0; i < 512*150; i++) + p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+ + p->iqbuf[2*i+1]*p->iqbuf[2*i+1])); + } + s = p->buf; + for (i = 0; i < 512; i++) { + v = 0; + for (j = 0; j < 150; j++, s++) v += *s; + v /= 150; + XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), i, 100, i, 100-v); + } + + XCopyArea(p->d, p->p, p->w, DefaultGC(p->d, DefaultScreen(p->d)), + 0, 0, p->width, p->height, 0, 0); + usleep(100*1000); + } + + return NULL; +} + +static void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + +void *make_plot(int width, int height, int bufsize) +{ + plot *p; + Display *d; + Window w; + Pixmap pm; + + d = XOpenDisplay(0); if (d == NULL) abort(); + w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height, + 0, WhitePixel(d, DefaultScreen(d)), WhitePixel(d, DefaultScreen(d))); + XSelectInput(d, w, ExposureMask); + XMapWindow(d, w); + + pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d))); + + p = malloc(sizeof(*p)); if (p == NULL) abort(); + p->width = width; + p->height = height; + p->buf = malloc(sizeof(float) * bufsize); if (p->buf == NULL) abort(); + p->iqbuf = malloc(sizeof(short) * 2 * bufsize); if (p->buf == NULL) abort(); + p->bufsize = bufsize; + + p->d = d; + p->w = w; + p->p = pm; + + new_thread(plot_thread, p); + + return p; +} + +void plot_set(void *_plot, float *data, int len, int pos) +{ + plot *p = _plot; + memcpy(p->buf + pos, data, len * sizeof(float)); +} + +void iq_plot_set(void *_plot, short *data, int len, int pos) +{ + plot *p = _plot; + memcpy(p->iqbuf + pos * 2, data, len * 2 * sizeof(short)); +} From 75b827f84689ff9cb2edef0d90dc06a0af4bac47 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 15 Mar 2016 18:44:00 +0100 Subject: [PATCH 004/217] don't accept spaces at end of lines in the messages' file --- genids.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/genids.c b/genids.c index 47383eccf3..734c506368 100644 --- a/genids.c +++ b/genids.c @@ -135,6 +135,11 @@ int main(int n, char **v) get_line(in, &name, &value); if (name == NULL) break; printf("name '%s' value '%s'\n", name, value); + if (isspace(value[strlen(value)-1])) { + printf("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)) { unlink(out_name); exit(1); } fprintf(out, "#define T_%s T_ID(%d)\n", value, n); From fe808cc3b411b19de8e49d8410185f9920f2cc72 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 15 Mar 2016 18:45:51 +0100 Subject: [PATCH 005/217] add a database of groups to, well, group IDs --- tracer/Makefile | 2 +- tracer/defs.h | 4 + tracer/main.c | 7 +- tracer/t_data.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 tracer/t_data.c diff --git a/tracer/Makefile b/tracer/Makefile index 047e1a5c38..99385f4593 100644 --- a/tracer/Makefile +++ b/tracer/Makefile @@ -8,7 +8,7 @@ CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer -OBJS=main.o plot.o +OBJS=main.o plot.o t_data.o $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) diff --git a/tracer/defs.h b/tracer/defs.h index 73e11a0c7d..5ba87131de 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -5,4 +5,8 @@ void *make_plot(int width, int height, int bufsize); void plot_set(void *plot, float *data, int len, int pos); void iq_plot_set(void *plot, short *data, int len, int pos); +/* returns an opaque pointer - truly a 'database *', see t_data.c */ +void *parse_database(char *filename); +void dump_database(void *database); + #endif /* _TRACER_DEFS_H_ */ diff --git a/tracer/main.c b/tracer/main.c index e80c5691a1..b045c58652 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -257,11 +257,16 @@ void init_shm(void) #endif /* T_USE_SHARED_MEMORY */ -int main(void) +int main(int n, char **v) { + void *database; int s; int l; char t; + + database = parse_database("../T_messages.txt"); + dump_database(database); + #ifdef T_USE_SHARED_MEMORY init_shm(); #endif diff --git a/tracer/t_data.c b/tracer/t_data.c new file mode 100644 index 0000000000..dc006e5830 --- /dev/null +++ b/tracer/t_data.c @@ -0,0 +1,213 @@ +#include "defs.h" +#include +#include +#include +#include + +typedef struct { + char *name; + char *desc; +} id; + +typedef struct { + char *name; + char **ids; + int size; +} group; + +typedef struct { + id *i; + int isize; + group *g; + int gsize; +} database; + +typedef struct { + char *data; + int size; + int maxsize; +} buffer; + +typedef struct { + buffer name; + buffer value; +} parser; + +void put(buffer *b, int c) +{ + if (b->size == b->maxsize) { + b->maxsize += 256; + b->data = realloc(b->data, b->maxsize); + if (b->data == NULL) { printf("memory allocation error\n"); exit(1); } + } + b->data[b->size] = c; + b->size++; +} + +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(parser *p, FILE *f, char **name, char **value) +{ + int c; + p->name.size = 0; + p->value.size = 0; + *name = NULL; + *value = NULL; + smash_spaces(f); + c = fgetc(f); + while (!(c == '=' || isspace(c) || c == EOF)) + { put(&p->name, c); c = fgetc(f); } + if (c == EOF) return; + put(&p->name, 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)) + { put(&p->value, c); c = fgetc(f); } + put(&p->value, 0); + if (p->name.size <= 1) return; + if (p->value.size <= 1) return; + *name = p->name.data; + *value = p->value.data; +} + +void add_id(database *r, char *id) +{ + if ((r->isize & 1023) == 0) { + r->i = realloc(r->i, (r->isize + 1024) * sizeof(id)); + if (r->i == NULL) { printf("out of memory\n"); exit(1); } + } + r->i[r->isize].name = strdup(id); + if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); } + r->isize++; +} + +int group_cmp(const void *_p1, const void *_p2) +{ + const group *p1 = _p1; + const group *p2 = _p2; + return strcmp(p1->name, p2->name); +} + +group *get_group(database *r, char *group_name) +{ + group gsearch; + group *ret; + + gsearch.name = group_name; + ret = bsearch(&gsearch, r->g, r->gsize, sizeof(group), group_cmp); + if (ret != NULL) return ret; + + if ((r->gsize & 1023) == 0) { + r->g = realloc(r->g, (r->gsize + 1024) * sizeof(group)); + if (r->g == NULL) abort(); + } + r->g[r->gsize].name = strdup(group_name); + if (r->g[r->gsize].name == NULL) abort(); + r->g[r->gsize].ids = NULL; + r->g[r->gsize].size = 0; + r->gsize++; + + qsort(r->g, r->gsize, sizeof(group), group_cmp); + + return bsearch(&gsearch, r->g, r->gsize, sizeof(group), group_cmp); +} + +void group_add_id(group *g, char *id) +{ + if ((g->size & 1023) == 0) { + g->ids = realloc(g->ids, (g->size + 1024) * sizeof(char *)); + if (g->ids == NULL) abort(); + } + g->ids[g->size] = id; + g->size++; +} + +void add_groups(database *r, char *groups) +{ + group *g; + + while (1) { + char *start = groups; + char *end = start; + while (!isspace(*end) && *end != ':' && *end != 0) end++; + if (end == start) { + printf("bad group line: groups are seperated by ':'\n"); + abort(); + } + if (*end == 0) end = NULL; else *end = 0; + + g = get_group(r, start); + group_add_id(g, r->i[r->isize-1].name); + + if (end == NULL) break; + end++; + while ((isspace(*end) || *end == ':') && *end != 0) end++; + if (*end == 0) break; + groups = end; + } +} + +void *parse_database(char *filename) +{ + FILE *in; + parser p; + database *r; + char *name, *value; + + r = calloc(1, sizeof(*r)); if (r == NULL) abort(); + memset(&p, 0, sizeof(p)); + + in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); } + + while (1) { + get_line(&p, in, &name, &value); + if (name == NULL) break; + printf("%s %s\n", name, value); + if (!strcmp(name, "ID")) add_id(r, value); + if (!strcmp(name, "GROUP")) add_groups(r, value); + } + + fclose(in); + free(p.name.data); + free(p.value.data); + + return r; +} + +void dump_database(void *_d) +{ + database *d = _d; + int i; + + printf("database: %d IDs, %d GROUPs\n", d->isize, d->gsize); + for (i = 0; i < d->isize; i++) + printf("ID %s [%s]\n", d->i[i].name, d->i[i].desc); + for (i = 0; i < d->gsize; i++) { + int j; + printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size); + for (j = 0; j < d->g[i].size; j++) + printf(" ID %s\n", d->g[i].ids[j]); + } +} From 1f4f0305810bfecfe39ae33e31f5027932918e6d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 16 Mar 2016 11:00:39 +0100 Subject: [PATCH 006/217] more work on database --- tracer/Makefile | 2 +- tracer/{t_data.c => database.c} | 119 +++++++++++++++++++++++++------- tracer/defs.h | 2 + tracer/main.c | 44 ++++++++++-- 4 files changed, 137 insertions(+), 30 deletions(-) rename tracer/{t_data.c => database.c} (59%) diff --git a/tracer/Makefile b/tracer/Makefile index 99385f4593..8388ec91e2 100644 --- a/tracer/Makefile +++ b/tracer/Makefile @@ -8,7 +8,7 @@ CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer -OBJS=main.o plot.o t_data.o +OBJS=main.o plot.o database.o $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) diff --git a/tracer/t_data.c b/tracer/database.c similarity index 59% rename from tracer/t_data.c rename to tracer/database.c index dc006e5830..87e793b8c3 100644 --- a/tracer/t_data.c +++ b/tracer/database.c @@ -7,6 +7,8 @@ typedef struct { char *name; char *desc; + char **groups; + int size; } id; typedef struct { @@ -16,6 +18,7 @@ typedef struct { } group; typedef struct { + char *name; id *i; int isize; group *g; @@ -92,17 +95,6 @@ void get_line(parser *p, FILE *f, char **name, char **value) *value = p->value.data; } -void add_id(database *r, char *id) -{ - if ((r->isize & 1023) == 0) { - r->i = realloc(r->i, (r->isize + 1024) * sizeof(id)); - if (r->i == NULL) { printf("out of memory\n"); exit(1); } - } - r->i[r->isize].name = strdup(id); - if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); } - r->isize++; -} - int group_cmp(const void *_p1, const void *_p2) { const group *p1 = _p1; @@ -110,13 +102,44 @@ int group_cmp(const void *_p1, const void *_p2) return strcmp(p1->name, p2->name); } +int id_cmp(const void *_p1, const void *_p2) +{ + const id *p1 = _p1; + const id *p2 = _p2; + return strcmp(p1->name, p2->name); +} + +int string_cmp(const void *_p1, const void *_p2) +{ + char * const *p1 = _p1; + char * const *p2 = _p2; + return strcmp(*p1, *p2); +} + +id *add_id(database *r, char *idname) +{ + if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL) + { printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); } + if ((r->isize & 1023) == 0) { + r->i = realloc(r->i, (r->isize + 1024) * sizeof(id)); + if (r->i == NULL) { printf("out of memory\n"); exit(1); } + } + r->i[r->isize].name = strdup(idname); + if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); } + r->i[r->isize].desc = NULL; + r->i[r->isize].groups = NULL; + r->i[r->isize].size = 0; + r->isize++; + qsort(r->i, r->isize, sizeof(id), id_cmp); + return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp); +} + group *get_group(database *r, char *group_name) { - group gsearch; group *ret; - gsearch.name = group_name; - ret = bsearch(&gsearch, r->g, r->gsize, sizeof(group), group_cmp); + ret = bsearch(&(group){name:group_name}, + r->g, r->gsize, sizeof(group), group_cmp); if (ret != NULL) return ret; if ((r->gsize & 1023) == 0) { @@ -131,7 +154,8 @@ group *get_group(database *r, char *group_name) qsort(r->g, r->gsize, sizeof(group), group_cmp); - return bsearch(&gsearch, r->g, r->gsize, sizeof(group), group_cmp); + return bsearch(&(group){name:group_name}, + r->g, r->gsize, sizeof(group), group_cmp); } void group_add_id(group *g, char *id) @@ -144,10 +168,24 @@ void group_add_id(group *g, char *id) g->size++; } -void add_groups(database *r, char *groups) +void id_add_group(id *i, char *group) +{ + char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp); + if (g != NULL) return; + + if ((i->size & 1023) == 0) { + i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *)); + if (i->groups == NULL) abort(); + } + i->groups[i->size] = group; + i->size++; + qsort(i->groups, i->size, sizeof(char *), string_cmp); +} + +void add_groups(database *r, id *i, char *groups) { group *g; - + if (i == NULL) {printf("ERROR: GROUP line before ID line\n");exit(1);} while (1) { char *start = groups; char *end = start; @@ -159,7 +197,8 @@ void add_groups(database *r, char *groups) if (*end == 0) end = NULL; else *end = 0; g = get_group(r, start); - group_add_id(g, r->i[r->isize-1].name); + group_add_id(g, i->name); + id_add_group(i, g->name); if (end == NULL) break; end++; @@ -169,24 +208,34 @@ void add_groups(database *r, char *groups) } } +void add_desc(id *i, char *desc) +{ + if (i == NULL) {printf("ERROR: DESC line before ID line\n");exit(1);} + i->desc = strdup(desc); if (i->desc == NULL) abort(); +} + void *parse_database(char *filename) { FILE *in; parser p; database *r; char *name, *value; + id *last_id = NULL; r = calloc(1, sizeof(*r)); if (r == NULL) abort(); memset(&p, 0, sizeof(p)); + r->name = strdup(filename); if (r->name == NULL) abort(); + in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); } while (1) { get_line(&p, in, &name, &value); if (name == NULL) break; - printf("%s %s\n", name, value); - if (!strcmp(name, "ID")) add_id(r, value); - if (!strcmp(name, "GROUP")) add_groups(r, value); +//printf("%s %s\n", name, value); + if (!strcmp(name, "ID")) last_id = add_id(r, value); + if (!strcmp(name, "GROUP")) add_groups(r, last_id, value); + if (!strcmp(name, "DESC")) add_desc(last_id, value); } fclose(in); @@ -201,13 +250,33 @@ void dump_database(void *_d) database *d = _d; int i; - printf("database: %d IDs, %d GROUPs\n", d->isize, d->gsize); - for (i = 0; i < d->isize; i++) - printf("ID %s [%s]\n", d->i[i].name, d->i[i].desc); + printf("database %s: %d IDs, %d GROUPs\n", d->name, d->isize, d->gsize); + for (i = 0; i < d->isize; i++) { + int j; + printf("ID %s [%s] [in %d group%s]\n", + d->i[i].name, d->i[i].desc ? d->i[i].desc : "", + d->i[i].size, d->i[i].size > 1 ? "s" : ""); + for (j = 0; j < d->i[i].size; j++) + printf(" in GROUP: %s\n", d->i[i].groups[j]); + } for (i = 0; i < d->gsize; i++) { int j; printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size); for (j = 0; j < d->g[i].size; j++) - printf(" ID %s\n", d->g[i].ids[j]); + printf(" contains ID: %s\n", d->g[i].ids[j]); } } + +void list_ids(void *_d) +{ + database *d = _d; + int i; + for (i = 0; i < d->isize; i++) printf("%s\n", d->i[i].name); +} + +void list_groups(void *_d) +{ + database *d = _d; + int i; + for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name); +} diff --git a/tracer/defs.h b/tracer/defs.h index 5ba87131de..6c2a026600 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -8,5 +8,7 @@ void iq_plot_set(void *plot, short *data, int len, int pos); /* returns an opaque pointer - truly a 'database *', see t_data.c */ void *parse_database(char *filename); void dump_database(void *database); +void list_ids(void *database); +void list_groups(void *database); #endif /* _TRACER_DEFS_H_ */ diff --git a/tracer/main.c b/tracer/main.c index b045c58652..fb5fcc99d9 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -257,15 +257,53 @@ void init_shm(void) #endif /* T_USE_SHARED_MEMORY */ +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -li print IDs in the database\n" +" -lg print GROUPs in the database\n" +" -dump dump the database\n" + ); + exit(1); +} + int main(int n, char **v) { + char *database_filename = NULL; void *database; int s; int l; char t; + int i; + int do_list_ids = 0; + int do_list_groups = 0; + int do_dump_database = 0; - database = parse_database("../T_messages.txt"); - dump_database(database); + 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], "-li")) { do_list_ids = 1; continue; } + if (!strcmp(v[i], "-lg")) { do_list_groups = 1; continue; } + if (!strcmp(v[i], "-dump")) { do_dump_database = 1; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + if (do_list_ids + do_list_groups + do_dump_database > 1) usage(); + if (do_list_ids) { list_ids(database); return 0; } + if (do_list_groups) { list_groups(database); return 0; } + if (do_dump_database) { dump_database(database); return 0; } + + ul_plot = make_plot(512, 100, 7680*2*10); #ifdef T_USE_SHARED_MEMORY init_shm(); @@ -279,8 +317,6 @@ int main(int n, char **v) for (l = 0; l < T_NUMBER_OF_IDS; l++) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - ul_plot = make_plot(512, 100, 7680*2*10); - /* read messages */ while (1) { #ifdef T_USE_SHARED_MEMORY From f18d59c95a6ff6de8072df823492892fde22f54f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 16 Mar 2016 16:26:53 +0100 Subject: [PATCH 007/217] - add channel estimation plot - add on/off command line options --- T_messages.txt | 4 ++++ tracer/Makefile | 2 ++ tracer/database.c | 33 +++++++++++++++++++++++++-- tracer/defs.h | 3 ++- tracer/main.c | 57 +++++++++++++++++++++++++++++++++++++++++++---- tracer/plot.c | 10 +++++---- 6 files changed, 98 insertions(+), 11 deletions(-) diff --git a/T_messages.txt b/T_messages.txt index e5f0c916a3..043062c598 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -3,6 +3,10 @@ ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms GROUP = PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata +ID = ENB_UL_CHANNEL_ESTIMATE + DESC = eNodeB channel estimation in the time domain + GROUP = PHY:GRAPHIC:HEAVY + FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t #legacy logs ID = LEGACY_MAC_INFO diff --git a/tracer/Makefile b/tracer/Makefile index 8388ec91e2..23309eb85e 100644 --- a/tracer/Makefile +++ b/tracer/Makefile @@ -1,6 +1,8 @@ CC=gcc CFLAGS=-Wall -g -pthread +CFLAGS += -O3 -ffast-math -fomit-frame-pointer + LIBS=-lX11 -lm #comment those two lines to NOT use shared memory diff --git a/tracer/database.c b/tracer/database.c index 87e793b8c3..3172105250 100644 --- a/tracer/database.c +++ b/tracer/database.c @@ -9,6 +9,7 @@ typedef struct { char *desc; char **groups; int size; + int id; } id; typedef struct { @@ -116,7 +117,7 @@ int string_cmp(const void *_p1, const void *_p2) return strcmp(*p1, *p2); } -id *add_id(database *r, char *idname) +id *add_id(database *r, char *idname, int i) { if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL) { printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); } @@ -129,6 +130,7 @@ id *add_id(database *r, char *idname) r->i[r->isize].desc = NULL; r->i[r->isize].groups = NULL; r->i[r->isize].size = 0; + r->i[r->isize].id = i; r->isize++; qsort(r->i, r->isize, sizeof(id), id_cmp); return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp); @@ -221,6 +223,7 @@ void *parse_database(char *filename) database *r; char *name, *value; id *last_id = NULL; + int i; r = calloc(1, sizeof(*r)); if (r == NULL) abort(); memset(&p, 0, sizeof(p)); @@ -229,11 +232,13 @@ void *parse_database(char *filename) in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); } + i = 0; + while (1) { get_line(&p, in, &name, &value); if (name == NULL) break; //printf("%s %s\n", name, value); - if (!strcmp(name, "ID")) last_id = add_id(r, value); + if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; } if (!strcmp(name, "GROUP")) add_groups(r, last_id, value); if (!strcmp(name, "DESC")) add_desc(last_id, value); } @@ -280,3 +285,27 @@ void list_groups(void *_d) int i; for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name); } + +static void onoff_id(database *d, char *name, int *a, int onoff) +{ + id *i; + i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp); + if (i == NULL) return; + a[i->id] = onoff; + printf("turning %s %s\n", name, onoff ? "ON" : "OFF"); +} + +static void onoff_group(database *d, char *name, int *a, int onoff) +{ + group *g; + int i; + g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp); + if (g == NULL) return; + for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff); +} + +void on_off(void *d, char *item, int *a, int onoff) +{ + onoff_group(d, item, a, onoff); + onoff_id(d, item, a, onoff); +} diff --git a/tracer/defs.h b/tracer/defs.h index 6c2a026600..71b9dd0cfb 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -1,7 +1,7 @@ #ifndef _TRACER_DEFS_H_ #define _TRACER_DEFS_H_ -void *make_plot(int width, int height, int bufsize); +void *make_plot(int width, int height, int bufsize, char *title); void plot_set(void *plot, float *data, int len, int pos); void iq_plot_set(void *plot, short *data, int len, int pos); @@ -10,5 +10,6 @@ void *parse_database(char *filename); void dump_database(void *database); void list_ids(void *database); void list_groups(void *database); +void on_off(void *d, char *item, int *a, int onoff); #endif /* _TRACER_DEFS_H_ */ diff --git a/tracer/main.c b/tracer/main.c index fb5fcc99d9..37774be4e5 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -15,6 +15,7 @@ #include "../T_defs.h" void *ul_plot; +void *chest_plot; #ifdef T_USE_SHARED_MEMORY @@ -209,11 +210,30 @@ void get_message(int s) GET(s, &antenna, sizeof(int)); GET(s, &size, sizeof(int)); GET(s, buf, size); +#if 0 printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna %d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); +#endif if (size != 4 * 7680) {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();} - iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680); + if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680); + break; + } + case T_ENB_UL_CHANNEL_ESTIMATE: { + unsigned char buf[T_BUFFER_MAX]; + int size; + int eNB, UE, frame, subframe, antenna; + GET(s, &eNB, sizeof(int)); + GET(s, &UE, sizeof(int)); + GET(s, &frame, sizeof(int)); + GET(s, &subframe, sizeof(int)); + GET(s, &antenna, sizeof(int)); + GET(s, &size, sizeof(int)); + GET(s, buf, size); + if (size != 512*4) + {printf("bad T_ENB_UL_CHANNEL_ESTIMATE, only 512 samples allowed\n"); + abort();} + if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0); break; } case T_buf_test: { @@ -265,6 +285,11 @@ void usage(void) " -li print IDs in the database\n" " -lg print GROUPs in the database\n" " -dump dump the database\n" +" -x run with XFORMS (revisited)\n" +" -on turn log ON for given GROUP or ID\n" +" -off turn log OFF for given GROUP or ID\n" +"note: you may pass several -on and -off, they will be processed in order\n" +" by default, all is off\n" ); exit(1); } @@ -280,6 +305,16 @@ int main(int n, char **v) int do_list_ids = 0; int do_list_groups = 0; int do_dump_database = 0; + int do_xforms = 0; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int is_on[T_NUMBER_OF_IDS]; + + memset(is_on, 0, sizeof(is_on)); + + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); + on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); @@ -288,6 +323,12 @@ int main(int n, char **v) if (!strcmp(v[i], "-li")) { do_list_ids = 1; continue; } if (!strcmp(v[i], "-lg")) { do_list_groups = 1; continue; } if (!strcmp(v[i], "-dump")) { do_dump_database = 1; continue; } + if (!strcmp(v[i], "-x")) { do_xforms = 1; continue; } + if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + printf("ERROR: unknown option %s\n", v[i]); usage(); } @@ -303,7 +344,13 @@ int main(int n, char **v) if (do_list_groups) { list_groups(database); return 0; } if (do_dump_database) { dump_database(database); return 0; } - ul_plot = make_plot(512, 100, 7680*2*10); + if (do_xforms) { + ul_plot = make_plot(512, 100, 7680*2*10, "UL Input Signal"); + chest_plot = make_plot(512, 100, 512*2, "UL Channel Estimate UE 0"); + } + + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); #ifdef T_USE_SHARED_MEMORY init_shm(); @@ -312,10 +359,12 @@ int main(int n, char **v) /* send the first message - activate all traces */ t = 0; if (write(s, &t, 1) != 1) abort(); - l = T_NUMBER_OF_IDS; + l = 0; + for (i = 0; i < T_NUMBER_OF_IDS; i++) if (is_on[i]) l++; if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); for (l = 0; l < T_NUMBER_OF_IDS; l++) - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + if (is_on[l]) + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); /* read messages */ while (1) { diff --git a/tracer/plot.c b/tracer/plot.c index ba203b0886..3cc0ad069f 100644 --- a/tracer/plot.c +++ b/tracer/plot.c @@ -44,15 +44,15 @@ static void *plot_thread(void *_p) { int i; - for (i = 0; i < 512*150; i++) + for (i = 0; i < p->bufsize/2; i++) p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+ p->iqbuf[2*i+1]*p->iqbuf[2*i+1])); } s = p->buf; for (i = 0; i < 512; i++) { v = 0; - for (j = 0; j < 150; j++, s++) v += *s; - v /= 150; + for (j = 0; j < p->bufsize/2/512; j++, s++) v += *s; + v /= p->bufsize/2/512; XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), i, 100, i, 100-v); } @@ -79,7 +79,7 @@ static void new_thread(void *(*f)(void *), void *data) { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } } -void *make_plot(int width, int height, int bufsize) +void *make_plot(int width, int height, int bufsize, char *title) { plot *p; Display *d; @@ -92,6 +92,8 @@ void *make_plot(int width, int height, int bufsize) XSelectInput(d, w, ExposureMask); XMapWindow(d, w); + XStoreName(d, w, title); + pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d))); p = malloc(sizeof(*p)); if (p == NULL) abort(); From 9f0789e0d02193be156e79312f0423f88abb0a75 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 16 Mar 2016 17:41:16 +0100 Subject: [PATCH 008/217] - add groups in T_messages.txt - minor fix --- T_messages.txt | 200 ++++++++++++++++++++++++++++++++++++++++++++++ tracer/database.c | 2 +- 2 files changed, 201 insertions(+), 1 deletion(-) diff --git a/T_messages.txt b/T_messages.txt index 043062c598..ba6197b569 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -42,128 +42,328 @@ ID = LEGACY_PHY_TRACE GROUP = PHY:TRACE:LEGACY ID = LEGACY_S1AP_INFO + DESC = S1AP legacy logs - info level + GROUP = S1AP:INFO:LEGACY ID = LEGACY_S1AP_ERROR + DESC = S1AP legacy logs - error level + GROUP = S1AP:ERROR:LEGACY ID = LEGACY_S1AP_WARNING + DESC = S1AP legacy logs - warning level + GROUP = S1AP:WARNING:LEGACY ID = LEGACY_S1AP_DEBUG + DESC = S1AP legacy logs - debug level + GROUP = S1AP:DEBUG:LEGACY ID = LEGACY_S1AP_TRACE + DESC = S1AP legacy logs - trace level + GROUP = S1AP:TRACE:LEGACY ID = LEGACY_RRC_INFO + DESC = RRC legacy logs - info level + GROUP = RRC:INFO:LEGACY ID = LEGACY_RRC_ERROR + DESC = RRC legacy logs - error level + GROUP = RRC:ERROR:LEGACY ID = LEGACY_RRC_WARNING + DESC = RRC legacy logs - warning level + GROUP = RRC:WARNING:LEGACY ID = LEGACY_RRC_DEBUG + DESC = RRC legacy logs - debug level + GROUP = RRC:DEBUG:LEGACY ID = LEGACY_RRC_TRACE + DESC = RRC legacy logs - trace level + GROUP = RRC:TRACE:LEGACY ID = LEGACY_RLC_INFO + DESC = RLC legacy logs - info level + GROUP = RLC:INFO:LEGACY ID = LEGACY_RLC_ERROR + DESC = RLC legacy logs - error level + GROUP = RLC:ERROR:LEGACY ID = LEGACY_RLC_WARNING + DESC = RLC legacy logs - warning level + GROUP = RLC:WARNING:LEGACY ID = LEGACY_RLC_DEBUG + DESC = RLC legacy logs - debug level + GROUP = RLC:DEBUG:LEGACY ID = LEGACY_RLC_TRACE + DESC = RLC legacy logs - trace level + GROUP = RLC:TRACE:LEGACY ID = LEGACY_PDCP_INFO + DESC = PDCP legacy logs - info level + GROUP = PDCP:INFO:LEGACY ID = LEGACY_PDCP_ERROR + DESC = PDCP legacy logs - error level + GROUP = PDCP:ERROR:LEGACY ID = LEGACY_PDCP_WARNING + DESC = PDCP legacy logs - warning level + GROUP = PDCP:WARNING:LEGACY ID = LEGACY_PDCP_DEBUG + DESC = PDCP legacy logs - debug level + GROUP = PDCP:DEBUG:LEGACY ID = LEGACY_PDCP_TRACE + DESC = PDCP legacy logs - trace level + GROUP = PDCP:TRACE:LEGACY ID = LEGACY_ENB_APP_INFO + DESC = ENB_APP legacy logs - info level + GROUP = ENB_APP:INFO:LEGACY ID = LEGACY_ENB_APP_ERROR + DESC = ENB_APP legacy logs - error level + GROUP = ENB_APP:ERROR:LEGACY ID = LEGACY_ENB_APP_WARNING + DESC = ENB_APP legacy logs - warning level + GROUP = ENB_APP:WARNING:LEGACY ID = LEGACY_ENB_APP_DEBUG + DESC = ENB_APP legacy logs - debug level + GROUP = ENB_APP:DEBUG:LEGACY ID = LEGACY_ENB_APP_TRACE + DESC = ENB_APP legacy logs - trace level + GROUP = ENB_APP:TRACE:LEGACY ID = LEGACY_SCTP_INFO + DESC = SCTP legacy logs - info level + GROUP = SCTP:INFO:LEGACY ID = LEGACY_SCTP_ERROR + DESC = SCTP legacy logs - error level + GROUP = SCTP:ERROR:LEGACY ID = LEGACY_SCTP_WARNING + DESC = SCTP legacy logs - warning level + GROUP = SCTP:WARNING:LEGACY ID = LEGACY_SCTP_DEBUG + DESC = SCTP legacy logs - debug level + GROUP = SCTP:DEBUG:LEGACY ID = LEGACY_SCTP_TRACE + DESC = SCTP legacy logs - trace level + GROUP = SCTP:TRACE:LEGACY ID = LEGACY_UDP__INFO + DESC = UDP_ legacy logs - info level + GROUP = UDP_:INFO:LEGACY ID = LEGACY_UDP__ERROR + DESC = UDP_ legacy logs - error level + GROUP = UDP_:ERROR:LEGACY ID = LEGACY_UDP__WARNING + DESC = UDP_ legacy logs - warning level + GROUP = UDP_:WARNING:LEGACY ID = LEGACY_UDP__DEBUG + DESC = UDP_ legacy logs - debug level + GROUP = UDP_:DEBUG:LEGACY ID = LEGACY_UDP__TRACE + DESC = UDP_ legacy logs - trace level + GROUP = UDP_:TRACE:LEGACY ID = LEGACY_NAS_INFO + DESC = NAS legacy logs - info level + GROUP = NAS:INFO:LEGACY ID = LEGACY_NAS_ERROR + DESC = NAS legacy logs - error level + GROUP = NAS:ERROR:LEGACY ID = LEGACY_NAS_WARNING + DESC = NAS legacy logs - warning level + GROUP = NAS:WARNING:LEGACY ID = LEGACY_NAS_DEBUG + DESC = NAS legacy logs - debug level + GROUP = NAS:DEBUG:LEGACY ID = LEGACY_NAS_TRACE + DESC = NAS legacy logs - trace level + GROUP = NAS:TRACE:LEGACY ID = LEGACY_HW_INFO + DESC = HW legacy logs - info level + GROUP = HW:INFO:LEGACY ID = LEGACY_HW_ERROR + DESC = HW legacy logs - error level + GROUP = HW:ERROR:LEGACY ID = LEGACY_HW_WARNING + DESC = HW legacy logs - warning level + GROUP = HW:WARNING:LEGACY ID = LEGACY_HW_DEBUG + DESC = HW legacy logs - debug level + GROUP = HW:DEBUG:LEGACY ID = LEGACY_HW_TRACE + DESC = HW legacy logs - trace level + GROUP = HW:TRACE:LEGACY ID = LEGACY_EMU_INFO + DESC = EMU legacy logs - info level + GROUP = EMU:INFO:LEGACY ID = LEGACY_EMU_ERROR + DESC = EMU legacy logs - error level + GROUP = EMU:ERROR:LEGACY ID = LEGACY_EMU_WARNING + DESC = EMU legacy logs - warning level + GROUP = EMU:WARNING:LEGACY ID = LEGACY_EMU_DEBUG + DESC = EMU legacy logs - debug level + GROUP = EMU:DEBUG:LEGACY ID = LEGACY_EMU_TRACE + DESC = EMU legacy logs - trace level + GROUP = EMU:TRACE:LEGACY ID = LEGACY_OTG_INFO + DESC = OTG legacy logs - info level + GROUP = OTG:INFO:LEGACY ID = LEGACY_OTG_ERROR + DESC = OTG legacy logs - error level + GROUP = OTG:ERROR:LEGACY ID = LEGACY_OTG_WARNING + DESC = OTG legacy logs - warning level + GROUP = OTG:WARNING:LEGACY ID = LEGACY_OTG_DEBUG + DESC = OTG legacy logs - debug level + GROUP = OTG:DEBUG:LEGACY ID = LEGACY_OTG_TRACE + DESC = OTG legacy logs - trace level + GROUP = OTG:TRACE:LEGACY ID = LEGACY_OCG_INFO + DESC = OCG legacy logs - info level + GROUP = OCG:INFO:LEGACY ID = LEGACY_OCG_ERROR + DESC = OCG legacy logs - error level + GROUP = OCG:ERROR:LEGACY ID = LEGACY_OCG_WARNING + DESC = OCG legacy logs - warning level + GROUP = OCG:WARNING:LEGACY ID = LEGACY_OCG_DEBUG + DESC = OCG legacy logs - debug level + GROUP = OCG:DEBUG:LEGACY ID = LEGACY_OCG_TRACE + DESC = OCG legacy logs - trace level + GROUP = OCG:TRACE:LEGACY ID = LEGACY_OMG_INFO + DESC = OMG legacy logs - info level + GROUP = OMG:INFO:LEGACY ID = LEGACY_OMG_ERROR + DESC = OMG legacy logs - error level + GROUP = OMG:ERROR:LEGACY ID = LEGACY_OMG_WARNING + DESC = OMG legacy logs - warning level + GROUP = OMG:WARNING:LEGACY ID = LEGACY_OMG_DEBUG + DESC = OMG legacy logs - debug level + GROUP = OMG:DEBUG:LEGACY ID = LEGACY_OMG_TRACE + DESC = OMG legacy logs - trace level + GROUP = OMG:TRACE:LEGACY ID = LEGACY_OPT_INFO + DESC = OPT legacy logs - info level + GROUP = OPT:INFO:LEGACY ID = LEGACY_OPT_ERROR + DESC = OPT legacy logs - error level + GROUP = OPT:ERROR:LEGACY ID = LEGACY_OPT_WARNING + DESC = OPT legacy logs - warning level + GROUP = OPT:WARNING:LEGACY ID = LEGACY_OPT_DEBUG + DESC = OPT legacy logs - debug level + GROUP = OPT:DEBUG:LEGACY ID = LEGACY_OPT_TRACE + DESC = OPT legacy logs - trace level + GROUP = OPT:TRACE:LEGACY ID = LEGACY_GTPU_INFO + DESC = GTPU legacy logs - info level + GROUP = GTPU:INFO:LEGACY ID = LEGACY_GTPU_ERROR + DESC = GTPU legacy logs - error level + GROUP = GTPU:ERROR:LEGACY ID = LEGACY_GTPU_WARNING + DESC = GTPU legacy logs - warning level + GROUP = GTPU:WARNING:LEGACY ID = LEGACY_GTPU_DEBUG + DESC = GTPU legacy logs - debug level + GROUP = GTPU:DEBUG:LEGACY ID = LEGACY_GTPU_TRACE + DESC = GTPU legacy logs - trace level + GROUP = GTPU:TRACE:LEGACY ID = LEGACY_TMR_INFO + DESC = TMR legacy logs - info level + GROUP = TMR:INFO:LEGACY ID = LEGACY_TMR_ERROR + DESC = TMR legacy logs - error level + GROUP = TMR:ERROR:LEGACY ID = LEGACY_TMR_WARNING + DESC = TMR legacy logs - warning level + GROUP = TMR:WARNING:LEGACY ID = LEGACY_TMR_DEBUG + DESC = TMR legacy logs - debug level + GROUP = TMR:DEBUG:LEGACY ID = LEGACY_TMR_TRACE + DESC = TMR legacy logs - trace level + GROUP = TMR:TRACE:LEGACY ID = LEGACY_OSA_INFO + DESC = OSA legacy logs - info level + GROUP = OSA:INFO:LEGACY ID = LEGACY_OSA_ERROR + DESC = OSA legacy logs - error level + GROUP = OSA:ERROR:LEGACY ID = LEGACY_OSA_WARNING + DESC = OSA legacy logs - warning level + GROUP = OSA:WARNING:LEGACY ID = LEGACY_OSA_DEBUG + DESC = OSA legacy logs - debug level + GROUP = OSA:DEBUG:LEGACY ID = LEGACY_OSA_TRACE + DESC = OSA legacy logs - trace level + GROUP = OSA:TRACE:LEGACY # this is a bad hack but I won't fix (function util_print_hex_octets # in openairinterface5g/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c # does funky things with the LOG_x macros but we work on the C pre-processor # level and this funkyness is not easily dealable with, so be it...) ID = LEGACY_component_INFO + DESC = component legacy logs - info level + GROUP = component:INFO:LEGACY ID = LEGACY_component_ERROR + DESC = component legacy logs - error level + GROUP = component:ERROR:LEGACY ID = LEGACY_component_WARNING + DESC = component legacy logs - warning level + GROUP = component:WARNING:LEGACY ID = LEGACY_component_DEBUG + DESC = component legacy logs - debug level + GROUP = component:DEBUG:LEGACY ID = LEGACY_component_TRACE + DESC = component legacy logs - trace level + GROUP = component:TRACE:LEGACY ID = LEGACY_componentP_INFO + DESC = componentP legacy logs - info level + GROUP = componentP:INFO:LEGACY ID = LEGACY_componentP_ERROR + DESC = componentP legacy logs - error level + GROUP = componentP:ERROR:LEGACY ID = LEGACY_componentP_WARNING + DESC = componentP legacy logs - warning level + GROUP = componentP:WARNING:LEGACY ID = LEGACY_componentP_DEBUG + DESC = componentP legacy logs - debug level + GROUP = componentP:DEBUG:LEGACY ID = LEGACY_componentP_TRACE + DESC = componentP legacy logs - trace level + GROUP = componentP:TRACE:LEGACY #needed? ID = LEGACY_CLI_INFO + DESC = CLI legacy logs - info level + GROUP = CLI:INFO:LEGACY ID = LEGACY_CLI_ERROR + DESC = CLI legacy logs - error level + GROUP = CLI:ERROR:LEGACY ID = LEGACY_CLI_WARNING + DESC = CLI legacy logs - warning level + GROUP = CLI:WARNING:LEGACY ID = LEGACY_CLI_DEBUG + DESC = CLI legacy logs - debug level + GROUP = CLI:DEBUG:LEGACY ID = LEGACY_CLI_TRACE + DESC = CLI legacy logs - trace level + GROUP = CLI:TRACE:LEGACY #for debug/test - not used ID = first diff --git a/tracer/database.c b/tracer/database.c index 3172105250..a430d1a696 100644 --- a/tracer/database.c +++ b/tracer/database.c @@ -292,7 +292,7 @@ static void onoff_id(database *d, char *name, int *a, int onoff) i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp); if (i == NULL) return; a[i->id] = onoff; - printf("turning %s %s\n", name, onoff ? "ON" : "OFF"); + printf("turning %s %s\n", onoff ? "ON" : "OFF", name); } static void onoff_group(database *d, char *name, int *a, int onoff) From 2d10951a2ed9d9c6dc312097aca5d4ae9a30f331 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 18 Mar 2016 12:10:49 +0100 Subject: [PATCH 009/217] introduce T_TRACER to globally enable/disable the T --- Makefile | 2 +- T.h | 9 +++++++++ tracer/Makefile | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c65ed27b8e..27e1c8a5c0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wall -g -pthread +CFLAGS=-Wall -g -pthread -DT_TRACER #comment those two lines to NOT use shared memory CFLAGS += -DT_USE_SHARED_MEMORY diff --git a/T.h b/T.h index 46c5bdc180..d88f33a81c 100644 --- a/T.h +++ b/T.h @@ -1,6 +1,8 @@ #ifndef _T_T_T_ #define _T_T_T_ +#if T_TRACER + #include #include "T_defs.h" @@ -517,4 +519,11 @@ extern int *T_active; void T_connect_to_tracer(char *addr, int port); +#else /* T_TRACER */ + +/* if T_TRACER is not defined or is 0, the T is deactivated */ +#define T(...) /**/ + +#endif /* T_TRACER */ + #endif /* _T_T_T_ */ diff --git a/tracer/Makefile b/tracer/Makefile index 23309eb85e..a38ba5c2c6 100644 --- a/tracer/Makefile +++ b/tracer/Makefile @@ -1,7 +1,7 @@ CC=gcc -CFLAGS=-Wall -g -pthread +CFLAGS=-Wall -g -pthread -DT_TRACER -CFLAGS += -O3 -ffast-math -fomit-frame-pointer +#CFLAGS += -O3 -ffast-math -fomit-frame-pointer LIBS=-lX11 -lm From fa49fe6780b575345eeb5487fe60e39a26c74340 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 18 Mar 2016 12:11:42 +0100 Subject: [PATCH 010/217] - add PUSCH/PUCCH plots - update X events management - lock to protect data while plotting (may become a problem in the future) - better naming of dimensions this commit should be cut in small pieces bah --- T_messages.txt | 8 +++ tracer/defs.h | 8 ++- tracer/main.c | 47 ++++++++++++- tracer/plot.c | 176 ++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 204 insertions(+), 35 deletions(-) diff --git a/T_messages.txt b/T_messages.txt index ba6197b569..f954dd46ec 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -7,6 +7,14 @@ ID = ENB_UL_CHANNEL_ESTIMATE DESC = eNodeB channel estimation in the time domain GROUP = PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t +ID = PUSCH_IQ + DESC = eNodeB PUSCH received IQ data + GROUP = PHY:GRAPHIC:HEAVY + FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : buffer,pusch_comp +ID = PUCCH_1AB_IQ + DESC = eNodeB PUCCH received IQ data + GROUP = PHY:GRAPHIC:HEAVY + FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,I : int,Q #legacy logs ID = LEGACY_MAC_INFO diff --git a/tracer/defs.h b/tracer/defs.h index 71b9dd0cfb..873292a70c 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -1,9 +1,15 @@ #ifndef _TRACER_DEFS_H_ #define _TRACER_DEFS_H_ -void *make_plot(int width, int height, int bufsize, char *title); +/* types of plots */ +#define PLOT_VS_TIME 0 +#define PLOT_IQ_POINTS 1 + +void *make_plot(int width, int height, int bufsize, char *title, int type); void plot_set(void *plot, float *data, int len, int pos); void iq_plot_set(void *plot, short *data, int len, int pos); +void iq_plot_set_sized(void *_plot, short *data, int len); +void iq_plot_add_point_loop(void *_plot, short i, short q); /* returns an opaque pointer - truly a 'database *', see t_data.c */ void *parse_database(char *filename); diff --git a/tracer/main.c b/tracer/main.c index 37774be4e5..853ed46fed 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -16,6 +16,8 @@ void *ul_plot; void *chest_plot; +void *pusch_iq_plot; +void *pucch_iq_plot; #ifdef T_USE_SHARED_MEMORY @@ -236,6 +238,44 @@ void get_message(int s) if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0); break; } + case T_PUSCH_IQ: { + unsigned char buf[T_BUFFER_MAX]; + int size; + int eNB, UE, frame, subframe, nb_rb; + GET(s, &eNB, sizeof(int)); + GET(s, &UE, sizeof(int)); + GET(s, &frame, sizeof(int)); + GET(s, &subframe, sizeof(int)); + GET(s, &nb_rb, sizeof(int)); + GET(s, &size, sizeof(int)); + GET(s, buf, size); + if (size != 12*25*14*4) + {printf("bad T_PUSCH_IQ, we want 25 RBs and 14 symbols/TTI\n"); + abort();} + if (pusch_iq_plot) { + uint32_t *src, *dst; + int i, l; + dst = (uint32_t*)buf; + for (l = 0; l < 14; l++) { + src = (uint32_t*)buf + l * 12 * 25; + for (i = 0; i < nb_rb*12; i++) *dst++ = *src++; + } + iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14); + } + break; + } + case T_PUCCH_1AB_IQ: { + int eNB, UE, frame, subframe, I, Q; + GET(s, &eNB, sizeof(int)); + GET(s, &UE, sizeof(int)); + GET(s, &frame, sizeof(int)); + GET(s, &subframe, sizeof(int)); + GET(s, &I, sizeof(int)); + GET(s, &Q, sizeof(int)); +printf("receiving %d %d\n", I, Q); + if (pucch_iq_plot) iq_plot_add_point_loop(pucch_iq_plot, I*10, Q*10); + break; + } case T_buf_test: { unsigned char buf[T_BUFFER_MAX]; int size; @@ -345,8 +385,11 @@ int main(int n, char **v) if (do_dump_database) { dump_database(database); return 0; } if (do_xforms) { - ul_plot = make_plot(512, 100, 7680*2*10, "UL Input Signal"); - chest_plot = make_plot(512, 100, 512*2, "UL Channel Estimate UE 0"); + ul_plot = make_plot(512, 100, 7680*10, "UL Input Signal", PLOT_VS_TIME); + chest_plot = make_plot(512, 100, 512, "UL Channel Estimate UE 0", + PLOT_VS_TIME); + pusch_iq_plot = make_plot(100, 100, 12*25*14, "PUSCH IQ",PLOT_IQ_POINTS); + pucch_iq_plot = make_plot(100, 100, 1000, "PUCCH IQ", PLOT_IQ_POINTS); } for (i = 0; i < on_off_n; i++) diff --git a/tracer/plot.c b/tracer/plot.c index 3cc0ad069f..e13398ab5e 100644 --- a/tracer/plot.c +++ b/tracer/plot.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include typedef struct { Display *d; @@ -15,50 +17,117 @@ typedef struct { int height; float *buf; short *iqbuf; - int bufsize; + int count; + int type; + volatile int iq_count; /* for ULSCH IQ data */ + int iq_insert_pos; + pthread_mutex_t lock; + float zoom; + int timer_pipe[2]; } plot; +static void *timer_thread(void *_p) +{ + plot *p = _p; + char c; + + while (1) { + /* more or less 10Hz */ + usleep(100*1000); + c = 1; + if (write(p->timer_pipe[1], &c, 1) != 1) abort(); + } + + return NULL; +} + static void *plot_thread(void *_p) { float v; float *s; int i, j; plot *p = _p; + int redraw = 0; + int replot = 0; + fd_set rset; + int xfd = ConnectionNumber(p->d); + int maxfd = xfd > p->timer_pipe[0] ? xfd : p->timer_pipe[0]; + while (1) { while (XPending(p->d)) { XEvent e; XNextEvent(p->d, &e); + switch (e.type) { + case ButtonPress: + /* button 4: zoom out */ + if (e.xbutton.button == 4) { p->zoom = p->zoom * 1.25; replot = 1; } + /* button 5: zoom in */ + if (e.xbutton.button == 5) { p->zoom = p->zoom * 0.8; replot = 1; } + printf("zoom: %f\n", p->zoom); + break; + case Expose: redraw = 1; break; + } } - { + if (replot == 1) { + replot = 0; + redraw = 1; + /* TODO: get white & black GCs at startup */ - GC gc; - XGCValues v; - gc = DefaultGC(p->d, DefaultScreen(p->d)); - v.foreground = WhitePixel(p->d, DefaultScreen(p->d)); - XChangeGC(p->d, gc, GCForeground, &v); - XFillRectangle(p->d, p->p, gc, 0, 0, p->width, p->height); - v.foreground = BlackPixel(p->d, DefaultScreen(p->d)); - XChangeGC(p->d, gc, GCForeground, &v); + { + GC gc; + XGCValues v; + gc = DefaultGC(p->d, DefaultScreen(p->d)); + v.foreground = WhitePixel(p->d, DefaultScreen(p->d)); + XChangeGC(p->d, gc, GCForeground, &v); + XFillRectangle(p->d, p->p, gc, 0, 0, p->width, p->height); + v.foreground = BlackPixel(p->d, DefaultScreen(p->d)); + XChangeGC(p->d, gc, GCForeground, &v); + } + + if (pthread_mutex_lock(&p->lock)) abort(); + + if (p->type == PLOT_VS_TIME) { + for (i = 0; i < p->count; i++) + p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+ + p->iqbuf[2*i+1]*p->iqbuf[2*i+1])); + s = p->buf; + for (i = 0; i < 512; i++) { + v = 0; + for (j = 0; j < p->count/512; j++, s++) v += *s; + v /= p->count/512; + XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), + i, 100, i, 100-v); + } + } else if (p->type == PLOT_IQ_POINTS) { + XPoint pts[p->iq_count]; + int count = p->iq_count; + for (i = 0; i < count; i++) { + pts[i].x = p->iqbuf[2*i]*p->zoom/20+50; + pts[i].y = -p->iqbuf[2*i+1]*p->zoom/20+50; + } + XDrawPoints(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), + pts, count, CoordModeOrigin); + } + + if (pthread_mutex_unlock(&p->lock)) abort(); } - { - int i; - for (i = 0; i < p->bufsize/2; i++) - p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+ - p->iqbuf[2*i+1]*p->iqbuf[2*i+1])); - } - s = p->buf; - for (i = 0; i < 512; i++) { - v = 0; - for (j = 0; j < p->bufsize/2/512; j++, s++) v += *s; - v /= p->bufsize/2/512; - XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), i, 100, i, 100-v); + if (redraw) { + redraw = 0; + XCopyArea(p->d, p->p, p->w, DefaultGC(p->d, DefaultScreen(p->d)), + 0, 0, p->width, p->height, 0, 0); } - XCopyArea(p->d, p->p, p->w, DefaultGC(p->d, DefaultScreen(p->d)), - 0, 0, p->width, p->height, 0, 0); - usleep(100*1000); + FD_ZERO(&rset); + FD_SET(p->timer_pipe[0], &rset); + FD_SET(xfd, &rset); + if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) abort(); + if (FD_ISSET(p->timer_pipe[0], &rset)) { + char b[512]; + read(p->timer_pipe[0], b, 512); + replot = 1; + } } return NULL; @@ -73,13 +142,15 @@ static void new_thread(void *(*f)(void *), void *data) { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_attr_setstacksize(&att, 10000000)) + { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } if (pthread_create(&t, &att, f, data)) { fprintf(stderr, "pthread_create err\n"); exit(1); } if (pthread_attr_destroy(&att)) { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } } -void *make_plot(int width, int height, int bufsize, char *title) +void *make_plot(int width, int height, int count, char *title, int type) { plot *p; Display *d; @@ -89,7 +160,7 @@ void *make_plot(int width, int height, int bufsize, char *title) d = XOpenDisplay(0); if (d == NULL) abort(); w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height, 0, WhitePixel(d, DefaultScreen(d)), WhitePixel(d, DefaultScreen(d))); - XSelectInput(d, w, ExposureMask); + XSelectInput(d, w, ExposureMask | ButtonPressMask); XMapWindow(d, w); XStoreName(d, w, title); @@ -99,15 +170,31 @@ void *make_plot(int width, int height, int bufsize, char *title) p = malloc(sizeof(*p)); if (p == NULL) abort(); p->width = width; p->height = height; - p->buf = malloc(sizeof(float) * bufsize); if (p->buf == NULL) abort(); - p->iqbuf = malloc(sizeof(short) * 2 * bufsize); if (p->buf == NULL) abort(); - p->bufsize = bufsize; + if (type == PLOT_VS_TIME) { + p->buf = malloc(sizeof(float) * count); if (p->buf == NULL) abort(); + p->iqbuf = malloc(sizeof(short) * count * 2); if(p->iqbuf==NULL)abort(); + } else { + p->buf = NULL; + p->iqbuf = malloc(sizeof(short) * count * 2); if(p->iqbuf==NULL)abort(); + } + p->count = count; p->d = d; p->w = w; p->p = pm; + p->type = type; + + p->iq_count = 0; + p->iq_insert_pos = 0; + + p->zoom = 1; + + pthread_mutex_init(&p->lock, NULL); + + if (pipe(p->timer_pipe)) abort(); new_thread(plot_thread, p); + new_thread(timer_thread, p); return p; } @@ -115,11 +202,36 @@ void *make_plot(int width, int height, int bufsize, char *title) void plot_set(void *_plot, float *data, int len, int pos) { plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); memcpy(p->buf + pos, data, len * sizeof(float)); + if (pthread_mutex_unlock(&p->lock)) abort(); } -void iq_plot_set(void *_plot, short *data, int len, int pos) +void iq_plot_set(void *_plot, short *data, int count, int pos) { plot *p = _plot; - memcpy(p->iqbuf + pos * 2, data, len * 2 * sizeof(short)); + if (pthread_mutex_lock(&p->lock)) abort(); + memcpy(p->iqbuf + pos * 2, data, count * 2 * sizeof(short)); + if (pthread_mutex_unlock(&p->lock)) abort(); +} + +void iq_plot_set_sized(void *_plot, short *data, int count) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + memcpy(p->iqbuf, data, count * 2 * sizeof(short)); + p->iq_count = count; + if (pthread_mutex_unlock(&p->lock)) abort(); +} + +void iq_plot_add_point_loop(void *_plot, short i, short q) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + p->iqbuf[p->iq_insert_pos*2] = i; + p->iqbuf[p->iq_insert_pos*2+1] = q; + if (p->iq_count != p->count) p->iq_count++; + p->iq_insert_pos++; + if (p->iq_insert_pos == p->count) p->iq_insert_pos = 0; + if (pthread_mutex_unlock(&p->lock)) abort(); } From b168a283a6f363d2c3061779625bb981f00a2635 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 18 Mar 2016 15:12:11 +0100 Subject: [PATCH 011/217] prepare code to handle more than one plot per plot - array of plots - deal with colors --- tracer/defs.h | 11 ++-- tracer/main.c | 21 +++--- tracer/plot.c | 175 +++++++++++++++++++++++++++++++------------------- 3 files changed, 127 insertions(+), 80 deletions(-) diff --git a/tracer/defs.h b/tracer/defs.h index 873292a70c..483e42ae90 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -5,11 +5,12 @@ #define PLOT_VS_TIME 0 #define PLOT_IQ_POINTS 1 -void *make_plot(int width, int height, int bufsize, char *title, int type); -void plot_set(void *plot, float *data, int len, int pos); -void iq_plot_set(void *plot, short *data, int len, int pos); -void iq_plot_set_sized(void *_plot, short *data, int len); -void iq_plot_add_point_loop(void *_plot, short i, short q); +/* ... is { int count; int type; char *color; } for 'nplots' plots */ +void *make_plot(int width, int height, char *title, int nplots, ...); +void plot_set(void *plot, float *data, int len, int pos, int pp); +void iq_plot_set(void *plot, short *data, int len, int pos, int pp); +void iq_plot_set_sized(void *_plot, short *data, int len, int pp); +void iq_plot_add_point_loop(void *_plot, short i, short q, int pp); /* returns an opaque pointer - truly a 'database *', see t_data.c */ void *parse_database(char *filename); diff --git a/tracer/main.c b/tracer/main.c index 853ed46fed..0b529b132b 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -218,7 +218,7 @@ void get_message(int s) #endif if (size != 4 * 7680) {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();} - if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680); + if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680, 0); break; } case T_ENB_UL_CHANNEL_ESTIMATE: { @@ -235,7 +235,7 @@ void get_message(int s) if (size != 512*4) {printf("bad T_ENB_UL_CHANNEL_ESTIMATE, only 512 samples allowed\n"); abort();} - if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0); + if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0, 0); break; } case T_PUSCH_IQ: { @@ -260,7 +260,7 @@ void get_message(int s) src = (uint32_t*)buf + l * 12 * 25; for (i = 0; i < nb_rb*12; i++) *dst++ = *src++; } - iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14); + iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14, 0); } break; } @@ -273,7 +273,7 @@ void get_message(int s) GET(s, &I, sizeof(int)); GET(s, &Q, sizeof(int)); printf("receiving %d %d\n", I, Q); - if (pucch_iq_plot) iq_plot_add_point_loop(pucch_iq_plot, I*10, Q*10); + if (pucch_iq_plot) iq_plot_add_point_loop(pucch_iq_plot, I*10, Q*10, 0); break; } case T_buf_test: { @@ -385,11 +385,14 @@ int main(int n, char **v) if (do_dump_database) { dump_database(database); return 0; } if (do_xforms) { - ul_plot = make_plot(512, 100, 7680*10, "UL Input Signal", PLOT_VS_TIME); - chest_plot = make_plot(512, 100, 512, "UL Channel Estimate UE 0", - PLOT_VS_TIME); - pusch_iq_plot = make_plot(100, 100, 12*25*14, "PUSCH IQ",PLOT_IQ_POINTS); - pucch_iq_plot = make_plot(100, 100, 1000, "PUCCH IQ", PLOT_IQ_POINTS); + ul_plot = make_plot(512, 100, "UL Input Signal", 1, + 7680*10, PLOT_VS_TIME, "blue"); + chest_plot = make_plot(512, 100, "UL Channel Estimate UE 0", 1, + 512, PLOT_VS_TIME, "blue"); + pusch_iq_plot = make_plot(100, 100, "PUSCH IQ", 1, + 12*25*14, PLOT_IQ_POINTS, "blue"); + pucch_iq_plot = make_plot(100, 100, "PUCCH IQ", 1, + 1000, PLOT_IQ_POINTS, "blue"); } for (i = 0; i < on_off_n; i++) diff --git a/tracer/plot.c b/tracer/plot.c index e13398ab5e..bdb864f295 100644 --- a/tracer/plot.c +++ b/tracer/plot.c @@ -8,22 +8,30 @@ #include #include #include +#include typedef struct { - Display *d; - Window w; - Pixmap p; - int width; - int height; float *buf; short *iqbuf; int count; int type; volatile int iq_count; /* for ULSCH IQ data */ int iq_insert_pos; + GC g; +} data; + +typedef struct { + Display *d; + Window w; + Pixmap px; + GC bg; + int width; + int height; pthread_mutex_t lock; float zoom; int timer_pipe[2]; + data *p; /* list of plots */ + int nplots; } plot; static void *timer_thread(void *_p) @@ -52,6 +60,7 @@ static void *plot_thread(void *_p) fd_set rset; int xfd = ConnectionNumber(p->d); int maxfd = xfd > p->timer_pipe[0] ? xfd : p->timer_pipe[0]; + int pp; while (1) { while (XPending(p->d)) { @@ -73,41 +82,31 @@ static void *plot_thread(void *_p) replot = 0; redraw = 1; - /* TODO: get white & black GCs at startup */ - { - GC gc; - XGCValues v; - gc = DefaultGC(p->d, DefaultScreen(p->d)); - v.foreground = WhitePixel(p->d, DefaultScreen(p->d)); - XChangeGC(p->d, gc, GCForeground, &v); - XFillRectangle(p->d, p->p, gc, 0, 0, p->width, p->height); - v.foreground = BlackPixel(p->d, DefaultScreen(p->d)); - XChangeGC(p->d, gc, GCForeground, &v); - } - if (pthread_mutex_lock(&p->lock)) abort(); - if (p->type == PLOT_VS_TIME) { - for (i = 0; i < p->count; i++) - p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+ - p->iqbuf[2*i+1]*p->iqbuf[2*i+1])); - s = p->buf; - for (i = 0; i < 512; i++) { - v = 0; - for (j = 0; j < p->count/512; j++, s++) v += *s; - v /= p->count/512; - XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), - i, 100, i, 100-v); + for (pp = 0; pp < p->nplots; pp++) { + XFillRectangle(p->d, p->px, p->bg, 0, 0, p->width, p->height); + if (p->p[pp].type == PLOT_VS_TIME) { + for (i = 0; i < p->p[pp].count; i++) + p->p[pp].buf[i] = + 10*log10(1.0+(float)(p->p[pp].iqbuf[2*i]*p->p[pp].iqbuf[2*i]+ + p->p[pp].iqbuf[2*i+1]*p->p[pp].iqbuf[2*i+1])); + s = p->p[pp].buf; + for (i = 0; i < 512; i++) { + v = 0; + for (j = 0; j < p->p[pp].count/512; j++, s++) v += *s; + v /= p->p[pp].count/512; + XDrawLine(p->d, p->px, p->p[pp].g, i, 100, i, 100-v); + } + } else if (p->p[pp].type == PLOT_IQ_POINTS) { + XPoint pts[p->p[pp].iq_count]; + int count = p->p[pp].iq_count; + for (i = 0; i < count; i++) { + pts[i].x = p->p[pp].iqbuf[2*i]*p->zoom/20+50; + pts[i].y = -p->p[pp].iqbuf[2*i+1]*p->zoom/20+50; + } + XDrawPoints(p->d, p->px, p->p[pp].g, pts, count, CoordModeOrigin); } - } else if (p->type == PLOT_IQ_POINTS) { - XPoint pts[p->iq_count]; - int count = p->iq_count; - for (i = 0; i < count; i++) { - pts[i].x = p->iqbuf[2*i]*p->zoom/20+50; - pts[i].y = -p->iqbuf[2*i+1]*p->zoom/20+50; - } - XDrawPoints(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), - pts, count, CoordModeOrigin); } if (pthread_mutex_unlock(&p->lock)) abort(); @@ -115,7 +114,7 @@ static void *plot_thread(void *_p) if (redraw) { redraw = 0; - XCopyArea(p->d, p->p, p->w, DefaultGC(p->d, DefaultScreen(p->d)), + XCopyArea(p->d, p->px, p->w, DefaultGC(p->d, DefaultScreen(p->d)), 0, 0, p->width, p->height, 0, 0); } @@ -125,7 +124,7 @@ static void *plot_thread(void *_p) if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) abort(); if (FD_ISSET(p->timer_pipe[0], &rset)) { char b[512]; - read(p->timer_pipe[0], b, 512); + if (read(p->timer_pipe[0], b, 512) <= 0) abort(); replot = 1; } } @@ -150,12 +149,17 @@ static void new_thread(void *(*f)(void *), void *data) { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } } -void *make_plot(int width, int height, int count, char *title, int type) +void *make_plot(int width, int height, char *title, int nplots, ...) { plot *p; Display *d; Window w; Pixmap pm; + int i; + va_list ap; + XGCValues gcv; + + p = malloc(sizeof(*p)); if (p == NULL) abort(); d = XOpenDisplay(0); if (d == NULL) abort(); w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height, @@ -163,31 +167,70 @@ void *make_plot(int width, int height, int count, char *title, int type) XSelectInput(d, w, ExposureMask | ButtonPressMask); XMapWindow(d, w); + { + XSetWindowAttributes att; + att.backing_store = Always; + XChangeWindowAttributes(d, w, CWBackingStore, &att); + } + XStoreName(d, w, title); + p->bg = XCreateGC(d, w, 0, NULL); + XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->bg); + gcv.foreground = WhitePixel(d, DefaultScreen(d)); + XChangeGC(d, p->bg, GCForeground, &gcv); + pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d))); - p = malloc(sizeof(*p)); if (p == NULL) abort(); p->width = width; p->height = height; - if (type == PLOT_VS_TIME) { - p->buf = malloc(sizeof(float) * count); if (p->buf == NULL) abort(); - p->iqbuf = malloc(sizeof(short) * count * 2); if(p->iqbuf==NULL)abort(); - } else { - p->buf = NULL; - p->iqbuf = malloc(sizeof(short) * count * 2); if(p->iqbuf==NULL)abort(); + p->p = malloc(nplots * sizeof(data)); if (p->p == NULL) abort(); + + va_start(ap, nplots); + for (i = 0; i < nplots; i++) { + int count; + int type; + char *color; + XColor rcol, scol; + + count = va_arg(ap, int); + type = va_arg(ap, int); + color = va_arg(ap, char *); + + p->p[i].g = XCreateGC(d, w, 0, NULL); + XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->p[i].g); + if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)), + color, &scol, &rcol)) { + gcv.foreground = scol.pixel; + XChangeGC(d, p->p[i].g, GCForeground, &gcv); + } else { + printf("could not allocate color '%s'\n", color); + abort(); + } + + if (type == PLOT_VS_TIME) { + p->p[i].buf = malloc(sizeof(float) * count); + if (p->p[i].buf == NULL) abort(); + p->p[i].iqbuf = malloc(sizeof(short) * count * 2); + if(p->p[i].iqbuf==NULL)abort(); + } else { + p->p[i].buf = NULL; + p->p[i].iqbuf = malloc(sizeof(short) * count * 2); + if(p->p[i].iqbuf==NULL)abort(); + } + p->p[i].count = count; + p->p[i].type = type; + p->p[i].iq_count = 0; + p->p[i].iq_insert_pos = 0; } - p->count = count; + va_end(ap); p->d = d; p->w = w; - p->p = pm; - p->type = type; - - p->iq_count = 0; - p->iq_insert_pos = 0; + p->px = pm; p->zoom = 1; + p->nplots = nplots; pthread_mutex_init(&p->lock, NULL); @@ -199,39 +242,39 @@ void *make_plot(int width, int height, int count, char *title, int type) return p; } -void plot_set(void *_plot, float *data, int len, int pos) +void plot_set(void *_plot, float *data, int len, int pos, int pp) { plot *p = _plot; if (pthread_mutex_lock(&p->lock)) abort(); - memcpy(p->buf + pos, data, len * sizeof(float)); + memcpy(p->p[pp].buf + pos, data, len * sizeof(float)); if (pthread_mutex_unlock(&p->lock)) abort(); } -void iq_plot_set(void *_plot, short *data, int count, int pos) +void iq_plot_set(void *_plot, short *data, int count, int pos, int pp) { plot *p = _plot; if (pthread_mutex_lock(&p->lock)) abort(); - memcpy(p->iqbuf + pos * 2, data, count * 2 * sizeof(short)); + memcpy(p->p[pp].iqbuf + pos * 2, data, count * 2 * sizeof(short)); if (pthread_mutex_unlock(&p->lock)) abort(); } -void iq_plot_set_sized(void *_plot, short *data, int count) +void iq_plot_set_sized(void *_plot, short *data, int count, int pp) { plot *p = _plot; if (pthread_mutex_lock(&p->lock)) abort(); - memcpy(p->iqbuf, data, count * 2 * sizeof(short)); - p->iq_count = count; + memcpy(p->p[pp].iqbuf, data, count * 2 * sizeof(short)); + p->p[pp].iq_count = count; if (pthread_mutex_unlock(&p->lock)) abort(); } -void iq_plot_add_point_loop(void *_plot, short i, short q) +void iq_plot_add_point_loop(void *_plot, short i, short q, int pp) { plot *p = _plot; if (pthread_mutex_lock(&p->lock)) abort(); - p->iqbuf[p->iq_insert_pos*2] = i; - p->iqbuf[p->iq_insert_pos*2+1] = q; - if (p->iq_count != p->count) p->iq_count++; - p->iq_insert_pos++; - if (p->iq_insert_pos == p->count) p->iq_insert_pos = 0; + p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2] = i; + p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2+1] = q; + if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++; + p->p[pp].iq_insert_pos++; + if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0; if (pthread_mutex_unlock(&p->lock)) abort(); } From 26a5da6cef019ee2b346f94568d057e7c3920113 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 18 Mar 2016 15:13:21 +0100 Subject: [PATCH 012/217] bugfix yes you need this xflush before sleeping into select... --- tracer/plot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tracer/plot.c b/tracer/plot.c index bdb864f295..e9aa57a5d2 100644 --- a/tracer/plot.c +++ b/tracer/plot.c @@ -118,6 +118,8 @@ static void *plot_thread(void *_p) 0, 0, p->width, p->height, 0, 0); } + XFlush(p->d); + FD_ZERO(&rset); FD_SET(p->timer_pipe[0], &rset); FD_SET(xfd, &rset); From 9e083707624636bf3f5e58c6a5baf74d5655dedb Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 18 Mar 2016 19:05:16 +0100 Subject: [PATCH 013/217] add pucch energy plot --- T_messages.txt | 4 ++++ tracer/defs.h | 4 +++- tracer/main.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- tracer/plot.c | 33 ++++++++++++++++++++++++++++++--- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/T_messages.txt b/T_messages.txt index f954dd46ec..dd5dd8eec1 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -15,6 +15,10 @@ ID = PUCCH_1AB_IQ DESC = eNodeB PUCCH received IQ data GROUP = PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,I : int,Q +ID = PUCCH_1_ENERGY + DESC = eNodeB PUCCH 1 energy and threshold + GROUP = PHY:GRAPHIC:HEAVY + FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold #legacy logs ID = LEGACY_MAC_INFO diff --git a/tracer/defs.h b/tracer/defs.h index 483e42ae90..231255b46d 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -4,13 +4,15 @@ /* types of plots */ #define PLOT_VS_TIME 0 #define PLOT_IQ_POINTS 1 +#define PLOT_MINMAX 2 /* ... is { int count; int type; char *color; } for 'nplots' plots */ void *make_plot(int width, int height, char *title, int nplots, ...); void plot_set(void *plot, float *data, int len, int pos, int pp); void iq_plot_set(void *plot, short *data, int len, int pos, int pp); void iq_plot_set_sized(void *_plot, short *data, int len, int pp); -void iq_plot_add_point_loop(void *_plot, short i, short q, int pp); +void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp); +void iq_plot_add_energy_point_loop(void *_plot, int e, int pp); /* returns an opaque pointer - truly a 'database *', see t_data.c */ void *parse_database(char *filename); diff --git a/tracer/main.c b/tracer/main.c index 0b529b132b..cedad0079d 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "defs.h" @@ -14,10 +15,14 @@ #include "../T_IDs.h" #include "../T_defs.h" +#define BLUE "#0c0c72" +#define RED "#d72828" + void *ul_plot; void *chest_plot; void *pusch_iq_plot; void *pucch_iq_plot; +void *pucch_plot; #ifdef T_USE_SHARED_MEMORY @@ -213,8 +218,12 @@ void get_message(int s) GET(s, &size, sizeof(int)); GET(s, buf, size); #if 0 - printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna %d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); + printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna " + "%d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x " + "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2], + buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10], + buf[11],buf[12],buf[13],buf[14],buf[15]); #endif if (size != 4 * 7680) {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();} @@ -272,8 +281,22 @@ void get_message(int s) GET(s, &subframe, sizeof(int)); GET(s, &I, sizeof(int)); GET(s, &Q, sizeof(int)); -printf("receiving %d %d\n", I, Q); - if (pucch_iq_plot) iq_plot_add_point_loop(pucch_iq_plot, I*10, Q*10, 0); + if (pucch_iq_plot) iq_plot_add_iq_point_loop(pucch_iq_plot,I*10,Q*10, 0); + break; + } + case T_PUCCH_1_ENERGY: { + int eNB, UE, frame, subframe, e, t; + GET(s, &eNB, sizeof(int)); + GET(s, &UE, sizeof(int)); + GET(s, &frame, sizeof(int)); + GET(s, &subframe, sizeof(int)); + GET(s, &e, sizeof(int)); + GET(s, &t, sizeof(int)); +//printf("t %d e %d\n", t, (int)(10*log10(e))); + if (pucch_plot) { + iq_plot_add_energy_point_loop(pucch_plot, t, 0); + iq_plot_add_energy_point_loop(pucch_plot, 10*log10(e), 1); + } break; } case T_buf_test: { @@ -281,8 +304,10 @@ printf("receiving %d %d\n", I, Q); int size; GET(s, &size, sizeof(int)); GET(s, buf, size); - printf("got buffer size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); + printf("got buffer size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x" + " %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7], + buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); break; } default: printf("unkown message type %d\n", m); abort(); @@ -386,13 +411,18 @@ int main(int n, char **v) if (do_xforms) { ul_plot = make_plot(512, 100, "UL Input Signal", 1, - 7680*10, PLOT_VS_TIME, "blue"); + 7680*10, PLOT_VS_TIME, BLUE); chest_plot = make_plot(512, 100, "UL Channel Estimate UE 0", 1, - 512, PLOT_VS_TIME, "blue"); + 512, PLOT_VS_TIME, BLUE); pusch_iq_plot = make_plot(100, 100, "PUSCH IQ", 1, - 12*25*14, PLOT_IQ_POINTS, "blue"); + 12*25*14, PLOT_IQ_POINTS, BLUE); pucch_iq_plot = make_plot(100, 100, "PUCCH IQ", 1, - 1000, PLOT_IQ_POINTS, "blue"); + 1000, PLOT_IQ_POINTS, BLUE); + pucch_plot = make_plot(512, 100, "PUCCH 1 energy (SR)", 2, + /* threshold */ + 10240, PLOT_MINMAX, RED, + /* pucch 1 */ + 10240, PLOT_MINMAX, BLUE); } for (i = 0; i < on_off_n; i++) diff --git a/tracer/plot.c b/tracer/plot.c index e9aa57a5d2..58f25fd41c 100644 --- a/tracer/plot.c +++ b/tracer/plot.c @@ -84,9 +84,21 @@ static void *plot_thread(void *_p) if (pthread_mutex_lock(&p->lock)) abort(); + XFillRectangle(p->d, p->px, p->bg, 0, 0, p->width, p->height); + for (pp = 0; pp < p->nplots; pp++) { - XFillRectangle(p->d, p->px, p->bg, 0, 0, p->width, p->height); - if (p->p[pp].type == PLOT_VS_TIME) { + if (p->p[pp].type == PLOT_MINMAX) { + s = p->p[pp].buf; + for (i = 0; i < 512; i++) { + int min = *s; + int max = *s; + for (j = 0; j < p->p[pp].count/512; j++, s++) { + if (*s < min) min = *s; + if (*s > max) max = *s; + } + XDrawLine(p->d, p->px, p->p[pp].g, i, 100-min, i, 100-max); + } + } else if (p->p[pp].type == PLOT_VS_TIME) { for (i = 0; i < p->p[pp].count; i++) p->p[pp].buf[i] = 10*log10(1.0+(float)(p->p[pp].iqbuf[2*i]*p->p[pp].iqbuf[2*i]+ @@ -215,6 +227,10 @@ void *make_plot(int width, int height, char *title, int nplots, ...) if (p->p[i].buf == NULL) abort(); p->p[i].iqbuf = malloc(sizeof(short) * count * 2); if(p->p[i].iqbuf==NULL)abort(); + } else if (type == PLOT_MINMAX) { + p->p[i].buf = malloc(sizeof(float) * count); + if (p->p[i].buf == NULL) abort(); + p->p[i].iqbuf = NULL; } else { p->p[i].buf = NULL; p->p[i].iqbuf = malloc(sizeof(short) * count * 2); @@ -269,7 +285,7 @@ void iq_plot_set_sized(void *_plot, short *data, int count, int pp) if (pthread_mutex_unlock(&p->lock)) abort(); } -void iq_plot_add_point_loop(void *_plot, short i, short q, int pp) +void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp) { plot *p = _plot; if (pthread_mutex_lock(&p->lock)) abort(); @@ -280,3 +296,14 @@ void iq_plot_add_point_loop(void *_plot, short i, short q, int pp) if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0; if (pthread_mutex_unlock(&p->lock)) abort(); } + +void iq_plot_add_energy_point_loop(void *_plot, int e, int pp) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + p->p[pp].buf[p->p[pp].iq_insert_pos] = e; + if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++; + p->p[pp].iq_insert_pos++; + if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0; + if (pthread_mutex_unlock(&p->lock)) abort(); +} From e11728a83bf16e002aad0b9c8077395fbcd1cdfb Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 19 Mar 2016 19:06:01 +0100 Subject: [PATCH 014/217] - make it work with oaisim - add global ON/OFF command line options (OFF is useless but just for completeness) --- T_messages.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++++ tracer/database.c | 9 ++++++++- tracer/main.c | 13 ++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/T_messages.txt b/T_messages.txt index dd5dd8eec1..4c6f6e7aca 100644 --- a/T_messages.txt +++ b/T_messages.txt @@ -69,6 +69,22 @@ ID = LEGACY_S1AP_TRACE DESC = S1AP legacy logs - trace level GROUP = S1AP:TRACE:LEGACY +ID = LEGACY_X2AP_INFO + DESC = X2AP legacy logs - info level + GROUP = X2AP:INFO:LEGACY +ID = LEGACY_X2AP_ERROR + DESC = X2AP legacy logs - error level + GROUP = X2AP:ERROR:LEGACY +ID = LEGACY_X2AP_WARNING + DESC = X2AP legacy logs - warning level + GROUP = X2AP:WARNING:LEGACY +ID = LEGACY_X2AP_DEBUG + DESC = X2AP legacy logs - debug level + GROUP = X2AP:DEBUG:LEGACY +ID = LEGACY_X2AP_TRACE + DESC = X2AP legacy logs - trace level + GROUP = X2AP:TRACE:LEGACY + ID = LEGACY_RRC_INFO DESC = RRC legacy logs - info level GROUP = RRC:INFO:LEGACY @@ -245,6 +261,38 @@ ID = LEGACY_OCG_TRACE DESC = OCG legacy logs - trace level GROUP = OCG:TRACE:LEGACY +ID = LEGACY_OCM_INFO + DESC = OCM legacy logs - info level + GROUP = OCM:INFO:LEGACY +ID = LEGACY_OCM_ERROR + DESC = OCM legacy logs - error level + GROUP = OCM:ERROR:LEGACY +ID = LEGACY_OCM_WARNING + DESC = OCM legacy logs - warning level + GROUP = OCM:WARNING:LEGACY +ID = LEGACY_OCM_DEBUG + DESC = OCM legacy logs - debug level + GROUP = OCM:DEBUG:LEGACY +ID = LEGACY_OCM_TRACE + DESC = OCM legacy logs - trace level + GROUP = OCM:TRACE:LEGACY + +ID = LEGACY_OIP_INFO + DESC = OIP legacy logs - info level + GROUP = OIP:INFO:LEGACY +ID = LEGACY_OIP_ERROR + DESC = OIP legacy logs - error level + GROUP = OIP:ERROR:LEGACY +ID = LEGACY_OIP_WARNING + DESC = OIP legacy logs - warning level + GROUP = OIP:WARNING:LEGACY +ID = LEGACY_OIP_DEBUG + DESC = OIP legacy logs - debug level + GROUP = OIP:DEBUG:LEGACY +ID = LEGACY_OIP_TRACE + DESC = OIP legacy logs - trace level + GROUP = OIP:TRACE:LEGACY + ID = LEGACY_OMG_INFO DESC = OMG legacy logs - info level GROUP = OMG:INFO:LEGACY diff --git a/tracer/database.c b/tracer/database.c index a430d1a696..5039deff5a 100644 --- a/tracer/database.c +++ b/tracer/database.c @@ -304,8 +304,15 @@ static void onoff_group(database *d, char *name, int *a, int onoff) for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff); } -void on_off(void *d, char *item, int *a, int onoff) +void on_off(void *_d, char *item, int *a, int onoff) { + database *d = _d; + int i; + if (item == NULL) { + for (i = 0; i < d->isize; i++) a[i] = onoff; + printf("turning %s all traces\n", onoff ? "ON" : "OFF"); + return; + } onoff_group(d, item, a, onoff); onoff_id(d, item, a, onoff); } diff --git a/tracer/main.c b/tracer/main.c index cedad0079d..de0523673b 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -172,6 +172,11 @@ void get_message(int s) case T_LEGACY_OCG_WARNING: S("OCG", "WARNING"); break; case T_LEGACY_OCG_DEBUG: S("OCG", "DEBUG"); break; case T_LEGACY_OCG_TRACE: S("OCG", "TRACE"); break; + case T_LEGACY_OCM_INFO: S("OCM", "INFO"); break; + case T_LEGACY_OCM_ERROR: S("OCM", "ERROR"); break; + case T_LEGACY_OCM_WARNING: S("OCM", "WARNING"); break; + case T_LEGACY_OCM_DEBUG: S("OCM", "DEBUG"); break; + case T_LEGACY_OCM_TRACE: S("OCM", "TRACE"); break; case T_LEGACY_OMG_INFO: S("OMG", "INFO"); break; case T_LEGACY_OMG_ERROR: S("OMG", "ERROR"); break; case T_LEGACY_OMG_WARNING: S("OMG", "WARNING"); break; @@ -353,7 +358,9 @@ void usage(void) " -x run with XFORMS (revisited)\n" " -on turn log ON for given GROUP or ID\n" " -off turn log OFF for given GROUP or ID\n" -"note: you may pass several -on and -off, they will be processed in order\n" +" -ON turn all logs ON\n" +" -OFF turn all logs OFF\n" +"note: you may pass several -on/-off/-ON/-OFF, they will be processed in order\n" " by default, all is off\n" ); exit(1); @@ -393,6 +400,10 @@ int main(int n, char **v) on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-ON")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-OFF")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } printf("ERROR: unknown option %s\n", v[i]); usage(); } From ef289848abc7cf81dc2a3419aa0180b3b07010b5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 19 Mar 2016 19:09:12 +0100 Subject: [PATCH 015/217] - add OIP traces - oaisim generates one of it at the end --- tracer/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tracer/main.c b/tracer/main.c index de0523673b..31f5d54171 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -182,6 +182,11 @@ void get_message(int s) case T_LEGACY_OMG_WARNING: S("OMG", "WARNING"); break; case T_LEGACY_OMG_DEBUG: S("OMG", "DEBUG"); break; case T_LEGACY_OMG_TRACE: S("OMG", "TRACE"); break; + case T_LEGACY_OIP_INFO: S("OIP", "INFO"); break; + case T_LEGACY_OIP_ERROR: S("OIP", "ERROR"); break; + case T_LEGACY_OIP_WARNING: S("OIP", "WARNING"); break; + case T_LEGACY_OIP_DEBUG: S("OIP", "DEBUG"); break; + case T_LEGACY_OIP_TRACE: S("OIP", "TRACE"); break; case T_LEGACY_GTPU_INFO: S("GTPU", "INFO"); break; case T_LEGACY_GTPU_ERROR: S("GTPU", "ERROR"); break; case T_LEGACY_GTPU_WARNING: S("GTPU", "WARNING"); break; From 2bd870afdcfc8872e1a116af6fa7315dbe0c74e6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 19 Mar 2016 22:40:20 +0100 Subject: [PATCH 016/217] - read may return partial content from a socket, deal with that --- tracer/main.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tracer/main.c b/tracer/main.c index 31f5d54171..1a30bbef95 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -44,7 +44,22 @@ static inline int GET(int s, void *out, int count) #else /* T_USE_SHARED_MEMORY */ -#define GET read +#define GET fullread + +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) { printf("read socket problem\n"); abort(); } + count -= l; + buf += l; + ret += l; + } + return ret; +} #endif /* T_USE_SHARED_MEMORY */ @@ -236,7 +251,8 @@ void get_message(int s) buf[11],buf[12],buf[13],buf[14],buf[15]); #endif if (size != 4 * 7680) - {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();} + {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed " + "(received %d bytes = %d samples)\n", size, size/4);abort();} if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680, 0); break; } From ee5d8c60fb8e614d85c28d7e1cf5cba4e42345d7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 19 Mar 2016 23:52:09 +0100 Subject: [PATCH 017/217] prepare forwarder --- T.h | 13 +++++++++++ tracer/Makefile | 2 +- tracer/defs.h | 3 +++ tracer/forward.c | 10 +++++++++ tracer/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 tracer/forward.c diff --git a/T.h b/T.h index d88f33a81c..405594f2d4 100644 --- a/T.h +++ b/T.h @@ -115,11 +115,24 @@ extern T_cache_t *T_cache; #define T_ACTIVE(x) T_active[(intptr_t)x] +#ifdef T_USE_SHARED_MEMORY + #define T_SEND() \ T_cache[T_LOCAL_slot].busy = 1; \ T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ T_send(T_LOCAL_buf, T_LOCAL_size) +#else /* T_USE_SHARED_MEMORY */ + +/* when not using shared memory, wait for send to finish */ +#define T_SEND() \ + T_cache[T_LOCAL_slot].busy = 1; \ + T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ + T_send(T_LOCAL_buf, T_LOCAL_size); \ + while (T_cache[T_LOCAL_slot].busy) usleep(1*1000) + +#endif /* T_USE_SHARED_MEMORY */ + #define T_CHECK_SIZE(len, argnum) \ if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \ printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ diff --git a/tracer/Makefile b/tracer/Makefile index a38ba5c2c6..093acfbe3c 100644 --- a/tracer/Makefile +++ b/tracer/Makefile @@ -10,7 +10,7 @@ CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer -OBJS=main.o plot.o database.o +OBJS=main.o plot.o database.o forward.o $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) diff --git a/tracer/defs.h b/tracer/defs.h index 231255b46d..d9074d35d7 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -21,4 +21,7 @@ void list_ids(void *database); void list_groups(void *database); void on_off(void *d, char *item, int *a, int onoff); +void *forwarder(char *ip, int port); +void forward(void *forwarder, char *buf, int size); + #endif /* _TRACER_DEFS_H_ */ diff --git a/tracer/forward.c b/tracer/forward.c new file mode 100644 index 0000000000..77ee156751 --- /dev/null +++ b/tracer/forward.c @@ -0,0 +1,10 @@ +#include "defs.h" + +void *forwarder(char *ip, int port) +{ + return 0; +} + +void forward(void *_fowarder, char *buf, int size) +{ +} diff --git a/tracer/main.c b/tracer/main.c index 1a30bbef95..ba6dc043c3 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -371,7 +371,7 @@ void init_shm(void) void usage(void) { printf( -"options:\n" +"common options:\n" " -d this option is mandatory\n" " -li print IDs in the database\n" " -lg print GROUPs in the database\n" @@ -383,6 +383,10 @@ void usage(void) " -OFF turn all logs OFF\n" "note: you may pass several -on/-off/-ON/-OFF, they will be processed in order\n" " by default, all is off\n" +"\n" +"remote mode options: in this mode you run a local tracer and a remote one\n" +" -r remote side\n" +" -l local side (forwards packets to remote IP:port)\n" ); exit(1); } @@ -403,6 +407,13 @@ int main(int n, char **v) int *on_off_action; int on_off_n = 0; int is_on[T_NUMBER_OF_IDS]; + int remote_local = 0; + int remote_remote = 0; + char *remote_ip = NULL; + int remote_port = -1; +#ifdef T_USE_SHARED_MEMORY + void *f; +#endif memset(is_on, 0, sizeof(is_on)); @@ -425,10 +436,43 @@ int main(int n, char **v) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } if (!strcmp(v[i], "-OFF")) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-r")) { remote_remote = 1; continue; } + if (!strcmp(v[i], "-l")) { if (i > n-3) usage(); remote_local = 1; + remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } printf("ERROR: unknown option %s\n", v[i]); usage(); } +#ifndef T_USE_SHARED_MEMORY + /* gcc shut up */ + (void)remote_port; + (void)remote_ip; +#endif + +#ifdef T_USE_SHARED_MEMORY + if (remote_remote) { + printf("ERROR: remote 'remote side' does not run with shared memory\n"); + printf("recompile without T_USE_SHARED_MEMORY (edit Makefile)\n"); + exit(1); + } +#endif + + if (remote_remote) { + /* TODO: setup 'secure' connection with remote part */ + } + +#ifndef T_USE_SHARED_MEMORY + if (remote_local) { + printf("ERROR: remote 'local side' does not run without shared memory\n"); + printf("recompile with T_USE_SHARED_MEMORY (edit Makefile)\n"); + exit(1); + } +#endif + +#ifdef T_USE_SHARED_MEMORY + if (remote_local) f = forwarder(remote_ip, remote_port); +#endif + if (database_filename == NULL) { printf("ERROR: provide a database file (-d)\n"); exit(1); @@ -479,6 +523,18 @@ int main(int n, char **v) #ifdef T_USE_SHARED_MEMORY wait_message(); #endif + +#ifdef T_USE_SHARED_MEMORY + if (remote_local) { + forward(f, T_cache[T_busylist_head].buffer, + T_cache[T_busylist_head].length); + T_cache[T_busylist_head].busy = 0; + T_busylist_head++; + T_busylist_head &= T_CACHE_SIZE - 1; + continue; + } +#endif + get_message(s); } return 0; From cb2454cca3bbe3aaacafdf2ee02a068611885fd2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 20 Mar 2016 00:23:15 +0100 Subject: [PATCH 018/217] first version of forwarder to be redone (the local tracer shall not configure the tracee by itself but only forward what the remote tracer sends) --- tracer/forward.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tracer/forward.c b/tracer/forward.c index 77ee156751..9e0df61fbf 100644 --- a/tracer/forward.c +++ b/tracer/forward.c @@ -1,10 +1,42 @@ #include "defs.h" +#include +#include +#include +#include +#include + +typedef struct { + int s; +} forward_data; void *forwarder(char *ip, int port) { - return 0; + forward_data *f; + struct sockaddr_in a; + + f = malloc(sizeof(*f)); if (f == NULL) abort(); + + f->s = socket(AF_INET, SOCK_STREAM, 0); + if (f->s == -1) { perror("socket"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(ip); + + if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) + { perror("connect"); exit(1); } + + return f; } -void forward(void *_fowarder, char *buf, int size) +void forward(void *_forwarder, char *buf, int size) { + forward_data *f = _forwarder; + + while (size) { + int l = write(f->s, buf, size); + if (l <= 0) { printf("forward error\n"); exit(1); } + size -= l; + buf += l; + } } From 8ca955f371f0f82d4425bc63e25ae286b403c040 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 20 Mar 2016 19:44:57 +0100 Subject: [PATCH 019/217] better forwarder --- tracer/defs.h | 3 +++ tracer/forward.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ tracer/main.c | 37 +++++++++++++++++++++++++++++--- tracer/plot.c | 18 ---------------- 4 files changed, 92 insertions(+), 21 deletions(-) diff --git a/tracer/defs.h b/tracer/defs.h index d9074d35d7..69b379ce0b 100644 --- a/tracer/defs.h +++ b/tracer/defs.h @@ -6,6 +6,8 @@ #define PLOT_IQ_POINTS 1 #define PLOT_MINMAX 2 +void new_thread(void *(*f)(void *), void *data); + /* ... is { int count; int type; char *color; } for 'nplots' plots */ void *make_plot(int width, int height, char *title, int nplots, ...); void plot_set(void *plot, float *data, int len, int pos, int pp); @@ -23,5 +25,6 @@ void on_off(void *d, char *item, int *a, int onoff); void *forwarder(char *ip, int port); void forward(void *forwarder, char *buf, int size); +void forward_start_client(void *forwarder, int socket); #endif /* _TRACER_DEFS_H_ */ diff --git a/tracer/forward.c b/tracer/forward.c index 9e0df61fbf..cfb837f9e5 100644 --- a/tracer/forward.c +++ b/tracer/forward.c @@ -4,11 +4,60 @@ #include #include #include +#include typedef struct { int s; + int sc; + pthread_mutex_t lock; } forward_data; +static void do_forward(forward_data *f, int from, int to, int lock) +{ + int l, len; + char *b; + char buf[1024]; + while (1) { + len = read(from, buf, 1024); + if (len <= 0) break; + b = buf; + + if (lock) if (pthread_mutex_lock(&f->lock)) abort(); + + while (len) { + l = write(to, b, len); + if (l <= 0) break; + len -= l; + b += l; + } + + if (lock) if (pthread_mutex_unlock(&f->lock)) abort(); + } +} + +static void *forward_s_to_sc(void *_f) +{ + forward_data *f = _f; + do_forward(f, f->s, f->sc, 0); + return NULL; +} + +static void *forward_sc_to_s(void *_f) +{ + forward_data *f = _f; + do_forward(f, f->sc, f->s, 1); + printf("INFO: forwarder exits\n"); + return NULL; +} + +void forward_start_client(void *_f, int s) +{ + forward_data *f = _f; + f->sc = s; + new_thread(forward_s_to_sc, f); + new_thread(forward_sc_to_s, f); +} + void *forwarder(char *ip, int port) { forward_data *f; @@ -16,6 +65,8 @@ void *forwarder(char *ip, int port) f = malloc(sizeof(*f)); if (f == NULL) abort(); + pthread_mutex_init(&f->lock, NULL); + f->s = socket(AF_INET, SOCK_STREAM, 0); if (f->s == -1) { perror("socket"); exit(1); } @@ -33,10 +84,14 @@ void forward(void *_forwarder, char *buf, int size) { forward_data *f = _forwarder; + if (pthread_mutex_lock(&f->lock)) abort(); + while (size) { int l = write(f->s, buf, size); if (l <= 0) { printf("forward error\n"); exit(1); } size -= l; buf += l; } + + if (pthread_mutex_unlock(&f->lock)) abort(); } diff --git a/tracer/main.c b/tracer/main.c index ba6dc043c3..317644f5a5 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "defs.h" @@ -368,6 +369,23 @@ void init_shm(void) #endif /* T_USE_SHARED_MEMORY */ +void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_attr_setstacksize(&att, 10000000)) + { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + void usage(void) { printf( @@ -473,6 +491,8 @@ int main(int n, char **v) if (remote_local) f = forwarder(remote_ip, remote_port); #endif + if (remote_local) goto no_database; + if (database_filename == NULL) { printf("ERROR: provide a database file (-d)\n"); exit(1); @@ -485,6 +505,10 @@ int main(int n, char **v) if (do_list_groups) { list_groups(database); return 0; } if (do_dump_database) { dump_database(database); return 0; } + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); + +no_database: if (do_xforms) { ul_plot = make_plot(512, 100, "UL Input Signal", 1, 7680*10, PLOT_VS_TIME, BLUE); @@ -501,13 +525,18 @@ int main(int n, char **v) 10240, PLOT_MINMAX, BLUE); } - for (i = 0; i < on_off_n; i++) - on_off(database, on_off_name[i], is_on, on_off_action[i]); - #ifdef T_USE_SHARED_MEMORY init_shm(); #endif s = get_connection("127.0.0.1", 2020); + + if (remote_local) { +#ifdef T_USE_SHARED_MEMORY + forward_start_client(f, s); +#endif + goto no_init_message; + } + /* send the first message - activate all traces */ t = 0; if (write(s, &t, 1) != 1) abort(); @@ -518,6 +547,8 @@ int main(int n, char **v) if (is_on[l]) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); +no_init_message: + /* read messages */ while (1) { #ifdef T_USE_SHARED_MEMORY diff --git a/tracer/plot.c b/tracer/plot.c index 58f25fd41c..7447384288 100644 --- a/tracer/plot.c +++ b/tracer/plot.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -146,23 +145,6 @@ static void *plot_thread(void *_p) return NULL; } -static void new_thread(void *(*f)(void *), void *data) -{ - pthread_t t; - pthread_attr_t att; - - if (pthread_attr_init(&att)) - { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } - if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) - { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } - if (pthread_attr_setstacksize(&att, 10000000)) - { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } - if (pthread_create(&t, &att, f, data)) - { fprintf(stderr, "pthread_create err\n"); exit(1); } - if (pthread_attr_destroy(&att)) - { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } -} - void *make_plot(int width, int height, char *title, int nplots, ...) { plot *p; From f846a9e564a15997d67bae02fa7fd196fed26f40 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 20 Mar 2016 21:22:56 +0100 Subject: [PATCH 020/217] forwarder uses a list to store messages better in case of slow link between local and remote tracers may smoke lots of memory though --- tracer/forward.c | 75 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/tracer/forward.c b/tracer/forward.c index cfb837f9e5..b982a89027 100644 --- a/tracer/forward.c +++ b/tracer/forward.c @@ -5,13 +5,61 @@ #include #include #include +#include + +typedef struct databuf { + char *d; + int l; + struct databuf *next; +} databuf; typedef struct { int s; int sc; pthread_mutex_t lock; + pthread_mutex_t datalock; + pthread_cond_t datacond; + databuf * volatile head, *tail; } forward_data; +static void *data_sender(void *_f) +{ + forward_data *f = _f; + databuf *cur; + char *buf, *b; + int size; + +wait: + if (pthread_mutex_lock(&f->datalock)) abort(); + while (f->head == NULL) + if (pthread_cond_wait(&f->datacond, &f->datalock)) abort(); + cur = f->head; + buf = cur->d; + size = cur->l; + f->head = cur->next; + if (f->head == NULL) f->tail = NULL; + if (pthread_mutex_unlock(&f->datalock)) abort(); + free(cur); + goto process; + +process: + if (pthread_mutex_lock(&f->lock)) abort(); + + b = buf; + while (size) { + int l = write(f->s, b, size); + if (l <= 0) { printf("forward error\n"); exit(1); } + size -= l; + b += l; + } + + if (pthread_mutex_unlock(&f->lock)) abort(); + + free(buf); + + goto wait; +} + static void do_forward(forward_data *f, int from, int to, int lock) { int l, len; @@ -66,6 +114,11 @@ void *forwarder(char *ip, int port) f = malloc(sizeof(*f)); if (f == NULL) abort(); pthread_mutex_init(&f->lock, NULL); + pthread_mutex_init(&f->datalock, NULL); + pthread_cond_init(&f->datacond, NULL); + + f->sc = -1; + f->head = f->tail = NULL; f->s = socket(AF_INET, SOCK_STREAM, 0); if (f->s == -1) { perror("socket"); exit(1); } @@ -77,21 +130,27 @@ void *forwarder(char *ip, int port) if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) { perror("connect"); exit(1); } + new_thread(data_sender, f); + return f; } void forward(void *_forwarder, char *buf, int size) { forward_data *f = _forwarder; + databuf *new; - if (pthread_mutex_lock(&f->lock)) abort(); + new = malloc(sizeof(*new)); if (new == NULL) abort(); - while (size) { - int l = write(f->s, buf, size); - if (l <= 0) { printf("forward error\n"); exit(1); } - size -= l; - buf += l; - } + if (pthread_mutex_lock(&f->datalock)) abort(); - if (pthread_mutex_unlock(&f->lock)) abort(); + new->d = malloc(size); if (new->d == NULL) abort(); + memcpy(new->d, buf, size); + new->l = size; + new->next = NULL; + if (f->head == NULL) f->head = new; + f->tail = new; + + if (pthread_cond_signal(&f->datacond)) abort(); + if (pthread_mutex_unlock(&f->datalock)) abort(); } From d4d361ed2f3ff99d56d069bb0aefe5cb48845327 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 20 Mar 2016 21:30:07 +0100 Subject: [PATCH 021/217] error if -on/-off id/group is not found --- tracer/database.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tracer/database.c b/tracer/database.c index 5039deff5a..59d8cbdc85 100644 --- a/tracer/database.c +++ b/tracer/database.c @@ -286,26 +286,29 @@ void list_groups(void *_d) for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name); } -static void onoff_id(database *d, char *name, int *a, int onoff) +static int onoff_id(database *d, char *name, int *a, int onoff) { id *i; i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp); - if (i == NULL) return; + if (i == NULL) return 0; a[i->id] = onoff; printf("turning %s %s\n", onoff ? "ON" : "OFF", name); + return 1; } -static void onoff_group(database *d, char *name, int *a, int onoff) +static int onoff_group(database *d, char *name, int *a, int onoff) { group *g; int i; g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp); - if (g == NULL) return; + if (g == NULL) return 0; for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff); + return 1; } void on_off(void *_d, char *item, int *a, int onoff) { + int done; database *d = _d; int i; if (item == NULL) { @@ -313,6 +316,10 @@ void on_off(void *_d, char *item, int *a, int onoff) printf("turning %s all traces\n", onoff ? "ON" : "OFF"); return; } - onoff_group(d, item, a, onoff); - onoff_id(d, item, a, onoff); + done = onoff_group(d, item, a, onoff); + done += onoff_id(d, item, a, onoff); + if (done == 0) { + printf("ERROR: ID/group '%s' not found in database\n", item); + exit(1); + } } From fe057b1bc4013ecadb6304061ea18ffec6638da0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Mar 2016 09:54:23 +0100 Subject: [PATCH 022/217] add port to -r option --- tracer/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tracer/main.c b/tracer/main.c index 317644f5a5..18ed8087cc 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -403,7 +403,7 @@ void usage(void) " by default, all is off\n" "\n" "remote mode options: in this mode you run a local tracer and a remote one\n" -" -r remote side\n" +" -r remote side (use given port)\n" " -l local side (forwards packets to remote IP:port)\n" ); exit(1); @@ -429,6 +429,7 @@ int main(int n, char **v) int remote_remote = 0; char *remote_ip = NULL; int remote_port = -1; + int port = 2020; #ifdef T_USE_SHARED_MEMORY void *f; #endif @@ -454,7 +455,8 @@ int main(int n, char **v) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } if (!strcmp(v[i], "-OFF")) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } - if (!strcmp(v[i], "-r")) { remote_remote = 1; continue; } + if (!strcmp(v[i], "-r")) { if (i > n-2) usage(); remote_remote = 1; + port = atoi(v[++i]); continue; } if (!strcmp(v[i], "-l")) { if (i > n-3) usage(); remote_local = 1; remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } printf("ERROR: unknown option %s\n", v[i]); @@ -528,7 +530,7 @@ no_database: #ifdef T_USE_SHARED_MEMORY init_shm(); #endif - s = get_connection("127.0.0.1", 2020); + s = get_connection("127.0.0.1", port); if (remote_local) { #ifdef T_USE_SHARED_MEMORY From 7c7d5caed23d35656aebdbf864cd44b67f58d589 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Mar 2016 16:42:24 +0100 Subject: [PATCH 023/217] do not forward data from tracee to remote tracer - no data is sent and it won't work anyway, it will mess up with the T --- tracer/forward.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tracer/forward.c b/tracer/forward.c index b982a89027..6082d5e7e3 100644 --- a/tracer/forward.c +++ b/tracer/forward.c @@ -92,9 +92,11 @@ static void *forward_s_to_sc(void *_f) static void *forward_sc_to_s(void *_f) { +#if 0 forward_data *f = _f; do_forward(f, f->sc, f->s, 1); printf("INFO: forwarder exits\n"); +#endif return NULL; } From 0fe08538e9b54abc95ccad708890523b2e284340 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Mar 2016 16:44:12 +0100 Subject: [PATCH 024/217] add __synch_synchronize for the T_cache it probably makes things zillion times slower but it seems to be necessary --- T.c | 13 ++++++++++--- T.h | 6 ++++-- tracer/main.c | 10 +++++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/T.c b/T.c index a33d1e90b6..13bf25b324 100644 --- a/T.c +++ b/T.c @@ -54,9 +54,16 @@ static void *T_send_thread(void *_) { while (1) { usleep(5000); + __sync_synchronize(); while (T_cache[T_busylist_head].busy) { - char *b = T_cache[T_busylist_head].buffer; - int l = T_cache[T_busylist_head].length; + char *b; + int l; + /* TODO: be sure about those memory barriers - in doubt one is + * put here too + */ + __sync_synchronize(); + b = T_cache[T_busylist_head].buffer; + l = T_cache[T_busylist_head].length; while (l) { int done = write(T_socket, b, l); if (done <= 0) { @@ -123,7 +130,7 @@ void T_connect_to_tracer(char *addr, int port) #ifdef T_USE_SHARED_MEMORY /* setup shared memory */ - T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR, 0666); + T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666); shm_unlink(T_SHM_FILENAME); if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); } T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), diff --git a/T.h b/T.h index 405594f2d4..6797213d31 100644 --- a/T.h +++ b/T.h @@ -118,16 +118,18 @@ extern T_cache_t *T_cache; #ifdef T_USE_SHARED_MEMORY #define T_SEND() \ - T_cache[T_LOCAL_slot].busy = 1; \ T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ + __sync_synchronize(); \ + T_cache[T_LOCAL_slot].busy = 1; \ T_send(T_LOCAL_buf, T_LOCAL_size) #else /* T_USE_SHARED_MEMORY */ /* when not using shared memory, wait for send to finish */ #define T_SEND() \ - T_cache[T_LOCAL_slot].busy = 1; \ T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ + __sync_synchronize(); \ + T_cache[T_LOCAL_slot].busy = 1; \ T_send(T_LOCAL_buf, T_LOCAL_size); \ while (T_cache[T_LOCAL_slot].busy) usleep(1*1000) diff --git a/tracer/main.c b/tracer/main.c index 18ed8087cc..cf8f8aac85 100644 --- a/tracer/main.c +++ b/tracer/main.c @@ -356,7 +356,8 @@ void wait_message(void) void init_shm(void) { - int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT, 0666); + int i; + int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); if (s == -1) { perror(T_SHM_FILENAME); abort(); } if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) { perror(T_SHM_FILENAME); abort(); } @@ -365,6 +366,12 @@ void init_shm(void) if (T_cache == NULL) { perror(T_SHM_FILENAME); abort(); } close(s); + + /* let's garbage the memory to catch some potential problems + * (think multiprocessor sync issues, barriers, etc.) + */ + memset(T_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t)); + for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0; } #endif /* T_USE_SHARED_MEMORY */ @@ -555,6 +562,7 @@ no_init_message: while (1) { #ifdef T_USE_SHARED_MEMORY wait_message(); + __sync_synchronize(); #endif #ifdef T_USE_SHARED_MEMORY From 9b0f4913e2d83af960b4d8fd0bb6593e110ef65a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Mar 2016 17:42:04 +0100 Subject: [PATCH 025/217] dirty bug... --- tracer/forward.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tracer/forward.c b/tracer/forward.c index 6082d5e7e3..b425e6444b 100644 --- a/tracer/forward.c +++ b/tracer/forward.c @@ -151,6 +151,7 @@ void forward(void *_forwarder, char *buf, int size) new->l = size; new->next = NULL; if (f->head == NULL) f->head = new; + if (f->tail != NULL) f->tail->next = new; f->tail = new; if (pthread_cond_signal(&f->datacond)) abort(); From f9d740eee6bdce4bb25d6452103178971a24c1c3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 10 Apr 2016 17:01:22 +0200 Subject: [PATCH 026/217] first commit of the T - review this commit, many things should probably not be here. --- cmake_targets/CMakeLists.txt | 15 + common/utils/T/T.c | 147 +++++ common/utils/T/T.h | 544 ++++++++++++++++++ common/utils/T/T_IDs.h | 135 +++++ common/utils/T/T_defs.h | 18 + common/utils/T/database.c | 325 +++++++++++ common/utils/T/defs.h | 30 + common/utils/T/forward.c | 162 ++++++ common/utils/T/generate_Txx.c | 25 + common/utils/T/genids.c | 155 +++++ common/utils/T/main.c | 21 + common/utils/T/plot.c | 291 ++++++++++ .../lte_ul_channel_estimation.c | 5 + openair1/PHY/LTE_TRANSPORT/pucch.c | 6 + .../PHY/LTE_TRANSPORT/ulsch_demodulation.c | 7 +- openair1/PHY/TOOLS/lte_phy_scope.c | 4 +- openair1/SCHED/phy_procedures_lte_eNb.c | 4 + openair2/UTIL/LOG/log.h | 54 +- openair2/UTIL/OTG/otg_kpi.c | 4 +- targets/RT/USER/lte-softmodem.c | 11 + targets/SIMU/USER/oaisim.c | 12 + 21 files changed, 1950 insertions(+), 25 deletions(-) create mode 100644 common/utils/T/T.c create mode 100644 common/utils/T/T.h create mode 100644 common/utils/T/T_IDs.h create mode 100644 common/utils/T/T_defs.h create mode 100644 common/utils/T/database.c create mode 100644 common/utils/T/defs.h create mode 100644 common/utils/T/forward.c create mode 100644 common/utils/T/generate_Txx.c create mode 100644 common/utils/T/genids.c create mode 100644 common/utils/T/main.c create mode 100644 common/utils/T/plot.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 7477ef819f..a95994a8b1 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1484,6 +1484,13 @@ endif (${XFORMS}) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") +#add the T tracer +add_boolean_option(T_TRACER True "Activate the T tracer" ) +include_directories("${OPENAIR_DIR}/common/utils/T") +add_boolean_option(T_USE_SHARED_MEMORY True "Use shared memory to communicate with the T tracer" ) +set(T_SOURCE + ${OPENAIR_DIR}/common/utils/T/T.c) +set (T_LIB "-lrt") # Hack on a test of asn1c version (already dirty) add_definitions(-DASN1_MINIMUM_VERSION=924) @@ -1516,6 +1523,7 @@ add_executable(lte-softmodem ${RTAI_SOURCE} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} ) target_link_libraries (lte-softmodem @@ -1529,6 +1537,8 @@ target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CR target_link_libraries (lte-softmodem ${LIBBOOST_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-softmodem ${T_LIB}) + # lte-softmodem-nos1 is both eNB and UE implementation ################################################### add_executable(lte-softmodem-nos1 @@ -1552,6 +1562,7 @@ add_executable(lte-softmodem-nos1 ${RTAI_SOURCE} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group @@ -1563,6 +1574,8 @@ target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt target_link_libraries (lte-softmodem-nos1 ${LIBBOOST_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-softmodem ${T_LIB}) + # rrh ################################ #Note: only one RF type (USRP) is currently supported for RRH @@ -1687,6 +1700,7 @@ add_executable(oaisim_nos1 ${HW_SOURCE} ${TRANSPORT_SOURCE} ${XFORMS_SOURCE} + ${T_SOURCE} ) target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim_nos1 @@ -1700,6 +1714,7 @@ target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYP #Force link with forms, regardless XFORMS option target_link_libraries (oaisim_nos1 forms) +target_link_libraries (lte-softmodem ${T_LIB}) # Unitary tests for each piece of L1: example, mbmssim is MBMS L1 simulator ##################################### diff --git a/common/utils/T/T.c b/common/utils/T/T.c new file mode 100644 index 0000000000..13bf25b324 --- /dev/null +++ b/common/utils/T/T.c @@ -0,0 +1,147 @@ +#include "T.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* array used to activate/disactivate a log */ +static int T_IDs[T_NUMBER_OF_IDS]; +int *T_active = T_IDs; + +static int T_socket; + +/* T_cache + * - the T macro picks up the head of freelist and marks it busy + * - the T sender thread periodically wakes up and sends what's to be sent + */ +volatile int _T_freelist_head; +volatile int *T_freelist_head = &_T_freelist_head; +int T_busylist_head; +T_cache_t _T_cache[T_CACHE_SIZE]; +T_cache_t *T_cache = _T_cache; + +static void get_message(int s) +{ + char t; + int l; + int id; + + if (read(s, &t, 1) != 1) abort(); +printf("got mess %d\n", t); + switch (t) { + case 0: + /* toggle all those IDs */ + /* optimze? (too much syscalls) */ + if (read(s, &l, sizeof(int)) != sizeof(int)) abort(); + while (l) { + if (read(s, &id, sizeof(int)) != sizeof(int)) abort(); + T_IDs[id] = 1 - T_IDs[id]; + l--; + } + break; + } +} + +#ifndef T_USE_SHARED_MEMORY + +static void *T_send_thread(void *_) +{ + while (1) { + usleep(5000); + __sync_synchronize(); + while (T_cache[T_busylist_head].busy) { + char *b; + int l; + /* TODO: be sure about those memory barriers - in doubt one is + * put here too + */ + __sync_synchronize(); + b = T_cache[T_busylist_head].buffer; + l = T_cache[T_busylist_head].length; + while (l) { + int done = write(T_socket, b, l); + if (done <= 0) { + printf("%s:%d:%s: error sending to socket\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } + b += done; + l -= done; + } + T_cache[T_busylist_head].busy = 0; + T_busylist_head++; + T_busylist_head &= T_CACHE_SIZE - 1; + } + } + return NULL; +} + +#endif /* T_USE_SHARED_MEMORY */ + +static void *T_receive_thread(void *_) +{ + while (1) get_message(T_socket); + return NULL; +} + +static void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + +void T_connect_to_tracer(char *addr, int port) +{ + struct sockaddr_in a; + int s; +#ifdef T_USE_SHARED_MEMORY + int T_shm_fd; +#endif + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) + { perror("connect"); exit(1); } + + /* wait for first message - initial list of active T events */ + get_message(s); + + T_socket = s; + +#ifdef T_USE_SHARED_MEMORY + /* setup shared memory */ + T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666); + shm_unlink(T_SHM_FILENAME); + if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); } + T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), + PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0); + if (T_cache == NULL) + { perror(T_SHM_FILENAME); abort(); } + close(T_shm_fd); +#endif + +#ifndef T_USE_SHARED_MEMORY + new_thread(T_send_thread, NULL); +#endif + new_thread(T_receive_thread, NULL); +} diff --git a/common/utils/T/T.h b/common/utils/T/T.h new file mode 100644 index 0000000000..6797213d31 --- /dev/null +++ b/common/utils/T/T.h @@ -0,0 +1,544 @@ +#ifndef _T_T_T_ +#define _T_T_T_ + +#if T_TRACER + +#include + +#include "T_defs.h" + +/* T message IDs */ +#include "T_IDs.h" + +/* known type - this is where you add new types */ + +#define T_INT(x) int, (x) +#define T_FLOAT(x) float, (x) +#define T_BUFFER(x, len) buffer, ((T_buffer){addr:(x), length:(len)}) +#define T_STRING(x) string, (x) +#define T_PRINTF(...) printf, (__VA_ARGS__) + +/* for each known type a T_PUT_XX macro is defined */ + +#define T_PUT_int(argnum, val) \ + do { \ + int T_PUT_var = (val); \ + T_CHECK_SIZE(sizeof(int), argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(int)); \ + T_LOCAL_size += sizeof(int); \ + } while (0) + +#define T_PUT_float(argnum, val) \ + do { \ + float T_PUT_var = (val); \ + T_CHECK_SIZE(sizeof(float), argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(float)); \ + T_LOCAL_size += sizeof(float); \ + } while (0) + +#define T_PUT_buffer(argnum, val) \ + do { \ + T_buffer T_PUT_buffer_var = (val); \ + T_PUT_int(argnum, T_PUT_buffer_var.length); \ + T_CHECK_SIZE(T_PUT_buffer_var.length, argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_buffer_var.addr, \ + T_PUT_buffer_var.length); \ + T_LOCAL_size += T_PUT_buffer_var.length; \ + } while (0) + +#define T_PUT_string(argnum, val) \ + do { \ + char *T_PUT_var = (val); \ + int T_PUT_len = strlen(T_PUT_var) + 1; \ + T_CHECK_SIZE(T_PUT_len, argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_var, T_PUT_len); \ + T_LOCAL_size += T_PUT_len; \ + } while (0) + +#define T_PUT_printf_deref(...) __VA_ARGS__ + +#define T_PUT_printf(argnum, x) \ + do { \ + int T_PUT_len = snprintf(T_LOCAL_buf + T_LOCAL_size, \ + T_BUFFER_MAX - T_LOCAL_size, T_PUT_printf_deref x); \ + if (T_PUT_len < 0) { \ + printf("%s:%d:%s: you can't read this, or can you?", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + if (T_PUT_len >= T_BUFFER_MAX - T_LOCAL_size) { \ + printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ + ", consider increasing T_BUFFER_MAX (%d)\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ + abort(); \ + } \ + T_LOCAL_size += T_PUT_len + 1; \ + } while (0) + +/* structure type to detect that you pass a known type as first arg of T */ +struct T_header; + +/* to define message ID */ +#define T_ID(x) ((struct T_header *)(uintptr_t)(x)) + +/* T macro tricks */ + +#define TN(...) TN_N(__VA_ARGS__,33,32,31,30,29,28,27,26,25,24,23,22,21,\ + 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__) +#define TN_N(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,\ + n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n,...) T##n +#define T(...) TN(__VA_ARGS__) + +/* type used to send arbitrary buffer data */ +typedef struct { + void *addr; + int length; +} T_buffer; + +extern volatile int *T_freelist_head; +extern T_cache_t *T_cache; + +/* used at header of Tn, allocates buffer */ +#define T_LOCAL_DATA \ + char *T_LOCAL_buf; \ + int T_LOCAL_size = 0; \ + int T_LOCAL_slot; \ + T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \ + & (T_CACHE_SIZE - 1); \ + (void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \ + if (T_cache[T_LOCAL_slot].busy) { \ + printf("%s:%d:%s: T cache is full - consider increasing its size\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + T_LOCAL_buf = T_cache[T_LOCAL_slot].buffer; + +#define T_ACTIVE(x) T_active[(intptr_t)x] + +#ifdef T_USE_SHARED_MEMORY + +#define T_SEND() \ + T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ + __sync_synchronize(); \ + T_cache[T_LOCAL_slot].busy = 1; \ + T_send(T_LOCAL_buf, T_LOCAL_size) + +#else /* T_USE_SHARED_MEMORY */ + +/* when not using shared memory, wait for send to finish */ +#define T_SEND() \ + T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ + __sync_synchronize(); \ + T_cache[T_LOCAL_slot].busy = 1; \ + T_send(T_LOCAL_buf, T_LOCAL_size); \ + while (T_cache[T_LOCAL_slot].busy) usleep(1*1000) + +#endif /* T_USE_SHARED_MEMORY */ + +#define T_CHECK_SIZE(len, argnum) \ + if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \ + printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ + ", consider increasing T_BUFFER_MAX (%d)\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ + abort(); \ + } + +#if 0 +#define T_PUT(type, var, argnum) \ + do { \ + if (T_LOCAL_size + sizeof(var) > T_BUFFER_MAX) { \ + printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ + ", consider increasing T_BUFFER_MAX (%d)\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \ + abort(); \ + } \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &var, sizeof(var)); \ + T_LOCAL_size += sizeof(var); \ + } while (0) +#endif + +#if 0 +#define T_PROCESS(x, argnum) \ + do { \ + T_PUT(typeof(x), x, argnum); \ + } while (0) +#endif + +#if 0 +#define T_PROCESS(x, argnum) \ + do { \ + if (__builtin_types_compatible_p(typeof(x), int)) \ + { T_PUT(int, (intptr_t)(x), argnum); printf("int\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), short)) \ + { T_PUT(short, (intptr_t)(x), argnum); printf("short\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), float)) \ + { T_PUT(float, (x), argnum); printf("float\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), char *)) \ + { T_PUT(char *, (char *)(intptr_t)(x), argnum); printf("char *\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), float *)) \ + { T_PUT(float *, (float *)(intptr_t)(x), argnum); printf("float *\n"); } \ + else if (__builtin_types_compatible_p(typeof(x), void *)) \ + { T_PUT(void *, (void *)(intptr_t)(x), argnum); printf("void *\n"); } \ + else { \ + printf("%s:%d:%s: unsupported type for argument %d in T macro\n", \ + __FILE__, __LINE__, __FUNCTION__, argnum); \ + abort(); \ + } \ + } while (0) +#endif + +#define T_HEADER(x) \ + do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + T_PUT_int(1, (int)(uintptr_t)(x)); \ + } while (0) + +#define T1(t) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_SEND(); \ + } \ + } while (0) + +#define T3(t,t0,x0) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_SEND(); \ + } \ + } while (0) + +#define T5(t,t0,x0,t1,x1) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_SEND(); \ + } \ + } while (0) + +#define T7(t,t0,x0,t1,x1,t2,x2) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_SEND(); \ + } \ + } while (0) + +#define T9(t,t0,x0,t1,x1,t2,x2,t3,x3) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_SEND(); \ + } \ + } while (0) + +#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_SEND(); \ + } \ + } while (0) + +#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_SEND(); \ + } \ + } while (0) + +#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_SEND(); \ + } \ + } while (0) + +#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_SEND(); \ + } \ + } while (0) + +#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_SEND(); \ + } \ + } while (0) + +#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_SEND(); \ + } \ + } while (0) + +#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_SEND(); \ + } \ + } while (0) + +#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_SEND(); \ + } \ + } while (0) + +#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_SEND(); \ + } \ + } while (0) + +#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_PUT_##t13(15, x13); \ + T_SEND(); \ + } \ + } while (0) + +#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_PUT_##t13(15, x13); \ + T_PUT_##t14(16, x14); \ + T_SEND(); \ + } \ + } while (0) + +#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15) \ + do { \ + if (T_ACTIVE(t)) { \ + T_LOCAL_DATA \ + T_HEADER(t); \ + T_PUT_##t0(2, x0); \ + T_PUT_##t1(3, x1); \ + T_PUT_##t2(4, x2); \ + T_PUT_##t3(5, x3); \ + T_PUT_##t4(6, x4); \ + T_PUT_##t5(7, x5); \ + T_PUT_##t6(8, x6); \ + T_PUT_##t7(9, x7); \ + T_PUT_##t8(10, x8); \ + T_PUT_##t9(11, x9); \ + T_PUT_##t10(12, x10); \ + T_PUT_##t11(13, x11); \ + T_PUT_##t12(14, x12); \ + T_PUT_##t13(15, x13); \ + T_PUT_##t14(16, x14); \ + T_PUT_##t15(17, x15); \ + T_SEND(); \ + } \ + } while (0) + +#define T_CALL_ERROR \ + do { \ + printf("%s:%d:%s: error calling T, you have to use T_INT() or T_XX()\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + } while (0) + +#define T2(...) T_CALL_ERROR +#define T4(...) T_CALL_ERROR +#define T6(...) T_CALL_ERROR +#define T8(...) T_CALL_ERROR +#define T10(...) T_CALL_ERROR +#define T12(...) T_CALL_ERROR +#define T14(...) T_CALL_ERROR +#define T16(...) T_CALL_ERROR +#define T18(...) T_CALL_ERROR +#define T20(...) T_CALL_ERROR +#define T22(...) T_CALL_ERROR +#define T24(...) T_CALL_ERROR +#define T26(...) T_CALL_ERROR +#define T28(...) T_CALL_ERROR +#define T30(...) T_CALL_ERROR +#define T32(...) T_CALL_ERROR + +#ifndef T_USE_SHARED_MEMORY + +#include + +static inline void T_send(char *buf, int size) +{ + int i; +return; + printf("sending %d bytes", size); + for (i = 0; i < size; i++) + printf("%s%2.2x", i?" ":"\n", (unsigned char)buf[i]); + printf("\n"); +} + +#else /* T_USE_SHARED_MEMORY */ + +#define T_send(...) /**/ + +#endif /* T_USE_SHARED_MEMORY */ + +extern int *T_active; + +void T_connect_to_tracer(char *addr, int port); + +#else /* T_TRACER */ + +/* if T_TRACER is not defined or is 0, the T is deactivated */ +#define T(...) /**/ + +#endif /* T_TRACER */ + +#endif /* _T_T_T_ */ diff --git a/common/utils/T/T_IDs.h b/common/utils/T/T_IDs.h new file mode 100644 index 0000000000..eb5377186c --- /dev/null +++ b/common/utils/T/T_IDs.h @@ -0,0 +1,135 @@ +/* generated file, do not edit by hand */ + +#define T_ENB_INPUT_SIGNAL T_ID(0) +#define T_ENB_UL_CHANNEL_ESTIMATE T_ID(1) +#define T_PUSCH_IQ T_ID(2) +#define T_PUCCH_1AB_IQ T_ID(3) +#define T_PUCCH_1_ENERGY T_ID(4) +#define T_LEGACY_MAC_INFO T_ID(5) +#define T_LEGACY_MAC_ERROR T_ID(6) +#define T_LEGACY_MAC_WARNING T_ID(7) +#define T_LEGACY_MAC_DEBUG T_ID(8) +#define T_LEGACY_MAC_TRACE T_ID(9) +#define T_LEGACY_PHY_INFO T_ID(10) +#define T_LEGACY_PHY_ERROR T_ID(11) +#define T_LEGACY_PHY_WARNING T_ID(12) +#define T_LEGACY_PHY_DEBUG T_ID(13) +#define T_LEGACY_PHY_TRACE T_ID(14) +#define T_LEGACY_S1AP_INFO T_ID(15) +#define T_LEGACY_S1AP_ERROR T_ID(16) +#define T_LEGACY_S1AP_WARNING T_ID(17) +#define T_LEGACY_S1AP_DEBUG T_ID(18) +#define T_LEGACY_S1AP_TRACE T_ID(19) +#define T_LEGACY_X2AP_INFO T_ID(20) +#define T_LEGACY_X2AP_ERROR T_ID(21) +#define T_LEGACY_X2AP_WARNING T_ID(22) +#define T_LEGACY_X2AP_DEBUG T_ID(23) +#define T_LEGACY_X2AP_TRACE T_ID(24) +#define T_LEGACY_RRC_INFO T_ID(25) +#define T_LEGACY_RRC_ERROR T_ID(26) +#define T_LEGACY_RRC_WARNING T_ID(27) +#define T_LEGACY_RRC_DEBUG T_ID(28) +#define T_LEGACY_RRC_TRACE T_ID(29) +#define T_LEGACY_RLC_INFO T_ID(30) +#define T_LEGACY_RLC_ERROR T_ID(31) +#define T_LEGACY_RLC_WARNING T_ID(32) +#define T_LEGACY_RLC_DEBUG T_ID(33) +#define T_LEGACY_RLC_TRACE T_ID(34) +#define T_LEGACY_PDCP_INFO T_ID(35) +#define T_LEGACY_PDCP_ERROR T_ID(36) +#define T_LEGACY_PDCP_WARNING T_ID(37) +#define T_LEGACY_PDCP_DEBUG T_ID(38) +#define T_LEGACY_PDCP_TRACE T_ID(39) +#define T_LEGACY_ENB_APP_INFO T_ID(40) +#define T_LEGACY_ENB_APP_ERROR T_ID(41) +#define T_LEGACY_ENB_APP_WARNING T_ID(42) +#define T_LEGACY_ENB_APP_DEBUG T_ID(43) +#define T_LEGACY_ENB_APP_TRACE T_ID(44) +#define T_LEGACY_SCTP_INFO T_ID(45) +#define T_LEGACY_SCTP_ERROR T_ID(46) +#define T_LEGACY_SCTP_WARNING T_ID(47) +#define T_LEGACY_SCTP_DEBUG T_ID(48) +#define T_LEGACY_SCTP_TRACE T_ID(49) +#define T_LEGACY_UDP__INFO T_ID(50) +#define T_LEGACY_UDP__ERROR T_ID(51) +#define T_LEGACY_UDP__WARNING T_ID(52) +#define T_LEGACY_UDP__DEBUG T_ID(53) +#define T_LEGACY_UDP__TRACE T_ID(54) +#define T_LEGACY_NAS_INFO T_ID(55) +#define T_LEGACY_NAS_ERROR T_ID(56) +#define T_LEGACY_NAS_WARNING T_ID(57) +#define T_LEGACY_NAS_DEBUG T_ID(58) +#define T_LEGACY_NAS_TRACE T_ID(59) +#define T_LEGACY_HW_INFO T_ID(60) +#define T_LEGACY_HW_ERROR T_ID(61) +#define T_LEGACY_HW_WARNING T_ID(62) +#define T_LEGACY_HW_DEBUG T_ID(63) +#define T_LEGACY_HW_TRACE T_ID(64) +#define T_LEGACY_EMU_INFO T_ID(65) +#define T_LEGACY_EMU_ERROR T_ID(66) +#define T_LEGACY_EMU_WARNING T_ID(67) +#define T_LEGACY_EMU_DEBUG T_ID(68) +#define T_LEGACY_EMU_TRACE T_ID(69) +#define T_LEGACY_OTG_INFO T_ID(70) +#define T_LEGACY_OTG_ERROR T_ID(71) +#define T_LEGACY_OTG_WARNING T_ID(72) +#define T_LEGACY_OTG_DEBUG T_ID(73) +#define T_LEGACY_OTG_TRACE T_ID(74) +#define T_LEGACY_OCG_INFO T_ID(75) +#define T_LEGACY_OCG_ERROR T_ID(76) +#define T_LEGACY_OCG_WARNING T_ID(77) +#define T_LEGACY_OCG_DEBUG T_ID(78) +#define T_LEGACY_OCG_TRACE T_ID(79) +#define T_LEGACY_OCM_INFO T_ID(80) +#define T_LEGACY_OCM_ERROR T_ID(81) +#define T_LEGACY_OCM_WARNING T_ID(82) +#define T_LEGACY_OCM_DEBUG T_ID(83) +#define T_LEGACY_OCM_TRACE T_ID(84) +#define T_LEGACY_OIP_INFO T_ID(85) +#define T_LEGACY_OIP_ERROR T_ID(86) +#define T_LEGACY_OIP_WARNING T_ID(87) +#define T_LEGACY_OIP_DEBUG T_ID(88) +#define T_LEGACY_OIP_TRACE T_ID(89) +#define T_LEGACY_OMG_INFO T_ID(90) +#define T_LEGACY_OMG_ERROR T_ID(91) +#define T_LEGACY_OMG_WARNING T_ID(92) +#define T_LEGACY_OMG_DEBUG T_ID(93) +#define T_LEGACY_OMG_TRACE T_ID(94) +#define T_LEGACY_OPT_INFO T_ID(95) +#define T_LEGACY_OPT_ERROR T_ID(96) +#define T_LEGACY_OPT_WARNING T_ID(97) +#define T_LEGACY_OPT_DEBUG T_ID(98) +#define T_LEGACY_OPT_TRACE T_ID(99) +#define T_LEGACY_GTPU_INFO T_ID(100) +#define T_LEGACY_GTPU_ERROR T_ID(101) +#define T_LEGACY_GTPU_WARNING T_ID(102) +#define T_LEGACY_GTPU_DEBUG T_ID(103) +#define T_LEGACY_GTPU_TRACE T_ID(104) +#define T_LEGACY_TMR_INFO T_ID(105) +#define T_LEGACY_TMR_ERROR T_ID(106) +#define T_LEGACY_TMR_WARNING T_ID(107) +#define T_LEGACY_TMR_DEBUG T_ID(108) +#define T_LEGACY_TMR_TRACE T_ID(109) +#define T_LEGACY_OSA_INFO T_ID(110) +#define T_LEGACY_OSA_ERROR T_ID(111) +#define T_LEGACY_OSA_WARNING T_ID(112) +#define T_LEGACY_OSA_DEBUG T_ID(113) +#define T_LEGACY_OSA_TRACE T_ID(114) +#define T_LEGACY_component_INFO T_ID(115) +#define T_LEGACY_component_ERROR T_ID(116) +#define T_LEGACY_component_WARNING T_ID(117) +#define T_LEGACY_component_DEBUG T_ID(118) +#define T_LEGACY_component_TRACE T_ID(119) +#define T_LEGACY_componentP_INFO T_ID(120) +#define T_LEGACY_componentP_ERROR T_ID(121) +#define T_LEGACY_componentP_WARNING T_ID(122) +#define T_LEGACY_componentP_DEBUG T_ID(123) +#define T_LEGACY_componentP_TRACE T_ID(124) +#define T_LEGACY_CLI_INFO T_ID(125) +#define T_LEGACY_CLI_ERROR T_ID(126) +#define T_LEGACY_CLI_WARNING T_ID(127) +#define T_LEGACY_CLI_DEBUG T_ID(128) +#define T_LEGACY_CLI_TRACE T_ID(129) +#define T_first T_ID(130) +#define T_buf_test T_ID(131) +#define T_NUMBER_OF_IDS 132 diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h new file mode 100644 index 0000000000..5aca54e8d6 --- /dev/null +++ b/common/utils/T/T_defs.h @@ -0,0 +1,18 @@ +#ifndef _T_defs_H_ +#define _T_defs_H_ + +/* maximum size of a message - increase if needed */ +#define T_BUFFER_MAX (1024*64) + +/* size of the local cache for messages (must be pow(2,something)) */ +#define T_CACHE_SIZE (8192 * 2) + +typedef struct { + volatile int busy; + char buffer[T_BUFFER_MAX]; + int length; +} T_cache_t; + +#define T_SHM_FILENAME "/T_shm_segment" + +#endif /* _T_defs_H_ */ diff --git a/common/utils/T/database.c b/common/utils/T/database.c new file mode 100644 index 0000000000..59d8cbdc85 --- /dev/null +++ b/common/utils/T/database.c @@ -0,0 +1,325 @@ +#include "defs.h" +#include +#include +#include +#include + +typedef struct { + char *name; + char *desc; + char **groups; + int size; + int id; +} id; + +typedef struct { + char *name; + char **ids; + int size; +} group; + +typedef struct { + char *name; + id *i; + int isize; + group *g; + int gsize; +} database; + +typedef struct { + char *data; + int size; + int maxsize; +} buffer; + +typedef struct { + buffer name; + buffer value; +} parser; + +void put(buffer *b, int c) +{ + if (b->size == b->maxsize) { + b->maxsize += 256; + b->data = realloc(b->data, b->maxsize); + if (b->data == NULL) { printf("memory allocation error\n"); exit(1); } + } + b->data[b->size] = c; + b->size++; +} + +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(parser *p, FILE *f, char **name, char **value) +{ + int c; + p->name.size = 0; + p->value.size = 0; + *name = NULL; + *value = NULL; + smash_spaces(f); + c = fgetc(f); + while (!(c == '=' || isspace(c) || c == EOF)) + { put(&p->name, c); c = fgetc(f); } + if (c == EOF) return; + put(&p->name, 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)) + { put(&p->value, c); c = fgetc(f); } + put(&p->value, 0); + if (p->name.size <= 1) return; + if (p->value.size <= 1) return; + *name = p->name.data; + *value = p->value.data; +} + +int group_cmp(const void *_p1, const void *_p2) +{ + const group *p1 = _p1; + const group *p2 = _p2; + return strcmp(p1->name, p2->name); +} + +int id_cmp(const void *_p1, const void *_p2) +{ + const id *p1 = _p1; + const id *p2 = _p2; + return strcmp(p1->name, p2->name); +} + +int string_cmp(const void *_p1, const void *_p2) +{ + char * const *p1 = _p1; + char * const *p2 = _p2; + return strcmp(*p1, *p2); +} + +id *add_id(database *r, char *idname, int i) +{ + if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL) + { printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); } + if ((r->isize & 1023) == 0) { + r->i = realloc(r->i, (r->isize + 1024) * sizeof(id)); + if (r->i == NULL) { printf("out of memory\n"); exit(1); } + } + r->i[r->isize].name = strdup(idname); + if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); } + r->i[r->isize].desc = NULL; + r->i[r->isize].groups = NULL; + r->i[r->isize].size = 0; + r->i[r->isize].id = i; + r->isize++; + qsort(r->i, r->isize, sizeof(id), id_cmp); + return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp); +} + +group *get_group(database *r, char *group_name) +{ + group *ret; + + ret = bsearch(&(group){name:group_name}, + r->g, r->gsize, sizeof(group), group_cmp); + if (ret != NULL) return ret; + + if ((r->gsize & 1023) == 0) { + r->g = realloc(r->g, (r->gsize + 1024) * sizeof(group)); + if (r->g == NULL) abort(); + } + r->g[r->gsize].name = strdup(group_name); + if (r->g[r->gsize].name == NULL) abort(); + r->g[r->gsize].ids = NULL; + r->g[r->gsize].size = 0; + r->gsize++; + + qsort(r->g, r->gsize, sizeof(group), group_cmp); + + return bsearch(&(group){name:group_name}, + r->g, r->gsize, sizeof(group), group_cmp); +} + +void group_add_id(group *g, char *id) +{ + if ((g->size & 1023) == 0) { + g->ids = realloc(g->ids, (g->size + 1024) * sizeof(char *)); + if (g->ids == NULL) abort(); + } + g->ids[g->size] = id; + g->size++; +} + +void id_add_group(id *i, char *group) +{ + char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp); + if (g != NULL) return; + + if ((i->size & 1023) == 0) { + i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *)); + if (i->groups == NULL) abort(); + } + i->groups[i->size] = group; + i->size++; + qsort(i->groups, i->size, sizeof(char *), string_cmp); +} + +void add_groups(database *r, id *i, char *groups) +{ + group *g; + if (i == NULL) {printf("ERROR: GROUP line before ID line\n");exit(1);} + while (1) { + char *start = groups; + char *end = start; + while (!isspace(*end) && *end != ':' && *end != 0) end++; + if (end == start) { + printf("bad group line: groups are seperated by ':'\n"); + abort(); + } + if (*end == 0) end = NULL; else *end = 0; + + g = get_group(r, start); + group_add_id(g, i->name); + id_add_group(i, g->name); + + if (end == NULL) break; + end++; + while ((isspace(*end) || *end == ':') && *end != 0) end++; + if (*end == 0) break; + groups = end; + } +} + +void add_desc(id *i, char *desc) +{ + if (i == NULL) {printf("ERROR: DESC line before ID line\n");exit(1);} + i->desc = strdup(desc); if (i->desc == NULL) abort(); +} + +void *parse_database(char *filename) +{ + FILE *in; + parser p; + database *r; + char *name, *value; + id *last_id = NULL; + int i; + + r = calloc(1, sizeof(*r)); if (r == NULL) abort(); + memset(&p, 0, sizeof(p)); + + r->name = strdup(filename); if (r->name == NULL) abort(); + + in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); } + + i = 0; + + while (1) { + get_line(&p, in, &name, &value); + if (name == NULL) break; +//printf("%s %s\n", name, value); + if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; } + if (!strcmp(name, "GROUP")) add_groups(r, last_id, value); + if (!strcmp(name, "DESC")) add_desc(last_id, value); + } + + fclose(in); + free(p.name.data); + free(p.value.data); + + return r; +} + +void dump_database(void *_d) +{ + database *d = _d; + int i; + + printf("database %s: %d IDs, %d GROUPs\n", d->name, d->isize, d->gsize); + for (i = 0; i < d->isize; i++) { + int j; + printf("ID %s [%s] [in %d group%s]\n", + d->i[i].name, d->i[i].desc ? d->i[i].desc : "", + d->i[i].size, d->i[i].size > 1 ? "s" : ""); + for (j = 0; j < d->i[i].size; j++) + printf(" in GROUP: %s\n", d->i[i].groups[j]); + } + for (i = 0; i < d->gsize; i++) { + int j; + printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size); + for (j = 0; j < d->g[i].size; j++) + printf(" contains ID: %s\n", d->g[i].ids[j]); + } +} + +void list_ids(void *_d) +{ + database *d = _d; + int i; + for (i = 0; i < d->isize; i++) printf("%s\n", d->i[i].name); +} + +void list_groups(void *_d) +{ + database *d = _d; + int i; + for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name); +} + +static int onoff_id(database *d, char *name, int *a, int onoff) +{ + id *i; + i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp); + if (i == NULL) return 0; + a[i->id] = onoff; + printf("turning %s %s\n", onoff ? "ON" : "OFF", name); + return 1; +} + +static int onoff_group(database *d, char *name, int *a, int onoff) +{ + group *g; + int i; + g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp); + if (g == NULL) return 0; + for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff); + return 1; +} + +void on_off(void *_d, char *item, int *a, int onoff) +{ + int done; + database *d = _d; + int i; + if (item == NULL) { + for (i = 0; i < d->isize; i++) a[i] = onoff; + printf("turning %s all traces\n", onoff ? "ON" : "OFF"); + return; + } + done = onoff_group(d, item, a, onoff); + done += onoff_id(d, item, a, onoff); + if (done == 0) { + printf("ERROR: ID/group '%s' not found in database\n", item); + exit(1); + } +} diff --git a/common/utils/T/defs.h b/common/utils/T/defs.h new file mode 100644 index 0000000000..69b379ce0b --- /dev/null +++ b/common/utils/T/defs.h @@ -0,0 +1,30 @@ +#ifndef _TRACER_DEFS_H_ +#define _TRACER_DEFS_H_ + +/* types of plots */ +#define PLOT_VS_TIME 0 +#define PLOT_IQ_POINTS 1 +#define PLOT_MINMAX 2 + +void new_thread(void *(*f)(void *), void *data); + +/* ... is { int count; int type; char *color; } for 'nplots' plots */ +void *make_plot(int width, int height, char *title, int nplots, ...); +void plot_set(void *plot, float *data, int len, int pos, int pp); +void iq_plot_set(void *plot, short *data, int len, int pos, int pp); +void iq_plot_set_sized(void *_plot, short *data, int len, int pp); +void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp); +void iq_plot_add_energy_point_loop(void *_plot, int e, int pp); + +/* returns an opaque pointer - truly a 'database *', see t_data.c */ +void *parse_database(char *filename); +void dump_database(void *database); +void list_ids(void *database); +void list_groups(void *database); +void on_off(void *d, char *item, int *a, int onoff); + +void *forwarder(char *ip, int port); +void forward(void *forwarder, char *buf, int size); +void forward_start_client(void *forwarder, int socket); + +#endif /* _TRACER_DEFS_H_ */ diff --git a/common/utils/T/forward.c b/common/utils/T/forward.c new file mode 100644 index 0000000000..3177e22b2c --- /dev/null +++ b/common/utils/T/forward.c @@ -0,0 +1,162 @@ +#include "defs.h" +#include +#include +#include +#include +#include +#include +#include + +typedef struct databuf { + char *d; + int l; + struct databuf *next; +} databuf; + +typedef struct { + int s; + int sc; + pthread_mutex_t lock; + pthread_mutex_t datalock; + pthread_cond_t datacond; + databuf * volatile head, *tail; +} forward_data; + +static void *data_sender(void *_f) +{ + forward_data *f = _f; + databuf *cur; + char *buf, *b; + int size; + +wait: + if (pthread_mutex_lock(&f->datalock)) abort(); + while (f->head == NULL) + if (pthread_cond_wait(&f->datacond, &f->datalock)) abort(); + cur = f->head; + buf = cur->d; + size = cur->l; + f->head = cur->next; + if (f->head == NULL) f->tail = NULL; + if (pthread_mutex_unlock(&f->datalock)) abort(); + free(cur); + goto process; + +process: + if (pthread_mutex_lock(&f->lock)) abort(); + +int *x = (int*)buf; +if (*x < 0 || *x >= 132) printf("bad id %d\n", *x); +printf("DATA_SENDER sends type %d\n", *x); + + b = buf; + while (size) { + int l = write(f->s, b, size); +printf("DATA_SENDER write buffer %p len %d returns %d\n", b, size, l); + if (l <= 0) { printf("forward error\n"); exit(1); } + size -= l; + b += l; + } + + if (pthread_mutex_unlock(&f->lock)) abort(); + + free(buf); + + goto wait; +} + +static void do_forward(forward_data *f, int from, int to, int lock) +{ + int l, len; + char *b; + char buf[1024]; + while (1) { + len = read(from, buf, 1024); + if (len <= 0) break; + b = buf; + + if (lock) if (pthread_mutex_lock(&f->lock)) abort(); + + while (len) { + l = write(to, b, len); +printf("DO_FORWARD write buffer %p len %d returns %d\n", b, len, l); + if (l <= 0) break; + len -= l; + b += l; + } + + if (lock) if (pthread_mutex_unlock(&f->lock)) abort(); + } +} + +static void *forward_s_to_sc(void *_f) +{ + forward_data *f = _f; + do_forward(f, f->s, f->sc, 0); + return NULL; +} + +static void *forward_sc_to_s(void *_f) +{ + forward_data *f = _f; + do_forward(f, f->sc, f->s, 1); + printf("INFO: forwarder exits\n"); + return NULL; +} + +void forward_start_client(void *_f, int s) +{ + forward_data *f = _f; + f->sc = s; + new_thread(forward_s_to_sc, f); + new_thread(forward_sc_to_s, f); +} + +void *forwarder(char *ip, int port) +{ + forward_data *f; + struct sockaddr_in a; + + f = malloc(sizeof(*f)); if (f == NULL) abort(); + + pthread_mutex_init(&f->lock, NULL); + pthread_mutex_init(&f->datalock, NULL); + pthread_cond_init(&f->datacond, NULL); + + f->sc = -1; + f->head = f->tail = NULL; + + f->s = socket(AF_INET, SOCK_STREAM, 0); + if (f->s == -1) { perror("socket"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(ip); + + if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) + { perror("connect"); exit(1); } + + new_thread(data_sender, f); + + return f; +} + +void forward(void *_forwarder, char *buf, int size) +{ + forward_data *f = _forwarder; + databuf *new; + + new = malloc(sizeof(*new)); if (new == NULL) abort(); + + if (pthread_mutex_lock(&f->datalock)) abort(); + + new->d = malloc(size); if (new->d == NULL) abort(); + memcpy(new->d, buf, size); + new->l = size; + new->next = NULL; + if (f->head == NULL) f->head = new; + f->tail = new; + + if (pthread_cond_signal(&f->datacond)) abort(); + if (pthread_mutex_unlock(&f->datalock)) abort(); +} diff --git a/common/utils/T/generate_Txx.c b/common/utils/T/generate_Txx.c new file mode 100644 index 0000000000..da6282adc1 --- /dev/null +++ b/common/utils/T/generate_Txx.c @@ -0,0 +1,25 @@ +#include + +void print(int n) +{ + int i; + printf("#define T%d(t", n); + for(i=0; i<(n-1)/2; i++) printf(",t%d,x%d", i, i); + printf(") \\\n"); + printf(" do { \\\n"); + printf(" if (T_ACTIVE(t)) { \\\n"); + printf(" T_LOCAL_DATA \\\n"); + printf(" T_HEADER(t); \\\n"); + for(i=0; i<(n-1)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i); + printf(" T_SEND(); \\\n"); + printf(" } \\\n"); + printf(" } while (0)\n"); + printf("\n"); +} + +int main(void) +{ + int i; + for (i = 11; i <= 33; i+=2) print(i); + return 0; +} diff --git a/common/utils/T/genids.c b/common/utils/T/genids.c new file mode 100644 index 0000000000..734c506368 --- /dev/null +++ b/common/utils/T/genids.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include + +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); +} + +/* return 1 if s was not already known, 0 if it was */ +int new_unique_id(char *s) +{ + if (unique_ids_size) + if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) { + printf("FATAL: ID %s is not unique\n", s); + 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("out of memory\n"); abort(); } + } + unique_ids[unique_ids_size] = strdup(s); + if (unique_ids[unique_ids_size] == NULL) + { printf("out of memory\n"); abort(); } + unique_ids_size++; + qsort(unique_ids, unique_ids_size, sizeof(char *), cmp); + return 1; +} + +char *bufname; +int bufname_size; +int bufname_maxsize; + +void putname(int c) +{ + if (bufname_size == bufname_maxsize) { + bufname_maxsize += 256; + bufname = realloc(bufname, bufname_maxsize); + if (bufname == NULL) { printf("memory allocation error\n"); exit(1); } + } + bufname[bufname_size] = c; + bufname_size++; +} + +char *bufvalue; +int bufvalue_size; +int bufvalue_maxsize; + +void putvalue(int c) +{ + if (bufvalue_size == bufvalue_maxsize) { + bufvalue_maxsize += 256; + bufvalue = realloc(bufvalue, bufvalue_maxsize); + if (bufvalue == NULL) { printf("memory allocation error\n"); exit(1); } + } + bufvalue[bufvalue_size] = c; + bufvalue_size++; +} + +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) +{ + int c; + bufname_size = 0; + bufvalue_size = 0; + *name = NULL; + *value = NULL; + smash_spaces(f); + 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); } + putvalue(0); + if (bufname_size <= 1) return; + if (bufvalue_size <= 1) return; + *name = bufname; + *value = bufvalue; +} + +int main(int n, char **v) +{ + FILE *in; + FILE *out; + char *name; + char *value; + char *in_name; + char *out_name; + + if (n != 3) { printf("gimme \n"); exit(1); } + + n = 0; + + in_name = v[1]; + out_name = v[2]; + + 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); } + + fprintf(out, "/* generated file, do not edit by hand */\n\n"); + + while (1) { + get_line(in, &name, &value); + if (name == NULL) break; + printf("name '%s' value '%s'\n", name, value); + if (isspace(value[strlen(value)-1])) { + printf("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)) { 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); + + fclose(in); + fclose(out); + + return 0; +} diff --git a/common/utils/T/main.c b/common/utils/T/main.c new file mode 100644 index 0000000000..3552f19df5 --- /dev/null +++ b/common/utils/T/main.c @@ -0,0 +1,21 @@ +#include "T.h" +#include +#include +#include +#include +#include + +int main(void) +{ + T_connect_to_tracer("127.0.0.1", 2020); + printf("after connect\n"); + while (1) { + char *buf = "hello world %s!\n"; + //T(T_first, T_PRINTF("hello world %s!\n", "yo")); + T(T_buf_test, T_BUFFER("hello world %s!\n", strlen(buf)+1)); + usleep(1); + } + while (1) pause(); + + return 0; +} diff --git a/common/utils/T/plot.c b/common/utils/T/plot.c new file mode 100644 index 0000000000..7447384288 --- /dev/null +++ b/common/utils/T/plot.c @@ -0,0 +1,291 @@ +#include "defs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + float *buf; + short *iqbuf; + int count; + int type; + volatile int iq_count; /* for ULSCH IQ data */ + int iq_insert_pos; + GC g; +} data; + +typedef struct { + Display *d; + Window w; + Pixmap px; + GC bg; + int width; + int height; + pthread_mutex_t lock; + float zoom; + int timer_pipe[2]; + data *p; /* list of plots */ + int nplots; +} plot; + +static void *timer_thread(void *_p) +{ + plot *p = _p; + char c; + + while (1) { + /* more or less 10Hz */ + usleep(100*1000); + c = 1; + if (write(p->timer_pipe[1], &c, 1) != 1) abort(); + } + + return NULL; +} + +static void *plot_thread(void *_p) +{ + float v; + float *s; + int i, j; + plot *p = _p; + int redraw = 0; + int replot = 0; + fd_set rset; + int xfd = ConnectionNumber(p->d); + int maxfd = xfd > p->timer_pipe[0] ? xfd : p->timer_pipe[0]; + int pp; + + while (1) { + while (XPending(p->d)) { + XEvent e; + XNextEvent(p->d, &e); + switch (e.type) { + case ButtonPress: + /* button 4: zoom out */ + if (e.xbutton.button == 4) { p->zoom = p->zoom * 1.25; replot = 1; } + /* button 5: zoom in */ + if (e.xbutton.button == 5) { p->zoom = p->zoom * 0.8; replot = 1; } + printf("zoom: %f\n", p->zoom); + break; + case Expose: redraw = 1; break; + } + } + + if (replot == 1) { + replot = 0; + redraw = 1; + + if (pthread_mutex_lock(&p->lock)) abort(); + + XFillRectangle(p->d, p->px, p->bg, 0, 0, p->width, p->height); + + for (pp = 0; pp < p->nplots; pp++) { + if (p->p[pp].type == PLOT_MINMAX) { + s = p->p[pp].buf; + for (i = 0; i < 512; i++) { + int min = *s; + int max = *s; + for (j = 0; j < p->p[pp].count/512; j++, s++) { + if (*s < min) min = *s; + if (*s > max) max = *s; + } + XDrawLine(p->d, p->px, p->p[pp].g, i, 100-min, i, 100-max); + } + } else if (p->p[pp].type == PLOT_VS_TIME) { + for (i = 0; i < p->p[pp].count; i++) + p->p[pp].buf[i] = + 10*log10(1.0+(float)(p->p[pp].iqbuf[2*i]*p->p[pp].iqbuf[2*i]+ + p->p[pp].iqbuf[2*i+1]*p->p[pp].iqbuf[2*i+1])); + s = p->p[pp].buf; + for (i = 0; i < 512; i++) { + v = 0; + for (j = 0; j < p->p[pp].count/512; j++, s++) v += *s; + v /= p->p[pp].count/512; + XDrawLine(p->d, p->px, p->p[pp].g, i, 100, i, 100-v); + } + } else if (p->p[pp].type == PLOT_IQ_POINTS) { + XPoint pts[p->p[pp].iq_count]; + int count = p->p[pp].iq_count; + for (i = 0; i < count; i++) { + pts[i].x = p->p[pp].iqbuf[2*i]*p->zoom/20+50; + pts[i].y = -p->p[pp].iqbuf[2*i+1]*p->zoom/20+50; + } + XDrawPoints(p->d, p->px, p->p[pp].g, pts, count, CoordModeOrigin); + } + } + + if (pthread_mutex_unlock(&p->lock)) abort(); + } + + if (redraw) { + redraw = 0; + XCopyArea(p->d, p->px, p->w, DefaultGC(p->d, DefaultScreen(p->d)), + 0, 0, p->width, p->height, 0, 0); + } + + XFlush(p->d); + + FD_ZERO(&rset); + FD_SET(p->timer_pipe[0], &rset); + FD_SET(xfd, &rset); + if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) abort(); + if (FD_ISSET(p->timer_pipe[0], &rset)) { + char b[512]; + if (read(p->timer_pipe[0], b, 512) <= 0) abort(); + replot = 1; + } + } + + return NULL; +} + +void *make_plot(int width, int height, char *title, int nplots, ...) +{ + plot *p; + Display *d; + Window w; + Pixmap pm; + int i; + va_list ap; + XGCValues gcv; + + p = malloc(sizeof(*p)); if (p == NULL) abort(); + + d = XOpenDisplay(0); if (d == NULL) abort(); + w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height, + 0, WhitePixel(d, DefaultScreen(d)), WhitePixel(d, DefaultScreen(d))); + XSelectInput(d, w, ExposureMask | ButtonPressMask); + XMapWindow(d, w); + + { + XSetWindowAttributes att; + att.backing_store = Always; + XChangeWindowAttributes(d, w, CWBackingStore, &att); + } + + XStoreName(d, w, title); + + p->bg = XCreateGC(d, w, 0, NULL); + XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->bg); + gcv.foreground = WhitePixel(d, DefaultScreen(d)); + XChangeGC(d, p->bg, GCForeground, &gcv); + + pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d))); + + p->width = width; + p->height = height; + p->p = malloc(nplots * sizeof(data)); if (p->p == NULL) abort(); + + va_start(ap, nplots); + for (i = 0; i < nplots; i++) { + int count; + int type; + char *color; + XColor rcol, scol; + + count = va_arg(ap, int); + type = va_arg(ap, int); + color = va_arg(ap, char *); + + p->p[i].g = XCreateGC(d, w, 0, NULL); + XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->p[i].g); + if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)), + color, &scol, &rcol)) { + gcv.foreground = scol.pixel; + XChangeGC(d, p->p[i].g, GCForeground, &gcv); + } else { + printf("could not allocate color '%s'\n", color); + abort(); + } + + if (type == PLOT_VS_TIME) { + p->p[i].buf = malloc(sizeof(float) * count); + if (p->p[i].buf == NULL) abort(); + p->p[i].iqbuf = malloc(sizeof(short) * count * 2); + if(p->p[i].iqbuf==NULL)abort(); + } else if (type == PLOT_MINMAX) { + p->p[i].buf = malloc(sizeof(float) * count); + if (p->p[i].buf == NULL) abort(); + p->p[i].iqbuf = NULL; + } else { + p->p[i].buf = NULL; + p->p[i].iqbuf = malloc(sizeof(short) * count * 2); + if(p->p[i].iqbuf==NULL)abort(); + } + p->p[i].count = count; + p->p[i].type = type; + p->p[i].iq_count = 0; + p->p[i].iq_insert_pos = 0; + } + va_end(ap); + + p->d = d; + p->w = w; + p->px = pm; + + p->zoom = 1; + p->nplots = nplots; + + pthread_mutex_init(&p->lock, NULL); + + if (pipe(p->timer_pipe)) abort(); + + new_thread(plot_thread, p); + new_thread(timer_thread, p); + + return p; +} + +void plot_set(void *_plot, float *data, int len, int pos, int pp) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + memcpy(p->p[pp].buf + pos, data, len * sizeof(float)); + if (pthread_mutex_unlock(&p->lock)) abort(); +} + +void iq_plot_set(void *_plot, short *data, int count, int pos, int pp) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + memcpy(p->p[pp].iqbuf + pos * 2, data, count * 2 * sizeof(short)); + if (pthread_mutex_unlock(&p->lock)) abort(); +} + +void iq_plot_set_sized(void *_plot, short *data, int count, int pp) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + memcpy(p->p[pp].iqbuf, data, count * 2 * sizeof(short)); + p->p[pp].iq_count = count; + if (pthread_mutex_unlock(&p->lock)) abort(); +} + +void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2] = i; + p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2+1] = q; + if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++; + p->p[pp].iq_insert_pos++; + if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0; + if (pthread_mutex_unlock(&p->lock)) abort(); +} + +void iq_plot_add_energy_point_loop(void *_plot, int e, int pp) +{ + plot *p = _plot; + if (pthread_mutex_lock(&p->lock)) abort(); + p->p[pp].buf[p->p[pp].iq_insert_pos] = e; + if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++; + p->p[pp].iq_insert_pos++; + if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0; + if (pthread_mutex_unlock(&p->lock)) abort(); +} diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 1eb663ec89..f17c69c5f3 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -331,6 +331,11 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB, break; } + if (aa == 0) + T(T_ENB_UL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(UE_id), + T_INT(phy_vars_eNB->proc[sched_subframe].frame_rx), T_INT(subframe), + T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4)); + #ifdef DEBUG_CH if (aa==0) { diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 837c99b073..07789e48e1 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -793,6 +793,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, phy_vars_eNB->pucch1_stats_thres[UE_id][(subframe<<10)+phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe]] = sigma2_dB+pucch1_thres; phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe] = (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe]+1)&1023; + T(T_PUCCH_1_ENERGY, T_INT(phy_vars_eNB->Mod_id), T_INT(UE_id), T_INT(-1), T_INT(subframe), + T_INT(stat_max), T_INT(sigma2_dB+pucch1_thres)); + /* if (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe] == 0) { write_output("pucch_debug.m","pucch_energy", @@ -1031,6 +1034,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, phy_vars_eNB->pucch1ab_stats[UE_id][(subframe<<11) + 1+2*(phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_im); phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe] = (phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023; + /* frame not available here - set to -1 for the moment */ +printf("sending %d %d\n", stat_re, stat_im); + T(T_PUCCH_1AB_IQ, T_INT(phy_vars_eNB->Mod_id), T_INT(UE_id), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im)); *payload = (stat_re<0) ? 1 : 0; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index f2e4dea58a..5a0115a24b 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1617,7 +1617,7 @@ void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB, rx_power_correction = 1; if (ulsch[UE_id]->harq_processes[harq_pid]->nb_rb == 0) { - LOG_E(PHY,"PUSCH (%d/%x) nb_rb=0!\n", harq_pid,ulsch[UE_id]->rnti,harq_pid); + LOG_E(PHY,"PUSCH (%d/%x) nb_rb=0!\n", harq_pid,ulsch[UE_id]->rnti); return; } @@ -1840,6 +1840,11 @@ void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB, #endif + T(T_PUSCH_IQ, T_INT(eNB_id), T_INT(UE_id), T_INT(phy_vars_eNB->proc[sched_subframe].frame_rx), + T_INT(subframe), T_INT(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb), + T_BUFFER(eNB_pusch_vars->rxdataF_comp[eNB_id][0], + 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2)); + llrp = (int16_t*)&eNB_pusch_vars->llr[0]; for (l=0; lsymbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active; l++) { diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 843a77fe62..c8029ee62b 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -352,8 +352,8 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED); - fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000); - fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000); + fl_set_xyplot_ybounds(form->pucch_comp,-100,100); + fl_set_xyplot_xbounds(form->pucch_comp,-100,100); fl_set_xyplot_ybounds(form->pucch_comp1,20,80); } diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 375c0dcd1f..d16ac720eb 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2443,6 +2443,10 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,frame, subframe); #endif + T(T_ENB_INPUT_SIGNAL, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), + T_BUFFER(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti], + phy_vars_eNB->lte_frame_parms.samples_per_tti * 4)); + /* #ifdef OAI_USRP for (aa=0;aalte_frame_parms.nb_antennas_rx;aa++) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index c6abbfa001..dce5a190e4 100755 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -147,26 +147,40 @@ extern "C" { // debugging macros #ifdef USER_MODE -#define LOG_G(c, x...) logIt(c, LOG_EMERG, x) -#define LOG_A(c, x...) logIt(c, LOG_ALERT, x) -#define LOG_C(c, x...) logIt(c, LOG_CRIT, x) -#define LOG_E(c, x...) logIt(c, LOG_ERR, x) -#define LOG_W(c, x...) logIt(c, LOG_WARNING, x) -#define LOG_N(c, x...) logIt(c, LOG_NOTICE, x) -#define LOG_I(c, x...) logIt(c, LOG_INFO, x) -#define LOG_D(c, x...) logIt(c, LOG_DEBUG, x) -#define LOG_F(c, x...) logIt(c, LOG_FILE, x) // log to a file, useful for the MSC chart generation -#define LOG_T(c, x...) logIt(c, LOG_TRACE, x) -#else -#define LOG_G(c, x...) printk(x) -#define LOG_A(c, x...) printk(x) -#define LOG_C(c, x...) printk(x) -#define LOG_E(c, x...) printk(x) -#define LOG_W(c, x...) printk(x) -#define LOG_N(c, x...) printk(x) -#define LOG_I(c, x...) printk(x) -#define LOG_D(c, x...) printk(x) -#define LOG_T(c, x...) printk(x) +# if T_TRACER +# include "T.h" +# define LOG_I(c, x...) T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) +# define LOG_W(c, x...) T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) +# define LOG_E(c, x...) T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) +# define LOG_D(c, x...) T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) +# define LOG_T(c, x...) T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) +# define LOG_G(c, x...) /* */ +# define LOG_A(c, x...) /* */ +# define LOG_C(c, x...) /* */ +# define LOG_N(c, x...) /* */ +# define LOG_F(c, x...) /* */ +# else /* T_TRACER */ +# define LOG_G(c, x...) logIt(c, LOG_EMERG, x) +# define LOG_A(c, x...) logIt(c, LOG_ALERT, x) +# define LOG_C(c, x...) logIt(c, LOG_CRIT, x) +# define LOG_E(c, x...) logIt(c, LOG_ERR, x) +# define LOG_W(c, x...) logIt(c, LOG_WARNING, x) +# define LOG_N(c, x...) logIt(c, LOG_NOTICE, x) +# define LOG_I(c, x...) logIt(c, LOG_INFO, x) +# define LOG_D(c, x...) logIt(c, LOG_DEBUG, x) +# define LOG_F(c, x...) logIt(c, LOG_FILE, x) // log to a file, useful for the MSC chart generation +# define LOG_T(c, x...) logIt(c, LOG_TRACE, x) +# endif /* T_TRACER */ +#else /* USER_MODE */ +# define LOG_G(c, x...) printk(x) +# define LOG_A(c, x...) printk(x) +# define LOG_C(c, x...) printk(x) +# define LOG_E(c, x...) printk(x) +# define LOG_W(c, x...) printk(x) +# define LOG_N(c, x...) printk(x) +# define LOG_I(c, x...) printk(x) +# define LOG_D(c, x...) printk(x) +# define LOG_T(c, x...) printk(x) #endif /* @}*/ diff --git a/openair2/UTIL/OTG/otg_kpi.c b/openair2/UTIL/OTG/otg_kpi.c index 3aa55df05f..877150d892 100644 --- a/openair2/UTIL/OTG/otg_kpi.c +++ b/openair2/UTIL/OTG/otg_kpi.c @@ -61,7 +61,7 @@ void tx_throughput(int src, int dst, int application) else if (g_otg->flow_start[src][dst][application] < get_ctime() ) otg_info->tx_throughput[src][dst][application]=((double)otg_info->tx_num_bytes[src][dst][application] *1000*8)/ ((get_ctime() - g_otg->flow_start[src][dst][application])*1024); else - LOG_W("[src %d][dst %d][app %d] flow start time less than the simu time (start %d, duration %d, ctime %d)\n", + LOG_W(OTG, "[src %d][dst %d][app %d] flow start time less than the simu time (start %d, duration %d, ctime %d)\n", src, dst, application, g_otg->flow_start[src][dst][application], g_otg->flow_duration[src][dst][application], @@ -94,7 +94,7 @@ if ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][app else if (g_otg->flow_start[src][dst][application] < get_ctime() ) otg_info->rx_goodput[src][dst][application]=((double)otg_info->rx_num_bytes[src][dst][application] *1000*8)/ ((get_ctime() - g_otg->flow_start[src][dst][application])*1024); else - LOG_W("[src %d][dst %d][app %d] flow start time less than the simu time (start %d, duration %d, ctime %d)\n", + LOG_W(OTG, "[src %d][dst %d][app %d] flow start time less than the simu time (start %d, duration %d, ctime %d)\n", src, dst, application, g_otg->flow_start[src][dst][application], g_otg->flow_duration[src][dst][application], diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 7df20f05c8..67ee981100 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -51,6 +51,10 @@ #include #include +#if T_TRACER +#include "T.h" +#endif + #include "rt_wrapper.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all @@ -2615,6 +2619,13 @@ int main( int argc, char **argv ) PHY_VARS_UE *UE[MAX_NUM_CCs]; +#if T_TRACER + char *T_ip = "127.0.0.1"; + int T_port = 2020; + printf("connecting to T tracer IP %s port %d\n", T_ip, T_port); + T_connect_to_tracer(T_ip, T_port); +#endif + mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 9e4880906d..c3700c9da9 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -114,6 +114,10 @@ char smbv_ip[16]; # include "create_tasks.h" #endif +#if T_TRACER +#include "T.h" +#endif + /* DCI0_5MHz_TDD0_t UL_alloc_pdu; DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; @@ -1264,6 +1268,14 @@ main (int argc, char **argv) int node_id; int port,Process_Flag=0,wgt,Channel_Flag=0,temp; #endif + +#if T_TRACER + char *T_ip = "127.0.0.1"; + int T_port = 2020; + printf("connecting to T tracer IP %s port %d\n", T_ip, T_port); + T_connect_to_tracer(T_ip, T_port); +#endif + //default parameters oai_emulation.info.n_frames = 0xffff; //1024; //10; oai_emulation.info.n_frames_flag = 0; //fixme From d37484b5aa673c10fb8a66dca28bea397016c316 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 10:20:23 +0200 Subject: [PATCH 027/217] put code in the right place for integration into openair --- Makefile => common/utils/T/Makefile | 0 T.c => common/utils/T/T.c | 0 T.h => common/utils/T/T.h | 0 T_defs.h => common/utils/T/T_defs.h | 0 T_messages.txt => common/utils/T/T_messages.txt | 0 generate_Txx.c => common/utils/T/generate_Txx.c | 0 genids.c => common/utils/T/genids.c | 0 main.c => common/utils/T/main.c | 0 {tracer => common/utils/T/tracer}/Makefile | 0 {tracer => common/utils/T/tracer}/database.c | 0 {tracer => common/utils/T/tracer}/defs.h | 0 {tracer => common/utils/T/tracer}/forward.c | 0 {tracer => common/utils/T/tracer}/main.c | 0 {tracer => common/utils/T/tracer}/plot.c | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename Makefile => common/utils/T/Makefile (100%) rename T.c => common/utils/T/T.c (100%) rename T.h => common/utils/T/T.h (100%) rename T_defs.h => common/utils/T/T_defs.h (100%) rename T_messages.txt => common/utils/T/T_messages.txt (100%) rename generate_Txx.c => common/utils/T/generate_Txx.c (100%) rename genids.c => common/utils/T/genids.c (100%) rename main.c => common/utils/T/main.c (100%) rename {tracer => common/utils/T/tracer}/Makefile (100%) rename {tracer => common/utils/T/tracer}/database.c (100%) rename {tracer => common/utils/T/tracer}/defs.h (100%) rename {tracer => common/utils/T/tracer}/forward.c (100%) rename {tracer => common/utils/T/tracer}/main.c (100%) rename {tracer => common/utils/T/tracer}/plot.c (100%) diff --git a/Makefile b/common/utils/T/Makefile similarity index 100% rename from Makefile rename to common/utils/T/Makefile diff --git a/T.c b/common/utils/T/T.c similarity index 100% rename from T.c rename to common/utils/T/T.c diff --git a/T.h b/common/utils/T/T.h similarity index 100% rename from T.h rename to common/utils/T/T.h diff --git a/T_defs.h b/common/utils/T/T_defs.h similarity index 100% rename from T_defs.h rename to common/utils/T/T_defs.h diff --git a/T_messages.txt b/common/utils/T/T_messages.txt similarity index 100% rename from T_messages.txt rename to common/utils/T/T_messages.txt diff --git a/generate_Txx.c b/common/utils/T/generate_Txx.c similarity index 100% rename from generate_Txx.c rename to common/utils/T/generate_Txx.c diff --git a/genids.c b/common/utils/T/genids.c similarity index 100% rename from genids.c rename to common/utils/T/genids.c diff --git a/main.c b/common/utils/T/main.c similarity index 100% rename from main.c rename to common/utils/T/main.c diff --git a/tracer/Makefile b/common/utils/T/tracer/Makefile similarity index 100% rename from tracer/Makefile rename to common/utils/T/tracer/Makefile diff --git a/tracer/database.c b/common/utils/T/tracer/database.c similarity index 100% rename from tracer/database.c rename to common/utils/T/tracer/database.c diff --git a/tracer/defs.h b/common/utils/T/tracer/defs.h similarity index 100% rename from tracer/defs.h rename to common/utils/T/tracer/defs.h diff --git a/tracer/forward.c b/common/utils/T/tracer/forward.c similarity index 100% rename from tracer/forward.c rename to common/utils/T/tracer/forward.c diff --git a/tracer/main.c b/common/utils/T/tracer/main.c similarity index 100% rename from tracer/main.c rename to common/utils/T/tracer/main.c diff --git a/tracer/plot.c b/common/utils/T/tracer/plot.c similarity index 100% rename from tracer/plot.c rename to common/utils/T/tracer/plot.c From ee6789cdde09ffae511c4ca53860487c9774db6e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 10:23:15 +0200 Subject: [PATCH 028/217] "make clean" cleans also the tracer --- common/utils/T/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 27e1c8a5c0..9694273c19 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -31,3 +31,4 @@ main.o: T.h T_IDs.h T_defs.h clean: rm -f *.o $(PROG) $(GENIDS) core T_IDs.h + cd tracer && make clean From 2bb04f0105db07604744a400fd955ae714a801a6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 11:18:26 +0200 Subject: [PATCH 029/217] first version of the generic gui for the tracer --- common/utils/T/tracer/Makefile | 6 +- common/utils/T/tracer/gui/Makefile | 17 ++ common/utils/T/tracer/gui/container.c | 206 ++++++++++++++ common/utils/T/tracer/gui/event.c | 165 ++++++++++++ common/utils/T/tracer/gui/gui.c | 24 ++ common/utils/T/tracer/gui/gui.h | 36 +++ common/utils/T/tracer/gui/gui_defs.h | 178 ++++++++++++ common/utils/T/tracer/gui/init.c | 29 ++ common/utils/T/tracer/gui/label.c | 46 ++++ common/utils/T/tracer/gui/loop.c | 59 ++++ common/utils/T/tracer/gui/test.c | 46 ++++ common/utils/T/tracer/gui/text_list.c | 95 +++++++ common/utils/T/tracer/gui/toplevel_window.c | 88 ++++++ common/utils/T/tracer/gui/widget.c | 216 +++++++++++++++ common/utils/T/tracer/gui/x.c | 284 ++++++++++++++++++++ common/utils/T/tracer/gui/x.h | 47 ++++ common/utils/T/tracer/gui/x_defs.h | 23 ++ common/utils/T/tracer/gui/xy_plot.c | 173 ++++++++++++ 18 files changed, 1737 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/gui/Makefile create mode 100644 common/utils/T/tracer/gui/container.c create mode 100644 common/utils/T/tracer/gui/event.c create mode 100644 common/utils/T/tracer/gui/gui.c create mode 100644 common/utils/T/tracer/gui/gui.h create mode 100644 common/utils/T/tracer/gui/gui_defs.h create mode 100644 common/utils/T/tracer/gui/init.c create mode 100644 common/utils/T/tracer/gui/label.c create mode 100644 common/utils/T/tracer/gui/loop.c create mode 100644 common/utils/T/tracer/gui/test.c create mode 100644 common/utils/T/tracer/gui/text_list.c create mode 100644 common/utils/T/tracer/gui/toplevel_window.c create mode 100644 common/utils/T/tracer/gui/widget.c create mode 100644 common/utils/T/tracer/gui/x.c create mode 100644 common/utils/T/tracer/gui/x.h create mode 100644 common/utils/T/tracer/gui/x_defs.h create mode 100644 common/utils/T/tracer/gui/xy_plot.c diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 093acfbe3c..fab5012c28 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -10,11 +10,14 @@ CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer -OBJS=main.o plot.o database.o forward.o +OBJS=main.o plot.o database.o forward.o gui/gui.a $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) +gui/gui.a: + cd gui && make + %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< @@ -22,3 +25,4 @@ main.o: ../T_IDs.h ../T_defs.h clean: rm -f *.o $(PROG) core + cd gui && make clean diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile new file mode 100644 index 0000000000..13820114dd --- /dev/null +++ b/common/utils/T/tracer/gui/Makefile @@ -0,0 +1,17 @@ +CC=gcc +CFLAGS=-Wall -g -pthread + +OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ + gui.o label.o event.o xy_plot.o text_list.o + +gui.a: $(OBJS) + ar cr gui.a $(OBJS) + +test: test.o gui.a + $(CC) -o test $(OBJS) test.o -lX11 -pthread -lm + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + rm -f *.a *.o test diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c new file mode 100644 index 0000000000..23f7a42295 --- /dev/null +++ b/common/utils/T/tracer/gui/container.c @@ -0,0 +1,206 @@ +#include "gui.h" +#include "gui_defs.h" +#include +#include + +static void repack(gui *g, widget *_this) +{ +printf("REPACK container %p\n", _this); + struct container_widget *this = _this; + this->hints_are_valid = 0; + return this->common.parent->repack(g, this->common.parent); +} + +static void add_child(gui *g, widget *this, widget *child, int position) +{ +printf("ADD_CHILD container\n"); + widget_add_child_internal(g, this, child, position); +} + +static void compute_vertical_hints(struct gui *g, + struct container_widget *this) +{ + struct widget_list *l; + int cwidth, cheight; + int allocated_width = 0, allocated_height = 0; + + /* get largest width */ + l = this->common.children; + while (l) { + l->item->hints(g, l->item, &cwidth, &cheight); + if (cwidth > allocated_width) allocated_width = cwidth; + allocated_height += cheight; + l = l->next; + } + this->hint_width = allocated_width; + this->hint_height = allocated_height; + this->hints_are_valid = 1; +} + +static void compute_horizontal_hints(struct gui *g, + struct container_widget *this) +{ + struct widget_list *l; + int cwidth, cheight; + int allocated_width = 0, allocated_height = 0; + + /* get largest height */ + l = this->common.children; + while (l) { + l->item->hints(g, l->item, &cwidth, &cheight); + if (cheight > allocated_height) allocated_height = cheight; + allocated_width += cwidth; + l = l->next; + } + this->hint_width = allocated_width; + this->hint_height = allocated_height; + this->hints_are_valid = 1; +} + +static void vertical_allocate(gui *_gui, widget *_this, + int x, int y, int width, int height) +{ +printf("ALLOCATE container vertical %p\n", _this); + int cy = 0; + int cwidth, cheight; + struct gui *g = _gui; + struct container_widget *this = _this; + struct widget_list *l; + + if (this->hints_are_valid == 1) goto hints_ok; + + compute_vertical_hints(g, this); + +hints_ok: + + this->common.x = x; + this->common.y = y; + this->common.width = width; + this->common.height = height; + + /* allocate */ + l = this->common.children; + while (l) { + l->item->hints(g, l->item, &cwidth, &cheight); + l->item->allocate(g, l->item, this->common.x, this->common.y + cy, + //this->hint_width, cheight); + width, cheight); + cy += cheight; + l = l->next; + } + + if (cy != this->hint_height) ERR("reachable?\n"); +} + +static void horizontal_allocate(gui *_gui, widget *_this, + int x, int y, int width, int height) +{ +printf("ALLOCATE container horizontal %p\n", _this); + int cx = 0; + int cwidth, cheight; + struct gui *g = _gui; + struct container_widget *this = _this; + struct widget_list *l; + + if (this->hints_are_valid == 1) goto hints_ok; + + compute_horizontal_hints(g, this); + +hints_ok: + + this->common.x = x; + this->common.y = y; + this->common.width = width; + this->common.height = height; + + /* allocate */ + l = this->common.children; + while (l) { + l->item->hints(g, l->item, &cwidth, &cheight); + l->item->allocate(g, l->item, this->common.x + cx, this->common.y, + cwidth, this->hint_height); + cx += cwidth; + l = l->next; + } + + if (cx != this->hint_width) ERR("reachable?\n"); +} + +static void vertical_hints(gui *_gui, widget *_w, int *width, int *height) +{ +printf("HINTS container vertical %p\n", _w); + struct gui *g = _gui; + struct container_widget *this = _w; + + if (this->hints_are_valid) { + *width = this->hint_width; + *height = this->hint_height; + return; + } + + compute_vertical_hints(g, this); + + *width = this->hint_width; + *height = this->hint_height; +} + +static void horizontal_hints(gui *_gui, widget *_w, int *width, int *height) +{ +printf("HINTS container horizontal %p\n", _w); + struct gui *g = _gui; + struct container_widget *this = _w; + + if (this->hints_are_valid) { + *width = this->hint_width; + *height = this->hint_height; + return; + } + + compute_horizontal_hints(g, this); + + *width = this->hint_width; + *height = this->hint_height; +} + +static void paint(gui *_gui, widget *_this) +{ +printf("PAINT container\n"); + struct gui *g = _gui; + struct widget *this = _this; + struct widget_list *l; + + l = this->children; + while (l) { + l->item->paint(g, l->item); + l = l->next; + } +} + +widget *new_container(gui *_gui, int vertical) +{ + struct gui *g = _gui; + struct container_widget *w; + + glock(g); + + w = new_widget(g, CONTAINER, sizeof(struct container_widget)); + + w->vertical = vertical; + w->hints_are_valid = 0; + + w->common.paint = paint; + w->common.add_child = add_child; + w->common.repack = repack; + + if (vertical) { + w->common.allocate = vertical_allocate; + w->common.hints = vertical_hints; + } else { + w->common.allocate = horizontal_allocate; + w->common.hints = horizontal_hints; + } + + gunlock(g); + + return w; +} diff --git a/common/utils/T/tracer/gui/event.c b/common/utils/T/tracer/gui/event.c new file mode 100644 index 0000000000..fe7f9fbb47 --- /dev/null +++ b/common/utils/T/tracer/gui/event.c @@ -0,0 +1,165 @@ +#include "gui.h" +#include "gui_defs.h" +#include +#include +#include +#include +#include +#include + +/*****************************************************************/ +/* generic functions */ +/*****************************************************************/ + +static void event_list_append(struct gui *g, struct event *e) +{ + struct event_list *new; + + new = calloc(1, sizeof(struct event_list)); + if (new == NULL) OOM; + + new->item = e; + + if (g->queued_events == NULL) { + g->queued_events = new; + new->last = new; + return; + } + + g->queued_events->last->next = new; + g->queued_events->last = new; +} + +static void free_event(struct event *e) +{ + switch (e->type) { + case REPACK: /* nothing */ break; + case DIRTY: /* nothing */ break; + } + free(e); +} + +/*****************************************************************/ +/* sending events */ +/*****************************************************************/ + +static event *new_event_repack(int id) +{ + struct repack_event *ret; + ret = calloc(1, sizeof(struct repack_event)); + if (ret == NULL) OOM; + ret->id = id; + return ret; +} + +static event *new_event_dirty(int id) +{ + struct dirty_event *ret; + ret = calloc(1, sizeof(struct dirty_event)); + if (ret == NULL) OOM; + ret->id = id; + return ret; +} + +void send_event(gui *_gui, enum event_type type, ...) +{ +printf("send_event %d\n", type); + struct gui *g = _gui; + int do_write = 0; + va_list ap; + struct event *e; + + if (g->queued_events == NULL) do_write = 1; + + va_start(ap, type); + + switch (type) { + case REPACK: { + int id; + id = va_arg(ap, int); + e = new_event_repack(id); + break; + } + case DIRTY: { + int id; + id = va_arg(ap, int); + e = new_event_dirty(id); + break; + } + } + + va_end(ap); + + e->type = type; + + event_list_append(g, e); + + if (do_write) { + char c = 1; + if (write(g->event_pipe[1], &c, 1) != 1) + ERR("error writing to pipe: %s\n", strerror(errno)); + } +} + +/*****************************************************************/ +/* processing events */ +/*****************************************************************/ + +static void repack_event(struct gui *g, int id) +{ + struct widget *w = find_widget(g, id); + if (w == NULL) { WARN("widget id %d not found\n", id); return; } + w->repack(g, w); +} + +/* TODO: put that function somewhere else? */ +static struct toplevel_window_widget *get_toplevel_window(struct widget *w) +{ + while (w != NULL) { + if (w->type == TOPLEVEL_WINDOW) + return (struct toplevel_window_widget *)w; + w = w->parent; + } + return NULL; +} + +static void dirty_event(struct gui *g, int id) +{ + struct widget *w = find_widget(g, id); + struct toplevel_window_widget *win; + if (w == NULL) { WARN("widget id %d not found\n", id); return; } + win = get_toplevel_window(w); + if (win == NULL) + { WARN("widget id %d not contained in a window\n", id); return; } + g->xwin = win->x; + w->paint(g, w); + g->xwin = NULL; + g->repainted = 1; +} + +static void process_event(struct gui *g, struct event *e) +{ +printf("processing event type %d\n", e->type); + switch (e->type) { + case REPACK: repack_event(g, ((struct repack_event *)e)->id); break; + case DIRTY: dirty_event(g, ((struct dirty_event *)e)->id); break; + } +} + +/* TODO: events' compression */ +void gui_events(gui *_gui) +{ + struct gui *g = _gui; + +printf("gui_events START: head %p\n", g->queued_events); + + while (g->queued_events) { + struct event_list *cur = g->queued_events; + g->queued_events = cur->next; + if (g->queued_events) g->queued_events->last = cur->last; + process_event(g, cur->item); + free_event(cur->item); + free(cur); + } +printf("gui_events DONE\n"); +} diff --git a/common/utils/T/tracer/gui/gui.c b/common/utils/T/tracer/gui/gui.c new file mode 100644 index 0000000000..55c7a3680a --- /dev/null +++ b/common/utils/T/tracer/gui/gui.c @@ -0,0 +1,24 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include + +void glock(gui *_gui) +{ + struct gui *g = _gui; + if (pthread_mutex_lock(g->lock)) ERR("mutex error\n"); +} + +void gunlock(gui *_gui) +{ + struct gui *g = _gui; + if (pthread_mutex_unlock(g->lock)) ERR("mutex error\n"); +} + +int new_color(gui *_gui, char *color) +{ + struct gui *g = _gui; + return x_new_color(g->x, color); +} diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h new file mode 100644 index 0000000000..846b16457d --- /dev/null +++ b/common/utils/T/tracer/gui/gui.h @@ -0,0 +1,36 @@ +#ifndef _GUI_H_ +#define _GUI_H_ + +/* defines the public API of the GUI */ + +typedef void gui; +typedef void widget; + +#define HORIZONTAL 0 +#define VERTICAL 1 + +gui *gui_init(void); + +/* position = -1 to put at the end */ +void widget_add_child(gui *gui, widget *parent, widget *child, int position); + +widget *new_toplevel_window(gui *gui, int width, int height, char *title); +widget *new_container(gui *gui, int vertical); +widget *new_label(gui *gui, const char *text); +widget *new_xy_plot(gui *gui, int width, int height, char *label, + int vruler_width); +widget *new_text_list(gui *_gui, int width, int nlines, int background_color); + +void xy_plot_set_range(gui *gui, widget *this, + float xmin, float xmax, float ymin, float ymax); + +void text_list_add(gui *gui, widget *this, const char *text, int position); + +void gui_loop(gui *gui); + +void glock(gui *gui); +void gunlock(gui *gui); + +int new_color(gui *gui, char *color); + +#endif /* _GUI_H_ */ diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h new file mode 100644 index 0000000000..d7032f95da --- /dev/null +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -0,0 +1,178 @@ +#ifndef _GUI_DEFS_H_ +#define _GUI_DEFS_H_ + +/* defines the private API of the GUI */ + +/*************************************************************************/ +/* logging macros */ +/*************************************************************************/ + +#define ERR(...) \ + do { \ + printf("%s:%d:%s: ERROR: ", __FILE__, __LINE__, __FUNCTION__); \ + printf(__VA_ARGS__); \ + abort(); \ + } while (0) + +#define WARN(...) \ + do { \ + printf("%s:%d:%s: WARNING: ", __FILE__, __LINE__, __FUNCTION__); \ + printf(__VA_ARGS__); \ + } while (0) + +#define OOM ERR("out of memory\n") + +/*************************************************************************/ +/* widgets */ +/*************************************************************************/ + +enum widget_type { + TOPLEVEL_WINDOW, CONTAINER, TEXT_LIST, XY_PLOT, BUTTON, LABEL +}; + +struct widget_list; + +struct widget { + enum widget_type type; + int id; + int x; /* allocated x after packing */ + int y; /* allocated y after packing */ + int width; /* allocated width after packing */ + int height; /* allocated height after packing */ + struct widget_list *children; + struct widget *parent; + void (*repack)(gui *g, widget *this); + void (*add_child)(gui *g, widget *this, widget *child, int position); + void (*allocate)(gui *g, widget *this, int x, int y, int width, int height); + void (*hints)(gui *g, widget *this, int *width, int *height); + void (*paint)(gui *g, widget *this); +}; + +struct widget_list { + struct widget *item; + struct widget_list *next; + //struct widget_list *prev; /* unused? */ + struct widget_list *last; /* valid only for the head of the list */ +}; + +struct toplevel_window_widget { + struct widget common; + void *x; /* opaque X data (type x_window), used in x.c */ +}; + +struct container_widget { + struct widget common; + int vertical; + int hints_are_valid; /* used to cache hints values */ + int hint_width; /* cached hint values - invalid if */ + int hint_height; /* repack_was_called == 1 */ +}; + +struct text_list_widget { + struct widget common; + char **text; + int text_count; + int wanted_width; + int wanted_nlines; /* number of lines of text the user wants to see */ + int allocated_nlines; /* actual number of visible lines */ + int starting_line; /* points to the first visible line of text */ + int line_height; + int baseline; + int background_color; +}; + +struct xy_plot_widget { + struct widget common; + float *x; + float *y; + int npoints; + char *label; + int label_width; + int label_height; + int label_baseline; + int vrule_width; /* the width of the vertical ruler text zone */ + float xmin, xmax; + float ymin, ymax; + int wanted_width; + int wanted_height; +}; + +struct button_widget { + struct widget common; +}; + +struct label_widget { + struct widget common; + const char *t; + int color; + int width; /* as given by the graphic's backend */ + int height; /* as given by the graphic's backend */ + int baseline; /* as given by the graphic's backend */ +}; + +/*************************************************************************/ +/* events */ +/*************************************************************************/ + +typedef void event; + +enum event_type { + DIRTY, REPACK +}; + +struct event { + enum event_type type; +}; + +struct event_list { + struct event *item; + struct event_list *next; + struct event_list *last; +}; + +struct dirty_event { + struct event common; + int id; +}; + +struct repack_event { + struct event common; + int id; +}; + +/*************************************************************************/ +/* main structure */ +/*************************************************************************/ + +struct gui { + void *lock; + void *x; /* opaque X data (type x_connection), used in x.c */ + struct widget_list *toplevel; + struct event_list *queued_events; + int event_pipe[2]; + int next_id; /* tells what is the ID of + the next created widget */ + int repainted; /* set to 1 when some widget has + * been repainted (TODO: can be any, + * to be optimized) */ + void *xwin; /* set by a toplevel_window when + * it paints itself, to be used + * by its children */ +}; + +/*************************************************************************/ +/* internal functions */ +/*************************************************************************/ + +widget *new_widget(struct gui *g, enum widget_type type, int size); +void widget_add_child_internal( + gui *_gui, widget *parent, widget *child, int position); + +const char *widget_name(enum widget_type type); + +void send_event(gui *gui, enum event_type type, ...); +void gui_events(gui *gui); + +struct widget *find_widget(struct gui *g, int id); + +#endif /* _GUI_DEFS_H_ */ diff --git a/common/utils/T/tracer/gui/init.c b/common/utils/T/tracer/gui/init.c new file mode 100644 index 0000000000..c708639674 --- /dev/null +++ b/common/utils/T/tracer/gui/init.c @@ -0,0 +1,29 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include +#include +#include +#include + +gui *gui_init(void) +{ + struct gui *ret; + + ret = calloc(1, sizeof(struct gui)); + if (ret == NULL) OOM; + + ret->lock = malloc(sizeof(pthread_mutex_t)); + if (ret->lock == NULL) OOM; + if (pthread_mutex_init(ret->lock, NULL)) + ERR("mutex initialization failed\n"); + + if (pipe(ret->event_pipe)) + ERR("%s\n", strerror(errno)); + + ret->x = x_open(); + + return ret; +} diff --git a/common/utils/T/tracer/gui/label.c b/common/utils/T/tracer/gui/label.c new file mode 100644 index 0000000000..be6c8794a0 --- /dev/null +++ b/common/utils/T/tracer/gui/label.c @@ -0,0 +1,46 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include + +static void paint(gui *_gui, widget *_w) +{ + struct gui *g = _gui; + struct label_widget *l = _w; +printf("PAINT label '%s'\n", l->t); + x_draw_string(g->x, g->xwin, l->color, + l->common.x, l->common.y + l->baseline, l->t); +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct label_widget *l = _w; +printf("HINTS label '%s'\n", l->t); + *width = l->width; + *height = l->height; +} + +widget *new_label(gui *_gui, const char *label) +{ + struct gui *g = _gui; + struct label_widget *w; + + glock(g); + + w = new_widget(g, LABEL, sizeof(struct label_widget)); + + w->t = strdup(label); + if (w->t == NULL) OOM; + w->color = FOREGROUND_COLOR; + + x_text_get_dimensions(g->x, label, &w->width, &w->height, &w->baseline); + + w->common.paint = paint; + w->common.hints = hints; + + gunlock(g); + + return w; +} diff --git a/common/utils/T/tracer/gui/loop.c b/common/utils/T/tracer/gui/loop.c new file mode 100644 index 0000000000..94b7fe54bd --- /dev/null +++ b/common/utils/T/tracer/gui/loop.c @@ -0,0 +1,59 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include +#include +#include +#include + +void gui_loop(gui *_gui) +{ + struct gui *g = _gui; + int xfd; + int eventfd; + int maxfd; + fd_set rd; + + xfd = x_connection_fd(g->x); + eventfd = g->event_pipe[0]; + + if (eventfd > xfd) maxfd = eventfd; + else maxfd = xfd; + + while (1) { + x_flush(g->x); + FD_ZERO(&rd); + FD_SET(xfd, &rd); + FD_SET(eventfd, &rd); + if (select(maxfd+1, &rd, NULL, NULL, NULL) == -1) + ERR("select: %s\n", strerror(errno)); + + glock(g); + + if (FD_ISSET(xfd, &rd)) + x_events(g); + + if (FD_ISSET(eventfd, &rd)) { + char c[256]; + if (read(eventfd, c, 256)); /* for no gcc warnings */ + } + + gui_events(g); + + if (g->repainted) { + struct widget_list *cur; + g->repainted = 0; + cur = g->toplevel; + while (cur) { + struct toplevel_window_widget *w = + (struct toplevel_window_widget *)cur->item; + x_draw(g->x, w->x); + cur = cur->next; + } + } + + gunlock(g); + } +} diff --git a/common/utils/T/tracer/gui/test.c b/common/utils/T/tracer/gui/test.c new file mode 100644 index 0000000000..06e3b6309d --- /dev/null +++ b/common/utils/T/tracer/gui/test.c @@ -0,0 +1,46 @@ +#include "gui.h" + +int main(void) +{ + gui *g; + widget *w, *c1, *c2, *l, *plot, *tl; + int tlcol; + + g = gui_init(); + + c1 = new_container(g, VERTICAL); + c2 = new_container(g, HORIZONTAL); + + l = new_label(g, "this is a good label"); + widget_add_child(g, c2, l, 0); + l = new_label(g, "this is another good label"); + widget_add_child(g, c2, l, -1); + + l = new_label(g, "OH! WHAT A LABEL!"); + widget_add_child(g, c1, l, -1); + + widget_add_child(g, c1, c2, 0); + + plot = new_xy_plot(g, 100, 100, "xy plot test", 30); +#if 0 + c2 = new_container(g, HORIZONTAL); + widget_add_child(g, c2, plot, -1); + widget_add_child(g, c1, c2, -1); +#else + widget_add_child(g, c1, plot, -1); +#endif + + tlcol = new_color(g, "#ddf"); + tl = new_text_list(g, 300, 10, tlcol); + widget_add_child(g, c1, tl, -1); + + text_list_add(g, tl, "hello", -1); + text_list_add(g, tl, "world", -1); + + w = new_toplevel_window(g, 500, 400, "test window"); + widget_add_child(g, w, c1, 0); + + gui_loop(g); + + return 0; +} diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c new file mode 100644 index 0000000000..89b7e8822d --- /dev/null +++ b/common/utils/T/tracer/gui/text_list.c @@ -0,0 +1,95 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include + +static void paint(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + int i, j; +printf("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height); + x_fill_rectangle(g->x, g->xwin, this->background_color, + this->common.x, this->common.y, + this->common.width, this->common.height); + for (i = 0, j = this->starting_line; + i < this->allocated_nlines && j < this->text_count; i++, j++) + x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + this->common.x, + this->common.y + i * this->line_height + this->baseline, + this->text[j]); +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct text_list_widget *w = _w; + *width = w->wanted_width; + *height = w->wanted_nlines * w->line_height; +printf("HINTS text_list wh %d %d\n", *width, *height); +} + +static void allocate( + gui *gui, widget *_this, int x, int y, int width, int height) +{ + struct text_list_widget *this = _this; + this->common.x = x; + this->common.y = y; + this->common.width = width; + this->common.height = height; + this->allocated_nlines = height / this->line_height; +printf("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); +} + +widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) +{ + struct gui *g = _gui; + struct text_list_widget *w; + int dummy; + + glock(g); + + w = new_widget(g, TEXT_LIST, sizeof(struct text_list_widget)); + + w->wanted_nlines = nlines; + x_text_get_dimensions(g->x, ".", &dummy, &w->line_height, &w->baseline); + w->background_color = bgcol; + w->wanted_width = width; + + w->common.paint = paint; + w->common.hints = hints; + w->common.allocate = allocate; + + gunlock(g); + + return w; +} + +/*************************************************************************/ +/* public functions */ +/*************************************************************************/ + +void text_list_add(gui *_gui, widget *_this, const char *text, int position) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + + glock(g); + + if (position < 0) position = this->text_count; + if (position > this->text_count) position = this->text_count; + + this->text_count++; + this->text = realloc(this->text, this->text_count * sizeof(char *)); + if (this->text == NULL) OOM; + + memmove(this->text + position + 1, this->text + position, + (this->text_count-1 - position) * sizeof(char *)); + + this->text[position] = strdup(text); if (this->text[position] == NULL) OOM; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} diff --git a/common/utils/T/tracer/gui/toplevel_window.c b/common/utils/T/tracer/gui/toplevel_window.c new file mode 100644 index 0000000000..b1dd251f6b --- /dev/null +++ b/common/utils/T/tracer/gui/toplevel_window.c @@ -0,0 +1,88 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include + +/**********************************************************************/ +/* callback functions */ +/**********************************************************************/ + +static void repack(gui *g, widget *_this) +{ +printf("REPACK toplevel_window\n"); + struct toplevel_window_widget *this = _this; + if (this->common.children == NULL) ERR("toplevel window has no child\n"); + if (this->common.children->next != NULL) + ERR("toplevel window has too much children\n"); + this->common.children->item->allocate(g, this->common.children->item, + 0 /* x */, 0 /* y */, this->common.width, this->common.height); + send_event(g, DIRTY, this->common.id); +} + +static void add_child(gui *_gui, widget *_this, widget *child, int position) +{ +printf("ADD_CHILD toplevel_window\n"); + struct widget *this = _this; + if (this->children != NULL) { + WARN("toplevel window already has a child\n"); + return; + } + if (position) + WARN("toplevel window doesn't care about 'position' " + "(you passed %d, you should always pass 0)\n", + position); + widget_add_child_internal(_gui, _this, child, 0); /* this does the REPACK */ +} + +/* called when the underlying window is resized by the user or the system */ +static void allocate( + gui *_gui, widget *_this, int x, int y, int width, int height) +{ +printf("ALLOCATE toplevel_window\n"); + struct toplevel_window_widget *this = _this; + this->common.width = width; + this->common.height = height; +// repack(_gui, _this); + send_event(_gui, REPACK, this->common.id); +} + +static void paint(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct toplevel_window_widget *this = _this; +printf("PAINT toplevel_window (%d %d)\n", this->common.width, this->common.height); + x_fill_rectangle(g->x, this->x, BACKGROUND_COLOR, + 0, 0, this->common.width, this->common.height); + g->xwin = this->x; + this->common.children->item->paint(_gui, this->common.children->item); + g->xwin = NULL; /* TODO: remove? it's just in case */ +} + +/**********************************************************************/ +/* creation */ +/**********************************************************************/ + +widget *new_toplevel_window(gui *_gui, int width, int height, char *title) +{ + struct gui *g = _gui; + struct toplevel_window_widget *w; + + glock(g); + + w = new_widget(g, TOPLEVEL_WINDOW, sizeof(struct toplevel_window_widget)); + + w->common.width = width; + w->common.height = height; + + w->x = x_create_window(g->x, width, height, title); + + w->common.repack = repack; + w->common.add_child = add_child; + w->common.allocate = allocate; + w->common.paint = paint; + + gunlock(g); + + return w; +} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c new file mode 100644 index 0000000000..8304420aa1 --- /dev/null +++ b/common/utils/T/tracer/gui/widget.c @@ -0,0 +1,216 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include +#include + +static void default_repack(gui *gui, widget *_this); +static void default_allocate( + gui *gui, widget *_this, int x, int y, int width, int height); +static void default_add_child( + gui *_gui, widget *_this, widget *child, int position); +static void default_hints(gui *g, widget *this, int *width, int *height); + +static void toplevel_list_append(struct gui *g, struct widget *e) +{ + struct widget_list *new; + + new = calloc(1, sizeof(struct widget_list)); + if (new == NULL) OOM; + + new->item = e; + + if (g->toplevel == NULL) { + g->toplevel = new; + new->last = new; + return; + } + + g->toplevel->last->next = new; + g->toplevel->last = new; +} + +widget *new_widget(struct gui *g, enum widget_type type, int size) +{ + struct widget *ret; + + //glock(g); + + ret = calloc(1, size); + if (ret == NULL) OOM; + + ret->repack = default_repack; + ret->add_child = default_add_child; + ret->allocate = default_allocate; + ret->hints = default_hints; + /* there is no default paint, on purpose */ + + ret->type = type; + ret->id = g->next_id; + g->next_id++; + ret->width = 0; + ret->height = 0; + + /* add toplevel windows to g->toplevel */ + if (type == TOPLEVEL_WINDOW) + toplevel_list_append(g, ret); + + //gunlock(g); + + return ret; +} + +/*************************************************************************/ +/* internal functions */ +/*************************************************************************/ + +void widget_add_child_internal( + gui *_gui, widget *parent, widget *child, int position) +{ + struct widget *p = parent; + struct widget *c = child; + struct widget_list *new; + struct widget_list *prev, *cur; + int i; + + new = calloc(1, sizeof(struct widget_list)); + if (new == NULL) OOM; + + new->item = c; + c->parent = p; + + prev = NULL; + cur = p->children; + + for (i = 0; position < 0 || i < position; i++) { + if (cur == NULL) break; + prev = cur; + cur = cur->next; + } + + /* TODO: warn/err if i != position+1? */ + + if (prev == NULL) { + /* new is at head */ + new->next = p->children; + if (p->children != NULL) new->last = p->children->last; + else new->last = new; + p->children = new; + goto repack; + } + + if (cur == NULL) { + /* new is at tail */ + prev->next = new; + p->children->last = new; + goto repack; + } + + /* new is between two existing items */ + prev->next = new; + new->next = cur; + +repack: + send_event(_gui, REPACK, p->id); +} + +/*************************************************************************/ +/* default functions */ +/*************************************************************************/ + +static void default_repack(gui *gui, widget *_this) +{ + struct widget *this = _this; + return this->parent->repack(gui, this->parent); +} + +static void default_add_child( + gui *_gui, widget *_this, widget *child, int position) +{ + struct widget *this = _this; + WARN("cannot add child to widget %s\n", widget_name(this->type)); +} + +static void default_allocate( + gui *gui, widget *_this, int x, int y, int width, int height) +{ + struct widget *this = _this; + this->x = x; + this->y = y; + this->width = width; + this->height = height; +} + +static void default_hints(gui *g, widget *this, int *width, int *height) +{ + *width = 1; + *height = 1; +} + +/*************************************************************************/ +/* utils functions */ +/*************************************************************************/ + +void widget_add_child(gui *_gui, widget *parent, widget *child, int position) +{ + struct widget *this = parent; + glock(_gui); + this->add_child(_gui, parent, child, position); + gunlock(_gui); +} + +static const char *names[] = { + "TOPLEVEL_WINDOW", "CONTAINER", "TEXT_LIST", "XY_PLOT", "BUTTON", "LABEL" +}; +const char *widget_name(enum widget_type type) +{ + switch (type) { + default: break; + case TOPLEVEL_WINDOW: + case CONTAINER: + case TEXT_LIST: + case XY_PLOT: + case BUTTON: + case LABEL: + return names[type]; + } + return "UNKNOWN (error)"; +} + +/*************************************************************************/ +/* find a widget */ +/*************************************************************************/ + +/* TODO: optimize traversal and also use a cache */ +struct widget *_find_widget(struct widget *c, int id) +{ + struct widget_list *l; + struct widget *ret; + if (c == NULL) return NULL; + if (c->id == id) return c; + l = c->children; + while (l) { + ret = _find_widget(l->item, id); + if (ret != NULL) return ret; + l = l->next; + } + return NULL; +} + +struct widget *find_widget(struct gui *g, int id) +{ + struct widget_list *l; + struct widget *ret; + + l = g->toplevel; + + while (l) { + ret = _find_widget(l->item, id); + if (ret != NULL) return ret; + l = l->next; + } + + return NULL; +} diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c new file mode 100644 index 0000000000..b498654fdb --- /dev/null +++ b/common/utils/T/tracer/gui/x.c @@ -0,0 +1,284 @@ +#include "x.h" +#include "x_defs.h" +#include "gui_defs.h" +#include +#include +#include +#include + +int x_connection_fd(x_connection *_x) +{ + struct x_connection *x = _x; + return ConnectionNumber(x->d); +} + +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)) { + gcv.foreground = scol.pixel; + XChangeGC(d, ret, GCForeground, &gcv); + } else ERR("X: could not allocate color '%s'\n", color); + + return ret; +} + +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); + return x->ncolors - 1; +} + +x_connection *x_open(void) +{ + struct x_connection *ret; + + ret = calloc(1, sizeof(struct x_connection)); + if (ret == NULL) OOM; + + ret->d = XOpenDisplay(0); +printf("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 */ + + return ret; +} + +x_window *x_create_window(x_connection *_x, int width, int height, + 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))); + 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))); + + /* enable backing store */ + { + XSetWindowAttributes att; + att.backing_store = Always; + XChangeWindowAttributes(x->d, ret->w, CWBackingStore, &att); + } + + XSelectInput(x->d, ret->w, + KeyPressMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + ExposureMask | + StructureNotifyMask); + + XMapWindow(x->d, ret->w); + +#if 0 + /* wait for window to be mapped */ +printf("wait for map\n"); + while (1) { + XEvent ev; + //XWindowEvent(x->d, ret->w, StructureNotifyMask, &ev); + XWindowEvent(x->d, ret->w, ExposureMask, &ev); +printf("got ev %d\n", ev.type); + //if (ev.type == MapNotify) break; + if (ev.type == Expose) break; + } +printf("XXX create connection %p window %p (win id %d pixmap %d) w h %d %d\n", x, ret, (int)ret->w, (int)ret->p, width, height); +#endif + + return ret; +} + +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) +{ + struct gui *g = _gui; + struct widget_list *cur; + struct x_connection *x = g->x; + struct toplevel_window_widget *w; + +printf("x_events START\n"); + /* preprocessing (to "compress" events) */ + cur = g->toplevel; + while (cur) { + struct x_window *xw; + w = (struct toplevel_window_widget *)cur->item; + xw = w->x; + xw->redraw = 0; + xw->repaint = 0; + xw->resize = 0; + cur = cur->next; + } + + while (XPending(x->d)) { + XEvent ev; + XNextEvent(x->d, &ev); +printf("XEV %d\n", ev.type); + switch (ev.type) { + 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.xexpose.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; +printf("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); + } + break; +#if 0 + case MapNotify: + if ((w = find_x_window(g, ev.xexpose.window)) != NULL) { + struct x_window *xw = w->x; + xw->repaint = 1; + } + break; +#endif + default: WARN("TODO: X event type %d\n", ev.type); break; + } + } + + /* postprocessing */ +printf("post processing\n"); + cur = g->toplevel; + while (cur) { + struct toplevel_window_widget *w = + (struct toplevel_window_widget *)cur->item; + struct x_window *xw = w->x; + if (xw->resize) { +printf("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; + xw->height = xw->new_height; + XFreePixmap(x->d, xw->p); + xw->p = XCreatePixmap(x->d, xw->w, xw->width, xw->height, + DefaultDepth(x->d, DefaultScreen(x->d))); + //xw->repaint = 1; + } + } + if (xw->repaint) { + w->common.paint(g, w); + xw->redraw = 1; + } + if (xw->redraw) { + struct x_connection *x = g->x; +printf("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); + } + cur = cur->next; + } +printf("x_events DONE\n"); +} + +void x_flush(x_connection *_x) +{ + struct x_connection *x = _x; + XFlush(x->d); +} + +void x_text_get_dimensions(x_connection *_c, const char *t, + int *width, int *height, int *baseline) +{ + struct x_connection *c = _c; + int dir; + int ascent; + int descent; + XCharStruct overall; + + /* TODO: don't use XQueryTextExtents (X roundtrip) */ + XQueryTextExtents(c->d, XGContextFromGC(c->colors[1]), t, strlen(t), + &dir, &ascent, &descent, &overall); + +//printf("dir %d ascent %d descent %d lbearing %d rbearing %d width %d ascent %d descent %d\n", dir, ascent, descent, overall.lbearing, overall.rbearing, overall.width, overall.ascent, overall.descent); + + *width = overall.width; + *height = ascent + descent; + *baseline = ascent; +} + +/***********************************************************************/ +/* public drawing functions */ +/***********************************************************************/ + +void x_draw_line(x_connection *_c, x_window *_w, int color, + 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) +{ + 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) +{ + 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 color, + int x, int y, const char *t) +{ + struct x_connection *c = _c; + struct x_window *w = _w; + int tlen = strlen(t); + XDrawString(c->d, w->p, c->colors[color], x, y, t, tlen); +} + +void x_draw(x_connection *_c, x_window *_w) +{ + struct x_connection *c = _c; + struct x_window *w = _w; +printf("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); + XCopyArea(c->d, w->p, w->w, c->colors[1], 0, 0, w->width, w->height, 0, 0); +} diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h new file mode 100644 index 0000000000..41cf65393b --- /dev/null +++ b/common/utils/T/tracer/gui/x.h @@ -0,0 +1,47 @@ +#ifndef _X_H_ +#define _X_H_ + +/* public X interface */ + +#define BACKGROUND_COLOR 0 +#define FOREGROUND_COLOR 1 + +typedef void x_connection; +typedef void x_window; + +x_connection *x_open(void); + +x_window *x_create_window(x_connection *x, int width, int height, + char *title); + +int x_connection_fd(x_connection *x); + +void x_flush(x_connection *x); + +int x_new_color(x_connection *x, char *color); + +/* for x_events, we pass the gui */ +#include "gui.h" +void x_events(gui *gui); + +void x_text_get_dimensions(x_connection *, const char *t, + int *width, int *height, int *baseline); + +/* drawing functions */ + +void x_draw_line(x_connection *c, x_window *w, int color, + int x1, int y1, int x2, int y2); + +void x_draw_rectangle(x_connection *c, x_window *w, int color, + int x, int y, int width, int height); + +void x_fill_rectangle(x_connection *c, x_window *w, int color, + int x, int y, int width, int height); + +void x_draw_string(x_connection *_c, x_window *_w, int color, + int x, int y, const char *t); + +/* this function copies the pixmap to the window */ +void x_draw(x_connection *c, x_window *w); + +#endif /* _X_H_ */ diff --git a/common/utils/T/tracer/gui/x_defs.h b/common/utils/T/tracer/gui/x_defs.h new file mode 100644 index 0000000000..43b99f7cf7 --- /dev/null +++ b/common/utils/T/tracer/gui/x_defs.h @@ -0,0 +1,23 @@ +#ifndef _X_DEFS_H_ +#define _X_DEFS_H_ + +#include + +struct x_connection { + Display *d; + GC *colors; + int ncolors; +}; + +struct x_window { + Window w; + Pixmap p; + int width; + int height; + /* below: internal data used for X events handling */ + int redraw; + int repaint; + int resize, new_width, new_height; +}; + +#endif /* _X_DEFS_H_ */ diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c new file mode 100644 index 0000000000..b2775fa054 --- /dev/null +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -0,0 +1,173 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include +#include + +static void paint(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct xy_plot_widget *this = _this; + int wanted_plot_width, allocated_plot_width; + int wanted_plot_height, allocated_plot_height; + float pxsize; + float ticdist; + float tic; + float ticstep; + int k, kmin, kmax; + float allocated_xmin, allocated_xmax; + float allocated_ymin, allocated_ymax; + float center; + +printf("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); + +//x_draw_rectangle(g->x, g->xwin, 1, this->common.x, this->common.y, this->common.width, this->common.height); + + /* plot zone */ + /* TODO: refine height - height of hrule text may be != from label */ + x_draw_rectangle(g->x, g->xwin, 1, + this->common.x + this->vrule_width, + this->common.y, + this->common.width - this->vrule_width -1, /* -1 to see right border */ + this->common.height - this->label_height * 2); + + /* horizontal tics */ + wanted_plot_width = this->wanted_width; + allocated_plot_width = this->common.width - this->vrule_width; + pxsize = (this->xmax - this->xmin) / wanted_plot_width; + ticdist = 100; + tic = floor(log10(ticdist * pxsize)); + ticstep = powf(10, tic); + center = (this->xmax + this->xmin) / 2; + allocated_xmin = center - ((this->xmax - this->xmin) * + allocated_plot_width / wanted_plot_width) / 2; + allocated_xmax = center + ((this->xmax - this->xmin) * + allocated_plot_width / wanted_plot_width) / 2; + /* adjust tic if too tight */ +printf("pre x ticstep %g\n", ticstep); + while (1) { + if (ticstep / (allocated_xmax - allocated_xmin) + * (allocated_plot_width - 1) > 40) break; + ticstep *= 2; + } +printf("post x ticstep %g\n", ticstep); +printf("xmin/max %g %g width wanted allocated %d %d alloc xmin/max %g %g ticstep %g\n", this->xmin, this->xmax, wanted_plot_width, allocated_plot_width, allocated_xmin, allocated_xmax, ticstep); + kmin = ceil(allocated_xmin / ticstep); + kmax = floor(allocated_xmax / ticstep); + for (k = kmin; k <= kmax; k++) { +/* + (k * ticstep - allocated_xmin) / (allocated_max - allocated_xmin) = + (x - 0) / (allocated_plot_width-1 - 0) + */ + char v[64]; + int vwidth, dummy; + float x = (k * ticstep - allocated_xmin) / + (allocated_xmax - allocated_xmin) * + (allocated_plot_width - 1); + x_draw_line(g->x, g->xwin, FOREGROUND_COLOR, + this->common.x + this->vrule_width + x, + this->common.y + this->common.height - this->label_height * 2, + this->common.x + this->vrule_width + x, + this->common.y + this->common.height - this->label_height * 2 - 5); + sprintf(v, "%g", k * ticstep); + x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy); + x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + this->common.x + this->vrule_width + x - vwidth/2, + this->common.y + this->common.height - this->label_height * 2 + this->label_baseline, + v); +printf("tic k %d val %g x %g\n", k, k * ticstep, x); + } + + /* vertical tics */ + wanted_plot_height = this->wanted_height; + allocated_plot_height = this->common.height - this->label_height * 2; + pxsize = (this->ymax - this->ymin) / wanted_plot_height; + ticdist = 30; + tic = floor(log10(ticdist * pxsize)); + ticstep = powf(10, tic); + center = (this->ymax + this->ymin) / 2; + allocated_ymin = center - ((this->ymax - this->ymin) * + allocated_plot_height / wanted_plot_height) / 2; + allocated_ymax = center + ((this->ymax - this->ymin) * + allocated_plot_height / wanted_plot_height) / 2; + /* adjust tic if too tight */ +printf("pre y ticstep %g\n", ticstep); + while (1) { + if (ticstep / (allocated_ymax - allocated_ymin) + * (allocated_plot_height - 1) > 20) break; + ticstep *= 2; + } +printf("post y ticstep %g\n", ticstep); +printf("ymin/max %g %g height wanted allocated %d %d alloc ymin/max %g %g ticstep %g\n", this->ymin, this->ymax, wanted_plot_height, allocated_plot_height, allocated_ymin, allocated_ymax, ticstep); + kmin = ceil(allocated_ymin / ticstep); + kmax = floor(allocated_ymax / ticstep); + for (k = kmin; k <= kmax; k++) { + char v[64]; + int vwidth, dummy; + float y = (k * ticstep - allocated_ymin) / + (allocated_ymax - allocated_ymin) * + (allocated_plot_height - 1); + sprintf(v, "%g", k * ticstep); + x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy); + x_draw_line(g->x, g->xwin, FOREGROUND_COLOR, + this->common.x + this->vrule_width, + this->common.y + y, + this->common.x + this->vrule_width + 5, + this->common.y + y); + x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + this->common.x + this->vrule_width - vwidth - 2, + this->common.y + y - this->label_height / 2 + this->label_baseline, + v); + } + + /* label at bottom, in the middle */ + x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + this->common.x + (this->common.width - this->label_width) / 2, + this->common.y + this->common.height - this->label_height + + this->label_baseline, + this->label); +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct xy_plot_widget *w = _w; + *width = w->wanted_width + w->vrule_width; + *height = w->wanted_height + w->label_height * 2; /* TODO: refine */ +printf("HINTS xy plot wh %d %d (vrule_width %d) (wanted wh %d %d)\n", *width, *height, w->vrule_width, w->wanted_width, w->wanted_height); +} + +widget *new_xy_plot(gui *_gui, int width, int height, char *label, + int vruler_width) +{ + struct gui *g = _gui; + struct xy_plot_widget *w; + + glock(g); + + w = new_widget(g, XY_PLOT, sizeof(struct xy_plot_widget)); + + w->label = strdup(label); if (w->label == NULL) OOM; + /* TODO: be sure calling X there is valid wrt "global model" (we are + * not in the "gui thread") */ + x_text_get_dimensions(g->x, label, &w->label_width, &w->label_height, + &w->label_baseline); +printf("XY PLOT label wh %d %d\n", w->label_width, w->label_height); + + w->wanted_width = width; + w->wanted_height = height; + w->vrule_width = vruler_width; + + w->xmin = -1; + w->xmax = 1; + w->ymin = -1; + w->ymax = 1; + + w->common.paint = paint; + w->common.hints = hints; + + gunlock(g); + + return w; +} From 066bac4a14d36cb4e8b35cd8f1709106a66e0478 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 11:28:33 +0200 Subject: [PATCH 030/217] remove T_IDs.h from git - this file is generated when compiling the T tracer (separate compilation for the moment) --- common/utils/T/T_IDs.h | 135 ----------------------------------------- 1 file changed, 135 deletions(-) delete mode 100644 common/utils/T/T_IDs.h diff --git a/common/utils/T/T_IDs.h b/common/utils/T/T_IDs.h deleted file mode 100644 index eb5377186c..0000000000 --- a/common/utils/T/T_IDs.h +++ /dev/null @@ -1,135 +0,0 @@ -/* generated file, do not edit by hand */ - -#define T_ENB_INPUT_SIGNAL T_ID(0) -#define T_ENB_UL_CHANNEL_ESTIMATE T_ID(1) -#define T_PUSCH_IQ T_ID(2) -#define T_PUCCH_1AB_IQ T_ID(3) -#define T_PUCCH_1_ENERGY T_ID(4) -#define T_LEGACY_MAC_INFO T_ID(5) -#define T_LEGACY_MAC_ERROR T_ID(6) -#define T_LEGACY_MAC_WARNING T_ID(7) -#define T_LEGACY_MAC_DEBUG T_ID(8) -#define T_LEGACY_MAC_TRACE T_ID(9) -#define T_LEGACY_PHY_INFO T_ID(10) -#define T_LEGACY_PHY_ERROR T_ID(11) -#define T_LEGACY_PHY_WARNING T_ID(12) -#define T_LEGACY_PHY_DEBUG T_ID(13) -#define T_LEGACY_PHY_TRACE T_ID(14) -#define T_LEGACY_S1AP_INFO T_ID(15) -#define T_LEGACY_S1AP_ERROR T_ID(16) -#define T_LEGACY_S1AP_WARNING T_ID(17) -#define T_LEGACY_S1AP_DEBUG T_ID(18) -#define T_LEGACY_S1AP_TRACE T_ID(19) -#define T_LEGACY_X2AP_INFO T_ID(20) -#define T_LEGACY_X2AP_ERROR T_ID(21) -#define T_LEGACY_X2AP_WARNING T_ID(22) -#define T_LEGACY_X2AP_DEBUG T_ID(23) -#define T_LEGACY_X2AP_TRACE T_ID(24) -#define T_LEGACY_RRC_INFO T_ID(25) -#define T_LEGACY_RRC_ERROR T_ID(26) -#define T_LEGACY_RRC_WARNING T_ID(27) -#define T_LEGACY_RRC_DEBUG T_ID(28) -#define T_LEGACY_RRC_TRACE T_ID(29) -#define T_LEGACY_RLC_INFO T_ID(30) -#define T_LEGACY_RLC_ERROR T_ID(31) -#define T_LEGACY_RLC_WARNING T_ID(32) -#define T_LEGACY_RLC_DEBUG T_ID(33) -#define T_LEGACY_RLC_TRACE T_ID(34) -#define T_LEGACY_PDCP_INFO T_ID(35) -#define T_LEGACY_PDCP_ERROR T_ID(36) -#define T_LEGACY_PDCP_WARNING T_ID(37) -#define T_LEGACY_PDCP_DEBUG T_ID(38) -#define T_LEGACY_PDCP_TRACE T_ID(39) -#define T_LEGACY_ENB_APP_INFO T_ID(40) -#define T_LEGACY_ENB_APP_ERROR T_ID(41) -#define T_LEGACY_ENB_APP_WARNING T_ID(42) -#define T_LEGACY_ENB_APP_DEBUG T_ID(43) -#define T_LEGACY_ENB_APP_TRACE T_ID(44) -#define T_LEGACY_SCTP_INFO T_ID(45) -#define T_LEGACY_SCTP_ERROR T_ID(46) -#define T_LEGACY_SCTP_WARNING T_ID(47) -#define T_LEGACY_SCTP_DEBUG T_ID(48) -#define T_LEGACY_SCTP_TRACE T_ID(49) -#define T_LEGACY_UDP__INFO T_ID(50) -#define T_LEGACY_UDP__ERROR T_ID(51) -#define T_LEGACY_UDP__WARNING T_ID(52) -#define T_LEGACY_UDP__DEBUG T_ID(53) -#define T_LEGACY_UDP__TRACE T_ID(54) -#define T_LEGACY_NAS_INFO T_ID(55) -#define T_LEGACY_NAS_ERROR T_ID(56) -#define T_LEGACY_NAS_WARNING T_ID(57) -#define T_LEGACY_NAS_DEBUG T_ID(58) -#define T_LEGACY_NAS_TRACE T_ID(59) -#define T_LEGACY_HW_INFO T_ID(60) -#define T_LEGACY_HW_ERROR T_ID(61) -#define T_LEGACY_HW_WARNING T_ID(62) -#define T_LEGACY_HW_DEBUG T_ID(63) -#define T_LEGACY_HW_TRACE T_ID(64) -#define T_LEGACY_EMU_INFO T_ID(65) -#define T_LEGACY_EMU_ERROR T_ID(66) -#define T_LEGACY_EMU_WARNING T_ID(67) -#define T_LEGACY_EMU_DEBUG T_ID(68) -#define T_LEGACY_EMU_TRACE T_ID(69) -#define T_LEGACY_OTG_INFO T_ID(70) -#define T_LEGACY_OTG_ERROR T_ID(71) -#define T_LEGACY_OTG_WARNING T_ID(72) -#define T_LEGACY_OTG_DEBUG T_ID(73) -#define T_LEGACY_OTG_TRACE T_ID(74) -#define T_LEGACY_OCG_INFO T_ID(75) -#define T_LEGACY_OCG_ERROR T_ID(76) -#define T_LEGACY_OCG_WARNING T_ID(77) -#define T_LEGACY_OCG_DEBUG T_ID(78) -#define T_LEGACY_OCG_TRACE T_ID(79) -#define T_LEGACY_OCM_INFO T_ID(80) -#define T_LEGACY_OCM_ERROR T_ID(81) -#define T_LEGACY_OCM_WARNING T_ID(82) -#define T_LEGACY_OCM_DEBUG T_ID(83) -#define T_LEGACY_OCM_TRACE T_ID(84) -#define T_LEGACY_OIP_INFO T_ID(85) -#define T_LEGACY_OIP_ERROR T_ID(86) -#define T_LEGACY_OIP_WARNING T_ID(87) -#define T_LEGACY_OIP_DEBUG T_ID(88) -#define T_LEGACY_OIP_TRACE T_ID(89) -#define T_LEGACY_OMG_INFO T_ID(90) -#define T_LEGACY_OMG_ERROR T_ID(91) -#define T_LEGACY_OMG_WARNING T_ID(92) -#define T_LEGACY_OMG_DEBUG T_ID(93) -#define T_LEGACY_OMG_TRACE T_ID(94) -#define T_LEGACY_OPT_INFO T_ID(95) -#define T_LEGACY_OPT_ERROR T_ID(96) -#define T_LEGACY_OPT_WARNING T_ID(97) -#define T_LEGACY_OPT_DEBUG T_ID(98) -#define T_LEGACY_OPT_TRACE T_ID(99) -#define T_LEGACY_GTPU_INFO T_ID(100) -#define T_LEGACY_GTPU_ERROR T_ID(101) -#define T_LEGACY_GTPU_WARNING T_ID(102) -#define T_LEGACY_GTPU_DEBUG T_ID(103) -#define T_LEGACY_GTPU_TRACE T_ID(104) -#define T_LEGACY_TMR_INFO T_ID(105) -#define T_LEGACY_TMR_ERROR T_ID(106) -#define T_LEGACY_TMR_WARNING T_ID(107) -#define T_LEGACY_TMR_DEBUG T_ID(108) -#define T_LEGACY_TMR_TRACE T_ID(109) -#define T_LEGACY_OSA_INFO T_ID(110) -#define T_LEGACY_OSA_ERROR T_ID(111) -#define T_LEGACY_OSA_WARNING T_ID(112) -#define T_LEGACY_OSA_DEBUG T_ID(113) -#define T_LEGACY_OSA_TRACE T_ID(114) -#define T_LEGACY_component_INFO T_ID(115) -#define T_LEGACY_component_ERROR T_ID(116) -#define T_LEGACY_component_WARNING T_ID(117) -#define T_LEGACY_component_DEBUG T_ID(118) -#define T_LEGACY_component_TRACE T_ID(119) -#define T_LEGACY_componentP_INFO T_ID(120) -#define T_LEGACY_componentP_ERROR T_ID(121) -#define T_LEGACY_componentP_WARNING T_ID(122) -#define T_LEGACY_componentP_DEBUG T_ID(123) -#define T_LEGACY_componentP_TRACE T_ID(124) -#define T_LEGACY_CLI_INFO T_ID(125) -#define T_LEGACY_CLI_ERROR T_ID(126) -#define T_LEGACY_CLI_WARNING T_ID(127) -#define T_LEGACY_CLI_DEBUG T_ID(128) -#define T_LEGACY_CLI_TRACE T_ID(129) -#define T_first T_ID(130) -#define T_buf_test T_ID(131) -#define T_NUMBER_OF_IDS 132 From 2c4bc7315542f8bbd49c30d0bbe801b019810df0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 16:39:02 +0200 Subject: [PATCH 031/217] clear newly created pixmap to avoid some flickering when resizing windows --- common/utils/T/tracer/gui/x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index b498654fdb..04b110a435 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -74,6 +74,8 @@ x_window *x_create_window(x_connection *_x, int width, int height, ret->p = XCreatePixmap(x->d, ret->w, width, height, DefaultDepth(x->d, DefaultScreen(x->d))); + XFillRectangle(x->d, ret->p, x->colors[BACKGROUND_COLOR], + 0, 0, width, height); /* enable backing store */ { @@ -194,6 +196,8 @@ printf("resize old %d %d new %d %d\n", xw->width, xw->height, xw->new_width, xw- XFreePixmap(x->d, xw->p); xw->p = XCreatePixmap(x->d, xw->w, xw->width, xw->height, DefaultDepth(x->d, DefaultScreen(x->d))); + XFillRectangle(x->d, xw->p, x->colors[BACKGROUND_COLOR], + 0, 0, xw->width, xw->height); //xw->repaint = 1; } } From 5a9401cd46256c377cca9912c7cbcd951d03367d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 17:38:11 +0200 Subject: [PATCH 032/217] remove useless warning --- common/utils/T/tracer/gui/toplevel_window.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/common/utils/T/tracer/gui/toplevel_window.c b/common/utils/T/tracer/gui/toplevel_window.c index b1dd251f6b..6231329077 100644 --- a/common/utils/T/tracer/gui/toplevel_window.c +++ b/common/utils/T/tracer/gui/toplevel_window.c @@ -28,10 +28,6 @@ printf("ADD_CHILD toplevel_window\n"); WARN("toplevel window already has a child\n"); return; } - if (position) - WARN("toplevel window doesn't care about 'position' " - "(you passed %d, you should always pass 0)\n", - position); widget_add_child_internal(_gui, _this, child, 0); /* this does the REPACK */ } From 7e382d2f9ac3e2690ad045fda07128bdd998bccd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 17:39:16 +0200 Subject: [PATCH 033/217] minor modification --- common/utils/T/tracer/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/main.c b/common/utils/T/tracer/main.c index cf8f8aac85..639a0b5652 100644 --- a/common/utils/T/tracer/main.c +++ b/common/utils/T/tracer/main.c @@ -546,7 +546,7 @@ no_database: goto no_init_message; } - /* send the first message - activate all traces */ + /* send the first message - activate selected traces */ t = 0; if (write(s, &t, 1) != 1) abort(); l = 0; From 4006af82903cf15ef1d46fc2d5f6d6a23e6788ca Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 17:40:28 +0200 Subject: [PATCH 034/217] minor modification --- common/utils/T/tracer/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index fab5012c28..0363cc9438 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -10,10 +10,12 @@ CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer -OBJS=main.o plot.o database.o forward.o gui/gui.a +OBJS=main.o plot.o database.o forward.o gui.o -$(PROG): $(OBJS) - $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) +$(PROG): $(OBJS) gui/gui.a + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) gui/gui.a + +.PHONY: gui/gui.a gui/gui.a: cd gui && make From 078b4ab9b97e5314bb3c1e6fbdbd985aafc57923 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 17:50:37 +0200 Subject: [PATCH 035/217] some minor modification again --- common/utils/T/tracer/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 0363cc9438..5ea5f4dd95 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -12,8 +12,8 @@ LIBS += -lrt PROG=tracer OBJS=main.o plot.o database.o forward.o gui.o -$(PROG): $(OBJS) gui/gui.a - $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) gui/gui.a +$(PROG): gui/gui.a $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) .PHONY: gui/gui.a From 3e334165170f1ac6fb9c2bd153a4d667c1f656b5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 18:02:03 +0200 Subject: [PATCH 036/217] fix container size allocation --- common/utils/T/tracer/gui/container.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 23f7a42295..bc14a6d0e4 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -3,6 +3,8 @@ #include #include +#define MAX(a, b) ((a)>(b)?(a):(b)) + static void repack(gui *g, widget *_this) { printf("REPACK container %p\n", _this); @@ -84,7 +86,7 @@ hints_ok: l->item->hints(g, l->item, &cwidth, &cheight); l->item->allocate(g, l->item, this->common.x, this->common.y + cy, //this->hint_width, cheight); - width, cheight); + MAX(width, cwidth), cheight); cy += cheight; l = l->next; } @@ -118,7 +120,7 @@ hints_ok: while (l) { l->item->hints(g, l->item, &cwidth, &cheight); l->item->allocate(g, l->item, this->common.x + cx, this->common.y, - cwidth, this->hint_height); + cwidth, MAX(height, cheight)/* this->hint_height */); cx += cwidth; l = l->next; } From 062f7fad97ade06b21889070f40de3f8516f0f67 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 18:31:37 +0200 Subject: [PATCH 037/217] add clear function to the gui --- common/utils/T/tracer/gui/event.c | 1 + common/utils/T/tracer/gui/gui_defs.h | 1 + common/utils/T/tracer/gui/widget.c | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/common/utils/T/tracer/gui/event.c b/common/utils/T/tracer/gui/event.c index fe7f9fbb47..d5ead45a79 100644 --- a/common/utils/T/tracer/gui/event.c +++ b/common/utils/T/tracer/gui/event.c @@ -132,6 +132,7 @@ static void dirty_event(struct gui *g, int id) if (win == NULL) { WARN("widget id %d not contained in a window\n", id); return; } g->xwin = win->x; + w->clear(g, w); w->paint(g, w); g->xwin = NULL; g->repainted = 1; diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index d7032f95da..8a3e4b7701 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -46,6 +46,7 @@ struct widget { void (*allocate)(gui *g, widget *this, int x, int y, int width, int height); void (*hints)(gui *g, widget *this, int *width, int *height); void (*paint)(gui *g, widget *this); + void (*clear)(gui *g, widget *this); }; struct widget_list { diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 8304420aa1..103d36d452 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -6,6 +6,7 @@ #include #include +static void default_clear(gui *gui, widget *_this); static void default_repack(gui *gui, widget *_this); static void default_allocate( gui *gui, widget *_this, int x, int y, int width, int height); @@ -41,6 +42,7 @@ widget *new_widget(struct gui *g, enum widget_type type, int size) ret = calloc(1, size); if (ret == NULL) OOM; + ret->clear = default_clear; ret->repack = default_repack; ret->add_child = default_add_child; ret->allocate = default_allocate; @@ -120,6 +122,14 @@ repack: /* default functions */ /*************************************************************************/ +static void default_clear(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct widget *this = _this; + x_fill_rectangle(g->x, g->xwin, BACKGROUND_COLOR, + this->x, this->y, this->width, this->height); +} + static void default_repack(gui *gui, widget *_this) { struct widget *this = _this; From 98d2cf8b0621cadab1a3a62eb5c6be5c85d11a15 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 18:34:26 +0200 Subject: [PATCH 038/217] add X functions to plot points --- common/utils/T/tracer/gui/x.c | 28 ++++++++++++++++++++++++++++ common/utils/T/tracer/gui/x.h | 6 ++++++ common/utils/T/tracer/gui/x_defs.h | 3 +++ 3 files changed, 37 insertions(+) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 04b110a435..e68e3bcb92 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -286,3 +286,31 @@ void x_draw(x_connection *_c, x_window *_w) printf("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); XCopyArea(c->d, w->p, w->w, c->colors[1], 0, 0, w->width, w->height, 0, 0); } + +/* 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) +{ + 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; + } + + c->pts[c->pts_size].x = x; + c->pts[c->pts_size].y = y; + c->pts_size++; +} + +void x_plot_points(x_connection *_c, x_window *_w, int color) +{ + struct x_connection *c = _c; +fprintf(stderr, "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); + c->pts_size = 0; +} diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index 41cf65393b..e8f1d42d13 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -41,6 +41,12 @@ void x_fill_rectangle(x_connection *c, x_window *w, int color, void x_draw_string(x_connection *_c, x_window *_w, int color, int x, int y, const char *t); +/* specials functions to plot many points + * you call several times x_add_point() then x_plot_points() + */ +void x_add_point(x_connection *c, int x, int y); +void x_plot_points(x_connection *c, x_window *w, int color); + /* this function copies the pixmap to the window */ void x_draw(x_connection *c, x_window *w); diff --git a/common/utils/T/tracer/gui/x_defs.h b/common/utils/T/tracer/gui/x_defs.h index 43b99f7cf7..41817d06ce 100644 --- a/common/utils/T/tracer/gui/x_defs.h +++ b/common/utils/T/tracer/gui/x_defs.h @@ -7,6 +7,9 @@ struct x_connection { Display *d; GC *colors; int ncolors; + XPoint *pts; + int pts_size; + int pts_maxsize; }; struct x_window { From 8114422fc5d25bf4ed54bc48e91d0c60d7c3157d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 18:35:43 +0200 Subject: [PATCH 039/217] plot points in XY plot --- common/utils/T/tracer/gui/gui.h | 2 + common/utils/T/tracer/gui/xy_plot.c | 65 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 846b16457d..45acf8de3d 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -23,6 +23,8 @@ widget *new_text_list(gui *_gui, int width, int nlines, int background_color); void xy_plot_set_range(gui *gui, widget *this, float xmin, float xmax, float ymin, float ymax); +void xy_plot_set_points(gui *gui, widget *this, + int npoints, float *x, float *y); void text_list_add(gui *gui, widget *this, const char *text, int position); diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index b2775fa054..8c02040b71 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -20,6 +20,7 @@ static void paint(gui *_gui, widget *_this) float allocated_xmin, allocated_xmax; float allocated_ymin, allocated_ymax; float center; + int i; printf("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); @@ -128,6 +129,24 @@ printf("ymin/max %g %g height wanted allocated %d %d alloc ymin/max %g %g ticste this->common.y + this->common.height - this->label_height + this->label_baseline, this->label); + + /* points */ + float ax, bx, ay, by; + ax = (allocated_plot_width-1) / (allocated_xmax - allocated_xmin); + bx = -ax * allocated_xmin; + ay = (allocated_plot_height-1) / (allocated_ymax - allocated_ymin); + by = -ay * allocated_ymin; + for (i = 0; i < this->npoints; i++) { + int x, y; + x = ax * this->x[i] + bx; + y = ay * this->y[i] + by; + if (x >= 0 && x < allocated_plot_width && + y >= 0 && y < allocated_plot_height) + x_add_point(g->x, + this->common.x + this->vrule_width + x, + this->common.y + y); + } + x_plot_points(g->x, g->xwin, FOREGROUND_COLOR); } static void hints(gui *_gui, widget *_w, int *width, int *height) @@ -171,3 +190,49 @@ printf("XY PLOT label wh %d %d\n", w->label_width, w->label_height); return w; } + +/*************************************************************************/ +/* public functions */ +/*************************************************************************/ + +void xy_plot_set_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); + + this->xmin = xmin; + this->xmax = xmax; + this->ymin = ymin; + this->ymax = ymax; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} + +void xy_plot_set_points(gui *_gui, widget *_this, + int npoints, float *x, float *y) +{ + struct gui *g = _gui; + struct xy_plot_widget *this = _this; + + glock(g); + + if (npoints != this->npoints) { + free(this->x); + free(this->y); + this->x = calloc(sizeof(float), npoints); + this->y = calloc(sizeof(float), npoints); + this->npoints = npoints; + } + + memcpy(this->x, x, npoints * sizeof(float)); + memcpy(this->y, y, npoints * sizeof(float)); + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} From 71b5c59fd5b93608d092e7c1920c9c3d99f304bd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 11 Apr 2016 18:43:17 +0200 Subject: [PATCH 040/217] minor modification --- common/utils/T/tracer/gui/xy_plot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index 8c02040b71..5f6a182b21 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -76,7 +76,8 @@ printf("xmin/max %g %g width wanted allocated %d %d alloc xmin/max %g %g ticstep x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy); x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, this->common.x + this->vrule_width + x - vwidth/2, - this->common.y + this->common.height - this->label_height * 2 + this->label_baseline, + this->common.y + this->common.height - this->label_height * 2 + + this->label_baseline, v); printf("tic k %d val %g x %g\n", k, k * ticstep, x); } From a1aa6658418fb94b449ece27c88d079b85306468 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 12 Apr 2016 11:45:15 +0200 Subject: [PATCH 041/217] flip vertically XY plot, it was plotted the other way around --- common/utils/T/tracer/gui/xy_plot.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index 5f6a182b21..3c0b05f60d 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -22,10 +22,17 @@ static void paint(gui *_gui, widget *_this) float center; int i; +# define FLIP(v) (-(v) + allocated_plot_height-1) + printf("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); //x_draw_rectangle(g->x, g->xwin, 1, this->common.x, this->common.y, this->common.width, this->common.height); + wanted_plot_width = this->wanted_width; + allocated_plot_width = this->common.width - this->vrule_width; + wanted_plot_height = this->wanted_height; + allocated_plot_height = this->common.height - this->label_height * 2; + /* plot zone */ /* TODO: refine height - height of hrule text may be != from label */ x_draw_rectangle(g->x, g->xwin, 1, @@ -35,8 +42,6 @@ printf("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this- this->common.height - this->label_height * 2); /* horizontal tics */ - wanted_plot_width = this->wanted_width; - allocated_plot_width = this->common.width - this->vrule_width; pxsize = (this->xmax - this->xmin) / wanted_plot_width; ticdist = 100; tic = floor(log10(ticdist * pxsize)); @@ -83,8 +88,6 @@ printf("tic k %d val %g x %g\n", k, k * ticstep, x); } /* vertical tics */ - wanted_plot_height = this->wanted_height; - allocated_plot_height = this->common.height - this->label_height * 2; pxsize = (this->ymax - this->ymin) / wanted_plot_height; ticdist = 30; tic = floor(log10(ticdist * pxsize)); @@ -115,12 +118,12 @@ printf("ymin/max %g %g height wanted allocated %d %d alloc ymin/max %g %g ticste x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy); x_draw_line(g->x, g->xwin, FOREGROUND_COLOR, this->common.x + this->vrule_width, - this->common.y + y, + this->common.y + FLIP(y), this->common.x + this->vrule_width + 5, - this->common.y + y); + this->common.y + FLIP(y)); x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, this->common.x + this->vrule_width - vwidth - 2, - this->common.y + y - this->label_height / 2 + this->label_baseline, + this->common.y + FLIP(y) - this->label_height/2+this->label_baseline, v); } @@ -145,7 +148,7 @@ printf("ymin/max %g %g height wanted allocated %d %d alloc ymin/max %g %g ticste y >= 0 && y < allocated_plot_height) x_add_point(g->x, this->common.x + this->vrule_width + x, - this->common.y + y); + this->common.y + FLIP(y)); } x_plot_points(g->x, g->xwin, FOREGROUND_COLOR); } From 4e88857b275cfe81fd6dd2f119e7c94081af7573 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 25 Apr 2016 17:27:22 +0200 Subject: [PATCH 042/217] let the soft-modem (or the program being traced, whatever it is) try to connect until it succeeds --- common/utils/T/T.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 13bf25b324..4876fe8652 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -113,15 +113,27 @@ void T_connect_to_tracer(char *addr, int port) int T_shm_fd; #endif + if (strcmp(addr, "127.0.0.1") != 0) { + printf("error: local tracer must be on same host\n"); + abort(); + } + + printf("connecting to local tracer on port %d\n", port); +again: s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("socket"); exit(1); } a.sin_family = AF_INET; a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(addr); + a.sin_addr.s_addr = inet_addr("127.0.0.1"); - if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) - { perror("connect"); exit(1); } + if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) { + perror("connect"); + close(s); + printf("trying again in 1s\n"); + sleep(1); + goto again; + } /* wait for first message - initial list of active T events */ get_message(s); From e7faea3553ac35823091814e77fdb6eca8424ea3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 25 Apr 2016 17:53:58 +0200 Subject: [PATCH 043/217] split tracer in local/remote and some work on the new gui --- common/utils/T/tracer/Makefile | 33 +---- common/utils/T/tracer/Makefile.local | 21 +++ common/utils/T/tracer/Makefile.remote | 26 ++++ common/utils/T/tracer/defs.h | 5 + common/utils/T/tracer/forward.c | 14 +- common/utils/T/tracer/local.c | 138 ++++++++++++++++++ common/utils/T/tracer/{main.c => remote.c} | 159 +++------------------ 7 files changed, 231 insertions(+), 165 deletions(-) create mode 100644 common/utils/T/tracer/Makefile.local create mode 100644 common/utils/T/tracer/Makefile.remote create mode 100644 common/utils/T/tracer/local.c rename common/utils/T/tracer/{main.c => remote.c} (82%) diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 5ea5f4dd95..9069d2be2c 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -1,30 +1,11 @@ -CC=gcc -CFLAGS=-Wall -g -pthread -DT_TRACER +all: local remote -#CFLAGS += -O3 -ffast-math -fomit-frame-pointer +local: + make -f Makefile.local -LIBS=-lX11 -lm - -#comment those two lines to NOT use shared memory -CFLAGS += -DT_USE_SHARED_MEMORY -LIBS += -lrt - -PROG=tracer -OBJS=main.o plot.o database.o forward.o gui.o - -$(PROG): gui/gui.a $(OBJS) - $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) - -.PHONY: gui/gui.a - -gui/gui.a: - cd gui && make - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -main.o: ../T_IDs.h ../T_defs.h +remote: + make -f Makefile.remote clean: - rm -f *.o $(PROG) core - cd gui && make clean + make -f Makefile.local clean + make -f Makefile.remote clean diff --git a/common/utils/T/tracer/Makefile.local b/common/utils/T/tracer/Makefile.local new file mode 100644 index 0000000000..ee730be866 --- /dev/null +++ b/common/utils/T/tracer/Makefile.local @@ -0,0 +1,21 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -DT_TRACER + +#CFLAGS += -O3 -ffast-math -fomit-frame-pointer + +CFLAGS += -DT_USE_SHARED_MEMORY +LIBS += -lrt + +PROG=tracer_local +OBJS=local.o forward.o + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +main.o: ../T_IDs.h ../T_defs.h + +clean: + rm -f *.o $(PROG) core diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote new file mode 100644 index 0000000000..cde59a2666 --- /dev/null +++ b/common/utils/T/tracer/Makefile.remote @@ -0,0 +1,26 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -DT_TRACER + +#CFLAGS += -O3 -ffast-math -fomit-frame-pointer + +LIBS=-lX11 -lm + +PROG=tracer_remote +OBJS=remote.o plot.o database.o gui.o + +$(PROG): gui/gui.a $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) + +.PHONY: gui/gui.a + +gui/gui.a: + cd gui && make + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +main.o: ../T_IDs.h ../T_defs.h + +clean: + rm -f *.o $(PROG) core + cd gui && make clean diff --git a/common/utils/T/tracer/defs.h b/common/utils/T/tracer/defs.h index 69b379ce0b..7c519f8878 100644 --- a/common/utils/T/tracer/defs.h +++ b/common/utils/T/tracer/defs.h @@ -27,4 +27,9 @@ void *forwarder(char *ip, int port); void forward(void *forwarder, char *buf, int size); void forward_start_client(void *forwarder, int socket); +/* T gui functions */ +void t_gui_start(void); +void t_gui_set_input_signal(int eNB, int frame, int subframe, int antenna, + int size, void *buf); + #endif /* _TRACER_DEFS_H_ */ diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c index b425e6444b..90ca43374e 100644 --- a/common/utils/T/tracer/forward.c +++ b/common/utils/T/tracer/forward.c @@ -122,6 +122,9 @@ void *forwarder(char *ip, int port) f->sc = -1; f->head = f->tail = NULL; + printf("connecting to remote tracer %s:%d\n", ip, port); + +again: f->s = socket(AF_INET, SOCK_STREAM, 0); if (f->s == -1) { perror("socket"); exit(1); } @@ -129,8 +132,15 @@ void *forwarder(char *ip, int port) a.sin_port = htons(port); a.sin_addr.s_addr = inet_addr(ip); - if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) - { perror("connect"); exit(1); } + if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) { + perror("connect"); + close(f->s); + printf("trying again in 1s\n"); + sleep(1); + goto again; + } + + printf("connected\n"); new_thread(data_sender, f); diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c new file mode 100644 index 0000000000..c681b36aa6 --- /dev/null +++ b/common/utils/T/tracer/local.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defs.h" + +#include "../T_defs.h" + +T_cache_t *T_cache; +int T_busylist_head; +int T_pos; + +int get_connection(char *addr, int port) +{ + struct sockaddr_in a; + socklen_t alen; + int s, t; + + printf("waiting for connection on %s:%d\n", addr, port); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + + printf("connected\n"); + + return t; +} + +void wait_message(void) +{ + while (T_cache[T_busylist_head].busy == 0) usleep(1000); +} + +void init_shm(void) +{ + int i; + int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); + if (s == -1) { perror(T_SHM_FILENAME); abort(); } + if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) + { perror(T_SHM_FILENAME); abort(); } + T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), + PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); + if (T_cache == NULL) + { perror(T_SHM_FILENAME); abort(); } + close(s); + + /* let's garbage the memory to catch some potential problems + * (think multiprocessor sync issues, barriers, etc.) + */ + memset(T_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t)); + for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0; +} + +void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_attr_setstacksize(&att, 10000000)) + { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + +void usage(void) +{ + printf( +"tracer - local side\n" +"options:\n" +" -l local side (forwards packets to remote IP:port)\n" + ); + exit(1); +} + +int main(int n, char **v) +{ + int s; + int i; + char *remote_ip = NULL; + int remote_port = -1; + int port = 2020; + void *f; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-l")) { if (i > n-3) usage(); + remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } + printf("ERROR: unknown option %s\n", v[i]); + usage(); + } + + if (remote_port == -1 || remote_ip == NULL) usage(); + + f = forwarder(remote_ip, remote_port); + init_shm(); + s = get_connection("127.0.0.1", port); + + forward_start_client(f, s); + + /* read messages */ + while (1) { + wait_message(); + __sync_synchronize(); + forward(f, T_cache[T_busylist_head].buffer, + T_cache[T_busylist_head].length); + T_cache[T_busylist_head].busy = 0; + T_busylist_head++; + T_busylist_head &= T_CACHE_SIZE - 1; + } + return 0; +} diff --git a/common/utils/T/tracer/main.c b/common/utils/T/tracer/remote.c similarity index 82% rename from common/utils/T/tracer/main.c rename to common/utils/T/tracer/remote.c index 639a0b5652..0656daa68d 100644 --- a/common/utils/T/tracer/main.c +++ b/common/utils/T/tracer/remote.c @@ -12,6 +12,8 @@ #include "defs.h" +#define DEFAULT_REMOTE_PORT 2020 + #define T_ID(x) x #include "../T_IDs.h" #include "../T_defs.h" @@ -25,26 +27,6 @@ void *pusch_iq_plot; void *pucch_iq_plot; void *pucch_plot; -#ifdef T_USE_SHARED_MEMORY - -T_cache_t *T_cache; -int T_busylist_head; -int T_pos; - -static inline int GET(int s, void *out, int count) -{ - if (count == 1) { - *(char *)out = T_cache[T_busylist_head].buffer[T_pos]; - T_pos++; - return 1; - } - memcpy(out, T_cache[T_busylist_head].buffer + T_pos, count); - T_pos += count; - return count; -} - -#else /* T_USE_SHARED_MEMORY */ - #define GET fullread int fullread(int fd, void *_buf, int count) @@ -62,14 +44,14 @@ int fullread(int fd, void *_buf, int count) return ret; } -#endif /* T_USE_SHARED_MEMORY */ - int get_connection(char *addr, int port) { struct sockaddr_in a; socklen_t alen; int s, t; + printf("waiting for connection on %s:%d\n", addr, port); + s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("socket"); exit(1); } t = 1; @@ -86,6 +68,9 @@ int get_connection(char *addr, int port) t = accept(s, (struct sockaddr *)&a, &alen); if (t == -1) { perror("accept"); exit(1); } close(s); + + printf("connected\n"); + return t; } @@ -107,9 +92,6 @@ void get_message(int s) } while (0) int m; -#ifdef T_USE_SHARED_MEMORY - T_pos = 0; -#endif if (GET(s, &m, sizeof(int)) != sizeof(int)) abort(); switch (m) { case T_first: { @@ -255,6 +237,7 @@ void get_message(int s) {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed " "(received %d bytes = %d samples)\n", size, size/4);abort();} if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680, 0); + t_gui_set_input_signal(eNB, frame, subframe, antenna, size, buf); break; } case T_ENB_UL_CHANNEL_ESTIMATE: { @@ -339,43 +322,8 @@ void get_message(int s) } default: printf("unkown message type %d\n", m); abort(); } - -#ifdef T_USE_SHARED_MEMORY - T_cache[T_busylist_head].busy = 0; - T_busylist_head++; - T_busylist_head &= T_CACHE_SIZE - 1; -#endif } -#ifdef T_USE_SHARED_MEMORY - -void wait_message(void) -{ - while (T_cache[T_busylist_head].busy == 0) usleep(1000); -} - -void init_shm(void) -{ - int i; - int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); - if (s == -1) { perror(T_SHM_FILENAME); abort(); } - if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) - { perror(T_SHM_FILENAME); abort(); } - T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), - PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); - if (T_cache == NULL) - { perror(T_SHM_FILENAME); abort(); } - close(s); - - /* let's garbage the memory to catch some potential problems - * (think multiprocessor sync issues, barriers, etc.) - */ - memset(T_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t)); - for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0; -} - -#endif /* T_USE_SHARED_MEMORY */ - void new_thread(void *(*f)(void *), void *data) { pthread_t t; @@ -396,22 +344,22 @@ void new_thread(void *(*f)(void *), void *data) void usage(void) { printf( -"common options:\n" +"tracer - remote side\n" +"options:\n" " -d this option is mandatory\n" " -li print IDs in the database\n" " -lg print GROUPs in the database\n" " -dump dump the database\n" " -x run with XFORMS (revisited)\n" +" -T run with T GUI\n" " -on turn log ON for given GROUP or ID\n" " -off turn log OFF for given GROUP or ID\n" " -ON turn all logs ON\n" " -OFF turn all logs OFF\n" "note: you may pass several -on/-off/-ON/-OFF, they will be processed in order\n" " by default, all is off\n" -"\n" -"remote mode options: in this mode you run a local tracer and a remote one\n" -" -r remote side (use given port)\n" -" -l local side (forwards packets to remote IP:port)\n" +" -r remote side: use given port (default %d)\n", + DEFAULT_REMOTE_PORT ); exit(1); } @@ -428,18 +376,12 @@ int main(int n, char **v) int do_list_groups = 0; int do_dump_database = 0; int do_xforms = 0; + int do_T_gui = 0; char **on_off_name; int *on_off_action; int on_off_n = 0; int is_on[T_NUMBER_OF_IDS]; - int remote_local = 0; - int remote_remote = 0; - char *remote_ip = NULL; - int remote_port = -1; - int port = 2020; -#ifdef T_USE_SHARED_MEMORY - void *f; -#endif + int port = DEFAULT_REMOTE_PORT; memset(is_on, 0, sizeof(is_on)); @@ -454,6 +396,7 @@ int main(int n, char **v) if (!strcmp(v[i], "-lg")) { do_list_groups = 1; continue; } if (!strcmp(v[i], "-dump")) { do_dump_database = 1; continue; } if (!strcmp(v[i], "-x")) { do_xforms = 1; continue; } + if (!strcmp(v[i], "-T")) { do_T_gui = 1; continue; } if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); @@ -462,45 +405,13 @@ int main(int n, char **v) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } if (!strcmp(v[i], "-OFF")) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } - if (!strcmp(v[i], "-r")) { if (i > n-2) usage(); remote_remote = 1; + if (!strcmp(v[i], "-r")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; } - if (!strcmp(v[i], "-l")) { if (i > n-3) usage(); remote_local = 1; - remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } printf("ERROR: unknown option %s\n", v[i]); usage(); } -#ifndef T_USE_SHARED_MEMORY - /* gcc shut up */ - (void)remote_port; - (void)remote_ip; -#endif - -#ifdef T_USE_SHARED_MEMORY - if (remote_remote) { - printf("ERROR: remote 'remote side' does not run with shared memory\n"); - printf("recompile without T_USE_SHARED_MEMORY (edit Makefile)\n"); - exit(1); - } -#endif - - if (remote_remote) { - /* TODO: setup 'secure' connection with remote part */ - } - -#ifndef T_USE_SHARED_MEMORY - if (remote_local) { - printf("ERROR: remote 'local side' does not run without shared memory\n"); - printf("recompile with T_USE_SHARED_MEMORY (edit Makefile)\n"); - exit(1); - } -#endif - -#ifdef T_USE_SHARED_MEMORY - if (remote_local) f = forwarder(remote_ip, remote_port); -#endif - - if (remote_local) goto no_database; + /* TODO: setup 'secure' connection with remote part */ if (database_filename == NULL) { printf("ERROR: provide a database file (-d)\n"); @@ -517,7 +428,6 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); -no_database: if (do_xforms) { ul_plot = make_plot(512, 100, "UL Input Signal", 1, 7680*10, PLOT_VS_TIME, BLUE); @@ -533,19 +443,12 @@ no_database: /* pucch 1 */ 10240, PLOT_MINMAX, BLUE); } - -#ifdef T_USE_SHARED_MEMORY - init_shm(); -#endif - s = get_connection("127.0.0.1", port); - - if (remote_local) { -#ifdef T_USE_SHARED_MEMORY - forward_start_client(f, s); -#endif - goto no_init_message; + if (do_T_gui) { + t_gui_start(); } + s = get_connection("127.0.0.1", port); + /* send the first message - activate selected traces */ t = 0; if (write(s, &t, 1) != 1) abort(); @@ -556,26 +459,8 @@ no_database: if (is_on[l]) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); -no_init_message: - /* read messages */ while (1) { -#ifdef T_USE_SHARED_MEMORY - wait_message(); - __sync_synchronize(); -#endif - -#ifdef T_USE_SHARED_MEMORY - if (remote_local) { - forward(f, T_cache[T_busylist_head].buffer, - T_cache[T_busylist_head].length); - T_cache[T_busylist_head].busy = 0; - T_busylist_head++; - T_busylist_head &= T_CACHE_SIZE - 1; - continue; - } -#endif - get_message(s); } return 0; From 06cd5665eb113aac603f8f5c6d46b2125fa538da Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 26 Apr 2016 12:26:39 +0200 Subject: [PATCH 044/217] gui.c was forgotten in the previous commit --- common/utils/T/tracer/gui.c | 101 ++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 common/utils/T/tracer/gui.c diff --git a/common/utils/T/tracer/gui.c b/common/utils/T/tracer/gui.c new file mode 100644 index 0000000000..2963e4c348 --- /dev/null +++ b/common/utils/T/tracer/gui.c @@ -0,0 +1,101 @@ +#include "defs.h" +#include "gui/gui.h" +#include +#include +#include +#include +#include +#include + +static struct { + gui *g; + widget *input_signal; /* CC_id 0 antenna 0 */ + volatile int input_signal_length; /* unit: byte */ + void *input_signal_iq; + pthread_mutex_t input_signal_lock; +} eNB_data; + +static void *gui_thread(void *g) +{ + gui_loop(g); + exit(0); +} + +static void *input_signal_plotter(void *_) +{ + short *iqbuf; + float *x; + float *y; + int i; + int length = eNB_data.input_signal_length / 4; + + x = calloc(1, sizeof(float) * eNB_data.input_signal_length / 4); + y = calloc(1, sizeof(float) * eNB_data.input_signal_length / 4); + if (x == NULL || y == NULL) abort(); + + while (1) { + usleep(100 * 1000); + + if (pthread_mutex_lock(&eNB_data.input_signal_lock)) abort(); + + if (length * 4 != eNB_data.input_signal_length) { + free(x); + free(y); + x = calloc(1, sizeof(float) * eNB_data.input_signal_length / 4); + y = calloc(1, sizeof(float) * eNB_data.input_signal_length / 4); + if (x == NULL || y == NULL) abort(); + length = eNB_data.input_signal_length / 4; + } + + iqbuf = eNB_data.input_signal_iq; + + for (i = 0; i < length; i++) { + x[i] = i; + y[i] = 10*log10(1.0+(float)(iqbuf[2*i]*iqbuf[2*i]+ + iqbuf[2*i+1]*iqbuf[2*i+1])); + } + + xy_plot_set_points(eNB_data.g, eNB_data.input_signal, + length, x, y); + + if (pthread_mutex_unlock(&eNB_data.input_signal_lock)) abort(); + } +} + +void t_gui_start(void) +{ + gui *g = gui_init(); + + widget *win = new_toplevel_window(g, 550, 140, "input signal"); + widget *plot = new_xy_plot(g, 512, 100, "eNB 0 input signal", 20); + widget_add_child(g, win, plot, -1); + xy_plot_set_range(g, plot, 0, 76800, 30, 70); + + eNB_data.input_signal = plot; + eNB_data.input_signal_length = 76800 * 4; + eNB_data.input_signal_iq = calloc(1, 76800 * 4); + if (eNB_data.input_signal_iq == NULL) abort(); + pthread_mutex_init(&eNB_data.input_signal_lock, NULL); + + eNB_data.g = g; + + new_thread(gui_thread, g); + new_thread(input_signal_plotter, NULL); +} + +void t_gui_set_input_signal(int eNB, int frame, int subframe, int antenna, + int size, void *buf) +{ + if (pthread_mutex_lock(&eNB_data.input_signal_lock)) abort(); + + if (eNB_data.input_signal_length != size * 10) { + free(eNB_data.input_signal_iq); + eNB_data.input_signal_length = size * 10; + eNB_data.input_signal_iq = calloc(1, eNB_data.input_signal_length); + if (eNB_data.input_signal_iq == NULL) abort(); + } + + memcpy((char *)eNB_data.input_signal_iq + subframe * size, buf, size); + + if (pthread_mutex_unlock(&eNB_data.input_signal_lock)) abort(); +} From ed71e94d1be3fc0ec138834ff8536fb786e0bb89 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 26 Apr 2016 13:39:41 +0200 Subject: [PATCH 045/217] add size of message when forwarding (so the remote end can skip unknown messages safely) --- common/utils/T/tracer/forward.c | 9 ++++++--- common/utils/T/tracer/remote.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c index 90ca43374e..27b36c9a9b 100644 --- a/common/utils/T/tracer/forward.c +++ b/common/utils/T/tracer/forward.c @@ -150,15 +150,18 @@ again: void forward(void *_forwarder, char *buf, int size) { forward_data *f = _forwarder; + int32_t ssize = size; databuf *new; new = malloc(sizeof(*new)); if (new == NULL) abort(); if (pthread_mutex_lock(&f->datalock)) abort(); - new->d = malloc(size); if (new->d == NULL) abort(); - memcpy(new->d, buf, size); - new->l = size; + new->d = malloc(size + 4); if (new->d == NULL) abort(); + /* put the size of the message at the head */ + memcpy(new->d, &ssize, 4); + memcpy(new->d+4, buf, size); + new->l = size+4; new->next = NULL; if (f->head == NULL) f->head = new; if (f->tail != NULL) f->tail->next = new; diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 0656daa68d..225db809b7 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -91,7 +91,9 @@ void get_message(int s) printf("["x"]["y"] %s", str); \ } while (0) + int32_t size; int m; + if (GET(s, &size, 4) != 4) abort(); if (GET(s, &m, sizeof(int)) != sizeof(int)) abort(); switch (m) { case T_first: { From 42d9180532c9f676e1f992d5e67e1c5f8fec686f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 26 Apr 2016 16:34:15 +0200 Subject: [PATCH 046/217] add FORMAT to legacy logs --- common/utils/T/T_messages.txt | 125 ++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 4c6f6e7aca..58d4107625 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -24,354 +24,464 @@ ID = PUCCH_1_ENERGY ID = LEGACY_MAC_INFO DESC = MAC legacy logs - info level GROUP = MAC:INFO:LEGACY + FORMAT = string,log ID = LEGACY_MAC_ERROR DESC = MAC legacy logs - error level GROUP = MAC:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_MAC_WARNING DESC = MAC legacy logs - warning level GROUP = MAC:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_MAC_DEBUG DESC = MAC legacy logs - debug level GROUP = MAC:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_MAC_TRACE DESC = MAC legacy logs - trace level GROUP = MAC:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_PHY_INFO DESC = PHY legacy logs - info level GROUP = PHY:INFO:LEGACY + FORMAT = string,log ID = LEGACY_PHY_ERROR DESC = PHY legacy logs - error level GROUP = PHY:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_PHY_WARNING DESC = PHY legacy logs - warning level GROUP = PHY:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_PHY_DEBUG DESC = PHY legacy logs - debug level GROUP = PHY:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_PHY_TRACE DESC = PHY legacy logs - trace level GROUP = PHY:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_S1AP_INFO DESC = S1AP legacy logs - info level GROUP = S1AP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_S1AP_ERROR DESC = S1AP legacy logs - error level GROUP = S1AP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_S1AP_WARNING DESC = S1AP legacy logs - warning level GROUP = S1AP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_S1AP_DEBUG DESC = S1AP legacy logs - debug level GROUP = S1AP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_S1AP_TRACE DESC = S1AP legacy logs - trace level GROUP = S1AP:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_X2AP_INFO DESC = X2AP legacy logs - info level GROUP = X2AP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_X2AP_ERROR DESC = X2AP legacy logs - error level GROUP = X2AP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_X2AP_WARNING DESC = X2AP legacy logs - warning level GROUP = X2AP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_X2AP_DEBUG DESC = X2AP legacy logs - debug level GROUP = X2AP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_X2AP_TRACE DESC = X2AP legacy logs - trace level GROUP = X2AP:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_RRC_INFO DESC = RRC legacy logs - info level GROUP = RRC:INFO:LEGACY + FORMAT = string,log ID = LEGACY_RRC_ERROR DESC = RRC legacy logs - error level GROUP = RRC:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_RRC_WARNING DESC = RRC legacy logs - warning level GROUP = RRC:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_RRC_DEBUG DESC = RRC legacy logs - debug level GROUP = RRC:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_RRC_TRACE DESC = RRC legacy logs - trace level GROUP = RRC:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_RLC_INFO DESC = RLC legacy logs - info level GROUP = RLC:INFO:LEGACY + FORMAT = string,log ID = LEGACY_RLC_ERROR DESC = RLC legacy logs - error level GROUP = RLC:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_RLC_WARNING DESC = RLC legacy logs - warning level GROUP = RLC:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_RLC_DEBUG DESC = RLC legacy logs - debug level GROUP = RLC:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_RLC_TRACE DESC = RLC legacy logs - trace level GROUP = RLC:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_PDCP_INFO DESC = PDCP legacy logs - info level GROUP = PDCP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_PDCP_ERROR DESC = PDCP legacy logs - error level GROUP = PDCP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_PDCP_WARNING DESC = PDCP legacy logs - warning level GROUP = PDCP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_PDCP_DEBUG DESC = PDCP legacy logs - debug level GROUP = PDCP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_PDCP_TRACE DESC = PDCP legacy logs - trace level GROUP = PDCP:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_ENB_APP_INFO DESC = ENB_APP legacy logs - info level GROUP = ENB_APP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_ENB_APP_ERROR DESC = ENB_APP legacy logs - error level GROUP = ENB_APP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_ENB_APP_WARNING DESC = ENB_APP legacy logs - warning level GROUP = ENB_APP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_ENB_APP_DEBUG DESC = ENB_APP legacy logs - debug level GROUP = ENB_APP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_ENB_APP_TRACE DESC = ENB_APP legacy logs - trace level GROUP = ENB_APP:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_SCTP_INFO DESC = SCTP legacy logs - info level GROUP = SCTP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_SCTP_ERROR DESC = SCTP legacy logs - error level GROUP = SCTP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_SCTP_WARNING DESC = SCTP legacy logs - warning level GROUP = SCTP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_SCTP_DEBUG DESC = SCTP legacy logs - debug level GROUP = SCTP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_SCTP_TRACE DESC = SCTP legacy logs - trace level GROUP = SCTP:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_UDP__INFO DESC = UDP_ legacy logs - info level GROUP = UDP_:INFO:LEGACY + FORMAT = string,log ID = LEGACY_UDP__ERROR DESC = UDP_ legacy logs - error level GROUP = UDP_:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_UDP__WARNING DESC = UDP_ legacy logs - warning level GROUP = UDP_:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_UDP__DEBUG DESC = UDP_ legacy logs - debug level GROUP = UDP_:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_UDP__TRACE DESC = UDP_ legacy logs - trace level GROUP = UDP_:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_NAS_INFO DESC = NAS legacy logs - info level GROUP = NAS:INFO:LEGACY + FORMAT = string,log ID = LEGACY_NAS_ERROR DESC = NAS legacy logs - error level GROUP = NAS:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_NAS_WARNING DESC = NAS legacy logs - warning level GROUP = NAS:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_NAS_DEBUG DESC = NAS legacy logs - debug level GROUP = NAS:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_NAS_TRACE DESC = NAS legacy logs - trace level GROUP = NAS:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_HW_INFO DESC = HW legacy logs - info level GROUP = HW:INFO:LEGACY + FORMAT = string,log ID = LEGACY_HW_ERROR DESC = HW legacy logs - error level GROUP = HW:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_HW_WARNING DESC = HW legacy logs - warning level GROUP = HW:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_HW_DEBUG DESC = HW legacy logs - debug level GROUP = HW:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_HW_TRACE DESC = HW legacy logs - trace level GROUP = HW:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_EMU_INFO DESC = EMU legacy logs - info level GROUP = EMU:INFO:LEGACY + FORMAT = string,log ID = LEGACY_EMU_ERROR DESC = EMU legacy logs - error level GROUP = EMU:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_EMU_WARNING DESC = EMU legacy logs - warning level GROUP = EMU:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_EMU_DEBUG DESC = EMU legacy logs - debug level GROUP = EMU:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_EMU_TRACE DESC = EMU legacy logs - trace level GROUP = EMU:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OTG_INFO DESC = OTG legacy logs - info level GROUP = OTG:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OTG_ERROR DESC = OTG legacy logs - error level GROUP = OTG:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OTG_WARNING DESC = OTG legacy logs - warning level GROUP = OTG:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OTG_DEBUG DESC = OTG legacy logs - debug level GROUP = OTG:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OTG_TRACE DESC = OTG legacy logs - trace level GROUP = OTG:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OCG_INFO DESC = OCG legacy logs - info level GROUP = OCG:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OCG_ERROR DESC = OCG legacy logs - error level GROUP = OCG:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OCG_WARNING DESC = OCG legacy logs - warning level GROUP = OCG:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OCG_DEBUG DESC = OCG legacy logs - debug level GROUP = OCG:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OCG_TRACE DESC = OCG legacy logs - trace level GROUP = OCG:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OCM_INFO DESC = OCM legacy logs - info level GROUP = OCM:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OCM_ERROR DESC = OCM legacy logs - error level GROUP = OCM:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OCM_WARNING DESC = OCM legacy logs - warning level GROUP = OCM:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OCM_DEBUG DESC = OCM legacy logs - debug level GROUP = OCM:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OCM_TRACE DESC = OCM legacy logs - trace level GROUP = OCM:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OIP_INFO DESC = OIP legacy logs - info level GROUP = OIP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OIP_ERROR DESC = OIP legacy logs - error level GROUP = OIP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OIP_WARNING DESC = OIP legacy logs - warning level GROUP = OIP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OIP_DEBUG DESC = OIP legacy logs - debug level GROUP = OIP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OIP_TRACE DESC = OIP legacy logs - trace level GROUP = OIP:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OMG_INFO DESC = OMG legacy logs - info level GROUP = OMG:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OMG_ERROR DESC = OMG legacy logs - error level GROUP = OMG:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OMG_WARNING DESC = OMG legacy logs - warning level GROUP = OMG:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OMG_DEBUG DESC = OMG legacy logs - debug level GROUP = OMG:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OMG_TRACE DESC = OMG legacy logs - trace level GROUP = OMG:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OPT_INFO DESC = OPT legacy logs - info level GROUP = OPT:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OPT_ERROR DESC = OPT legacy logs - error level GROUP = OPT:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OPT_WARNING DESC = OPT legacy logs - warning level GROUP = OPT:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OPT_DEBUG DESC = OPT legacy logs - debug level GROUP = OPT:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OPT_TRACE DESC = OPT legacy logs - trace level GROUP = OPT:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_GTPU_INFO DESC = GTPU legacy logs - info level GROUP = GTPU:INFO:LEGACY + FORMAT = string,log ID = LEGACY_GTPU_ERROR DESC = GTPU legacy logs - error level GROUP = GTPU:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_GTPU_WARNING DESC = GTPU legacy logs - warning level GROUP = GTPU:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_GTPU_DEBUG DESC = GTPU legacy logs - debug level GROUP = GTPU:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_GTPU_TRACE DESC = GTPU legacy logs - trace level GROUP = GTPU:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_TMR_INFO DESC = TMR legacy logs - info level GROUP = TMR:INFO:LEGACY + FORMAT = string,log ID = LEGACY_TMR_ERROR DESC = TMR legacy logs - error level GROUP = TMR:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_TMR_WARNING DESC = TMR legacy logs - warning level GROUP = TMR:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_TMR_DEBUG DESC = TMR legacy logs - debug level GROUP = TMR:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_TMR_TRACE DESC = TMR legacy logs - trace level GROUP = TMR:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_OSA_INFO DESC = OSA legacy logs - info level GROUP = OSA:INFO:LEGACY + FORMAT = string,log ID = LEGACY_OSA_ERROR DESC = OSA legacy logs - error level GROUP = OSA:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_OSA_WARNING DESC = OSA legacy logs - warning level GROUP = OSA:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_OSA_DEBUG DESC = OSA legacy logs - debug level GROUP = OSA:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_OSA_TRACE DESC = OSA legacy logs - trace level GROUP = OSA:TRACE:LEGACY + FORMAT = string,log # this is a bad hack but I won't fix (function util_print_hex_octets # in openairinterface5g/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c @@ -380,50 +490,65 @@ ID = LEGACY_OSA_TRACE ID = LEGACY_component_INFO DESC = component legacy logs - info level GROUP = component:INFO:LEGACY + FORMAT = string,log ID = LEGACY_component_ERROR DESC = component legacy logs - error level GROUP = component:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_component_WARNING DESC = component legacy logs - warning level GROUP = component:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_component_DEBUG DESC = component legacy logs - debug level GROUP = component:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_component_TRACE DESC = component legacy logs - trace level GROUP = component:TRACE:LEGACY + FORMAT = string,log ID = LEGACY_componentP_INFO DESC = componentP legacy logs - info level GROUP = componentP:INFO:LEGACY + FORMAT = string,log ID = LEGACY_componentP_ERROR DESC = componentP legacy logs - error level GROUP = componentP:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_componentP_WARNING DESC = componentP legacy logs - warning level GROUP = componentP:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_componentP_DEBUG DESC = componentP legacy logs - debug level GROUP = componentP:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_componentP_TRACE DESC = componentP legacy logs - trace level GROUP = componentP:TRACE:LEGACY + FORMAT = string,log #needed? ID = LEGACY_CLI_INFO DESC = CLI legacy logs - info level GROUP = CLI:INFO:LEGACY + FORMAT = string,log ID = LEGACY_CLI_ERROR DESC = CLI legacy logs - error level GROUP = CLI:ERROR:LEGACY + FORMAT = string,log ID = LEGACY_CLI_WARNING DESC = CLI legacy logs - warning level GROUP = CLI:WARNING:LEGACY + FORMAT = string,log ID = LEGACY_CLI_DEBUG DESC = CLI legacy logs - debug level GROUP = CLI:DEBUG:LEGACY + FORMAT = string,log ID = LEGACY_CLI_TRACE DESC = CLI legacy logs - trace level GROUP = CLI:TRACE:LEGACY + FORMAT = string,log #for debug/test - not used ID = first From 092f7ce5462e84f24f169e576bad3336e3b802df Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 11:06:20 +0200 Subject: [PATCH 047/217] parse FORMAT from config file --- common/utils/T/tracer/database.c | 108 +++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 11 deletions(-) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index 59d8cbdc85..e2362f8f08 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -8,8 +8,11 @@ typedef struct { char *name; char *desc; char **groups; - int size; - int id; + int gsize; + char **arg_type; + char **arg_name; + int asize; + int id; } id; typedef struct { @@ -129,7 +132,10 @@ id *add_id(database *r, char *idname, int i) if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); } r->i[r->isize].desc = NULL; r->i[r->isize].groups = NULL; - r->i[r->isize].size = 0; + r->i[r->isize].gsize = 0; + r->i[r->isize].arg_type = NULL; + r->i[r->isize].arg_name = NULL; + r->i[r->isize].asize = 0; r->i[r->isize].id = i; r->isize++; qsort(r->i, r->isize, sizeof(id), id_cmp); @@ -172,16 +178,16 @@ void group_add_id(group *g, char *id) void id_add_group(id *i, char *group) { - char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp); + char *g = bsearch(&group, i->groups, i->gsize, sizeof(char *), string_cmp); if (g != NULL) return; - if ((i->size & 1023) == 0) { - i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *)); + if ((i->gsize & 1023) == 0) { + i->groups = realloc(i->groups, (i->gsize+1024) * sizeof(char *)); if (i->groups == NULL) abort(); } - i->groups[i->size] = group; - i->size++; - qsort(i->groups, i->size, sizeof(char *), string_cmp); + i->groups[i->gsize] = group; + i->gsize++; + qsort(i->groups, i->gsize, sizeof(char *), string_cmp); } void add_groups(database *r, id *i, char *groups) @@ -216,6 +222,76 @@ void add_desc(id *i, char *desc) i->desc = strdup(desc); if (i->desc == NULL) abort(); } +char *format_get_next_token(char **cur) +{ + char *start; + char *end; + char *ret; + + start = *cur; + + /* remove spaces */ + while (*start && isspace(*start)) start ++; + if (*start == 0) return NULL; + + /* special cases: ',' and ':' */ + if (*start == ',' || *start == ':') { end = start + 1; goto special; } + + end = start; + + /* go to end of token */ + while (*end && !isspace(*end) && *end != ',' && *end != ':') end++; + +special: + ret = malloc(end-start+1); if (ret == NULL) abort(); + memcpy(ret, start, end-start); + ret[end-start] = 0; + + *cur = end; + return ret; +} + +void add_format(id *id, char *format) +{ + char *cur = format; + char *type; + char *name; + char *sep; + while (1) { + /* parse next type/name: expected " , :" */ + /* get type */ + type = format_get_next_token(&cur); + if (type == NULL) break; + /* get comma */ + sep = format_get_next_token(&cur); + if (sep == NULL || strcmp(sep, ",") != 0) goto error; + free(sep); + /* get name */ + name = format_get_next_token(&cur); + if (name == NULL) goto error; + /* if there is a next token it has to be : */ + sep = format_get_next_token(&cur); + if (sep != NULL && strcmp(sep, ":") != 0) goto error; + free(sep); + + /* add type/name */ + if (id->asize % 64 == 0) { + id->arg_type = realloc(id->arg_type, (id->asize + 64) * sizeof(char *)); + if (id->arg_type == NULL) abort(); + id->arg_name = realloc(id->arg_name, (id->asize + 64) * sizeof(char *)); + if (id->arg_name == NULL) abort(); + } + id->arg_type[id->asize] = type; + id->arg_name[id->asize] = name; + id->asize++; + } + return; + +error: + printf("bad format '%s'\n", format); + abort(); +} + void *parse_database(char *filename) { FILE *in; @@ -241,6 +317,7 @@ void *parse_database(char *filename) if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; } if (!strcmp(name, "GROUP")) add_groups(r, last_id, value); if (!strcmp(name, "DESC")) add_desc(last_id, value); + if (!strcmp(name, "FORMAT")) add_format(last_id, value); } fclose(in); @@ -260,9 +337,18 @@ void dump_database(void *_d) int j; printf("ID %s [%s] [in %d group%s]\n", d->i[i].name, d->i[i].desc ? d->i[i].desc : "", - d->i[i].size, d->i[i].size > 1 ? "s" : ""); - for (j = 0; j < d->i[i].size; j++) + d->i[i].gsize, d->i[i].gsize > 1 ? "s" : ""); + for (j = 0; j < d->i[i].gsize; j++) printf(" in GROUP: %s\n", d->i[i].groups[j]); + if (d->i[i].asize == 0) printf(" no FORMAT\n"); + else { + int j; + printf(" FORMAT: "); + for (j = 0; j < d->i[i].asize; j++) + printf("'%s' , '%s' %s", d->i[i].arg_type[j], d->i[i].arg_name[j], + j == d->i[i].asize-1 ? "" : " : "); + printf("\n"); + } } for (i = 0; i < d->gsize; i++) { int j; From 0a820ba1ce36050be7b153f031aa4d227558286b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 11:16:20 +0200 Subject: [PATCH 048/217] define T_MAX_ARGS --- common/utils/T/T_defs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 5aca54e8d6..97da76fe1f 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -1,6 +1,9 @@ #ifndef _T_defs_H_ #define _T_defs_H_ +/* maximum number of arguments for the T macro */ +#define T_MAX_ARGS 16 + /* maximum size of a message - increase if needed */ #define T_BUFFER_MAX (1024*64) From 7ef7fdfa4a77087c72dc8a0eb9258455640e525c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 11:32:13 +0200 Subject: [PATCH 049/217] create database.h, all in defs.h is messy --- common/utils/T/tracer/database.c | 2 +- common/utils/T/tracer/database.h | 11 +++++++++++ common/utils/T/tracer/defs.h | 7 ------- common/utils/T/tracer/remote.c | 1 + 4 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 common/utils/T/tracer/database.h diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index e2362f8f08..5ea1781415 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -1,4 +1,4 @@ -#include "defs.h" +#include "database.h" #include #include #include diff --git a/common/utils/T/tracer/database.h b/common/utils/T/tracer/database.h new file mode 100644 index 0000000000..4ca4606c15 --- /dev/null +++ b/common/utils/T/tracer/database.h @@ -0,0 +1,11 @@ +#ifndef _DATABASE_H_ +#define _DATABASE_H_ + +/* returns an opaque pointer - truly a 'database *', see database.c */ +void *parse_database(char *filename); +void dump_database(void *database); +void list_ids(void *database); +void list_groups(void *database); +void on_off(void *d, char *item, int *a, int onoff); + +#endif /* _DATABASE_H_ */ diff --git a/common/utils/T/tracer/defs.h b/common/utils/T/tracer/defs.h index 7c519f8878..7a6f57b312 100644 --- a/common/utils/T/tracer/defs.h +++ b/common/utils/T/tracer/defs.h @@ -16,13 +16,6 @@ void iq_plot_set_sized(void *_plot, short *data, int len, int pp); void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp); void iq_plot_add_energy_point_loop(void *_plot, int e, int pp); -/* returns an opaque pointer - truly a 'database *', see t_data.c */ -void *parse_database(char *filename); -void dump_database(void *database); -void list_ids(void *database); -void list_groups(void *database); -void on_off(void *d, char *item, int *a, int onoff); - void *forwarder(char *ip, int port); void forward(void *forwarder, char *buf, int size); void forward_start_client(void *forwarder, int socket); diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 225db809b7..4988bd336e 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -11,6 +11,7 @@ #include #include "defs.h" +#include "database.h" #define DEFAULT_REMOTE_PORT 2020 From 8e7ee86cc9f5f29b2c79bb718a197841995b5b47 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 11:47:35 +0200 Subject: [PATCH 050/217] remote.c becomes remote_old.c --- common/utils/T/tracer/Makefile.remote | 2 +- common/utils/T/tracer/{remote.c => remote_old.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename common/utils/T/tracer/{remote.c => remote_old.c} (100%) diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index cde59a2666..1e7468861d 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -6,7 +6,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER LIBS=-lX11 -lm PROG=tracer_remote -OBJS=remote.o plot.o database.o gui.o +OBJS=remote_old.o plot.o database.o gui.o $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote_old.c similarity index 100% rename from common/utils/T/tracer/remote.c rename to common/utils/T/tracer/remote_old.c From f0a704145b96b19b479432a05a344475c647e6b8 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 12:13:53 +0200 Subject: [PATCH 051/217] add get_format to database --- common/utils/T/tracer/database.c | 17 +++++++++++++++++ common/utils/T/tracer/database.h | 12 ++++++++++++ 2 files changed, 29 insertions(+) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index 5ea1781415..5e7c9ec8f6 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -409,3 +409,20 @@ void on_off(void *_d, char *item, int *a, int onoff) exit(1); } } + +database_event_format get_format(void *_database, int event_id) +{ + database *d = _database; + database_event_format ret; + + if (event_id < 0 || event_id >= d->isize) { + printf("%s:%d: bad event ID (%d)\n", __FILE__, __LINE__, event_id); + abort(); + } + + ret.type = d->i[event_id].arg_type; + ret.name = d->i[event_id].arg_name; + ret.count = d->i[event_id].asize; + + return ret; +} diff --git a/common/utils/T/tracer/database.h b/common/utils/T/tracer/database.h index 4ca4606c15..544f0ad06f 100644 --- a/common/utils/T/tracer/database.h +++ b/common/utils/T/tracer/database.h @@ -8,4 +8,16 @@ void list_ids(void *database); void list_groups(void *database); void on_off(void *d, char *item, int *a, int onoff); +/****************************************************************************/ +/* get format of an event */ +/****************************************************************************/ + +typedef struct { + char **type; + char **name; + int count; +} database_event_format; + +database_event_format get_format(void *database, int event_id); + #endif /* _DATABASE_H_ */ From 7dbb2b8c3f5bb666de37f27def040e60b3bfb94d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 14:10:47 +0200 Subject: [PATCH 052/217] id management / bug fixes in database --- common/utils/T/tracer/database.c | 18 +++++++++++++++--- common/utils/T/tracer/database.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index 5e7c9ec8f6..a5d41fb325 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -27,6 +27,7 @@ typedef struct { int isize; group *g; int gsize; + int *pos; } database; typedef struct { @@ -324,6 +325,11 @@ void *parse_database(char *filename) free(p.name.data); free(p.value.data); + /* setup pos */ + r->pos = malloc(sizeof(int) * r->isize); if (r->pos == NULL) abort(); + for (i = 0; i < r->isize; i++) + r->pos[r->i[i].id] = i; + return r; } @@ -410,6 +416,12 @@ void on_off(void *_d, char *item, int *a, int onoff) } } +char *event_name_from_id(void *_database, int id) +{ + database *d = _database; + return d->i[d->pos[id]].name; +} + database_event_format get_format(void *_database, int event_id) { database *d = _database; @@ -420,9 +432,9 @@ database_event_format get_format(void *_database, int event_id) abort(); } - ret.type = d->i[event_id].arg_type; - ret.name = d->i[event_id].arg_name; - ret.count = d->i[event_id].asize; + ret.type = d->i[d->pos[event_id]].arg_type; + ret.name = d->i[d->pos[event_id]].arg_name; + ret.count = d->i[d->pos[event_id]].asize; return ret; } diff --git a/common/utils/T/tracer/database.h b/common/utils/T/tracer/database.h index 544f0ad06f..b21f323932 100644 --- a/common/utils/T/tracer/database.h +++ b/common/utils/T/tracer/database.h @@ -7,6 +7,7 @@ void dump_database(void *database); void list_ids(void *database); void list_groups(void *database); void on_off(void *d, char *item, int *a, int onoff); +char *event_name_from_id(void *database, int id); /****************************************************************************/ /* get format of an event */ From dca2143b044ccd9058cc1256c2e401f15aa08fde Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 18:29:17 +0200 Subject: [PATCH 053/217] add some functions in database.c --- common/utils/T/tracer/database.c | 15 +++++++++++++++ common/utils/T/tracer/database.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index a5d41fb325..c0224af5d0 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -422,6 +422,15 @@ char *event_name_from_id(void *_database, int id) return d->i[d->pos[id]].name; } +int event_id_from_name(void *_database, char *name) +{ + database *d = _database; + id *i = (id*)bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp); + if (i == NULL) + { printf("%s:%d: '%s' not found\n", __FILE__, __LINE__, name); abort(); } + return i->id; +} + database_event_format get_format(void *_database, int event_id) { database *d = _database; @@ -438,3 +447,9 @@ database_event_format get_format(void *_database, int event_id) return ret; } + +int number_of_ids(void *_d) +{ + database *d = _d; + return d->isize; +} diff --git a/common/utils/T/tracer/database.h b/common/utils/T/tracer/database.h index b21f323932..e2f8aee8b7 100644 --- a/common/utils/T/tracer/database.h +++ b/common/utils/T/tracer/database.h @@ -8,6 +8,8 @@ void list_ids(void *database); void list_groups(void *database); void on_off(void *d, char *item, int *a, int onoff); char *event_name_from_id(void *database, int id); +int event_id_from_name(void *database, char *name); +int number_of_ids(void *database); /****************************************************************************/ /* get format of an event */ From e15a8094589cc1f1c1f7b4dcf3fab530f92a4ff5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 18:31:34 +0200 Subject: [PATCH 054/217] first version of a textlog remote logger --- common/utils/T/tracer/Makefile.remote | 5 +- common/utils/T/tracer/event.c | 52 ++++++++ common/utils/T/tracer/event.h | 34 ++++++ common/utils/T/tracer/handler.c | 104 ++++++++++++++++ common/utils/T/tracer/handler.h | 16 +++ common/utils/T/tracer/remote.c | 169 ++++++++++++++++++++++++++ common/utils/T/tracer/textlog.c | 168 +++++++++++++++++++++++++ common/utils/T/tracer/textlog.h | 9 ++ 8 files changed, 556 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/event.c create mode 100644 common/utils/T/tracer/event.h create mode 100644 common/utils/T/tracer/handler.c create mode 100644 common/utils/T/tracer/handler.h create mode 100644 common/utils/T/tracer/remote.c create mode 100644 common/utils/T/tracer/textlog.c create mode 100644 common/utils/T/tracer/textlog.h diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 1e7468861d..fdebee915c 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -11,6 +11,9 @@ OBJS=remote_old.o plot.o database.o gui.o $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) +textlog: remote.o database.o event.o handler.o textlog.o + $(CC) $(CFLAGS) -o textlog $^ + .PHONY: gui/gui.a gui/gui.a: @@ -22,5 +25,5 @@ gui/gui.a: main.o: ../T_IDs.h ../T_defs.h clean: - rm -f *.o $(PROG) core + rm -f *.o $(PROG) core textlog cd gui && make clean diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c new file mode 100644 index 0000000000..88668eaf7f --- /dev/null +++ b/common/utils/T/tracer/event.c @@ -0,0 +1,52 @@ +#include "event.h" +#include "database.h" +#include +#include +#include + +event new_event(int type, int length, char *buffer, void *database) +{ + database_event_format f; + event e; + int i; + int offset; + + e.type = type; + e.buffer = buffer; + + f = get_format(database, type); + + e.ecount = f.count; + + offset = 0; + + /* setup offsets */ + /* TODO: speedup (no strcmp, string event to include length at head) */ + for (i = 0; i < f.count; i++) { + //e.e[i].offset = offset; + if (!strcmp(f.type[i], "int")) { + e.e[i].type = EVENT_INT; + e.e[i].i = *(int *)(&buffer[offset]); + offset += 4; + } else if (!strcmp(f.type[i], "string")) { + e.e[i].type = EVENT_STRING; + e.e[i].s = &buffer[offset]; + while (buffer[offset]) offset++; + offset++; + } else if (!strcmp(f.type[i], "buffer")) { + int len; + e.e[i].type = EVENT_BUFFER; + len = *(int *)(&buffer[offset]); + e.e[i].bsize = len; + e.e[i].b = &buffer[offset+sizeof(int)]; + offset += len+sizeof(int); + } else { + printf("unhandled type '%s'\n", f.type[i]); + abort(); + } + } + + if (e.ecount==0) { printf("FORMAT not set in event %d\n", type); abort(); } + + return e; +} diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h new file mode 100644 index 0000000000..88f6e4eeb4 --- /dev/null +++ b/common/utils/T/tracer/event.h @@ -0,0 +1,34 @@ +#ifndef _EVENT_H_ +#define _EVENT_H_ + +#include "../T_defs.h" + +enum event_arg_type { + EVENT_INT, + EVENT_STRING, + EVENT_BUFFER +}; + +typedef struct { + enum event_arg_type type; + //int offset; + union { + int i; + char *s; + struct { + int bsize; + void *b; + }; + }; +} event_arg; + +typedef struct { + int type; + char *buffer; + event_arg e[T_MAX_ARGS]; + int ecount; +} event; + +event new_event(int type, int length, char *buffer, void *database); + +#endif /* _EVENT_H_ */ diff --git a/common/utils/T/tracer/handler.c b/common/utils/T/tracer/handler.c new file mode 100644 index 0000000000..15722f5e5f --- /dev/null +++ b/common/utils/T/tracer/handler.c @@ -0,0 +1,104 @@ +#include "handler.h" +#include "event.h" +#include "database.h" +#include +#include + +typedef void (*handler_function)(void *p, event e); + +struct handler_data { + handler_function f; + void *p; + unsigned long id; +}; + +struct handler_list { + struct handler_data *f; + int size; + int maxsize; +}; + +/* internal definition of an event handler */ +struct _event_handler { + void *database; + struct handler_list *events; + unsigned long next_id; +}; + +#if 0 +#include +void handle_event(event_handler *h, event e) +{ + int i; + printf("event %s (%d)\n", event_name_from_id(h->database, e.type), e.type); + for (i = 0; i < e.ecount; i++) { + switch (e.e[i].type) { + case EVENT_INT: + printf(" %d: INT %d\n", i, *(int *)&e.buffer[e.e[i].offset]); + break; + case EVENT_STRING: + printf(" %d: STRING '%s'\n", i, &e.buffer[e.e[i].offset]); + break; + case EVENT_BUFFER: + printf(" %d: BUFFER size %d\n", i, *(int *)&e.buffer[e.e[i].offset]); + break; + } + } +} +#endif + +void handle_event(event_handler *_h, event e) +{ + struct _event_handler *h = _h; + int i; + for (i = 0; i < h->events[e.type].size; i++) + h->events[e.type].f[i].f(h->events[e.type].f[i].p, e); +} + +event_handler *new_handler(void *database) +{ + struct _event_handler *ret = calloc(1, sizeof(struct _event_handler)); + if (ret == NULL) abort(); + + ret->database = database; + + ret->events = calloc(number_of_ids(database), sizeof(struct handler_list)); + if (ret->events == NULL) abort(); + + ret->next_id = 1; + + return ret; +} + +unsigned long register_handler_function(event_handler *_h, int event_id, + void (*f)(void *, event), void *p) +{ + struct _event_handler *h = _h; + unsigned long ret = h->next_id; + struct handler_list *l; + + h->next_id++; + if (h->next_id == 2UL * 1024 * 1024 * 1024) + { printf("%s:%d: this is bad...\n", __FILE__, __LINE__); abort(); } + + l = &h->events[event_id]; + if (l->size == l->maxsize) { + l->maxsize += 16; + l->f = realloc(l->f, l->maxsize * sizeof(struct handler_data)); + if (l->f == NULL) abort(); + } + l->f[l->size].f = f; + l->f[l->size].p = p; + l->f[l->size].id = ret; + + l->size++; + + return ret; +} + +void remove_handler_function(event_handler *h, int event_id, + unsigned long handler_id) +{ + printf("%s:%d: TODO\n", __FILE__, __LINE__); + abort(); +} diff --git a/common/utils/T/tracer/handler.h b/common/utils/T/tracer/handler.h new file mode 100644 index 0000000000..5934e1704c --- /dev/null +++ b/common/utils/T/tracer/handler.h @@ -0,0 +1,16 @@ +#ifndef _HANDLER_H_ +#define _HANDLER_H_ + +typedef void event_handler; + +#include "event.h" + +event_handler *new_handler(void *database); +void handle_event(event_handler *h, event e); + +unsigned long register_handler_function(event_handler *_h, int event_id, + void (*f)(void *, event), void *p); +void remove_handler_function(event_handler *h, int event_id, + unsigned long handler_id); + +#endif /* _HANDLER_H_ */ diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c new file mode 100644 index 0000000000..367772d721 --- /dev/null +++ b/common/utils/T/tracer/remote.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include +#include "database.h" +#include "event.h" +#include "handler.h" +#include "textlog.h" +#include "../T_defs.h" + +#define DEFAULT_REMOTE_PORT 2020 + +int get_connection(char *addr, int port) +{ + struct sockaddr_in a; + socklen_t alen; + int s, t; + + printf("waiting for connection on %s:%d\n", addr, port); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + + printf("connected\n"); + + return t; +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -on turn log ON for given GROUP or ID\n" +" -off turn log OFF for given GROUP or ID\n" +" -ON turn all logs ON\n" +" -OFF turn all logs OFF\n" +" note: you may pass several -on/-off/-ON/-OFF,\n" +" they will be processed in order\n" +" by default, all is off\n" +" -r remote side: use given port (default %d)\n", + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) { printf("read socket problem\n"); abort(); } + count -= l; + buf += l; + ret += l; + } + return ret; +} + +event get_event(int s, char *v, void *d) +{ + int type; + int32_t length; + + fullread(s, &length, 4); + fullread(s, &type, sizeof(int)); + length -= sizeof(int); + fullread(s, v, length); + + return new_event(type, length, v, d); +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + void *database; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int s; + int i; + char t; + int l; + event_handler *h; + textlog *textlog; + + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); + on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-r")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-ON")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-OFF")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(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); + + textlog = new_textlog(h, database, + "ENB_UL_CHANNEL_ESTIMATE", + "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); + + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); + + s = get_connection("127.0.0.1", port); + + /* send the first message - activate selected traces */ + t = 0; + if (write(s, &t, 1) != 1) abort(); + l = 0; + for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + for (l = 0; l < number_of_events; l++) + if (is_on[l]) + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + + /* read messages */ + while (1) { + char v[T_BUFFER_MAX]; + event e; + e = get_event(s, v, database); + handle_event(h, e); + } + + return 0; +} diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c new file mode 100644 index 0000000000..e6728f9674 --- /dev/null +++ b/common/utils/T/tracer/textlog.c @@ -0,0 +1,168 @@ +#include "textlog.h" +#include "handler.h" +#include "database.h" +#include +#include + +enum format_item_type { + INSTRING, + INT, STRING, BUFFER }; + +struct format_item { + enum format_item_type type; + union { + /* INSTRING */ + char *s; + /* others */ + int event_arg; + }; +}; + +struct textlog { + char *event_name; + char *format; + void *database; + unsigned long handler_id; + struct format_item *f; + int fsize; +}; + +#include +static void _event(void *p, event e) +{ + struct textlog *l = p; + int i; +//printf("%s %s\n", l->event_name, l->format); + + for (i = 0; i < l->fsize; i++) + switch(l->f[i].type) { + case INSTRING: printf("%s", l->f[i].s); break; + case INT: printf("%d", e.e[l->f[i].event_arg].i); break; + case STRING: printf("%s", e.e[l->f[i].event_arg].s); break; + case BUFFER: printf("{buffer size:%d}",e.e[l->f[i].event_arg].bsize);break; + } + printf("\n"); +} + +enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; +struct chunk { + enum chunk_type type; + char *s; + enum format_item_type it; + int event_arg; +}; + +/* TODO: speed it up? */ +static int find_argument(char *name, database_event_format f, + enum format_item_type *it, int *event_arg) +{ + int i; + for (i = 0; i < f.count; i++) if (!strcmp(name, f.name[i])) break; + if (i == f.count) return 0; + *event_arg = i; + if (!strcmp(f.type[i], "int")) *it = INT; + else if (!strcmp(f.type[i], "string")) *it = STRING; + else if (!strcmp(f.type[i], "buffer")) *it = BUFFER; + else return 0; + return 1; +} + +static struct chunk next_chunk(char **s, database_event_format f) +{ + char *cur = *s; + char *name; + enum format_item_type it; + int event_arg; + + /* argument in [ ] */ + if (*cur == '[') { + *cur = 0; + cur++; + name = cur; + /* no \ allowed there */ + while (*cur && *cur != ']' && *cur != '\\') cur++; + if (*cur != ']') goto error; + *cur = 0; + cur++; + *s = cur; + if (find_argument(name, f, &it, &event_arg) == 0) goto error; + return (struct chunk){type:C_ARG_NAME, s:name, it:it, event_arg:event_arg}; + } + + /* { } is name of event (anything in between is smashed) */ + if (*cur == '{') { + *cur = 0; + cur++; + while (*cur && *cur != '}') cur++; + if (*cur != '}') goto error; + *cur = 0; + cur++; + *s = cur; + return (struct chunk){type:C_EVENT_NAME}; + } + + /* anything but [ and { is raw string */ + /* TODO: deal with \ */ + name = cur; + while (*cur && *cur != '[' && *cur != '{') cur++; + *s = cur; + return (struct chunk){type:C_STRING, s:name}; + +error: + return (struct chunk){type:C_ERROR}; +} + +textlog *new_textlog(event_handler *h, void *database, + char *event_name, char *format) +{ + struct textlog *ret; + int event_id; + database_event_format f; + char *cur; + + ret = calloc(1, sizeof(struct textlog)); if (ret == NULL) abort(); + + ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); + ret->format = strdup(format); if (ret->format == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->handler_id = register_handler_function(h, event_id, _event, ret); + + f = get_format(database, event_id); + + /* we won't get more than strlen(format) "chunks" */ + ret->f = malloc(sizeof(struct format_item) * strlen(format)); + if (ret->f == NULL) abort(); + + cur = ret->format; + + while (*cur) { +printf("before chunk cur '%s'\n", cur); + struct chunk c = next_chunk(&cur, f); +printf("after chunk, cur is '%s' (%d) (type %d)\n", cur, *cur, c.type); + switch (c.type) { + case C_ERROR: goto error; + case C_STRING: + ret->f[ret->fsize].type = INSTRING; + ret->f[ret->fsize].s = c.s; + break; + case C_ARG_NAME: + ret->f[ret->fsize].type = c.it; + ret->f[ret->fsize].event_arg = c.event_arg; + break; + case C_EVENT_NAME: + ret->f[ret->fsize].type = INSTRING; + ret->f[ret->fsize].s = ret->event_name; + break; + } + ret->fsize++; + } + + return ret; + +error: + printf("%s:%d: bad format '%s'\n", __FILE__, __LINE__, format); + abort(); +} diff --git a/common/utils/T/tracer/textlog.h b/common/utils/T/tracer/textlog.h new file mode 100644 index 0000000000..5c23f3a2db --- /dev/null +++ b/common/utils/T/tracer/textlog.h @@ -0,0 +1,9 @@ +#ifndef _TEXTLOG_H_ +#define _TEXTLOG_H_ + +typedef void textlog; + +textlog *new_textlog(void *event_handler, void *database, + char *event_name, char *format); + +#endif /* _TEXTLOG_H_ */ From f8733535c9a65adfb955725a5bcaea1178c4654b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 27 Apr 2016 18:31:55 +0200 Subject: [PATCH 055/217] cleanup --- common/utils/T/tracer/Makefile.local | 2 -- common/utils/T/tracer/Makefile.remote | 2 -- 2 files changed, 4 deletions(-) diff --git a/common/utils/T/tracer/Makefile.local b/common/utils/T/tracer/Makefile.local index ee730be866..a34378470b 100644 --- a/common/utils/T/tracer/Makefile.local +++ b/common/utils/T/tracer/Makefile.local @@ -15,7 +15,5 @@ $(PROG): $(OBJS) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -main.o: ../T_IDs.h ../T_defs.h - clean: rm -f *.o $(PROG) core diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index fdebee915c..79b1d6ea1e 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -22,8 +22,6 @@ gui/gui.a: %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -main.o: ../T_IDs.h ../T_defs.h - clean: rm -f *.o $(PROG) core textlog cd gui && make clean From 624aba07ddb745b84ca253451cafb189e929210d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 14:54:14 +0200 Subject: [PATCH 056/217] new function text_list_del --- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/text_list.c | 28 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 45acf8de3d..7646b0849e 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -27,6 +27,7 @@ void xy_plot_set_points(gui *gui, widget *this, int npoints, float *x, float *y); void text_list_add(gui *gui, widget *this, const char *text, int position); +void text_list_del(gui *gui, widget *this, int position); void gui_loop(gui *gui); diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index 89b7e8822d..59de2809d7 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -93,3 +93,31 @@ void text_list_add(gui *_gui, widget *_this, const char *text, int position) gunlock(g); } + +void text_list_del(gui *_gui, widget *_this, int position) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + + glock(g); + + /* TODO: useful check? */ + if (this->text_count == 0) goto done; + + if (position < 0) position = this->text_count; + if (position > this->text_count-1) position = this->text_count-1; + + free(this->text[position]); + + memmove(this->text + position, this->text + position + 1, + (this->text_count-1 - position) * sizeof(char *)); + + this->text_count--; + this->text = realloc(this->text, this->text_count * sizeof(char *)); + if (this->text == NULL) OOM; + + send_event(g, DIRTY, this->common.id); + +done: + gunlock(g); +} From 7283168ffd9d9d9d77053bca0609a2aef014e72b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 14:54:51 +0200 Subject: [PATCH 057/217] -l option renamed -r, it's more "natural" plus there is a default now --- common/utils/T/tracer/local.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c index c681b36aa6..bc205d40d5 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/tracer/local.c @@ -9,6 +9,9 @@ #include #include +#define DEFAULT_REMOTE_IP "127.0.0.1" +#define DEFAULT_REMOTE_PORT 2021 + #include "defs.h" #include "../T_defs.h" @@ -94,7 +97,9 @@ void usage(void) printf( "tracer - local side\n" "options:\n" -" -l local side (forwards packets to remote IP:port)\n" +" -r forwards packets to remote IP:port\n" +" (default %s:%d)\n", + DEFAULT_REMOTE_IP, DEFAULT_REMOTE_PORT ); exit(1); } @@ -103,8 +108,8 @@ int main(int n, char **v) { int s; int i; - char *remote_ip = NULL; - int remote_port = -1; + char *remote_ip = DEFAULT_REMOTE_IP; + int remote_port = DEFAULT_REMOTE_PORT; int port = 2020; void *f; @@ -116,8 +121,6 @@ int main(int n, char **v) usage(); } - if (remote_port == -1 || remote_ip == NULL) usage(); - f = forwarder(remote_ip, remote_port); init_shm(); s = get_connection("127.0.0.1", port); From 29859bb930c73141a0f8a9f56948cbcef5697698 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 14:58:56 +0200 Subject: [PATCH 058/217] -r option becomes -p, it's more "natural" --- common/utils/T/tracer/remote.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 367772d721..c22cc1bf55 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -10,7 +10,7 @@ #include "textlog.h" #include "../T_defs.h" -#define DEFAULT_REMOTE_PORT 2020 +#define DEFAULT_REMOTE_PORT 2021 int get_connection(char *addr, int port) { @@ -54,7 +54,7 @@ void usage(void) " note: you may pass several -on/-off/-ON/-OFF,\n" " they will be processed in order\n" " by default, all is off\n" -" -r remote side: use given port (default %d)\n", +" -p use given port (default %d)\n" DEFAULT_REMOTE_PORT ); exit(1); @@ -112,7 +112,7 @@ int main(int n, char **v) 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], "-r")) + if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; } if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } From ca945b53de338818d60742f17f542e63db2d009c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 15:02:01 +0200 Subject: [PATCH 059/217] first version of textlog with GUI introducing generic "view" with two instantiations: stdout and textlist --- common/utils/T/tracer/Makefile.remote | 13 ++-- common/utils/T/tracer/remote.c | 30 ++++++++++ common/utils/T/tracer/textlog.c | 61 ++++++++++++++++--- common/utils/T/tracer/textlog.h | 4 ++ common/utils/T/tracer/utils.c | 61 +++++++++++++++++++ common/utils/T/tracer/utils.h | 19 ++++++ common/utils/T/tracer/view/Makefile | 13 ++++ common/utils/T/tracer/view/stdout.c | 35 +++++++++++ common/utils/T/tracer/view/textlist.c | 85 +++++++++++++++++++++++++++ common/utils/T/tracer/view/view.h | 16 +++++ 10 files changed, 326 insertions(+), 11 deletions(-) create mode 100644 common/utils/T/tracer/utils.c create mode 100644 common/utils/T/tracer/utils.h create mode 100644 common/utils/T/tracer/view/Makefile create mode 100644 common/utils/T/tracer/view/stdout.c create mode 100644 common/utils/T/tracer/view/textlist.c create mode 100644 common/utils/T/tracer/view/view.h diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 79b1d6ea1e..9dc082e01e 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wall -g -pthread -DT_TRACER +CFLAGS=-Wall -g -pthread -DT_TRACER -I. #CFLAGS += -O3 -ffast-math -fomit-frame-pointer @@ -11,10 +11,14 @@ OBJS=remote_old.o plot.o database.o gui.o $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) -textlog: remote.o database.o event.o handler.o textlog.o - $(CC) $(CFLAGS) -o textlog $^ +textlog: utils.o remote.o database.o event.o handler.o textlog.o \ + view/view.a gui/gui.a + $(CC) $(CFLAGS) -o textlog $^ $(LIBS) -.PHONY: gui/gui.a +.PHONY: gui/gui.a view/view.a + +view/view.a: + cd view && make gui/gui.a: cd gui && make @@ -25,3 +29,4 @@ gui/gui.a: clean: rm -f *.o $(PROG) core textlog cd gui && make clean + cd view && make clean diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index c22cc1bf55..020aba3cdb 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -8,6 +8,9 @@ #include "event.h" #include "handler.h" #include "textlog.h" +#include "view/view.h" +#include "gui/gui.h" +#include "utils.h" #include "../T_defs.h" #define DEFAULT_REMOTE_PORT 2021 @@ -55,6 +58,7 @@ void usage(void) " they will be processed in order\n" " by default, all is off\n" " -p use given port (default %d)\n" +" -x GUI output\n", DEFAULT_REMOTE_PORT ); exit(1); @@ -88,6 +92,13 @@ event get_event(int s, char *v, void *d) return new_event(type, length, v, d); } +static void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return NULL; +} + int main(int n, char **v) { char *database_filename = NULL; @@ -104,6 +115,7 @@ int main(int n, char **v) int l; event_handler *h; textlog *textlog; + int gui_mode = 0; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -122,6 +134,7 @@ int main(int n, char **v) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } if (!strcmp(v[i], "-OFF")) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-x")) { gui_mode = 1; continue; } usage(); } @@ -142,6 +155,23 @@ int main(int n, char **v) "ENB_UL_CHANNEL_ESTIMATE", "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); + if (gui_mode) { + view *tout; + gui *g; + widget *w, *win; + g = gui_init(); + w = new_text_list(g, 600, 20, 0); + win = new_toplevel_window(g, 600, 20*12, "textlog"); + widget_add_child(g, win, w, -1); + //tout = new_textlist(1000, 10, g, w); + tout = new_textlist(7, 4, g, w); + new_thread(gui_thread, g); + textlog_add_view(textlog, tout); + } else { + view *sout = new_stdout(); + textlog_add_view(textlog, sout); + } + for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index e6728f9674..4bc66953d5 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -1,8 +1,10 @@ #include "textlog.h" #include "handler.h" #include "database.h" +#include "view/view.h" #include #include +#include enum format_item_type { INSTRING, @@ -23,25 +25,62 @@ struct textlog { char *format; void *database; unsigned long handler_id; + /* parsed format string */ struct format_item *f; int fsize; + /* list of views */ + view **v; + int vsize; + /* local output buffer */ + int osize; + int omaxsize; + char *obuf; }; -#include +static void PUTC(struct textlog *l, char c) +{ + if (l->osize == l->omaxsize) { + l->omaxsize += 512; + l->obuf = realloc(l->obuf, l->omaxsize); + if (l->obuf == NULL) abort(); + } + l->obuf[l->osize] = c; + l->osize++; +} + +static void PUTS(struct textlog *l, char *s) +{ + while (*s) PUTC(l, *s++); +} + +static void PUTI(struct textlog *l, int i) +{ + char s[64]; + sprintf(s, "%d", i); + PUTS(l, s); +} + static void _event(void *p, event e) { struct textlog *l = p; int i; -//printf("%s %s\n", l->event_name, l->format); + + l->osize = 0; for (i = 0; i < l->fsize; i++) switch(l->f[i].type) { - case INSTRING: printf("%s", l->f[i].s); break; - case INT: printf("%d", e.e[l->f[i].event_arg].i); break; - case STRING: printf("%s", e.e[l->f[i].event_arg].s); break; - case BUFFER: printf("{buffer size:%d}",e.e[l->f[i].event_arg].bsize);break; + case INSTRING: PUTS(l, l->f[i].s); break; + case INT: PUTI(l, e.e[l->f[i].event_arg].i); break; + case STRING: PUTS(l, e.e[l->f[i].event_arg].s); break; + case BUFFER: + PUTS(l, "{buffer size:"); + PUTI(l, e.e[l->f[i].event_arg].bsize); + PUTS(l, "}"); + break; } - printf("\n"); + PUTC(l, 0); + + for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->obuf); } enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; @@ -166,3 +205,11 @@ error: printf("%s:%d: bad format '%s'\n", __FILE__, __LINE__, format); abort(); } + +void textlog_add_view(textlog *_l, view *v) +{ + struct textlog *l = _l; + l->vsize++; + l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); + l->v[l->vsize-1] = v; +} diff --git a/common/utils/T/tracer/textlog.h b/common/utils/T/tracer/textlog.h index 5c23f3a2db..b9e9a3e8e3 100644 --- a/common/utils/T/tracer/textlog.h +++ b/common/utils/T/tracer/textlog.h @@ -6,4 +6,8 @@ typedef void textlog; textlog *new_textlog(void *event_handler, void *database, char *event_name, char *format); +#include "view/view.h" + +void textlog_add_view(textlog *l, view *v); + #endif /* _TEXTLOG_H_ */ diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c new file mode 100644 index 0000000000..2e18ccb60e --- /dev/null +++ b/common/utils/T/tracer/utils.c @@ -0,0 +1,61 @@ +#include "utils.h" +#include +#include +#include +#include + +void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_attr_setstacksize(&att, 10000000)) + { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + +void sleepms(int ms) +{ + struct timespec t; + + t.tv_sec = ms / 1000; + t.tv_nsec = (ms % 1000) * 1000000L; + + /* TODO: deal with EINTR */ + if (nanosleep(&t, NULL)) abort(); +} + +/****************************************************************************/ +/* list */ +/****************************************************************************/ + +list *list_remove_head(list *l) +{ + list *ret; + if (l == NULL) return NULL; + ret = l->next; + if (ret != NULL) ret->last = l->last; + free(l); + return ret; +} + +list *list_append(list *l, void *data) +{ + list *new = calloc(1, sizeof(list)); + if (new == NULL) abort(); + new->data = data; + if (l == NULL) { + new->last = new; + return new; + } + l->last->next = new; + l->last = new; + return l; +} diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h new file mode 100644 index 0000000000..5a37aa34c3 --- /dev/null +++ b/common/utils/T/tracer/utils.h @@ -0,0 +1,19 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +void new_thread(void *(*f)(void *), void *data); +void sleepms(int ms); + +/****************************************************************************/ +/* list */ +/****************************************************************************/ + +typedef struct list { + struct list *last, *next; + void *data; +} list; + +list *list_remove_head(list *l); +list *list_append(list *l, void *data); + +#endif /* _UTILS_H_ */ diff --git a/common/utils/T/tracer/view/Makefile b/common/utils/T/tracer/view/Makefile new file mode 100644 index 0000000000..bcf49d15cb --- /dev/null +++ b/common/utils/T/tracer/view/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -I.. + +OBJS=stdout.o textlist.o + +view.a: $(OBJS) + ar cr view.a $(OBJS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + rm -f *.a *.o diff --git a/common/utils/T/tracer/view/stdout.c b/common/utils/T/tracer/view/stdout.c new file mode 100644 index 0000000000..695704e422 --- /dev/null +++ b/common/utils/T/tracer/view/stdout.c @@ -0,0 +1,35 @@ +#include "view.h" +#include +#include +#include + +struct stdout { + view common; + pthread_mutex_t lock; +}; + +static void clear(view *this) +{ + /* do nothing */ +} + +static void append(view *_this, char *s) +{ + struct stdout *this = (struct stdout *)_this; + if (pthread_mutex_lock(&this->lock)) abort(); + printf("%s\n", s); + if (pthread_mutex_unlock(&this->lock)) abort(); +} + +view *new_stdout(void) +{ + struct stdout *ret = calloc(1, sizeof(struct stdout)); + if (ret == NULL) abort(); + + ret->common.clear = clear; + ret->common.append = (void (*)(view *, ...))append; + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + + return (view *)ret; +} diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c new file mode 100644 index 0000000000..7d1948e044 --- /dev/null +++ b/common/utils/T/tracer/view/textlist.c @@ -0,0 +1,85 @@ +#include "view.h" +#include "../utils.h" +#include "gui/gui.h" +#include +#include +#include + +struct textlist { + view common; + gui *g; + widget *w; + int maxsize; + int cursize; + float refresh_rate; + int autoscroll; + pthread_mutex_t lock; + list * volatile to_append; +}; + +static void _append(struct textlist *this, char *s) +{ + if (this->cursize == this->maxsize) { + text_list_del(this->g, this->w, 0); + this->cursize--; + } + text_list_add(this->g, this->w, s, -1); + this->cursize++; +} + +static void *textlist_thread(void *_this) +{ + struct textlist *this = _this; + + while (1) { + if (pthread_mutex_lock(&this->lock)) abort(); + while (this->to_append != NULL) { + char *s = this->to_append->data; + this->to_append = list_remove_head(this->to_append); + _append(this, s); + free(s); + } + if (pthread_mutex_unlock(&this->lock)) abort(); + sleepms(1000/this->refresh_rate); + } + + return 0; +} + +static void clear(view *this) +{ + /* TODO */ +} + +static void append(view *_this, char *s) +{ + struct textlist *this = (struct textlist *)_this; + char *dup; + + if (pthread_mutex_lock(&this->lock)) abort(); + dup = strdup(s); if (dup == NULL) abort(); + this->to_append = list_append(this->to_append, dup); + if (pthread_mutex_unlock(&this->lock)) abort(); +} + +view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w) +{ + struct textlist *ret = calloc(1, sizeof(struct textlist)); + if (ret == NULL) abort(); + + ret->common.clear = clear; + ret->common.append = (void (*)(view *, ...))append; + + ret->cursize = 0; + ret->maxsize = maxsize; + ret->refresh_rate = refresh_rate; + ret->g = g; + ret->w = w; + ret->autoscroll = 1; + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + + new_thread(textlist_thread, ret); + + return (view *)ret; +} diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h new file mode 100644 index 0000000000..9929e6e5d4 --- /dev/null +++ b/common/utils/T/tracer/view/view.h @@ -0,0 +1,16 @@ +#ifndef _VIEW_H_ +#define _VIEW_H_ + +#include "gui/gui.h" + +/* defines the public API of views */ + +typedef struct view { + void (*clear)(struct view *this); + void (*append)(struct view *this, ...); +} view; + +view *new_stdout(void); +view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w); + +#endif /* _VIEW_H_ */ From c9f51868e286689890337ec03cc2f657443e0f5e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 15:50:04 +0200 Subject: [PATCH 060/217] add x_draw_clipped_string and use it in the text_list gui --- common/utils/T/tracer/gui/text_list.c | 6 ++++-- common/utils/T/tracer/gui/x.c | 12 ++++++++++++ common/utils/T/tracer/gui/x.h | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index 59de2809d7..bd664bdb65 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -16,10 +16,12 @@ printf("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->com this->common.width, this->common.height); for (i = 0, j = this->starting_line; i < this->allocated_nlines && j < this->text_count; i++, j++) - x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + x_draw_clipped_string(g->x, g->xwin, FOREGROUND_COLOR, this->common.x, this->common.y + i * this->line_height + this->baseline, - this->text[j]); + this->text[j], + this->common.x, this->common.y, + this->common.width, this->common.height); } static void hints(gui *_gui, widget *_w, int *width, int *height) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index e68e3bcb92..d739cc9b4f 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -279,6 +279,18 @@ void x_draw_string(x_connection *_c, x_window *_w, int color, XDrawString(c->d, w->p, c->colors[color], x, y, t, tlen); } +void x_draw_clipped_string(x_connection *_c, x_window *_w, int color, + int x, int y, const char *t, + int clipx, int clipy, int clipwidth, int clipheight) +{ + struct x_connection *c = _c; + + XRectangle clip = { clipx, clipy, clipwidth, clipheight }; + XSetClipRectangles(c->d, c->colors[color], 0, 0, &clip, 1, Unsorted); + x_draw_string(_c, _w, color, x, y, t); + XSetClipMask(c->d, c->colors[color], None); +} + void x_draw(x_connection *_c, x_window *_w) { struct x_connection *c = _c; diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index e8f1d42d13..165785923c 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -41,6 +41,10 @@ void x_fill_rectangle(x_connection *c, x_window *w, int color, void x_draw_string(x_connection *_c, x_window *_w, int color, int x, int y, const char *t); +void x_draw_clipped_string(x_connection *_c, x_window *_w, int color, + int x, int y, const char *t, + int clipx, int clipy, int clipwidth, int clipheight); + /* specials functions to plot many points * you call several times x_add_point() then x_plot_points() */ From 2df85ee84ae3bef5a82109749cd7790328aba0b3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 16:36:03 +0200 Subject: [PATCH 061/217] cleanup --- common/utils/T/tracer/textlog.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 4bc66953d5..0cb5bd855a 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -178,9 +178,7 @@ textlog *new_textlog(event_handler *h, void *database, cur = ret->format; while (*cur) { -printf("before chunk cur '%s'\n", cur); struct chunk c = next_chunk(&cur, f); -printf("after chunk, cur is '%s' (%d) (type %d)\n", cur, *cur, c.type); switch (c.type) { case C_ERROR: goto error; case C_STRING: From e742718c2d5ddf412742fc84b0bcba56bdb3d4db Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Apr 2016 17:10:55 +0200 Subject: [PATCH 062/217] handle button press/release first version, to be finished --- common/utils/T/tracer/gui/container.c | 38 +++++++++++++++++++++ common/utils/T/tracer/gui/gui_defs.h | 2 ++ common/utils/T/tracer/gui/text_list.c | 8 +++++ common/utils/T/tracer/gui/toplevel_window.c | 12 +++++++ common/utils/T/tracer/gui/widget.c | 9 +++++ common/utils/T/tracer/gui/x.c | 16 +++++++-- 6 files changed, 83 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index bc14a6d0e4..d46af7b209 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -164,6 +164,42 @@ printf("HINTS container horizontal %p\n", _w); *height = this->hint_height; } +static void horizontal_button(gui *_g, widget *_this, int x, int y, + int button, int up) +{ +printf("BUTTON container horizontal %p xy %d %d button %d up %d\n", _this, x, y, button, up); + struct gui *g = _g; + struct container_widget *this = _this; + struct widget_list *l; + + l = this->common.children; + while (l) { + if (l->item->x <= x && x < l->item->x + l->item->width) { + l->item->button(g, l->item, x - l->item->x, y, button, up); + break; + } + l = l->next; + } +} + +static void vertical_button(gui *_g, widget *_this, int x, int y, + int button, int up) +{ +printf("BUTTON container vertical %p xy %d %d button %d up %d\n", _this, x, y, button, up); + struct gui *g = _g; + struct container_widget *this = _this; + struct widget_list *l; + + l = this->common.children; + while (l) { + if (l->item->y <= y && y < l->item->y + l->item->height) { + l->item->button(g, l->item, x, y - l->item->y, button, up); + break; + } + l = l->next; + } +} + static void paint(gui *_gui, widget *_this) { printf("PAINT container\n"); @@ -197,9 +233,11 @@ widget *new_container(gui *_gui, int vertical) if (vertical) { w->common.allocate = vertical_allocate; w->common.hints = vertical_hints; + w->common.button = vertical_button; } else { w->common.allocate = horizontal_allocate; w->common.hints = horizontal_hints; + w->common.button = horizontal_button; } gunlock(g); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 8a3e4b7701..8f680c9503 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -47,6 +47,8 @@ struct widget { void (*hints)(gui *g, widget *this, int *width, int *height); void (*paint)(gui *g, widget *this); void (*clear)(gui *g, widget *this); + /* user input */ + void (*button)(gui *g, widget *this, int x, int y, int button, int up); }; struct widget_list { diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index bd664bdb65..009964cdc3 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -44,6 +44,12 @@ static void allocate( printf("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); } +static void button(gui *g, widget *_this, int x, int y, int button, int up) +{ + struct text_list_widget *this = _this; +printf("BUTTON test_list %p xy %d %d button %d up %d\n", this, x, y, button, up); +} + widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) { struct gui *g = _gui; @@ -63,6 +69,8 @@ widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) w->common.hints = hints; w->common.allocate = allocate; + w->common.button = button; + gunlock(g); return w; diff --git a/common/utils/T/tracer/gui/toplevel_window.c b/common/utils/T/tracer/gui/toplevel_window.c index 6231329077..fef72b32cc 100644 --- a/common/utils/T/tracer/gui/toplevel_window.c +++ b/common/utils/T/tracer/gui/toplevel_window.c @@ -55,6 +55,16 @@ printf("PAINT toplevel_window (%d %d)\n", this->common.width, this->common.heigh g->xwin = NULL; /* TODO: remove? it's just in case */ } +static void button(gui *_g, widget *_this, int x, int y, int button, int up) +{ + struct gui *g = _g; + struct toplevel_window_widget *this = _this; + g->xwin = this->x; + this->common.children->item->button(_g, this->common.children->item, + x, y, button, up); + g->xwin = NULL; /* TODO: remove? it's just in case */ +} + /**********************************************************************/ /* creation */ /**********************************************************************/ @@ -78,6 +88,8 @@ widget *new_toplevel_window(gui *_gui, int width, int height, char *title) w->common.allocate = allocate; w->common.paint = paint; + w->common.button = button; + gunlock(g); return w; diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 103d36d452..6a34d00d06 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -13,6 +13,8 @@ static void default_allocate( static void default_add_child( gui *_gui, widget *_this, widget *child, int position); static void default_hints(gui *g, widget *this, int *width, int *height); +static void default_button(gui *gui, widget *_this, int x, int y, int button, + int up); static void toplevel_list_append(struct gui *g, struct widget *e) { @@ -47,6 +49,7 @@ widget *new_widget(struct gui *g, enum widget_type type, int size) ret->add_child = default_add_child; ret->allocate = default_allocate; ret->hints = default_hints; + ret->button = default_button; /* there is no default paint, on purpose */ ret->type = type; @@ -159,6 +162,12 @@ static void default_hints(gui *g, widget *this, int *width, int *height) *height = 1; } +static void default_button(gui *gui, widget *_this, int x, int y, int button, + int up) +{ + /* nothing */ +} + /*************************************************************************/ /* utils functions */ /*************************************************************************/ diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index d739cc9b4f..50164dce35 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -158,7 +158,7 @@ printf("XEV %d\n", ev.type); } break; case ConfigureNotify: - if ((w = find_x_window(g, ev.xexpose.window)) != NULL) { + 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; @@ -168,9 +168,21 @@ printf("XEV %d\n", ev.type); printf("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); } break; + case ButtonPress: + if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { + w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, + ev.xbutton.button, 0); + } + break; + case ButtonRelease: + if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { + w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, + ev.xbutton.button, 1); + } + break; #if 0 case MapNotify: - if ((w = find_x_window(g, ev.xexpose.window)) != NULL) { + if ((w = find_x_window(g, ev.xmap.window)) != NULL) { struct x_window *xw = w->x; xw->repaint = 1; } From f2195ba4e3fa66e04c7cc77df90789e2b78f04ac Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 15:51:44 +0200 Subject: [PATCH 063/217] notification system (from user input to application basically) --- common/utils/T/tracer/gui/Makefile | 2 +- common/utils/T/tracer/gui/gui.h | 15 ++++ common/utils/T/tracer/gui/gui_defs.h | 24 ++++++ common/utils/T/tracer/gui/notify.c | 120 +++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/gui/notify.c diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index 13820114dd..cc6a409e75 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ - gui.o label.o event.o xy_plot.o text_list.o + gui.o label.o event.o xy_plot.o text_list.o notify.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 7646b0849e..b1321c1e49 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -36,4 +36,19 @@ void gunlock(gui *gui); int new_color(gui *gui, char *color); +/* notifications */ +/* known notifications: + * - text_list: + * - scrollup { } + * - scrolldown { } + * //- click { int line, int button } + */ + +/* same type as in gui_defs.h */ +typedef void (*notifier)(void *private, gui *g, + char *notification, widget *w, void *notification_data); +unsigned long register_notifier(gui *g, char *notification, widget *w, + notifier handler, void *private); +void unregister_notifier(gui *g, unsigned long notifier_id); + #endif /* _GUI_H_ */ diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 8f680c9503..9bb22c9daa 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -143,6 +143,24 @@ struct repack_event { int id; }; +/*************************************************************************/ +/* notifications */ +/*************************************************************************/ + +/* same type as in gui.h */ +typedef void (*notifier)(void *private, gui *g, + char *notification, widget *w, void *notification_data); + +struct notifier { + notifier handler; + unsigned long id; + char *notification; + widget *w; + void *private; + /* done is used bu gui_notify */ + int done; +}; + /*************************************************************************/ /* main structure */ /*************************************************************************/ @@ -161,6 +179,9 @@ struct gui { void *xwin; /* set by a toplevel_window when * it paints itself, to be used * by its children */ + struct notifier *notifiers; + int notifiers_count; + unsigned long next_notifier_id; }; /*************************************************************************/ @@ -178,4 +199,7 @@ void gui_events(gui *gui); struct widget *find_widget(struct gui *g, int id); +void gui_notify(struct gui *g, char *notification, widget *w, + void *notification_data); + #endif /* _GUI_DEFS_H_ */ diff --git a/common/utils/T/tracer/gui/notify.c b/common/utils/T/tracer/gui/notify.c new file mode 100644 index 0000000000..dc6bc2fd59 --- /dev/null +++ b/common/utils/T/tracer/gui/notify.c @@ -0,0 +1,120 @@ +#include "gui.h" +#include "gui_defs.h" +#include +#include +#include + +unsigned long register_notifier(gui *_g, char *notification, widget *w, + notifier handler, void *private) +{ + struct gui *g = _g; + unsigned long ret; + + glock(g); + + if (g->next_notifier_id == 2UL * 1024 * 1024 * 1024) + { printf("%s:%d: report a bug\n", __FILE__, __LINE__); abort(); } + + g->notifiers = realloc(g->notifiers, + (g->notifiers_count+1) * sizeof(struct notifier)); + if (g->notifiers == NULL) abort(); + + ret = g->next_notifier_id; + + g->notifiers[g->notifiers_count].handler = handler; + g->notifiers[g->notifiers_count].id = g->next_notifier_id; + g->next_notifier_id++; + g->notifiers[g->notifiers_count].notification = strdup(notification); + if (g->notifiers[g->notifiers_count].notification == NULL) abort(); + g->notifiers[g->notifiers_count].w = w; + g->notifiers[g->notifiers_count].private = private; + /* initialize done to 1 so as not to call the handler if it's created + * by the call of another one that is in progress + */ + g->notifiers[g->notifiers_count].done = 1; + + g->notifiers_count++; + + gunlock(g); + + return ret; +} + +void unregister_notifier(gui *_g, unsigned long notifier_id) +{ + struct gui *g = _g; + int i; + + glock(g); + + for (i = 0; i < g->notifiers_count; i++) + if (g->notifiers[i].id == notifier_id) break; + + if (i == g->notifiers_count) { + printf("%s:%d: notifier_id %ld not found\n", __FILE__, __LINE__, + notifier_id); + abort(); + } + + free(g->notifiers[i].notification); + + memmove(g->notifiers + i, g->notifiers + i + 1, + (g->notifiers_count-1 - i) * sizeof(struct notifier)); + + g->notifiers_count--; + g->notifiers = realloc(g->notifiers, + g->notifiers_count * sizeof(struct notifier)); + if (g->notifiers == NULL) abort(); + + gunlock(g); +} + +/* called with lock ON */ +void gui_notify(struct gui *g, char *notification, widget *w, + void *notification_data) +{ + void *private; + notifier handler; + int i; + + /* this function is not re-entrant, for the moment keep as is + * and if the need is there, we'll make a new thread to handle + * notifications (or something) + * for now let's crash in case of recursive call + */ + static int inside = 0; + if (inside) + {printf("%s:%d: BUG! contact the authors\n", __FILE__, __LINE__);abort();} + inside = 1; + + /* clear all handlers */ + /* TODO: speedup */ + for (i = 0; i < g->notifiers_count; i++) g->notifiers[i].done = 0; + + /* calling the handler may modify the list of notifiers, we + * need to be careful here + */ +loop: + for (i = 0; i < g->notifiers_count; i++) { + if (g->notifiers[i].done == 1 || + g->notifiers[i].w != w || + strcmp(g->notifiers[i].notification, notification) != 0) + continue; + break; + } + if (i == g->notifiers_count) goto done; + + g->notifiers[i].done = 1; + + handler = g->notifiers[i].handler; + private = g->notifiers[i].private; + + gunlock(g); + handler(private, g, notification, w, notification_data); + glock(g); + + goto loop; + +done: + inside = 0; +} From 2fb9ec7d548d801d816c21d64a612a984d85df22 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 15:53:13 +0200 Subject: [PATCH 064/217] background and foreground colors are first class citizens! --- common/utils/T/tracer/gui/gui.h | 3 +++ common/utils/T/tracer/gui/x.h | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index b1321c1e49..a26f9a77e2 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -9,6 +9,9 @@ typedef void widget; #define HORIZONTAL 0 #define VERTICAL 1 +#define BACKGROUND_COLOR 0 +#define FOREGROUND_COLOR 1 + gui *gui_init(void); /* position = -1 to put at the end */ diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index 165785923c..c1f8d33d89 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -3,9 +3,6 @@ /* public X interface */ -#define BACKGROUND_COLOR 0 -#define FOREGROUND_COLOR 1 - typedef void x_connection; typedef void x_window; From 3bba991e773a612e117b2722cb6e40601906494a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 17:04:53 +0200 Subject: [PATCH 065/217] some work on text list --- common/utils/T/tracer/gui/gui.h | 15 +++-- common/utils/T/tracer/gui/gui_defs.h | 1 + common/utils/T/tracer/gui/text_list.c | 97 +++++++++++++++++++++++++-- common/utils/T/tracer/view/textlist.c | 2 +- 4 files changed, 106 insertions(+), 9 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index a26f9a77e2..c1bbbd7d06 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -29,8 +29,15 @@ void xy_plot_set_range(gui *gui, widget *this, void xy_plot_set_points(gui *gui, widget *this, int npoints, float *x, float *y); -void text_list_add(gui *gui, widget *this, const char *text, int position); +void text_list_add(gui *gui, widget *this, const char *text, int position, + int color); void text_list_del(gui *gui, widget *this, int position); +void text_list_state(gui *_gui, widget *_this, + int *visible_lines, int *start_line, int *number_of_lines); +void text_list_set_start_line(gui *gui, widget *this, int line); +void text_list_get_line(gui *gui, widget *this, int line, + char **text, int *color); +void text_list_set_color(gui *gui, widget *this, int line, int color); void gui_loop(gui *gui); @@ -42,9 +49,9 @@ int new_color(gui *gui, char *color); /* notifications */ /* known notifications: * - text_list: - * - scrollup { } - * - scrolldown { } - * //- click { int line, int button } + * - scrollup { void *: NULL } + * - scrolldown { void *: NULL } + * - click { int [2]: line, button } */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 9bb22c9daa..a80dc24798 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -74,6 +74,7 @@ struct container_widget { struct text_list_widget { struct widget common; char **text; + int *color; int text_count; int wanted_width; int wanted_nlines; /* number of lines of text the user wants to see */ diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index 009964cdc3..bc0001cf8b 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -16,7 +16,7 @@ printf("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->com this->common.width, this->common.height); for (i = 0, j = this->starting_line; i < this->allocated_nlines && j < this->text_count; i++, j++) - x_draw_clipped_string(g->x, g->xwin, FOREGROUND_COLOR, + x_draw_clipped_string(g->x, g->xwin, this->color[j], this->common.x, this->common.y + i * this->line_height + this->baseline, this->text[j], @@ -44,10 +44,25 @@ static void allocate( printf("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); } -static void button(gui *g, widget *_this, int x, int y, int button, int up) +static void button(gui *_g, widget *_this, int x, int y, int button, int up) { + struct gui *g = _g; struct text_list_widget *this = _this; -printf("BUTTON test_list %p xy %d %d button %d up %d\n", this, x, y, button, up); +printf("BUTTON test_list %p xy %d %d button %d up %d\n", _this, x, y, button, up); + /* scroll up */ + if (button == 4 && up == 0) { + gui_notify(g, "scrollup", _this, NULL); + } + /* scroll down */ + if (button == 5 && up == 0) { + gui_notify(g, "scrolldown", _this, NULL); + } + /* button 1/2/3 click */ + if (button >= 1 && button <= 3 && up == 0) { + int line = this->starting_line + y / this->line_height; + if (line >= 0 && line < this->text_count) + gui_notify(g, "click", _this, (int[2]){ line, button }); + } } widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) @@ -80,7 +95,8 @@ widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) /* public functions */ /*************************************************************************/ -void text_list_add(gui *_gui, widget *_this, const char *text, int position) +void text_list_add(gui *_gui, widget *_this, const char *text, int position, + int color) { struct gui *g = _gui; struct text_list_widget *this = _this; @@ -93,11 +109,16 @@ void text_list_add(gui *_gui, widget *_this, const char *text, int position) this->text_count++; this->text = realloc(this->text, this->text_count * sizeof(char *)); if (this->text == NULL) OOM; + this->color = realloc(this->color, this->text_count * sizeof(int)); + if (this->color == NULL) OOM; memmove(this->text + position + 1, this->text + position, (this->text_count-1 - position) * sizeof(char *)); + memmove(this->color + position + 1, this->color + position, + (this->text_count-1 - position) * sizeof(int)); this->text[position] = strdup(text); if (this->text[position] == NULL) OOM; + this->color[position] = color; send_event(g, DIRTY, this->common.id); @@ -121,13 +142,81 @@ void text_list_del(gui *_gui, widget *_this, int position) memmove(this->text + position, this->text + position + 1, (this->text_count-1 - position) * sizeof(char *)); + memmove(this->color + position, this->color + position + 1, + (this->text_count-1 - position) * sizeof(int)); this->text_count--; this->text = realloc(this->text, this->text_count * sizeof(char *)); if (this->text == NULL) OOM; + this->color = realloc(this->color, this->text_count * sizeof(int)); + if (this->color == NULL) OOM; send_event(g, DIRTY, this->common.id); done: gunlock(g); } + +void text_list_state(gui *_gui, widget *_this, + int *visible_lines, int *start_line, int *number_of_lines) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + + glock(g); + + *visible_lines = this->allocated_nlines; + *start_line = this->starting_line; + *number_of_lines = this->text_count; + + gunlock(g); +} + +void text_list_set_start_line(gui *_gui, widget *_this, int line) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + + glock(g); + + this->starting_line = line; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} + +void text_list_get_line(gui *_gui, widget *_this, int line, + char **text, int *color) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + + glock(g); + + if (line < 0 || line >= this->text_count) { + *text = NULL; + *color = -1; + } else { + *text = this->text[line]; + *color = this->color[line]; + } + + gunlock(g); +} + +void text_list_set_color(gui *_gui, widget *_this, int line, int color) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + + glock(g); + + if (line >= 0 && line < this->text_count) { + this->color[line] = color; + + send_event(g, DIRTY, this->common.id); + } + + gunlock(g); +} diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c index 7d1948e044..314cc3b47e 100644 --- a/common/utils/T/tracer/view/textlist.c +++ b/common/utils/T/tracer/view/textlist.c @@ -23,7 +23,7 @@ static void _append(struct textlist *this, char *s) text_list_del(this->g, this->w, 0); this->cursize--; } - text_list_add(this->g, this->w, s, -1); + text_list_add(this->g, this->w, s, -1, FOREGROUND_COLOR); this->cursize++; } From 88bef83d8ba630f573f41495b0e7ff5381a43047 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 18:29:04 +0200 Subject: [PATCH 066/217] X threading handling --- common/utils/T/tracer/gui/gui.c | 2 ++ common/utils/T/tracer/gui/init.c | 2 ++ common/utils/T/tracer/gui/x.c | 17 +++++++++++++++++ common/utils/T/tracer/gui/x.h | 5 +++++ 4 files changed, 26 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.c b/common/utils/T/tracer/gui/gui.c index 55c7a3680a..2166774d92 100644 --- a/common/utils/T/tracer/gui/gui.c +++ b/common/utils/T/tracer/gui/gui.c @@ -9,11 +9,13 @@ void glock(gui *_gui) { struct gui *g = _gui; if (pthread_mutex_lock(g->lock)) ERR("mutex error\n"); + xlock(g->x); } void gunlock(gui *_gui) { struct gui *g = _gui; + xunlock(g->x); if (pthread_mutex_unlock(g->lock)) ERR("mutex error\n"); } diff --git a/common/utils/T/tracer/gui/init.c b/common/utils/T/tracer/gui/init.c index c708639674..445f696643 100644 --- a/common/utils/T/tracer/gui/init.c +++ b/common/utils/T/tracer/gui/init.c @@ -12,6 +12,8 @@ gui *gui_init(void) { struct gui *ret; + x_init_threading(); + ret = calloc(1, sizeof(struct gui)); if (ret == NULL) OOM; diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 50164dce35..12888da468 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -6,6 +6,23 @@ #include #include +void x_init_threading(void) +{ + if (XInitThreads() == False) abort(); +} + +void xlock(x_connection *_x) +{ + struct x_connection *x = _x; + XLockDisplay(x->d); +} + +void xunlock(x_connection *_x) +{ + struct x_connection *x = _x; + XUnlockDisplay(x->d); +} + int x_connection_fd(x_connection *_x) { struct x_connection *x = _x; diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index c1f8d33d89..82e46cac9d 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -6,6 +6,11 @@ typedef void x_connection; typedef void x_window; +void x_init_threading(void); + +void xlock(x_connection *x); +void xunlock(x_connection *x); + x_connection *x_open(void); x_window *x_create_window(x_connection *x, int width, int height, From 53fd31ef530a4a6636ccd024881aa91c41eed62a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 18:46:43 +0200 Subject: [PATCH 067/217] bugfix: hints are not valid anymore after adding a child to a container --- common/utils/T/tracer/gui/container.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index d46af7b209..939f75bc55 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -13,9 +13,11 @@ printf("REPACK container %p\n", _this); return this->common.parent->repack(g, this->common.parent); } -static void add_child(gui *g, widget *this, widget *child, int position) +static void add_child(gui *g, widget *_this, widget *child, int position) { printf("ADD_CHILD container\n"); + struct container_widget *this = _this; + this->hints_are_valid = 0; widget_add_child_internal(g, this, child, position); } From 69e2a15e311f93d024773284436fd7886071929f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 19:40:31 +0200 Subject: [PATCH 068/217] prepare container to deal with growable children --- common/utils/T/tracer/gui/container.c | 44 +++++++++++++++++++++++++++ common/utils/T/tracer/gui/gui.h | 3 ++ common/utils/T/tracer/gui/gui_defs.h | 2 ++ 3 files changed, 49 insertions(+) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 939f75bc55..97cac62066 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -2,6 +2,7 @@ #include "gui_defs.h" #include #include +#include #define MAX(a, b) ((a)>(b)?(a):(b)) @@ -19,6 +20,19 @@ printf("ADD_CHILD container\n"); struct container_widget *this = _this; this->hints_are_valid = 0; widget_add_child_internal(g, this, child, position); + + /* initially not growable */ + this->growable = realloc(this->growable, (this->nchildren+1)*sizeof(int)); + if (this->growable == NULL) abort(); + + if (position == -1) position = this->nchildren; + + memmove(this->growable + position+1, this->growable + position, + (this->nchildren - position) * sizeof(int)); + + this->growable[position] = 0; + + this->nchildren++; } static void compute_vertical_hints(struct gui *g, @@ -246,3 +260,33 @@ widget *new_container(gui *_gui, int vertical) return w; } + +/*************************************************************************/ +/* public functions */ +/*************************************************************************/ + +void container_set_child_growable(gui *_gui, widget *_this, + widget *child, int growable) +{ + gui *g = _gui; + struct container_widget *this = _this; + struct widget_list *lcur; + int i; + + glock(g); + + lcur = this->common.children; + i = 0; + while (lcur) { + if (lcur->item == child) break; + lcur = lcur->next; + i++; + } + if (lcur == NULL) ERR("%s:%d: child not found\n", __FILE__, __LINE__); + + this->growable[i] = growable; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index c1bbbd7d06..b1440a20c4 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -24,6 +24,9 @@ widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); widget *new_text_list(gui *_gui, int width, int nlines, int background_color); +void container_set_child_growable(gui *_gui, widget *_this, + widget *child, int growable); + void xy_plot_set_range(gui *gui, widget *this, float xmin, float xmax, float ymin, float ymax); void xy_plot_set_points(gui *gui, widget *this, diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index a80dc24798..58ae329467 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -69,6 +69,8 @@ struct container_widget { int hints_are_valid; /* used to cache hints values */ int hint_width; /* cached hint values - invalid if */ int hint_height; /* repack_was_called == 1 */ + int *growable; + int nchildren; }; struct text_list_widget { From 018da0589730333b052cf1c9759c4f3e99b5b1e5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 29 Apr 2016 20:10:19 +0200 Subject: [PATCH 069/217] container deals with growable children --- common/utils/T/tracer/gui/container.c | 65 +++++++++++++++++++-------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 97cac62066..2e979e785d 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -84,6 +84,8 @@ printf("ALLOCATE container vertical %p\n", _this); struct gui *g = _gui; struct container_widget *this = _this; struct widget_list *l; + int over_pixels = 0; + int i; if (this->hints_are_valid == 1) goto hints_ok; @@ -96,18 +98,29 @@ hints_ok: this->common.width = width; this->common.height = height; - /* allocate */ - l = this->common.children; - while (l) { - l->item->hints(g, l->item, &cwidth, &cheight); - l->item->allocate(g, l->item, this->common.x, this->common.y + cy, - //this->hint_width, cheight); - MAX(width, cwidth), cheight); - cy += cheight; - l = l->next; + /* TODO: some pixels won't be allocated, take care of it? */ + if (height > this->hint_height) { + int ngrowable = 0; + for (i = 0; i < this->nchildren; i++) if (this->growable[i]) ngrowable++; + if (ngrowable) + over_pixels = (height - this->hint_height) / ngrowable; } - if (cy != this->hint_height) ERR("reachable?\n"); + /* allocate */ + l = this->common.children; + i = 0; + while (l) { + int allocated_height; + l->item->hints(g, l->item, &cwidth, &cheight); + allocated_height = cheight + (this->growable[i] ? over_pixels : 0); + l->item->allocate(g, l->item, this->common.x, this->common.y + cy, + MAX(width, cwidth), allocated_height); + cy += allocated_height; + l = l->next; + i++; + } + +// if (cy != this->hint_height) ERR("reachable?\n"); } static void horizontal_allocate(gui *_gui, widget *_this, @@ -119,6 +132,8 @@ printf("ALLOCATE container horizontal %p\n", _this); struct gui *g = _gui; struct container_widget *this = _this; struct widget_list *l; + int over_pixels = 0; + int i; if (this->hints_are_valid == 1) goto hints_ok; @@ -131,17 +146,29 @@ hints_ok: this->common.width = width; this->common.height = height; - /* allocate */ - l = this->common.children; - while (l) { - l->item->hints(g, l->item, &cwidth, &cheight); - l->item->allocate(g, l->item, this->common.x + cx, this->common.y, - cwidth, MAX(height, cheight)/* this->hint_height */); - cx += cwidth; - l = l->next; + /* TODO: some pixels won't be allocated, take care of it? */ + if (width > this->hint_width) { + int ngrowable = 0; + for (i = 0; i < this->nchildren; i++) if (this->growable[i]) ngrowable++; + if (ngrowable) + over_pixels = (width - this->hint_width) / ngrowable; } - if (cx != this->hint_width) ERR("reachable?\n"); + /* allocate */ + l = this->common.children; + i = 0; + while (l) { + int allocated_width; + l->item->hints(g, l->item, &cwidth, &cheight); + allocated_width = cwidth + (this->growable[i] ? over_pixels : 0); + l->item->allocate(g, l->item, this->common.x + cx, this->common.y, + allocated_width, MAX(height, cheight)/* this->hint_height */); + cx += allocated_width; + l = l->next; + i++; + } + +// if (cx != this->hint_width) ERR("reachable?\n"); } static void vertical_hints(gui *_gui, widget *_w, int *width, int *height) From 9463903d3a781a560c7b4526d27c3aa84a965e8d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 12:56:22 +0200 Subject: [PATCH 070/217] typo fix --- common/utils/T/tracer/local.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c index bc205d40d5..6c1368cc13 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/tracer/local.c @@ -115,7 +115,7 @@ int main(int n, char **v) for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-l")) { if (i > n-3) usage(); + if (!strcmp(v[i], "-r")) { if (i > n-3) usage(); remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } printf("ERROR: unknown option %s\n", v[i]); usage(); From 6ffa65f1d215a528f35821f7883d147dece7fc65 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 14:06:20 +0200 Subject: [PATCH 071/217] get rid of X locks, there were missing glock/gunlock here and there --- common/utils/T/tracer/gui/gui.c | 12 +++++++++--- common/utils/T/tracer/gui/init.c | 7 +++++-- common/utils/T/tracer/gui/loop.c | 7 +++++++ common/utils/T/tracer/gui/x.c | 17 ----------------- common/utils/T/tracer/gui/x.h | 5 ----- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.c b/common/utils/T/tracer/gui/gui.c index 2166774d92..ef8640b0de 100644 --- a/common/utils/T/tracer/gui/gui.c +++ b/common/utils/T/tracer/gui/gui.c @@ -9,18 +9,24 @@ void glock(gui *_gui) { struct gui *g = _gui; if (pthread_mutex_lock(g->lock)) ERR("mutex error\n"); - xlock(g->x); } void gunlock(gui *_gui) { struct gui *g = _gui; - xunlock(g->x); if (pthread_mutex_unlock(g->lock)) ERR("mutex error\n"); } int new_color(gui *_gui, char *color) { struct gui *g = _gui; - return x_new_color(g->x, color); + int ret; + + glock(g); + + ret = x_new_color(g->x, color); + + gunlock(g); + + return ret; } diff --git a/common/utils/T/tracer/gui/init.c b/common/utils/T/tracer/gui/init.c index 445f696643..c6d5e3e435 100644 --- a/common/utils/T/tracer/gui/init.c +++ b/common/utils/T/tracer/gui/init.c @@ -12,8 +12,6 @@ gui *gui_init(void) { struct gui *ret; - x_init_threading(); - ret = calloc(1, sizeof(struct gui)); if (ret == NULL) OOM; @@ -25,7 +23,12 @@ gui *gui_init(void) if (pipe(ret->event_pipe)) ERR("%s\n", strerror(errno)); + /* lock not necessary but there for consistency (when instrumenting x.c + * we need the gui to be locked when calling any function in x.c) + */ + glock(ret); ret->x = x_open(); + gunlock(ret); return ret; } diff --git a/common/utils/T/tracer/gui/loop.c b/common/utils/T/tracer/gui/loop.c index 94b7fe54bd..8ceb3c06e1 100644 --- a/common/utils/T/tracer/gui/loop.c +++ b/common/utils/T/tracer/gui/loop.c @@ -16,14 +16,21 @@ void gui_loop(gui *_gui) int maxfd; fd_set rd; + /* lock not necessary but there for consistency (when instrumenting x.c + * we need the gui to be locked when calling any function in x.c) + */ + glock(g); xfd = x_connection_fd(g->x); + gunlock(g); eventfd = g->event_pipe[0]; if (eventfd > xfd) maxfd = eventfd; else maxfd = xfd; while (1) { + glock(g); x_flush(g->x); + gunlock(g); FD_ZERO(&rd); FD_SET(xfd, &rd); FD_SET(eventfd, &rd); diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 12888da468..50164dce35 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -6,23 +6,6 @@ #include #include -void x_init_threading(void) -{ - if (XInitThreads() == False) abort(); -} - -void xlock(x_connection *_x) -{ - struct x_connection *x = _x; - XLockDisplay(x->d); -} - -void xunlock(x_connection *_x) -{ - struct x_connection *x = _x; - XUnlockDisplay(x->d); -} - int x_connection_fd(x_connection *_x) { struct x_connection *x = _x; diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index 82e46cac9d..c1f8d33d89 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -6,11 +6,6 @@ typedef void x_connection; typedef void x_window; -void x_init_threading(void); - -void xlock(x_connection *x); -void xunlock(x_connection *x); - x_connection *x_open(void); x_window *x_create_window(x_connection *x, int width, int height, From 951882adaaaeff4c2809fe37a041e15c77d4485a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 14:09:20 +0200 Subject: [PATCH 072/217] redraw window when receiving MapNotify (not sure if correct) --- common/utils/T/tracer/gui/x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 50164dce35..68869d6e0f 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -151,6 +151,7 @@ printf("x_events START\n"); XNextEvent(x->d, &ev); printf("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; From 4911b107dae26150ec87cc31cada0e52f97061d6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 14:10:59 +0200 Subject: [PATCH 073/217] instrument X using gcc's -finstrument-functions used to debug locking --- common/utils/T/tracer/gui/Makefile | 3 +++ common/utils/T/tracer/gui/gui.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index cc6a409e75..9552d03d82 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -10,6 +10,9 @@ gui.a: $(OBJS) test: test.o gui.a $(CC) -o test $(OBJS) test.o -lX11 -pthread -lm +x.o:x.c + $(CC) $(CFLAGS) -o $@ -c $< -finstrument-functions + %.o: %.c $(CC) $(CFLAGS) -o $@ -c $< diff --git a/common/utils/T/tracer/gui/gui.c b/common/utils/T/tracer/gui/gui.c index ef8640b0de..52e1b1cc74 100644 --- a/common/utils/T/tracer/gui/gui.c +++ b/common/utils/T/tracer/gui/gui.c @@ -5,15 +5,31 @@ #include #include +static volatile int locked = 0; + +void __cyg_profile_func_enter (void *func, void *caller) +{ + if (locked == 0) abort(); + printf("E %p %p %lu\n", func, caller, time(NULL)); +} + +void __cyg_profile_func_exit (void *func, void *caller) +{ + if (locked == 0) abort(); + printf("X %p %p %lu\n", func, caller, time(NULL)); +} + void glock(gui *_gui) { struct gui *g = _gui; if (pthread_mutex_lock(g->lock)) ERR("mutex error\n"); + locked = 1; } void gunlock(gui *_gui) { struct gui *g = _gui; + locked = 0; if (pthread_mutex_unlock(g->lock)) ERR("mutex error\n"); } From bd50539fda96214ac1a35f5471e4872cdeb05b2d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 14:13:15 +0200 Subject: [PATCH 074/217] Revert "instrument X using gcc's -finstrument-functions" This reverts commit 4911b107dae26150ec87cc31cada0e52f97061d6. The idea was to keep the stuff in the git history. --- common/utils/T/tracer/gui/Makefile | 3 --- common/utils/T/tracer/gui/gui.c | 16 ---------------- 2 files changed, 19 deletions(-) diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index 9552d03d82..cc6a409e75 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -10,9 +10,6 @@ gui.a: $(OBJS) test: test.o gui.a $(CC) -o test $(OBJS) test.o -lX11 -pthread -lm -x.o:x.c - $(CC) $(CFLAGS) -o $@ -c $< -finstrument-functions - %.o: %.c $(CC) $(CFLAGS) -o $@ -c $< diff --git a/common/utils/T/tracer/gui/gui.c b/common/utils/T/tracer/gui/gui.c index 52e1b1cc74..ef8640b0de 100644 --- a/common/utils/T/tracer/gui/gui.c +++ b/common/utils/T/tracer/gui/gui.c @@ -5,31 +5,15 @@ #include #include -static volatile int locked = 0; - -void __cyg_profile_func_enter (void *func, void *caller) -{ - if (locked == 0) abort(); - printf("E %p %p %lu\n", func, caller, time(NULL)); -} - -void __cyg_profile_func_exit (void *func, void *caller) -{ - if (locked == 0) abort(); - printf("X %p %p %lu\n", func, caller, time(NULL)); -} - void glock(gui *_gui) { struct gui *g = _gui; if (pthread_mutex_lock(g->lock)) ERR("mutex error\n"); - locked = 1; } void gunlock(gui *_gui) { struct gui *g = _gui; - locked = 0; if (pthread_mutex_unlock(g->lock)) ERR("mutex error\n"); } From 68106e4a3550952b2e73b567ab9f2a7cb4d93731 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 14:16:50 +0200 Subject: [PATCH 075/217] start working on the event selector window --- common/utils/T/tracer/Makefile | 1 + common/utils/T/tracer/Makefile.remote | 2 +- common/utils/T/tracer/event_selector.c | 41 ++++++++++++++++++++++++++ common/utils/T/tracer/event_selector.h | 8 +++++ common/utils/T/tracer/remote.c | 19 +++++++----- 5 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 common/utils/T/tracer/event_selector.c create mode 100644 common/utils/T/tracer/event_selector.h diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 9069d2be2c..b06ff4dd4d 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -5,6 +5,7 @@ local: remote: make -f Makefile.remote + make -f Makefile.remote textlog clean: make -f Makefile.local clean diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 9dc082e01e..8dd9d9a7e2 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -12,7 +12,7 @@ $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) textlog: utils.o remote.o database.o event.o handler.o textlog.o \ - view/view.a gui/gui.a + event_selector.o view/view.a gui/gui.a $(CC) $(CFLAGS) -o textlog $^ $(LIBS) .PHONY: gui/gui.a view/view.a diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c new file mode 100644 index 0000000000..f632efb8da --- /dev/null +++ b/common/utils/T/tracer/event_selector.c @@ -0,0 +1,41 @@ +#include "event_selector.h" +#include "gui/gui.h" + +void setup_event_selector(gui *g, void *database, int socket, int *is_on) +{ + widget *win; + widget *main_container; + widget *container; + widget *left, *right; + widget *events, *groups; + + win = new_toplevel_window(g, 610, 800, "event selector"); + main_container = new_container(g, VERTICAL); + widget_add_child(g, win, main_container, -1); + + container = new_container(g, HORIZONTAL); + widget_add_child(g, main_container, container, -1); + container_set_child_growable(g, main_container, container, 1); + widget_add_child(g, main_container, + new_label(g, "mouse scroll to scroll - " + "left click to activate - " + "right click to deactivate"), -1); + + left = new_container(g, VERTICAL); + right = new_container(g, VERTICAL); + widget_add_child(g, container, left, -1); + widget_add_child(g, container, right, -1); + container_set_child_growable(g, container, left, 1); + container_set_child_growable(g, container, right, 1); + + widget_add_child(g, left, new_label(g, "Events"), -1); + widget_add_child(g, right, new_label(g, "Groups"), -1); + + events = new_text_list(g, 300, 10, new_color(g, "#ccccff")); + groups = new_text_list(g, 300, 10, new_color(g, "#ccffee")); + + widget_add_child(g, left, events, -1); + widget_add_child(g, right, groups, -1); + container_set_child_growable(g, left, events, 1); + container_set_child_growable(g, right, groups, 1); +} diff --git a/common/utils/T/tracer/event_selector.h b/common/utils/T/tracer/event_selector.h new file mode 100644 index 0000000000..11e977b4f6 --- /dev/null +++ b/common/utils/T/tracer/event_selector.h @@ -0,0 +1,8 @@ +#ifndef _EVENT_SELECTOR_H_ +#define _EVENT_SELECTOR_H_ + +#include "gui/gui.h" + +void setup_event_selector(gui *g, void *database, int socket, int *is_on); + +#endif /* _EVENT_SELECTOR_H_ */ diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 020aba3cdb..9d1d2b0968 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -12,6 +12,7 @@ #include "gui/gui.h" #include "utils.h" #include "../T_defs.h" +#include "event_selector.h" #define DEFAULT_REMOTE_PORT 2021 @@ -115,6 +116,7 @@ int main(int n, char **v) int l; event_handler *h; textlog *textlog; + gui *g; int gui_mode = 0; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); @@ -155,17 +157,18 @@ int main(int n, char **v) "ENB_UL_CHANNEL_ESTIMATE", "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); + g = gui_init(); + new_thread(gui_thread, g); + if (gui_mode) { view *tout; - gui *g; widget *w, *win; - g = gui_init(); - w = new_text_list(g, 600, 20, 0); +// w = new_text_list(g, 600, 20, 0); + w = new_text_list(g, 600, 20, new_color(g, "#ffabab")); win = new_toplevel_window(g, 600, 20*12, "textlog"); widget_add_child(g, win, w, -1); - //tout = new_textlist(1000, 10, g, w); - tout = new_textlist(7, 4, g, w); - new_thread(gui_thread, g); + tout = new_textlist(1000, 10, g, w); + //tout = new_textlist(7, 4, g, w); textlog_add_view(textlog, tout); } else { view *sout = new_stdout(); @@ -175,7 +178,7 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = get_connection("127.0.0.1", port); + s = get_connection("0.0.0.0", port); /* send the first message - activate selected traces */ t = 0; @@ -187,6 +190,8 @@ int main(int n, char **v) if (is_on[l]) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + setup_event_selector(g, database, s, is_on); + /* read messages */ while (1) { char v[T_BUFFER_MAX]; From d079dadb95f785260389bf4c1b585378d2a4f3d4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 17:36:24 +0200 Subject: [PATCH 076/217] changing the growable attribute of a child requires a repack, not just "dirty" --- common/utils/T/tracer/gui/container.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 2e979e785d..c2913db2d6 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -313,7 +313,7 @@ void container_set_child_growable(gui *_gui, widget *_this, this->growable[i] = growable; - send_event(g, DIRTY, this->common.id); + send_event(g, REPACK, this->common.id); gunlock(g); } From e6d5f22c8bbc9b2bebba514f47d488e11f95a1b5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 22:39:23 +0200 Subject: [PATCH 077/217] add message 1 to the T This message sends configuration for all events. --- common/utils/T/T.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 4876fe8652..541cd239b7 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -31,6 +31,7 @@ static void get_message(int s) char t; int l; int id; + int is_on; if (read(s, &t, 1) != 1) abort(); printf("got mess %d\n", t); @@ -45,6 +46,18 @@ printf("got mess %d\n", t); l--; } break; + case 1: + /* set IDs as given */ + /* optimize? */ + if (read(s, &l, sizeof(int)) != sizeof(int)) abort(); + id = 0; + while (l) { + if (read(s, &is_on, sizeof(int)) != sizeof(int)) abort(); + T_IDs[id] = is_on; + id++; + l--; + } + break; } } From c3e59b16b33a30a3a57518fbbf8df211382fabbd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 1 May 2016 22:43:36 +0200 Subject: [PATCH 078/217] some work on event selector --- common/utils/T/tracer/Makefile.remote | 2 +- common/utils/T/tracer/database.c | 46 +++++++++ common/utils/T/tracer/database.h | 5 + common/utils/T/tracer/event_selector.c | 131 ++++++++++++++++++++++++- common/utils/T/tracer/event_selector.h | 5 +- common/utils/T/tracer/remote.c | 23 +++-- common/utils/T/tracer/remote_old.c | 17 ---- common/utils/T/tracer/textlog.c | 46 +++------ common/utils/T/tracer/utils.c | 44 +++++++++ common/utils/T/tracer/utils.h | 20 ++++ 10 files changed, 275 insertions(+), 64 deletions(-) diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 8dd9d9a7e2..08b79f2aa1 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -6,7 +6,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. LIBS=-lX11 -lm PROG=tracer_remote -OBJS=remote_old.o plot.o database.o gui.o +OBJS=remote_old.o plot.o database.o gui.o utils.o $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index c0224af5d0..62796149b3 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -1,4 +1,5 @@ #include "database.h" +#include "utils.h" #include #include #include @@ -453,3 +454,48 @@ int number_of_ids(void *_d) database *d = _d; return d->isize; } + +int database_get_ids(void *_d, char ***ids) +{ + database *d = _d; + int i; + *ids = malloc(d->isize * sizeof(char **)); + for (i = 0; i < d->isize; i++) (*ids)[i] = d->i[i].name; + return d->isize; +} + +int database_get_groups(void *_d, char ***groups) +{ + database *d = _d; + int i; + *groups = malloc(d->gsize * sizeof(char **)); + for (i = 0; i < d->gsize; i++) (*groups)[i] = d->g[i].name; + return d->gsize; +} + +int database_pos_to_id(void *_d, int pos) +{ + database *d = _d; + return d->i[pos].id; +} + +void database_get_generic_description(void *_d, int id, + char **name, char **desc) +{ + database *d = _d; + OBUF o; + int i; + *name = strdup(d->i[id].name); + o.osize = o.omaxsize = 0; + o.obuf = NULL; + PUTS(&o, *name); + for (i = 0; i < d->i[id].asize; i++) { + PUTC(&o, ' '); + PUTS(&o, d->i[id].arg_name[i]); + PUTS(&o, " ["); + PUTS(&o, d->i[id].arg_name[i]); + PUTS(&o, "]"); + } + PUTC(&o, 0); + *desc = o.obuf; +} diff --git a/common/utils/T/tracer/database.h b/common/utils/T/tracer/database.h index e2f8aee8b7..c5cab05d9f 100644 --- a/common/utils/T/tracer/database.h +++ b/common/utils/T/tracer/database.h @@ -10,6 +10,11 @@ void on_off(void *d, char *item, int *a, int onoff); char *event_name_from_id(void *database, int id); int event_id_from_name(void *database, char *name); int number_of_ids(void *database); +int database_get_ids(void *database, char ***ids); +int database_get_groups(void *database, char ***groups); +int database_pos_to_id(void *database, int pos); +void database_get_generic_description(void *database, int id, + char **name, char **desc); /****************************************************************************/ /* get format of an event */ diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index f632efb8da..650a6af59a 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -1,13 +1,106 @@ #include "event_selector.h" #include "gui/gui.h" +#include "database.h" +#include "utils.h" +#include +#include -void setup_event_selector(gui *g, void *database, int socket, int *is_on) +struct event_selector { + int *is_on; + int red; + int green; + gui *g; + widget *events; + widget *groups; + void *database; + int nevents; + int ngroups; + int socket; +}; + +static void scroll(void *private, gui *g, + char *notification, widget *w, void *notification_data) { + int visible_lines; + int start_line; + int number_of_lines; + int new_line; + int inc; + + text_list_state(g, w, &visible_lines, &start_line, &number_of_lines); + inc = 10; + if (inc > visible_lines - 2) inc = visible_lines - 2; + if (inc < 1) inc = 1; + if (!strcmp(notification, "scrollup")) inc = -inc; + + new_line = start_line + inc; + if (new_line > number_of_lines - visible_lines) + new_line = number_of_lines - visible_lines; + if (new_line < 0) new_line = 0; + + text_list_set_start_line(g, w, new_line); +} + +static void click(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + int *d = notification_data; + struct event_selector *this = private; + int set_on; + int line = d[0]; + int button = d[1]; + char *text; + int color; + int i; + char t; + + if (button != 1 && button != 3) return; + + if (button == 1) set_on = 1; else set_on = 0; + + if (w == this->events) + text_list_get_line(this->g, this->events, line, &text, &color); + else + text_list_get_line(this->g, this->groups, line, &text, &color); + + on_off(this->database, text, this->is_on, set_on); + + for (i = 0; i < this->nevents; i++) + text_list_set_color(this->g, this->events, i, + this->is_on[database_pos_to_id(this->database, i)] ? + this->green : this->red); + + for (i = 0; i < this->ngroups; i++) + text_list_set_color(this->g, this->groups, i, FOREGROUND_COLOR); + if (w == this->groups) + text_list_set_color(this->g, this->groups, line, + set_on ? this->green : this->red); + + t = 1; + socket_send(this->socket, &t, 1); + socket_send(this->socket, &this->nevents, sizeof(int)); + socket_send(this->socket, this->is_on, this->nevents * sizeof(int)); +} + +event_selector *setup_event_selector(gui *g, void *database, int socket, + int *is_on) +{ + struct event_selector *ret; widget *win; widget *main_container; widget *container; widget *left, *right; widget *events, *groups; + char **ids; + char **gps; + int n; + int i; + int red, green; + + ret = calloc(1, sizeof(struct event_selector)); if (ret == NULL) abort(); + + red = new_color(g, "#944"); + green = new_color(g, "#272"); win = new_toplevel_window(g, 610, 800, "event selector"); main_container = new_container(g, VERTICAL); @@ -38,4 +131,40 @@ void setup_event_selector(gui *g, void *database, int socket, int *is_on) widget_add_child(g, right, groups, -1); container_set_child_growable(g, left, events, 1); container_set_child_growable(g, right, groups, 1); + + n = database_get_ids(database, &ids); + for (i = 0; i < n; i++) { + text_list_add(g, events, ids[i], -1, + is_on[database_pos_to_id(database, i)] ? green : red); + } + free(ids); + + ret->nevents = n; + + n = database_get_groups(database, &gps); + for (i = 0; i < n; i++) { + text_list_add(g, groups, gps[i], -1, FOREGROUND_COLOR); + } + free(gps); + + ret->ngroups = n; + + ret->g = g; + ret->is_on = is_on; + ret->red = red; + ret->green = green; + ret->events = events; + ret->groups = groups; + ret->database = database; + ret->socket = socket; + + register_notifier(g, "scrollup", events, scroll, ret); + register_notifier(g, "scrolldown", events, scroll, ret); + register_notifier(g, "click", events, click, ret); + + register_notifier(g, "scrollup", groups, scroll, ret); + register_notifier(g, "scrolldown", groups, scroll, ret); + register_notifier(g, "click", groups, click, ret); + + return ret; } diff --git a/common/utils/T/tracer/event_selector.h b/common/utils/T/tracer/event_selector.h index 11e977b4f6..60da0a07e5 100644 --- a/common/utils/T/tracer/event_selector.h +++ b/common/utils/T/tracer/event_selector.h @@ -3,6 +3,9 @@ #include "gui/gui.h" -void setup_event_selector(gui *g, void *database, int socket, int *is_on); +typedef void event_selector; + +event_selector *setup_event_selector(gui *g, void *database, int socket, + int *is_on); #endif /* _EVENT_SELECTOR_H_ */ diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 9d1d2b0968..e99bcf2c36 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -118,6 +118,7 @@ int main(int n, char **v) textlog *textlog; gui *g; int gui_mode = 0; + view *out; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -153,26 +154,30 @@ int main(int n, char **v) h = new_handler(database); - textlog = new_textlog(h, database, - "ENB_UL_CHANNEL_ESTIMATE", - "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); - g = gui_init(); new_thread(gui_thread, g); if (gui_mode) { - view *tout; widget *w, *win; // w = new_text_list(g, 600, 20, 0); w = new_text_list(g, 600, 20, new_color(g, "#ffabab")); win = new_toplevel_window(g, 600, 20*12, "textlog"); widget_add_child(g, win, w, -1); - tout = new_textlist(1000, 10, g, w); + out = new_textlist(1000, 10, g, w); //tout = new_textlist(7, 4, g, w); - textlog_add_view(textlog, tout); } else { - view *sout = new_stdout(); - textlog_add_view(textlog, sout); + out = new_stdout(); + } + + for (i = 0; i < number_of_events; i++) { + char *name, *desc; + database_get_generic_description(database, i, &name, &desc); + textlog = new_textlog(h, database, name, desc); +// "ENB_UL_CHANNEL_ESTIMATE", +// "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); + textlog_add_view(textlog, out); + free(name); + free(desc); } for (i = 0; i < on_off_n; i++) diff --git a/common/utils/T/tracer/remote_old.c b/common/utils/T/tracer/remote_old.c index 4988bd336e..5c3a751baf 100644 --- a/common/utils/T/tracer/remote_old.c +++ b/common/utils/T/tracer/remote_old.c @@ -327,23 +327,6 @@ void get_message(int s) } } -void new_thread(void *(*f)(void *), void *data) -{ - pthread_t t; - pthread_attr_t att; - - if (pthread_attr_init(&att)) - { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } - if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) - { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } - if (pthread_attr_setstacksize(&att, 10000000)) - { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } - if (pthread_create(&t, &att, f, data)) - { fprintf(stderr, "pthread_create err\n"); exit(1); } - if (pthread_attr_destroy(&att)) - { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } -} - void usage(void) { printf( diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 0cb5bd855a..2b02fb1441 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -2,6 +2,7 @@ #include "handler.h" #include "database.h" #include "view/view.h" +#include "utils.h" #include #include #include @@ -32,55 +33,30 @@ struct textlog { view **v; int vsize; /* local output buffer */ - int osize; - int omaxsize; - char *obuf; + OBUF o; }; -static void PUTC(struct textlog *l, char c) -{ - if (l->osize == l->omaxsize) { - l->omaxsize += 512; - l->obuf = realloc(l->obuf, l->omaxsize); - if (l->obuf == NULL) abort(); - } - l->obuf[l->osize] = c; - l->osize++; -} - -static void PUTS(struct textlog *l, char *s) -{ - while (*s) PUTC(l, *s++); -} - -static void PUTI(struct textlog *l, int i) -{ - char s[64]; - sprintf(s, "%d", i); - PUTS(l, s); -} - static void _event(void *p, event e) { struct textlog *l = p; int i; - l->osize = 0; + l->o.osize = 0; for (i = 0; i < l->fsize; i++) switch(l->f[i].type) { - case INSTRING: PUTS(l, l->f[i].s); break; - case INT: PUTI(l, e.e[l->f[i].event_arg].i); break; - case STRING: PUTS(l, e.e[l->f[i].event_arg].s); break; + case INSTRING: PUTS(&l->o, l->f[i].s); break; + case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; + case STRING: PUTS(&l->o, e.e[l->f[i].event_arg].s); break; case BUFFER: - PUTS(l, "{buffer size:"); - PUTI(l, e.e[l->f[i].event_arg].bsize); - PUTS(l, "}"); + PUTS(&l->o, "{buffer size:"); + PUTI(&l->o, e.e[l->f[i].event_arg].bsize); + PUTS(&l->o, "}"); break; } - PUTC(l, 0); + PUTC(&l->o, 0); - for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->obuf); + for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->o.obuf); } enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index 2e18ccb60e..f00097160f 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -3,6 +3,7 @@ #include #include #include +#include void new_thread(void *(*f)(void *), void *data) { @@ -59,3 +60,46 @@ list *list_append(list *l, void *data) l->last = new; return l; } + +/****************************************************************************/ +/* socket */ +/****************************************************************************/ + +void socket_send(int socket, void *buffer, int size) +{ + char *x = buffer; + int ret; + while (size) { + ret = write(socket, x, size); + if (ret <= 0) abort(); + size -= ret; + x += ret; + } +} + +/****************************************************************************/ +/* buffer */ +/****************************************************************************/ + +void PUTC(OBUF *o, char c) +{ + if (o->osize == o->omaxsize) { + o->omaxsize += 512; + o->obuf = realloc(o->obuf, o->omaxsize); + if (o->obuf == NULL) abort(); + } + o->obuf[o->osize] = c; + o->osize++; +} + +void PUTS(OBUF *o, char *s) +{ + while (*s) PUTC(o, *s++); +} + +void PUTI(OBUF *o, int i) +{ + char s[64]; + sprintf(s, "%d", i); + PUTS(o, s); +} diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index 5a37aa34c3..eb9aa15506 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -16,4 +16,24 @@ typedef struct list { list *list_remove_head(list *l); list *list_append(list *l, void *data); +/****************************************************************************/ +/* socket */ +/****************************************************************************/ + +void socket_send(int socket, void *buffer, int size); + +/****************************************************************************/ +/* buffer */ +/****************************************************************************/ + +typedef struct { + int osize; + int omaxsize; + char *obuf; +} OBUF; + +void PUTC(OBUF *o, char c); +void PUTS(OBUF *o, char *s); +void PUTI(OBUF *o, int i); + #endif /* _UTILS_H_ */ From e4e46473455f63c3ed9a499e5292ad18bb78178e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 09:47:30 +0200 Subject: [PATCH 079/217] cleanup logging in the GUI --- common/utils/T/tracer/gui/container.c | 18 ++++++------- common/utils/T/tracer/gui/event.c | 8 +++--- common/utils/T/tracer/gui/gui.c | 2 ++ common/utils/T/tracer/gui/gui_defs.h | 3 +++ common/utils/T/tracer/gui/label.c | 4 +-- common/utils/T/tracer/gui/notify.c | 12 +++------ common/utils/T/tracer/gui/text_list.c | 8 +++--- common/utils/T/tracer/gui/toplevel_window.c | 8 +++--- common/utils/T/tracer/gui/x.c | 28 ++++++++++----------- common/utils/T/tracer/gui/xy_plot.c | 20 +++++++-------- 10 files changed, 56 insertions(+), 55 deletions(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index c2913db2d6..3dfcef2e2c 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -8,7 +8,7 @@ static void repack(gui *g, widget *_this) { -printf("REPACK container %p\n", _this); + LOGD("REPACK container %p\n", _this); struct container_widget *this = _this; this->hints_are_valid = 0; return this->common.parent->repack(g, this->common.parent); @@ -16,7 +16,7 @@ printf("REPACK container %p\n", _this); static void add_child(gui *g, widget *_this, widget *child, int position) { -printf("ADD_CHILD container\n"); + LOGD("ADD_CHILD container\n"); struct container_widget *this = _this; this->hints_are_valid = 0; widget_add_child_internal(g, this, child, position); @@ -78,7 +78,7 @@ static void compute_horizontal_hints(struct gui *g, static void vertical_allocate(gui *_gui, widget *_this, int x, int y, int width, int height) { -printf("ALLOCATE container vertical %p\n", _this); + LOGD("ALLOCATE container vertical %p\n", _this); int cy = 0; int cwidth, cheight; struct gui *g = _gui; @@ -126,7 +126,7 @@ hints_ok: static void horizontal_allocate(gui *_gui, widget *_this, int x, int y, int width, int height) { -printf("ALLOCATE container horizontal %p\n", _this); + LOGD("ALLOCATE container horizontal %p\n", _this); int cx = 0; int cwidth, cheight; struct gui *g = _gui; @@ -173,7 +173,7 @@ hints_ok: static void vertical_hints(gui *_gui, widget *_w, int *width, int *height) { -printf("HINTS container vertical %p\n", _w); + LOGD("HINTS container vertical %p\n", _w); struct gui *g = _gui; struct container_widget *this = _w; @@ -191,7 +191,7 @@ printf("HINTS container vertical %p\n", _w); static void horizontal_hints(gui *_gui, widget *_w, int *width, int *height) { -printf("HINTS container horizontal %p\n", _w); + LOGD("HINTS container horizontal %p\n", _w); struct gui *g = _gui; struct container_widget *this = _w; @@ -210,7 +210,7 @@ printf("HINTS container horizontal %p\n", _w); static void horizontal_button(gui *_g, widget *_this, int x, int y, int button, int up) { -printf("BUTTON container horizontal %p xy %d %d button %d up %d\n", _this, x, y, button, up); + LOGD("BUTTON container horizontal %p xy %d %d button %d up %d\n", _this, x, y, button, up); struct gui *g = _g; struct container_widget *this = _this; struct widget_list *l; @@ -228,7 +228,7 @@ printf("BUTTON container horizontal %p xy %d %d button %d up %d\n", _this, x, y, static void vertical_button(gui *_g, widget *_this, int x, int y, int button, int up) { -printf("BUTTON container vertical %p xy %d %d button %d up %d\n", _this, x, y, button, up); + LOGD("BUTTON container vertical %p xy %d %d button %d up %d\n", _this, x, y, button, up); struct gui *g = _g; struct container_widget *this = _this; struct widget_list *l; @@ -245,7 +245,7 @@ printf("BUTTON container vertical %p xy %d %d button %d up %d\n", _this, x, y, b static void paint(gui *_gui, widget *_this) { -printf("PAINT container\n"); + LOGD("PAINT container\n"); struct gui *g = _gui; struct widget *this = _this; struct widget_list *l; diff --git a/common/utils/T/tracer/gui/event.c b/common/utils/T/tracer/gui/event.c index d5ead45a79..378b80ccdd 100644 --- a/common/utils/T/tracer/gui/event.c +++ b/common/utils/T/tracer/gui/event.c @@ -63,7 +63,7 @@ static event *new_event_dirty(int id) void send_event(gui *_gui, enum event_type type, ...) { -printf("send_event %d\n", type); + LOGD("send_event %d\n", type); struct gui *g = _gui; int do_write = 0; va_list ap; @@ -140,7 +140,7 @@ static void dirty_event(struct gui *g, int id) static void process_event(struct gui *g, struct event *e) { -printf("processing event type %d\n", e->type); + LOGD("processing event type %d\n", e->type); switch (e->type) { case REPACK: repack_event(g, ((struct repack_event *)e)->id); break; case DIRTY: dirty_event(g, ((struct dirty_event *)e)->id); break; @@ -152,7 +152,7 @@ void gui_events(gui *_gui) { struct gui *g = _gui; -printf("gui_events START: head %p\n", g->queued_events); + LOGD("gui_events START: head %p\n", g->queued_events); while (g->queued_events) { struct event_list *cur = g->queued_events; @@ -162,5 +162,5 @@ printf("gui_events START: head %p\n", g->queued_events); free_event(cur->item); free(cur); } -printf("gui_events DONE\n"); + LOGD("gui_events DONE\n"); } diff --git a/common/utils/T/tracer/gui/gui.c b/common/utils/T/tracer/gui/gui.c index ef8640b0de..f0d7dcbcb1 100644 --- a/common/utils/T/tracer/gui/gui.c +++ b/common/utils/T/tracer/gui/gui.c @@ -5,6 +5,8 @@ #include #include +int volatile gui_logd; + void glock(gui *_gui) { struct gui *g = _gui; diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 58ae329467..fc9cd39bb3 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -3,6 +3,9 @@ /* defines the private API of the GUI */ +extern int volatile gui_logd; +#define LOGD(...) do { if (gui_logd) printf(__VA_ARGS__); } while (0) + /*************************************************************************/ /* logging macros */ /*************************************************************************/ diff --git a/common/utils/T/tracer/gui/label.c b/common/utils/T/tracer/gui/label.c index be6c8794a0..35b4f7b667 100644 --- a/common/utils/T/tracer/gui/label.c +++ b/common/utils/T/tracer/gui/label.c @@ -9,7 +9,7 @@ static void paint(gui *_gui, widget *_w) { struct gui *g = _gui; struct label_widget *l = _w; -printf("PAINT label '%s'\n", l->t); + LOGD("PAINT label '%s'\n", l->t); x_draw_string(g->x, g->xwin, l->color, l->common.x, l->common.y + l->baseline, l->t); } @@ -17,7 +17,7 @@ printf("PAINT label '%s'\n", l->t); static void hints(gui *_gui, widget *_w, int *width, int *height) { struct label_widget *l = _w; -printf("HINTS label '%s'\n", l->t); + LOGD("HINTS label '%s'\n", l->t); *width = l->width; *height = l->height; } diff --git a/common/utils/T/tracer/gui/notify.c b/common/utils/T/tracer/gui/notify.c index dc6bc2fd59..7ff4006941 100644 --- a/common/utils/T/tracer/gui/notify.c +++ b/common/utils/T/tracer/gui/notify.c @@ -13,7 +13,7 @@ unsigned long register_notifier(gui *_g, char *notification, widget *w, glock(g); if (g->next_notifier_id == 2UL * 1024 * 1024 * 1024) - { printf("%s:%d: report a bug\n", __FILE__, __LINE__); abort(); } + ERR("%s:%d: report a bug\n", __FILE__, __LINE__); g->notifiers = realloc(g->notifiers, (g->notifiers_count+1) * sizeof(struct notifier)); @@ -50,11 +50,8 @@ void unregister_notifier(gui *_g, unsigned long notifier_id) for (i = 0; i < g->notifiers_count; i++) if (g->notifiers[i].id == notifier_id) break; - if (i == g->notifiers_count) { - printf("%s:%d: notifier_id %ld not found\n", __FILE__, __LINE__, - notifier_id); - abort(); - } + if (i == g->notifiers_count) + ERR("%s:%d: notifier_id %ld not found\n", __FILE__,__LINE__,notifier_id); free(g->notifiers[i].notification); @@ -83,8 +80,7 @@ void gui_notify(struct gui *g, char *notification, widget *w, * for now let's crash in case of recursive call */ static int inside = 0; - if (inside) - {printf("%s:%d: BUG! contact the authors\n", __FILE__, __LINE__);abort();} + if (inside) ERR("%s:%d: BUG! contact the authors\n", __FILE__, __LINE__); inside = 1; /* clear all handlers */ diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index bc0001cf8b..086234d952 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -10,7 +10,7 @@ static void paint(gui *_gui, widget *_this) struct gui *g = _gui; struct text_list_widget *this = _this; int i, j; -printf("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height); + LOGD("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height); x_fill_rectangle(g->x, g->xwin, this->background_color, this->common.x, this->common.y, this->common.width, this->common.height); @@ -29,7 +29,7 @@ static void hints(gui *_gui, widget *_w, int *width, int *height) struct text_list_widget *w = _w; *width = w->wanted_width; *height = w->wanted_nlines * w->line_height; -printf("HINTS text_list wh %d %d\n", *width, *height); + LOGD("HINTS text_list wh %d %d\n", *width, *height); } static void allocate( @@ -41,14 +41,14 @@ static void allocate( this->common.width = width; this->common.height = height; this->allocated_nlines = height / this->line_height; -printf("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); + LOGD("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); } static void button(gui *_g, widget *_this, int x, int y, int button, int up) { struct gui *g = _g; struct text_list_widget *this = _this; -printf("BUTTON test_list %p xy %d %d button %d up %d\n", _this, x, y, button, up); + LOGD("BUTTON test_list %p xy %d %d button %d up %d\n", _this, x, y, button, up); /* scroll up */ if (button == 4 && up == 0) { gui_notify(g, "scrollup", _this, NULL); diff --git a/common/utils/T/tracer/gui/toplevel_window.c b/common/utils/T/tracer/gui/toplevel_window.c index fef72b32cc..03d5091bc7 100644 --- a/common/utils/T/tracer/gui/toplevel_window.c +++ b/common/utils/T/tracer/gui/toplevel_window.c @@ -10,7 +10,7 @@ static void repack(gui *g, widget *_this) { -printf("REPACK toplevel_window\n"); + LOGD("REPACK toplevel_window\n"); struct toplevel_window_widget *this = _this; if (this->common.children == NULL) ERR("toplevel window has no child\n"); if (this->common.children->next != NULL) @@ -22,7 +22,7 @@ printf("REPACK toplevel_window\n"); static void add_child(gui *_gui, widget *_this, widget *child, int position) { -printf("ADD_CHILD toplevel_window\n"); + LOGD("ADD_CHILD toplevel_window\n"); struct widget *this = _this; if (this->children != NULL) { WARN("toplevel window already has a child\n"); @@ -35,7 +35,7 @@ printf("ADD_CHILD toplevel_window\n"); static void allocate( gui *_gui, widget *_this, int x, int y, int width, int height) { -printf("ALLOCATE toplevel_window\n"); + LOGD("ALLOCATE toplevel_window\n"); struct toplevel_window_widget *this = _this; this->common.width = width; this->common.height = height; @@ -47,7 +47,7 @@ static void paint(gui *_gui, widget *_this) { struct gui *g = _gui; struct toplevel_window_widget *this = _this; -printf("PAINT toplevel_window (%d %d)\n", this->common.width, this->common.height); + LOGD("PAINT toplevel_window (%d %d)\n", this->common.width, this->common.height); x_fill_rectangle(g->x, this->x, BACKGROUND_COLOR, 0, 0, this->common.width, this->common.height); g->xwin = this->x; diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 68869d6e0f..f29a0c6adb 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -46,7 +46,7 @@ x_connection *x_open(void) if (ret == NULL) OOM; ret->d = XOpenDisplay(0); -printf("XOpenDisplay display %p return x_connection %p\n", ret->d, ret); + 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 */ @@ -96,16 +96,16 @@ x_window *x_create_window(x_connection *_x, int width, int height, #if 0 /* wait for window to be mapped */ -printf("wait for map\n"); + LOGD("wait for map\n"); while (1) { XEvent ev; //XWindowEvent(x->d, ret->w, StructureNotifyMask, &ev); XWindowEvent(x->d, ret->w, ExposureMask, &ev); -printf("got ev %d\n", ev.type); + LOGD("got ev %d\n", ev.type); //if (ev.type == MapNotify) break; if (ev.type == Expose) break; } -printf("XXX create connection %p window %p (win id %d pixmap %d) w h %d %d\n", x, ret, (int)ret->w, (int)ret->p, width, height); + LOGD("XXX create connection %p window %p (win id %d pixmap %d) w h %d %d\n", x, ret, (int)ret->w, (int)ret->p, width, height); #endif return ret; @@ -133,7 +133,7 @@ void x_events(gui *_gui) struct x_connection *x = g->x; struct toplevel_window_widget *w; -printf("x_events START\n"); + LOGD("x_events START\n"); /* preprocessing (to "compress" events) */ cur = g->toplevel; while (cur) { @@ -149,7 +149,7 @@ printf("x_events START\n"); while (XPending(x->d)) { XEvent ev; XNextEvent(x->d, &ev); -printf("XEV %d\n", ev.type); + LOGD("XEV %d\n", ev.type); switch (ev.type) { case MapNotify: case Expose: @@ -166,7 +166,7 @@ printf("XEV %d\n", ev.type); xw->new_height = ev.xconfigure.height; if (xw->new_width < 10) xw->new_width = 10; if (xw->new_height < 10) xw->new_height = 10; -printf("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); + LOGD("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); } break; case ButtonPress: @@ -194,14 +194,14 @@ printf("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); } /* postprocessing */ -printf("post processing\n"); + LOGD("post processing\n"); cur = g->toplevel; while (cur) { struct toplevel_window_widget *w = (struct toplevel_window_widget *)cur->item; struct x_window *xw = w->x; if (xw->resize) { -printf("resize old %d %d new %d %d\n", xw->width, xw->height, xw->new_width, xw->new_height); + 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; @@ -220,13 +220,13 @@ printf("resize old %d %d new %d %d\n", xw->width, xw->height, xw->new_width, xw- } if (xw->redraw) { struct x_connection *x = g->x; -printf("XCopyArea w h %d %d\n", xw->width, xw->height); + 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); } cur = cur->next; } -printf("x_events DONE\n"); + LOGD("x_events DONE\n"); } void x_flush(x_connection *_x) @@ -248,7 +248,7 @@ void x_text_get_dimensions(x_connection *_c, const char *t, XQueryTextExtents(c->d, XGContextFromGC(c->colors[1]), t, strlen(t), &dir, &ascent, &descent, &overall); -//printf("dir %d ascent %d descent %d lbearing %d rbearing %d width %d ascent %d descent %d\n", dir, ascent, descent, overall.lbearing, overall.rbearing, overall.width, overall.ascent, overall.descent); +//LOGD("dir %d ascent %d descent %d lbearing %d rbearing %d width %d ascent %d descent %d\n", dir, ascent, descent, overall.lbearing, overall.rbearing, overall.width, overall.ascent, overall.descent); *width = overall.width; *height = ascent + descent; @@ -308,7 +308,7 @@ void x_draw(x_connection *_c, x_window *_w) { struct x_connection *c = _c; struct x_window *w = _w; -printf("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); + 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); XCopyArea(c->d, w->p, w->w, c->colors[1], 0, 0, w->width, w->height, 0, 0); } @@ -333,7 +333,7 @@ void x_add_point(x_connection *_c, int x, int y) void x_plot_points(x_connection *_c, x_window *_w, int color) { struct x_connection *c = _c; -fprintf(stderr, "x_plot_points %d points\n", c->pts_size); + 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); diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index 3c0b05f60d..c1ca608f49 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -24,7 +24,7 @@ static void paint(gui *_gui, widget *_this) # define FLIP(v) (-(v) + allocated_plot_height-1) -printf("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); + LOGD("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); //x_draw_rectangle(g->x, g->xwin, 1, this->common.x, this->common.y, this->common.width, this->common.height); @@ -52,14 +52,14 @@ printf("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this- allocated_xmax = center + ((this->xmax - this->xmin) * allocated_plot_width / wanted_plot_width) / 2; /* adjust tic if too tight */ -printf("pre x ticstep %g\n", ticstep); + LOGD("pre x ticstep %g\n", ticstep); while (1) { if (ticstep / (allocated_xmax - allocated_xmin) * (allocated_plot_width - 1) > 40) break; ticstep *= 2; } -printf("post x ticstep %g\n", ticstep); -printf("xmin/max %g %g width wanted allocated %d %d alloc xmin/max %g %g ticstep %g\n", this->xmin, this->xmax, wanted_plot_width, allocated_plot_width, allocated_xmin, allocated_xmax, ticstep); + LOGD("post x ticstep %g\n", ticstep); + LOGD("xmin/max %g %g width wanted allocated %d %d alloc xmin/max %g %g ticstep %g\n", this->xmin, this->xmax, wanted_plot_width, allocated_plot_width, allocated_xmin, allocated_xmax, ticstep); kmin = ceil(allocated_xmin / ticstep); kmax = floor(allocated_xmax / ticstep); for (k = kmin; k <= kmax; k++) { @@ -84,7 +84,7 @@ printf("xmin/max %g %g width wanted allocated %d %d alloc xmin/max %g %g ticstep this->common.y + this->common.height - this->label_height * 2 + this->label_baseline, v); -printf("tic k %d val %g x %g\n", k, k * ticstep, x); + LOGD("tic k %d val %g x %g\n", k, k * ticstep, x); } /* vertical tics */ @@ -98,14 +98,14 @@ printf("tic k %d val %g x %g\n", k, k * ticstep, x); allocated_ymax = center + ((this->ymax - this->ymin) * allocated_plot_height / wanted_plot_height) / 2; /* adjust tic if too tight */ -printf("pre y ticstep %g\n", ticstep); + LOGD("pre y ticstep %g\n", ticstep); while (1) { if (ticstep / (allocated_ymax - allocated_ymin) * (allocated_plot_height - 1) > 20) break; ticstep *= 2; } -printf("post y ticstep %g\n", ticstep); -printf("ymin/max %g %g height wanted allocated %d %d alloc ymin/max %g %g ticstep %g\n", this->ymin, this->ymax, wanted_plot_height, allocated_plot_height, allocated_ymin, allocated_ymax, ticstep); + LOGD("post y ticstep %g\n", ticstep); + LOGD("ymin/max %g %g height wanted allocated %d %d alloc ymin/max %g %g ticstep %g\n", this->ymin, this->ymax, wanted_plot_height, allocated_plot_height, allocated_ymin, allocated_ymax, ticstep); kmin = ceil(allocated_ymin / ticstep); kmax = floor(allocated_ymax / ticstep); for (k = kmin; k <= kmax; k++) { @@ -158,7 +158,7 @@ static void hints(gui *_gui, widget *_w, int *width, int *height) struct xy_plot_widget *w = _w; *width = w->wanted_width + w->vrule_width; *height = w->wanted_height + w->label_height * 2; /* TODO: refine */ -printf("HINTS xy plot wh %d %d (vrule_width %d) (wanted wh %d %d)\n", *width, *height, w->vrule_width, w->wanted_width, w->wanted_height); + LOGD("HINTS xy plot wh %d %d (vrule_width %d) (wanted wh %d %d)\n", *width, *height, w->vrule_width, w->wanted_width, w->wanted_height); } widget *new_xy_plot(gui *_gui, int width, int height, char *label, @@ -176,7 +176,7 @@ widget *new_xy_plot(gui *_gui, int width, int height, char *label, * not in the "gui thread") */ x_text_get_dimensions(g->x, label, &w->label_width, &w->label_height, &w->label_baseline); -printf("XY PLOT label wh %d %d\n", w->label_width, w->label_height); + LOGD("XY PLOT label wh %d %d\n", w->label_width, w->label_height); w->wanted_width = width; w->wanted_height = height; From 3a622778e5f95520b9f60585ff86b0224bf39959 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 11:26:54 +0200 Subject: [PATCH 080/217] basic event compression --- common/utils/T/tracer/gui/event.c | 47 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/event.c b/common/utils/T/tracer/gui/event.c index 378b80ccdd..842318fcea 100644 --- a/common/utils/T/tracer/gui/event.c +++ b/common/utils/T/tracer/gui/event.c @@ -39,6 +39,24 @@ static void free_event(struct event *e) free(e); } +static int events_equal(struct event *e1, struct event *e2) +{ + if (e1->type != e2->type) return 0; + switch (e1->type) { + case REPACK: { + struct repack_event *re1 = (struct repack_event *)e1; + struct repack_event *re2 = (struct repack_event *)e2; + return re1->id == re2->id; + } + case DIRTY: { + struct dirty_event *re1 = (struct dirty_event *)e1; + struct dirty_event *re2 = (struct dirty_event *)e2; + return re1->id == re2->id; + }} + /* unreachable */ + abort(); +} + /*****************************************************************/ /* sending events */ /*****************************************************************/ @@ -61,6 +79,28 @@ static event *new_event_dirty(int id) return ret; } +static void compress_event_list(struct gui *g) +{ + struct event *last; + struct event_list *cur; + /* basic compression, to be refined */ + + /* pickup last event and remove every copy of it found before + * if it's DIRTY or REPACK + */ + last = g->queued_events->last->item; + if (last->type == DIRTY || last->type == REPACK) { + cur = g->queued_events; + while (cur->item != last) { + if (cur->item != NULL && events_equal(cur->item, last)) { + free_event(cur->item); + cur->item = NULL; + } + cur = cur->next; + } + } +} + void send_event(gui *_gui, enum event_type type, ...) { LOGD("send_event %d\n", type); @@ -93,6 +133,7 @@ void send_event(gui *_gui, enum event_type type, ...) e->type = type; event_list_append(g, e); + compress_event_list(g); if (do_write) { char c = 1; @@ -158,8 +199,10 @@ void gui_events(gui *_gui) struct event_list *cur = g->queued_events; g->queued_events = cur->next; if (g->queued_events) g->queued_events->last = cur->last; - process_event(g, cur->item); - free_event(cur->item); + if (cur->item != NULL) { + process_event(g, cur->item); + free_event(cur->item); + } free(cur); } LOGD("gui_events DONE\n"); From 629eb5115178471733628d87486fe82c0cf4f4f5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 11:57:01 +0200 Subject: [PATCH 081/217] trying other colors in event selector --- common/utils/T/tracer/event_selector.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index 650a6af59a..bd9189adea 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -99,8 +99,8 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, ret = calloc(1, sizeof(struct event_selector)); if (ret == NULL) abort(); - red = new_color(g, "#944"); - green = new_color(g, "#272"); + red = new_color(g, "#c93535"); + green = new_color(g, "#2f9e2a"); win = new_toplevel_window(g, 610, 800, "event selector"); main_container = new_container(g, VERTICAL); @@ -124,8 +124,8 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, widget_add_child(g, left, new_label(g, "Events"), -1); widget_add_child(g, right, new_label(g, "Groups"), -1); - events = new_text_list(g, 300, 10, new_color(g, "#ccccff")); - groups = new_text_list(g, 300, 10, new_color(g, "#ccffee")); + events = new_text_list(g, 300, 10, new_color(g, "#b3c1e1")); + groups = new_text_list(g, 300, 10, new_color(g, "#edd6cb")); widget_add_child(g, left, events, -1); widget_add_child(g, right, groups, -1); From 23ec84ef6b7312ce7a1d5e7bc8aa1de5059a84aa Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 12:09:45 +0200 Subject: [PATCH 082/217] option -debug-gui to textlog --- common/utils/T/tracer/gui/x.c | 2 +- common/utils/T/tracer/remote.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index f29a0c6adb..bbc51e8a94 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -189,7 +189,7 @@ void x_events(gui *_gui) } break; #endif - default: WARN("TODO: X event type %d\n", ev.type); break; + default: if (gui_logd) WARN("TODO: X event type %d\n", ev.type); break; } } diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index e99bcf2c36..85112bf6eb 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -59,7 +59,8 @@ void usage(void) " they will be processed in order\n" " by default, all is off\n" " -p use given port (default %d)\n" -" -x GUI output\n", +" -x GUI output\n" +" -debug-gui active GUI debug logs\n", DEFAULT_REMOTE_PORT ); exit(1); @@ -102,6 +103,7 @@ static void *gui_thread(void *_g) int main(int n, char **v) { + extern int volatile gui_logd; char *database_filename = NULL; void *database; int port = DEFAULT_REMOTE_PORT; @@ -138,6 +140,7 @@ int main(int n, char **v) if (!strcmp(v[i], "-OFF")) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } if (!strcmp(v[i], "-x")) { gui_mode = 1; continue; } + if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } usage(); } From d3997824fcc08976d97ea593305ecd1dfa995126 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 12:16:22 +0200 Subject: [PATCH 083/217] add option -no-gui to disable GUI entirely for textlog (no more event selector) --- common/utils/T/tracer/remote.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 85112bf6eb..f64c5034c9 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -60,7 +60,8 @@ void usage(void) " by default, all is off\n" " -p use given port (default %d)\n" " -x GUI output\n" -" -debug-gui active GUI debug logs\n", +" -debug-gui activate GUI debug logs\n" +" -no-gui disable GUI entirely\n", DEFAULT_REMOTE_PORT ); exit(1); @@ -121,6 +122,7 @@ int main(int n, char **v) gui *g; int gui_mode = 0; view *out; + int gui_active = 1; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -141,9 +143,12 @@ int main(int n, char **v) { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } if (!strcmp(v[i], "-x")) { gui_mode = 1; continue; } if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } + if (!strcmp(v[i], "-no-gui")) { gui_active = 0; continue; } usage(); } + if (gui_active == 0) gui_mode = 0; + if (database_filename == NULL) { printf("ERROR: provide a database file (-d)\n"); exit(1); @@ -157,8 +162,10 @@ int main(int n, char **v) h = new_handler(database); - g = gui_init(); - new_thread(gui_thread, g); + if (gui_active) { + g = gui_init(); + new_thread(gui_thread, g); + } if (gui_mode) { widget *w, *win; @@ -198,7 +205,8 @@ int main(int n, char **v) if (is_on[l]) if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - setup_event_selector(g, database, s, is_on); + if (gui_active) + setup_event_selector(g, database, s, is_on); /* read messages */ while (1) { From ca3a05a592ef648198680ffd2d011df488017857 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 14:26:16 +0200 Subject: [PATCH 084/217] optimize text list view when too much data has been sent to the text list view, way too much GUI processing is done, let's batch-process the changes and then tell the GUI that something has changed --- common/utils/T/tracer/gui/gui.h | 4 +++ common/utils/T/tracer/gui/text_list.c | 43 +++++++++++++++++++++++---- common/utils/T/tracer/view/textlist.c | 7 +++-- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index b1440a20c4..ed763fa84c 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -35,12 +35,16 @@ void xy_plot_set_points(gui *gui, widget *this, void text_list_add(gui *gui, widget *this, const char *text, int position, int color); void text_list_del(gui *gui, widget *this, int position); +void text_list_add_silent(gui *gui, widget *this, const char *text, + int position, int color); +void text_list_del_silent(gui *gui, widget *this, int position); void text_list_state(gui *_gui, widget *_this, int *visible_lines, int *start_line, int *number_of_lines); void text_list_set_start_line(gui *gui, widget *this, int line); void text_list_get_line(gui *gui, widget *this, int line, char **text, int *color); void text_list_set_color(gui *gui, widget *this, int line, int color); +void text_list_dirty(gui *_gui, widget *_this); void gui_loop(gui *gui); diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index 086234d952..416ae10d25 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -10,7 +10,7 @@ static void paint(gui *_gui, widget *_this) struct gui *g = _gui; struct text_list_widget *this = _this; int i, j; - LOGD("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height); + LOGD("PAINT text_list %p xywh %d %d %d %d starting line %d allocated nlines %d text_count %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height, this->starting_line, this->allocated_nlines, this->text_count); x_fill_rectangle(g->x, g->xwin, this->background_color, this->common.x, this->common.y, this->common.width, this->common.height); @@ -95,8 +95,8 @@ widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) /* public functions */ /*************************************************************************/ -void text_list_add(gui *_gui, widget *_this, const char *text, int position, - int color) +static void _text_list_add(gui *_gui, widget *_this, const char *text, + int position, int color, int silent) { struct gui *g = _gui; struct text_list_widget *this = _this; @@ -120,12 +120,12 @@ void text_list_add(gui *_gui, widget *_this, const char *text, int position, this->text[position] = strdup(text); if (this->text[position] == NULL) OOM; this->color[position] = color; - send_event(g, DIRTY, this->common.id); + if (!silent) send_event(g, DIRTY, this->common.id); gunlock(g); } -void text_list_del(gui *_gui, widget *_this, int position) +static void _text_list_del(gui *_gui, widget *_this, int position, int silent) { struct gui *g = _gui; struct text_list_widget *this = _this; @@ -151,12 +151,34 @@ void text_list_del(gui *_gui, widget *_this, int position) this->color = realloc(this->color, this->text_count * sizeof(int)); if (this->color == NULL) OOM; - send_event(g, DIRTY, this->common.id); + if (!silent) send_event(g, DIRTY, this->common.id); done: gunlock(g); } +void text_list_add(gui *gui, widget *this, const char *text, int position, + int color) +{ + _text_list_add(gui, this, text, position, color, 0); +} + +void text_list_del(gui *gui, widget *this, int position) +{ + _text_list_del(gui, this, position, 0); +} + +void text_list_add_silent(gui *gui, widget *this, const char *text, + int position, int color) +{ + _text_list_add(gui, this, text, position, color, 1); +} + +void text_list_del_silent(gui *gui, widget *this, int position) +{ + _text_list_del(gui, this, position, 1); +} + void text_list_state(gui *_gui, widget *_this, int *visible_lines, int *start_line, int *number_of_lines) { @@ -220,3 +242,12 @@ void text_list_set_color(gui *_gui, widget *_this, int line, int color) gunlock(g); } + +void text_list_dirty(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct text_list_widget *this = _this; + glock(g); + send_event(g, DIRTY, this->common.id); + gunlock(g); +} diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c index 314cc3b47e..7572f79e54 100644 --- a/common/utils/T/tracer/view/textlist.c +++ b/common/utils/T/tracer/view/textlist.c @@ -20,19 +20,21 @@ struct textlist { static void _append(struct textlist *this, char *s) { if (this->cursize == this->maxsize) { - text_list_del(this->g, this->w, 0); + text_list_del_silent(this->g, this->w, 0); this->cursize--; } - text_list_add(this->g, this->w, s, -1, FOREGROUND_COLOR); + text_list_add_silent(this->g, this->w, s, -1, FOREGROUND_COLOR); this->cursize++; } static void *textlist_thread(void *_this) { struct textlist *this = _this; + int dirty; while (1) { if (pthread_mutex_lock(&this->lock)) abort(); + dirty = this->to_append == NULL ? 0 : 1; while (this->to_append != NULL) { char *s = this->to_append->data; this->to_append = list_remove_head(this->to_append); @@ -40,6 +42,7 @@ static void *textlist_thread(void *_this) free(s); } if (pthread_mutex_unlock(&this->lock)) abort(); + if (dirty) text_list_dirty(this->g, this->w); sleepms(1000/this->refresh_rate); } From 042f284bc2ca467e9a105de24bf384b6aaed9558 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 14:33:07 +0200 Subject: [PATCH 085/217] introduce widget_dirty - not only text list might want the optimization --- common/utils/T/tracer/gui/gui.h | 2 +- common/utils/T/tracer/gui/text_list.c | 9 --------- common/utils/T/tracer/gui/widget.c | 9 +++++++++ common/utils/T/tracer/view/textlist.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index ed763fa84c..142e34a0a8 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -16,6 +16,7 @@ gui *gui_init(void); /* position = -1 to put at the end */ void widget_add_child(gui *gui, widget *parent, widget *child, int position); +void widget_dirty(gui *gui, widget *this); widget *new_toplevel_window(gui *gui, int width, int height, char *title); widget *new_container(gui *gui, int vertical); @@ -44,7 +45,6 @@ void text_list_set_start_line(gui *gui, widget *this, int line); void text_list_get_line(gui *gui, widget *this, int line, char **text, int *color); void text_list_set_color(gui *gui, widget *this, int line, int color); -void text_list_dirty(gui *_gui, widget *_this); void gui_loop(gui *gui); diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index 416ae10d25..c37aa774d3 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -242,12 +242,3 @@ void text_list_set_color(gui *_gui, widget *_this, int line, int color) gunlock(g); } - -void text_list_dirty(gui *_gui, widget *_this) -{ - struct gui *g = _gui; - struct text_list_widget *this = _this; - glock(g); - send_event(g, DIRTY, this->common.id); - gunlock(g); -} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 6a34d00d06..8411a4602f 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -180,6 +180,15 @@ void widget_add_child(gui *_gui, widget *parent, widget *child, int position) gunlock(_gui); } +void widget_dirty(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct widget *this = _this; + glock(g); + send_event(g, DIRTY, this->id); + gunlock(g); +} + static const char *names[] = { "TOPLEVEL_WINDOW", "CONTAINER", "TEXT_LIST", "XY_PLOT", "BUTTON", "LABEL" }; diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c index 7572f79e54..de453a67cf 100644 --- a/common/utils/T/tracer/view/textlist.c +++ b/common/utils/T/tracer/view/textlist.c @@ -42,7 +42,7 @@ static void *textlist_thread(void *_this) free(s); } if (pthread_mutex_unlock(&this->lock)) abort(); - if (dirty) text_list_dirty(this->g, this->w); + if (dirty) widget_dirty(this->g, this->w); sleepms(1000/this->refresh_rate); } From 66f03d3978f92ca51edfbd844bcdb5bbfdfe8397 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 14:39:12 +0200 Subject: [PATCH 086/217] change the textlog window color and size --- common/utils/T/tracer/remote.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index f64c5034c9..9b06673e8e 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -170,8 +170,8 @@ int main(int n, char **v) if (gui_mode) { widget *w, *win; // w = new_text_list(g, 600, 20, 0); - w = new_text_list(g, 600, 20, new_color(g, "#ffabab")); - win = new_toplevel_window(g, 600, 20*12, "textlog"); + w = new_text_list(g, 800, 50, BACKGROUND_COLOR); + win = new_toplevel_window(g, 800, 50*12, "textlog"); widget_add_child(g, win, w, -1); out = new_textlist(1000, 10, g, w); //tout = new_textlist(7, 4, g, w); From 98c46f70f7060a91612c0af4e1461bc6cdbcb448 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 14:51:12 +0200 Subject: [PATCH 087/217] add a very basic tracee to ease debugging of the tracer --- common/utils/T/tracee/Makefile | 14 ++++++++++++++ common/utils/T/tracee/README | 1 + common/utils/T/tracee/tracee.c | 16 ++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 common/utils/T/tracee/Makefile create mode 100644 common/utils/T/tracee/README create mode 100644 common/utils/T/tracee/tracee.c diff --git a/common/utils/T/tracee/Makefile b/common/utils/T/tracee/Makefile new file mode 100644 index 0000000000..bc7c01d86b --- /dev/null +++ b/common/utils/T/tracee/Makefile @@ -0,0 +1,14 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -DT_TRACER -DT_USE_SHARED_MEMORY -I. + +PROG=tracee +OBJS=tracee.o ../T.o + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) -lrt + +tracee.o: tracee.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f *.o $(PROG) core diff --git a/common/utils/T/tracee/README b/common/utils/T/tracee/README new file mode 100644 index 0000000000..f18dda85ac --- /dev/null +++ b/common/utils/T/tracee/README @@ -0,0 +1 @@ +this is a very basic tracee, used to debug the tracer diff --git a/common/utils/T/tracee/tracee.c b/common/utils/T/tracee/tracee.c new file mode 100644 index 0000000000..86cf3012aa --- /dev/null +++ b/common/utils/T/tracee/tracee.c @@ -0,0 +1,16 @@ +#include "../T.h" +#include +#include +#include + +int main(void) +{ + int frame = 0; + T_connect_to_tracer("127.0.0.1", 2020); + while (1) { + getchar(); + T(T_PUCCH_1AB_IQ, T_INT(0), T_INT(0), T_INT(frame), T_INT(0), T_INT(0), T_INT(0)); + frame++; + } + return 0; +} From f0d32a8611fc00cfea1e46d018fd5839694259b9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 16:55:17 +0200 Subject: [PATCH 088/217] smaller event selector window --- common/utils/T/tracer/event_selector.c | 6 +++--- common/utils/T/tracer/textlog.c | 2 +- common/utils/T/tracer/utils.c | 12 ++++++++++++ common/utils/T/tracer/utils.h | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index bd9189adea..2e950ac974 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -102,7 +102,7 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, red = new_color(g, "#c93535"); green = new_color(g, "#2f9e2a"); - win = new_toplevel_window(g, 610, 800, "event selector"); + win = new_toplevel_window(g, 470, 300, "event selector"); main_container = new_container(g, VERTICAL); widget_add_child(g, win, main_container, -1); @@ -124,8 +124,8 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, widget_add_child(g, left, new_label(g, "Events"), -1); widget_add_child(g, right, new_label(g, "Groups"), -1); - events = new_text_list(g, 300, 10, new_color(g, "#b3c1e1")); - groups = new_text_list(g, 300, 10, new_color(g, "#edd6cb")); + events = new_text_list(g, 235, 10, new_color(g, "#b3c1e1")); + groups = new_text_list(g, 235, 10, new_color(g, "#edd6cb")); widget_add_child(g, left, events, -1); widget_add_child(g, right, groups, -1); diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 2b02fb1441..264068c617 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -47,7 +47,7 @@ static void _event(void *p, event e) switch(l->f[i].type) { case INSTRING: PUTS(&l->o, l->f[i].s); break; case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; - case STRING: PUTS(&l->o, e.e[l->f[i].event_arg].s); break; + case STRING: PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break; case BUFFER: PUTS(&l->o, "{buffer size:"); PUTI(&l->o, e.e[l->f[i].event_arg].bsize); diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index f00097160f..f4bcd1243c 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -4,6 +4,7 @@ #include #include #include +#include void new_thread(void *(*f)(void *), void *data) { @@ -97,6 +98,17 @@ void PUTS(OBUF *o, char *s) while (*s) PUTC(o, *s++); } +static int clean(char c) +{ + if (!isprint(c)) c = ' '; + return c; +} + +void PUTS_CLEAN(OBUF *o, char *s) +{ + while (*s) PUTC(o, clean(*s++)); +} + void PUTI(OBUF *o, int i) { char s[64]; diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index eb9aa15506..dd96d39941 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -34,6 +34,7 @@ typedef struct { void PUTC(OBUF *o, char c); void PUTS(OBUF *o, char *s); +void PUTS_CLEAN(OBUF *o, char *s); void PUTI(OBUF *o, int i); #endif /* _UTILS_H_ */ From d45551dda11f0ea9023ccdb3f6ee3f2f21c786b5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 2 May 2016 16:56:38 +0200 Subject: [PATCH 089/217] deal with scroll in text list --- common/utils/T/tracer/view/textlist.c | 64 +++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c index de453a67cf..e849cb964a 100644 --- a/common/utils/T/tracer/view/textlist.c +++ b/common/utils/T/tracer/view/textlist.c @@ -17,11 +17,12 @@ struct textlist { list * volatile to_append; }; -static void _append(struct textlist *this, char *s) +static void _append(struct textlist *this, char *s, int *deleted) { if (this->cursize == this->maxsize) { text_list_del_silent(this->g, this->w, 0); this->cursize--; + (*deleted)++; } text_list_add_silent(this->g, this->w, s, -1, FOREGROUND_COLOR); this->cursize++; @@ -31,18 +32,32 @@ static void *textlist_thread(void *_this) { struct textlist *this = _this; int dirty; + int deleted; + int visible_lines, start_line, number_of_lines; while (1) { if (pthread_mutex_lock(&this->lock)) abort(); dirty = this->to_append == NULL ? 0 : 1; + deleted = 0; while (this->to_append != NULL) { char *s = this->to_append->data; this->to_append = list_remove_head(this->to_append); - _append(this, s); + _append(this, s, &deleted); free(s); } if (pthread_mutex_unlock(&this->lock)) abort(); - if (dirty) widget_dirty(this->g, this->w); + if (dirty) { + text_list_state(this->g, this->w, &visible_lines, &start_line, + &number_of_lines); + if (this->autoscroll) + start_line = number_of_lines - visible_lines; + else + start_line -= deleted; + if (start_line < 0) start_line = 0; + text_list_set_start_line(this->g, this->w, start_line); + /* this call is not necessary, but if things change in text_list... */ + widget_dirty(this->g, this->w); + } sleepms(1000/this->refresh_rate); } @@ -65,6 +80,45 @@ static void append(view *_this, char *s) if (pthread_mutex_unlock(&this->lock)) abort(); } +static void scroll(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + struct textlist *this = private; + int visible_lines; + int start_line; + int number_of_lines; + int new_line; + int inc; + + text_list_state(g, w, &visible_lines, &start_line, &number_of_lines); + inc = 10; + if (inc > visible_lines - 2) inc = visible_lines - 2; + if (inc < 1) inc = 1; + if (!strcmp(notification, "scrollup")) inc = -inc; + + new_line = start_line + inc; + if (new_line > number_of_lines - visible_lines) + new_line = number_of_lines - visible_lines; + if (new_line < 0) new_line = 0; + + text_list_set_start_line(g, w, new_line); + + if (new_line + visible_lines < number_of_lines) + this->autoscroll = 0; + else + this->autoscroll = 1; +} + +static void click(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + struct textlist *this = private; + int *d = notification_data; + int button = d[1]; + + if (button == 1) this->autoscroll = 1 - this->autoscroll; +} + view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w) { struct textlist *ret = calloc(1, sizeof(struct textlist)); @@ -82,6 +136,10 @@ view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w) if (pthread_mutex_init(&ret->lock, NULL)) abort(); + register_notifier(g, "scrollup", w, scroll, ret); + register_notifier(g, "scrolldown", w, scroll, ret); + register_notifier(g, "click", w, click, ret); + new_thread(textlist_thread, ret); return (view *)ret; From 0d0756c0c9773291c570d0d0f46932b52fe7b853 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 3 May 2016 16:33:50 +0200 Subject: [PATCH 090/217] typo --- common/utils/T/tracer/gui/text_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/text_list.c index c37aa774d3..9efdedd2a9 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/text_list.c @@ -48,7 +48,7 @@ static void button(gui *_g, widget *_this, int x, int y, int button, int up) { struct gui *g = _g; struct text_list_widget *this = _this; - LOGD("BUTTON test_list %p xy %d %d button %d up %d\n", _this, x, y, button, up); + LOGD("BUTTON text_list %p xy %d %d button %d up %d\n", _this, x, y, button, up); /* scroll up */ if (button == 4 && up == 0) { gui_notify(g, "scrollup", _this, NULL); From 4d7440bfcf34853101e59923d3df0cad1b2f5e56 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 3 May 2016 16:40:53 +0200 Subject: [PATCH 091/217] add more locks in view/textlist.c no deadlock should be possible as of the current state of things. When the textlist's lock is set the GUI lock is never on. Let's cross fingers that things don't change crazily in the future... --- common/utils/T/tracer/view/textlist.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c index e849cb964a..6aec4848d3 100644 --- a/common/utils/T/tracer/view/textlist.c +++ b/common/utils/T/tracer/view/textlist.c @@ -45,7 +45,6 @@ static void *textlist_thread(void *_this) _append(this, s, &deleted); free(s); } - if (pthread_mutex_unlock(&this->lock)) abort(); if (dirty) { text_list_state(this->g, this->w, &visible_lines, &start_line, &number_of_lines); @@ -58,6 +57,7 @@ static void *textlist_thread(void *_this) /* this call is not necessary, but if things change in text_list... */ widget_dirty(this->g, this->w); } + if (pthread_mutex_unlock(&this->lock)) abort(); sleepms(1000/this->refresh_rate); } @@ -90,6 +90,8 @@ static void scroll(void *private, gui *g, int new_line; int inc; + if (pthread_mutex_lock(&this->lock)) abort(); + text_list_state(g, w, &visible_lines, &start_line, &number_of_lines); inc = 10; if (inc > visible_lines - 2) inc = visible_lines - 2; @@ -107,6 +109,8 @@ static void scroll(void *private, gui *g, this->autoscroll = 0; else this->autoscroll = 1; + + if (pthread_mutex_unlock(&this->lock)) abort(); } static void click(void *private, gui *g, @@ -116,7 +120,11 @@ static void click(void *private, gui *g, int *d = notification_data; int button = d[1]; + if (pthread_mutex_lock(&this->lock)) abort(); + if (button == 1) this->autoscroll = 1 - this->autoscroll; + + if (pthread_mutex_unlock(&this->lock)) abort(); } view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w) From 1dea159028a44024eafe3a063d07b62e9e492d00 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 10:09:33 +0200 Subject: [PATCH 092/217] gui "text_list" becomes "textlist" view "textlist" becomes "view_textlist" (this one may change at some point) --- common/utils/T/tracer/event_selector.c | 22 +++---- common/utils/T/tracer/gui/Makefile | 2 +- common/utils/T/tracer/gui/gui.h | 20 +++--- common/utils/T/tracer/gui/gui_defs.h | 2 +- common/utils/T/tracer/gui/test.c | 6 +- .../T/tracer/gui/{text_list.c => textlist.c} | 62 +++++++++---------- common/utils/T/tracer/remote.c | 10 +-- common/utils/T/tracer/view/stdout.c | 2 +- common/utils/T/tracer/view/textlist.c | 16 ++--- common/utils/T/tracer/view/view.h | 4 +- 10 files changed, 73 insertions(+), 73 deletions(-) rename common/utils/T/tracer/gui/{text_list.c => textlist.c} (71%) diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index 2e950ac974..833939ff5d 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -27,7 +27,7 @@ static void scroll(void *private, gui *g, int new_line; int inc; - text_list_state(g, w, &visible_lines, &start_line, &number_of_lines); + textlist_state(g, w, &visible_lines, &start_line, &number_of_lines); inc = 10; if (inc > visible_lines - 2) inc = visible_lines - 2; if (inc < 1) inc = 1; @@ -38,7 +38,7 @@ static void scroll(void *private, gui *g, new_line = number_of_lines - visible_lines; if (new_line < 0) new_line = 0; - text_list_set_start_line(g, w, new_line); + textlist_set_start_line(g, w, new_line); } static void click(void *private, gui *g, @@ -59,21 +59,21 @@ static void click(void *private, gui *g, if (button == 1) set_on = 1; else set_on = 0; if (w == this->events) - text_list_get_line(this->g, this->events, line, &text, &color); + textlist_get_line(this->g, this->events, line, &text, &color); else - text_list_get_line(this->g, this->groups, line, &text, &color); + textlist_get_line(this->g, this->groups, line, &text, &color); on_off(this->database, text, this->is_on, set_on); for (i = 0; i < this->nevents; i++) - text_list_set_color(this->g, this->events, i, + textlist_set_color(this->g, this->events, i, this->is_on[database_pos_to_id(this->database, i)] ? this->green : this->red); for (i = 0; i < this->ngroups; i++) - text_list_set_color(this->g, this->groups, i, FOREGROUND_COLOR); + textlist_set_color(this->g, this->groups, i, FOREGROUND_COLOR); if (w == this->groups) - text_list_set_color(this->g, this->groups, line, + textlist_set_color(this->g, this->groups, line, set_on ? this->green : this->red); t = 1; @@ -124,8 +124,8 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, widget_add_child(g, left, new_label(g, "Events"), -1); widget_add_child(g, right, new_label(g, "Groups"), -1); - events = new_text_list(g, 235, 10, new_color(g, "#b3c1e1")); - groups = new_text_list(g, 235, 10, new_color(g, "#edd6cb")); + events = new_textlist(g, 235, 10, new_color(g, "#b3c1e1")); + groups = new_textlist(g, 235, 10, new_color(g, "#edd6cb")); widget_add_child(g, left, events, -1); widget_add_child(g, right, groups, -1); @@ -134,7 +134,7 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, n = database_get_ids(database, &ids); for (i = 0; i < n; i++) { - text_list_add(g, events, ids[i], -1, + textlist_add(g, events, ids[i], -1, is_on[database_pos_to_id(database, i)] ? green : red); } free(ids); @@ -143,7 +143,7 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, n = database_get_groups(database, &gps); for (i = 0; i < n; i++) { - text_list_add(g, groups, gps[i], -1, FOREGROUND_COLOR); + textlist_add(g, groups, gps[i], -1, FOREGROUND_COLOR); } free(gps); diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index cc6a409e75..adec8fdd79 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ - gui.o label.o event.o xy_plot.o text_list.o notify.o + gui.o label.o event.o xy_plot.o textlist.o notify.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 142e34a0a8..aa89a53c75 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -23,7 +23,7 @@ widget *new_container(gui *gui, int vertical); widget *new_label(gui *gui, const char *text); widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); -widget *new_text_list(gui *_gui, int width, int nlines, int background_color); +widget *new_textlist(gui *_gui, int width, int nlines, int background_color); void container_set_child_growable(gui *_gui, widget *_this, widget *child, int growable); @@ -33,18 +33,18 @@ void xy_plot_set_range(gui *gui, widget *this, void xy_plot_set_points(gui *gui, widget *this, int npoints, float *x, float *y); -void text_list_add(gui *gui, widget *this, const char *text, int position, +void textlist_add(gui *gui, widget *this, const char *text, int position, int color); -void text_list_del(gui *gui, widget *this, int position); -void text_list_add_silent(gui *gui, widget *this, const char *text, +void textlist_del(gui *gui, widget *this, int position); +void textlist_add_silent(gui *gui, widget *this, const char *text, int position, int color); -void text_list_del_silent(gui *gui, widget *this, int position); -void text_list_state(gui *_gui, widget *_this, +void textlist_del_silent(gui *gui, widget *this, int position); +void textlist_state(gui *_gui, widget *_this, int *visible_lines, int *start_line, int *number_of_lines); -void text_list_set_start_line(gui *gui, widget *this, int line); -void text_list_get_line(gui *gui, widget *this, int line, +void textlist_set_start_line(gui *gui, widget *this, int line); +void textlist_get_line(gui *gui, widget *this, int line, char **text, int *color); -void text_list_set_color(gui *gui, widget *this, int line, int color); +void textlist_set_color(gui *gui, widget *this, int line, int color); void gui_loop(gui *gui); @@ -55,7 +55,7 @@ int new_color(gui *gui, char *color); /* notifications */ /* known notifications: - * - text_list: + * - textlist: * - scrollup { void *: NULL } * - scrolldown { void *: NULL } * - click { int [2]: line, button } diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index fc9cd39bb3..afc590c7be 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -76,7 +76,7 @@ struct container_widget { int nchildren; }; -struct text_list_widget { +struct textlist_widget { struct widget common; char **text; int *color; diff --git a/common/utils/T/tracer/gui/test.c b/common/utils/T/tracer/gui/test.c index 06e3b6309d..f64d02347e 100644 --- a/common/utils/T/tracer/gui/test.c +++ b/common/utils/T/tracer/gui/test.c @@ -31,11 +31,11 @@ int main(void) #endif tlcol = new_color(g, "#ddf"); - tl = new_text_list(g, 300, 10, tlcol); + tl = new_textlist(g, 300, 10, tlcol); widget_add_child(g, c1, tl, -1); - text_list_add(g, tl, "hello", -1); - text_list_add(g, tl, "world", -1); + textlist_add(g, tl, "hello", -1, FOREGROUND_COLOR); + textlist_add(g, tl, "world", -1, FOREGROUND_COLOR); w = new_toplevel_window(g, 500, 400, "test window"); widget_add_child(g, w, c1, 0); diff --git a/common/utils/T/tracer/gui/text_list.c b/common/utils/T/tracer/gui/textlist.c similarity index 71% rename from common/utils/T/tracer/gui/text_list.c rename to common/utils/T/tracer/gui/textlist.c index 9efdedd2a9..9244b8c9bf 100644 --- a/common/utils/T/tracer/gui/text_list.c +++ b/common/utils/T/tracer/gui/textlist.c @@ -8,9 +8,9 @@ static void paint(gui *_gui, widget *_this) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; int i, j; - LOGD("PAINT text_list %p xywh %d %d %d %d starting line %d allocated nlines %d text_count %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height, this->starting_line, this->allocated_nlines, this->text_count); + LOGD("PAINT textlist %p xywh %d %d %d %d starting line %d allocated nlines %d text_count %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height, this->starting_line, this->allocated_nlines, this->text_count); x_fill_rectangle(g->x, g->xwin, this->background_color, this->common.x, this->common.y, this->common.width, this->common.height); @@ -26,29 +26,29 @@ static void paint(gui *_gui, widget *_this) static void hints(gui *_gui, widget *_w, int *width, int *height) { - struct text_list_widget *w = _w; + struct textlist_widget *w = _w; *width = w->wanted_width; *height = w->wanted_nlines * w->line_height; - LOGD("HINTS text_list wh %d %d\n", *width, *height); + LOGD("HINTS textlist wh %d %d\n", *width, *height); } static void allocate( gui *gui, widget *_this, int x, int y, int width, int height) { - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; this->common.x = x; this->common.y = y; this->common.width = width; this->common.height = height; this->allocated_nlines = height / this->line_height; - LOGD("ALLOCATE text_list %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); + LOGD("ALLOCATE textlist %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); } static void button(gui *_g, widget *_this, int x, int y, int button, int up) { struct gui *g = _g; - struct text_list_widget *this = _this; - LOGD("BUTTON text_list %p xy %d %d button %d up %d\n", _this, x, y, button, up); + struct textlist_widget *this = _this; + LOGD("BUTTON textlist %p xy %d %d button %d up %d\n", _this, x, y, button, up); /* scroll up */ if (button == 4 && up == 0) { gui_notify(g, "scrollup", _this, NULL); @@ -65,15 +65,15 @@ static void button(gui *_g, widget *_this, int x, int y, int button, int up) } } -widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) +widget *new_textlist(gui *_gui, int width, int nlines, int bgcol) { struct gui *g = _gui; - struct text_list_widget *w; + struct textlist_widget *w; int dummy; glock(g); - w = new_widget(g, TEXT_LIST, sizeof(struct text_list_widget)); + w = new_widget(g, TEXT_LIST, sizeof(struct textlist_widget)); w->wanted_nlines = nlines; x_text_get_dimensions(g->x, ".", &dummy, &w->line_height, &w->baseline); @@ -95,11 +95,11 @@ widget *new_text_list(gui *_gui, int width, int nlines, int bgcol) /* public functions */ /*************************************************************************/ -static void _text_list_add(gui *_gui, widget *_this, const char *text, +static void _textlist_add(gui *_gui, widget *_this, const char *text, int position, int color, int silent) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; glock(g); @@ -125,10 +125,10 @@ static void _text_list_add(gui *_gui, widget *_this, const char *text, gunlock(g); } -static void _text_list_del(gui *_gui, widget *_this, int position, int silent) +static void _textlist_del(gui *_gui, widget *_this, int position, int silent) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; glock(g); @@ -157,33 +157,33 @@ done: gunlock(g); } -void text_list_add(gui *gui, widget *this, const char *text, int position, +void textlist_add(gui *gui, widget *this, const char *text, int position, int color) { - _text_list_add(gui, this, text, position, color, 0); + _textlist_add(gui, this, text, position, color, 0); } -void text_list_del(gui *gui, widget *this, int position) +void textlist_del(gui *gui, widget *this, int position) { - _text_list_del(gui, this, position, 0); + _textlist_del(gui, this, position, 0); } -void text_list_add_silent(gui *gui, widget *this, const char *text, +void textlist_add_silent(gui *gui, widget *this, const char *text, int position, int color) { - _text_list_add(gui, this, text, position, color, 1); + _textlist_add(gui, this, text, position, color, 1); } -void text_list_del_silent(gui *gui, widget *this, int position) +void textlist_del_silent(gui *gui, widget *this, int position) { - _text_list_del(gui, this, position, 1); + _textlist_del(gui, this, position, 1); } -void text_list_state(gui *_gui, widget *_this, +void textlist_state(gui *_gui, widget *_this, int *visible_lines, int *start_line, int *number_of_lines) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; glock(g); @@ -194,10 +194,10 @@ void text_list_state(gui *_gui, widget *_this, gunlock(g); } -void text_list_set_start_line(gui *_gui, widget *_this, int line) +void textlist_set_start_line(gui *_gui, widget *_this, int line) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; glock(g); @@ -208,11 +208,11 @@ void text_list_set_start_line(gui *_gui, widget *_this, int line) gunlock(g); } -void text_list_get_line(gui *_gui, widget *_this, int line, +void textlist_get_line(gui *_gui, widget *_this, int line, char **text, int *color) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; glock(g); @@ -227,10 +227,10 @@ void text_list_get_line(gui *_gui, widget *_this, int line, gunlock(g); } -void text_list_set_color(gui *_gui, widget *_this, int line, int color) +void textlist_set_color(gui *_gui, widget *_this, int line, int color) { struct gui *g = _gui; - struct text_list_widget *this = _this; + struct textlist_widget *this = _this; glock(g); diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c index 9b06673e8e..2ef9e5bc28 100644 --- a/common/utils/T/tracer/remote.c +++ b/common/utils/T/tracer/remote.c @@ -169,14 +169,14 @@ int main(int n, char **v) if (gui_mode) { widget *w, *win; -// w = new_text_list(g, 600, 20, 0); - w = new_text_list(g, 800, 50, BACKGROUND_COLOR); +// w = new_textlist(g, 600, 20, 0); + w = new_textlist(g, 800, 50, BACKGROUND_COLOR); win = new_toplevel_window(g, 800, 50*12, "textlog"); widget_add_child(g, win, w, -1); - out = new_textlist(1000, 10, g, w); - //tout = new_textlist(7, 4, g, w); + out = new_view_textlist(1000, 10, g, w); + //tout = new_view_textlist(7, 4, g, w); } else { - out = new_stdout(); + out = new_view_stdout(); } for (i = 0; i < number_of_events; i++) { diff --git a/common/utils/T/tracer/view/stdout.c b/common/utils/T/tracer/view/stdout.c index 695704e422..93223e59d8 100644 --- a/common/utils/T/tracer/view/stdout.c +++ b/common/utils/T/tracer/view/stdout.c @@ -21,7 +21,7 @@ static void append(view *_this, char *s) if (pthread_mutex_unlock(&this->lock)) abort(); } -view *new_stdout(void) +view *new_view_stdout(void) { struct stdout *ret = calloc(1, sizeof(struct stdout)); if (ret == NULL) abort(); diff --git a/common/utils/T/tracer/view/textlist.c b/common/utils/T/tracer/view/textlist.c index 6aec4848d3..5227900e4e 100644 --- a/common/utils/T/tracer/view/textlist.c +++ b/common/utils/T/tracer/view/textlist.c @@ -20,11 +20,11 @@ struct textlist { static void _append(struct textlist *this, char *s, int *deleted) { if (this->cursize == this->maxsize) { - text_list_del_silent(this->g, this->w, 0); + textlist_del_silent(this->g, this->w, 0); this->cursize--; (*deleted)++; } - text_list_add_silent(this->g, this->w, s, -1, FOREGROUND_COLOR); + textlist_add_silent(this->g, this->w, s, -1, FOREGROUND_COLOR); this->cursize++; } @@ -46,15 +46,15 @@ static void *textlist_thread(void *_this) free(s); } if (dirty) { - text_list_state(this->g, this->w, &visible_lines, &start_line, + textlist_state(this->g, this->w, &visible_lines, &start_line, &number_of_lines); if (this->autoscroll) start_line = number_of_lines - visible_lines; else start_line -= deleted; if (start_line < 0) start_line = 0; - text_list_set_start_line(this->g, this->w, start_line); - /* this call is not necessary, but if things change in text_list... */ + textlist_set_start_line(this->g, this->w, start_line); + /* this call is not necessary, but if things change in textlist... */ widget_dirty(this->g, this->w); } if (pthread_mutex_unlock(&this->lock)) abort(); @@ -92,7 +92,7 @@ static void scroll(void *private, gui *g, if (pthread_mutex_lock(&this->lock)) abort(); - text_list_state(g, w, &visible_lines, &start_line, &number_of_lines); + textlist_state(g, w, &visible_lines, &start_line, &number_of_lines); inc = 10; if (inc > visible_lines - 2) inc = visible_lines - 2; if (inc < 1) inc = 1; @@ -103,7 +103,7 @@ static void scroll(void *private, gui *g, new_line = number_of_lines - visible_lines; if (new_line < 0) new_line = 0; - text_list_set_start_line(g, w, new_line); + textlist_set_start_line(g, w, new_line); if (new_line + visible_lines < number_of_lines) this->autoscroll = 0; @@ -127,7 +127,7 @@ static void click(void *private, gui *g, if (pthread_mutex_unlock(&this->lock)) abort(); } -view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w) +view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w) { struct textlist *ret = calloc(1, sizeof(struct textlist)); if (ret == NULL) abort(); diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 9929e6e5d4..a5855b1098 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -10,7 +10,7 @@ typedef struct view { void (*append)(struct view *this, ...); } view; -view *new_stdout(void); -view *new_textlist(int maxsize, float refresh_rate, gui *g, widget *w); +view *new_view_stdout(void); +view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w); #endif /* _VIEW_H_ */ From 8cca28b3e71dc0a7a55f7e33a91ac3dc0d2ae97e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 10:31:42 +0200 Subject: [PATCH 093/217] put textlog.[ch] in logger/ and rename remote.c to textlog.c --- common/utils/T/tracer/Makefile.remote | 14 +- common/utils/T/tracer/logger/Makefile | 13 + common/utils/T/tracer/logger/textlog.c | 189 ++++++++++ common/utils/T/tracer/{ => logger}/textlog.h | 0 common/utils/T/tracer/remote.c | 220 ----------- common/utils/T/tracer/textlog.c | 369 ++++++++++--------- 6 files changed, 411 insertions(+), 394 deletions(-) create mode 100644 common/utils/T/tracer/logger/Makefile create mode 100644 common/utils/T/tracer/logger/textlog.c rename common/utils/T/tracer/{ => logger}/textlog.h (100%) delete mode 100644 common/utils/T/tracer/remote.c diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 08b79f2aa1..3eadcc27da 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -11,17 +11,20 @@ OBJS=remote_old.o plot.o database.o gui.o utils.o $(PROG): gui/gui.a $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) -textlog: utils.o remote.o database.o event.o handler.o textlog.o \ - event_selector.o view/view.a gui/gui.a +textlog: utils.o textlog.o database.o event.o handler.o \ + event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o textlog $^ $(LIBS) -.PHONY: gui/gui.a view/view.a +.PHONY: gui/gui.a view/view.a logger/logger.a + +gui/gui.a: + cd gui && make view/view.a: cd view && make -gui/gui.a: - cd gui && make +logger/logger.a: + cd logger && make %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< @@ -30,3 +33,4 @@ clean: rm -f *.o $(PROG) core textlog cd gui && make clean cd view && make clean + cd logger && make clean diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile new file mode 100644 index 0000000000..1b4c3b1d28 --- /dev/null +++ b/common/utils/T/tracer/logger/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -I.. + +OBJS=textlog.o + +logger.a: $(OBJS) + ar cr logger.a $(OBJS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + rm -f *.a *.o diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c new file mode 100644 index 0000000000..264068c617 --- /dev/null +++ b/common/utils/T/tracer/logger/textlog.c @@ -0,0 +1,189 @@ +#include "textlog.h" +#include "handler.h" +#include "database.h" +#include "view/view.h" +#include "utils.h" +#include +#include +#include + +enum format_item_type { + INSTRING, + INT, STRING, BUFFER }; + +struct format_item { + enum format_item_type type; + union { + /* INSTRING */ + char *s; + /* others */ + int event_arg; + }; +}; + +struct textlog { + char *event_name; + char *format; + void *database; + unsigned long handler_id; + /* parsed format string */ + struct format_item *f; + int fsize; + /* list of views */ + view **v; + int vsize; + /* local output buffer */ + OBUF o; +}; + +static void _event(void *p, event e) +{ + struct textlog *l = p; + int i; + + l->o.osize = 0; + + for (i = 0; i < l->fsize; i++) + switch(l->f[i].type) { + case INSTRING: PUTS(&l->o, l->f[i].s); break; + case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; + case STRING: PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break; + case BUFFER: + PUTS(&l->o, "{buffer size:"); + PUTI(&l->o, e.e[l->f[i].event_arg].bsize); + PUTS(&l->o, "}"); + break; + } + PUTC(&l->o, 0); + + for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->o.obuf); +} + +enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; +struct chunk { + enum chunk_type type; + char *s; + enum format_item_type it; + int event_arg; +}; + +/* TODO: speed it up? */ +static int find_argument(char *name, database_event_format f, + enum format_item_type *it, int *event_arg) +{ + int i; + for (i = 0; i < f.count; i++) if (!strcmp(name, f.name[i])) break; + if (i == f.count) return 0; + *event_arg = i; + if (!strcmp(f.type[i], "int")) *it = INT; + else if (!strcmp(f.type[i], "string")) *it = STRING; + else if (!strcmp(f.type[i], "buffer")) *it = BUFFER; + else return 0; + return 1; +} + +static struct chunk next_chunk(char **s, database_event_format f) +{ + char *cur = *s; + char *name; + enum format_item_type it; + int event_arg; + + /* argument in [ ] */ + if (*cur == '[') { + *cur = 0; + cur++; + name = cur; + /* no \ allowed there */ + while (*cur && *cur != ']' && *cur != '\\') cur++; + if (*cur != ']') goto error; + *cur = 0; + cur++; + *s = cur; + if (find_argument(name, f, &it, &event_arg) == 0) goto error; + return (struct chunk){type:C_ARG_NAME, s:name, it:it, event_arg:event_arg}; + } + + /* { } is name of event (anything in between is smashed) */ + if (*cur == '{') { + *cur = 0; + cur++; + while (*cur && *cur != '}') cur++; + if (*cur != '}') goto error; + *cur = 0; + cur++; + *s = cur; + return (struct chunk){type:C_EVENT_NAME}; + } + + /* anything but [ and { is raw string */ + /* TODO: deal with \ */ + name = cur; + while (*cur && *cur != '[' && *cur != '{') cur++; + *s = cur; + return (struct chunk){type:C_STRING, s:name}; + +error: + return (struct chunk){type:C_ERROR}; +} + +textlog *new_textlog(event_handler *h, void *database, + char *event_name, char *format) +{ + struct textlog *ret; + int event_id; + database_event_format f; + char *cur; + + ret = calloc(1, sizeof(struct textlog)); if (ret == NULL) abort(); + + ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); + ret->format = strdup(format); if (ret->format == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->handler_id = register_handler_function(h, event_id, _event, ret); + + f = get_format(database, event_id); + + /* we won't get more than strlen(format) "chunks" */ + ret->f = malloc(sizeof(struct format_item) * strlen(format)); + if (ret->f == NULL) abort(); + + cur = ret->format; + + while (*cur) { + struct chunk c = next_chunk(&cur, f); + switch (c.type) { + case C_ERROR: goto error; + case C_STRING: + ret->f[ret->fsize].type = INSTRING; + ret->f[ret->fsize].s = c.s; + break; + case C_ARG_NAME: + ret->f[ret->fsize].type = c.it; + ret->f[ret->fsize].event_arg = c.event_arg; + break; + case C_EVENT_NAME: + ret->f[ret->fsize].type = INSTRING; + ret->f[ret->fsize].s = ret->event_name; + break; + } + ret->fsize++; + } + + return ret; + +error: + printf("%s:%d: bad format '%s'\n", __FILE__, __LINE__, format); + abort(); +} + +void textlog_add_view(textlog *_l, view *v) +{ + struct textlog *l = _l; + l->vsize++; + l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); + l->v[l->vsize-1] = v; +} diff --git a/common/utils/T/tracer/textlog.h b/common/utils/T/tracer/logger/textlog.h similarity index 100% rename from common/utils/T/tracer/textlog.h rename to common/utils/T/tracer/logger/textlog.h diff --git a/common/utils/T/tracer/remote.c b/common/utils/T/tracer/remote.c deleted file mode 100644 index 2ef9e5bc28..0000000000 --- a/common/utils/T/tracer/remote.c +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "database.h" -#include "event.h" -#include "handler.h" -#include "textlog.h" -#include "view/view.h" -#include "gui/gui.h" -#include "utils.h" -#include "../T_defs.h" -#include "event_selector.h" - -#define DEFAULT_REMOTE_PORT 2021 - -int get_connection(char *addr, int port) -{ - struct sockaddr_in a; - socklen_t alen; - int s, t; - - printf("waiting for connection on %s:%d\n", addr, port); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } - t = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) - { perror("setsockopt"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(addr); - - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("bind"); exit(1); } - alen = sizeof(a); - t = accept(s, (struct sockaddr *)&a, &alen); - if (t == -1) { perror("accept"); exit(1); } - close(s); - - printf("connected\n"); - - return t; -} - -void usage(void) -{ - printf( -"options:\n" -" -d this option is mandatory\n" -" -on turn log ON for given GROUP or ID\n" -" -off turn log OFF for given GROUP or ID\n" -" -ON turn all logs ON\n" -" -OFF turn all logs OFF\n" -" note: you may pass several -on/-off/-ON/-OFF,\n" -" they will be processed in order\n" -" by default, all is off\n" -" -p use given port (default %d)\n" -" -x GUI output\n" -" -debug-gui activate GUI debug logs\n" -" -no-gui disable GUI entirely\n", - DEFAULT_REMOTE_PORT - ); - exit(1); -} - -int fullread(int fd, void *_buf, int count) -{ - char *buf = _buf; - int ret = 0; - int l; - while (count) { - l = read(fd, buf, count); - if (l <= 0) { printf("read socket problem\n"); abort(); } - count -= l; - buf += l; - ret += l; - } - return ret; -} - -event get_event(int s, char *v, void *d) -{ - int type; - int32_t length; - - fullread(s, &length, 4); - fullread(s, &type, sizeof(int)); - length -= sizeof(int); - fullread(s, v, length); - - return new_event(type, length, v, d); -} - -static void *gui_thread(void *_g) -{ - gui *g = _g; - gui_loop(g); - return NULL; -} - -int main(int n, char **v) -{ - extern int volatile gui_logd; - char *database_filename = NULL; - void *database; - int port = DEFAULT_REMOTE_PORT; - char **on_off_name; - int *on_off_action; - int on_off_n = 0; - int *is_on; - int number_of_events; - int s; - int i; - char t; - int l; - event_handler *h; - textlog *textlog; - gui *g; - int gui_mode = 0; - view *out; - int gui_active = 1; - - on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); - on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); - - for (i = 1; i < n; i++) { - if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-d")) - { if (i > n-2) usage(); database_filename = v[++i]; continue; } - if (!strcmp(v[i], "-p")) - { if (i > n-2) usage(); port = atoi(v[++i]); continue; } - if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); - on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } - if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); - on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } - if (!strcmp(v[i], "-ON")) - { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } - if (!strcmp(v[i], "-OFF")) - { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } - if (!strcmp(v[i], "-x")) { gui_mode = 1; continue; } - if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } - if (!strcmp(v[i], "-no-gui")) { gui_active = 0; continue; } - usage(); - } - - if (gui_active == 0) gui_mode = 0; - - if (database_filename == NULL) { - printf("ERROR: provide a database file (-d)\n"); - exit(1); - } - - database = parse_database(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); - - if (gui_active) { - g = gui_init(); - new_thread(gui_thread, g); - } - - if (gui_mode) { - widget *w, *win; -// w = new_textlist(g, 600, 20, 0); - w = new_textlist(g, 800, 50, BACKGROUND_COLOR); - win = new_toplevel_window(g, 800, 50*12, "textlog"); - widget_add_child(g, win, w, -1); - out = new_view_textlist(1000, 10, g, w); - //tout = new_view_textlist(7, 4, g, w); - } else { - out = new_view_stdout(); - } - - for (i = 0; i < number_of_events; i++) { - char *name, *desc; - database_get_generic_description(database, i, &name, &desc); - textlog = new_textlog(h, database, name, desc); -// "ENB_UL_CHANNEL_ESTIMATE", -// "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); - textlog_add_view(textlog, out); - free(name); - free(desc); - } - - for (i = 0; i < on_off_n; i++) - on_off(database, on_off_name[i], is_on, on_off_action[i]); - - s = get_connection("0.0.0.0", port); - - /* send the first message - activate selected traces */ - t = 0; - if (write(s, &t, 1) != 1) abort(); - l = 0; - for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - for (l = 0; l < number_of_events; l++) - if (is_on[l]) - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - - if (gui_active) - setup_event_selector(g, database, s, is_on); - - /* read messages */ - while (1) { - char v[T_BUFFER_MAX]; - event e; - e = get_event(s, v, database); - handle_event(h, e); - } - - return 0; -} diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 264068c617..f3e6f7178c 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -1,189 +1,220 @@ -#include "textlog.h" -#include "handler.h" -#include "database.h" -#include "view/view.h" -#include "utils.h" +#include #include #include -#include +#include +#include +#include +#include "database.h" +#include "event.h" +#include "handler.h" +#include "logger/textlog.h" +#include "view/view.h" +#include "gui/gui.h" +#include "utils.h" +#include "../T_defs.h" +#include "event_selector.h" -enum format_item_type { - INSTRING, - INT, STRING, BUFFER }; +#define DEFAULT_REMOTE_PORT 2021 -struct format_item { - enum format_item_type type; - union { - /* INSTRING */ - char *s; - /* others */ - int event_arg; - }; -}; - -struct textlog { - char *event_name; - char *format; - void *database; - unsigned long handler_id; - /* parsed format string */ - struct format_item *f; - int fsize; - /* list of views */ - view **v; - int vsize; - /* local output buffer */ - OBUF o; -}; - -static void _event(void *p, event e) +int get_connection(char *addr, int port) { - struct textlog *l = p; - int i; + struct sockaddr_in a; + socklen_t alen; + int s, t; - l->o.osize = 0; + printf("waiting for connection on %s:%d\n", addr, port); - for (i = 0; i < l->fsize; i++) - switch(l->f[i].type) { - case INSTRING: PUTS(&l->o, l->f[i].s); break; - case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; - case STRING: PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break; - case BUFFER: - PUTS(&l->o, "{buffer size:"); - PUTI(&l->o, e.e[l->f[i].event_arg].bsize); - PUTS(&l->o, "}"); - break; - } - PUTC(&l->o, 0); + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } - for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->o.obuf); + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + + printf("connected\n"); + + return t; } -enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; -struct chunk { - enum chunk_type type; - char *s; - enum format_item_type it; - int event_arg; -}; - -/* TODO: speed it up? */ -static int find_argument(char *name, database_event_format f, - enum format_item_type *it, int *event_arg) +void usage(void) { - int i; - for (i = 0; i < f.count; i++) if (!strcmp(name, f.name[i])) break; - if (i == f.count) return 0; - *event_arg = i; - if (!strcmp(f.type[i], "int")) *it = INT; - else if (!strcmp(f.type[i], "string")) *it = STRING; - else if (!strcmp(f.type[i], "buffer")) *it = BUFFER; - else return 0; - return 1; + printf( +"options:\n" +" -d this option is mandatory\n" +" -on turn log ON for given GROUP or ID\n" +" -off turn log OFF for given GROUP or ID\n" +" -ON turn all logs ON\n" +" -OFF turn all logs OFF\n" +" note: you may pass several -on/-off/-ON/-OFF,\n" +" they will be processed in order\n" +" by default, all is off\n" +" -p use given port (default %d)\n" +" -x GUI output\n" +" -debug-gui activate GUI debug logs\n" +" -no-gui disable GUI entirely\n", + DEFAULT_REMOTE_PORT + ); + exit(1); } -static struct chunk next_chunk(char **s, database_event_format f) +int fullread(int fd, void *_buf, int count) { - char *cur = *s; - char *name; - enum format_item_type it; - int event_arg; - - /* argument in [ ] */ - if (*cur == '[') { - *cur = 0; - cur++; - name = cur; - /* no \ allowed there */ - while (*cur && *cur != ']' && *cur != '\\') cur++; - if (*cur != ']') goto error; - *cur = 0; - cur++; - *s = cur; - if (find_argument(name, f, &it, &event_arg) == 0) goto error; - return (struct chunk){type:C_ARG_NAME, s:name, it:it, event_arg:event_arg}; + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) { printf("read socket problem\n"); abort(); } + count -= l; + buf += l; + ret += l; } - - /* { } is name of event (anything in between is smashed) */ - if (*cur == '{') { - *cur = 0; - cur++; - while (*cur && *cur != '}') cur++; - if (*cur != '}') goto error; - *cur = 0; - cur++; - *s = cur; - return (struct chunk){type:C_EVENT_NAME}; - } - - /* anything but [ and { is raw string */ - /* TODO: deal with \ */ - name = cur; - while (*cur && *cur != '[' && *cur != '{') cur++; - *s = cur; - return (struct chunk){type:C_STRING, s:name}; - -error: - return (struct chunk){type:C_ERROR}; -} - -textlog *new_textlog(event_handler *h, void *database, - char *event_name, char *format) -{ - struct textlog *ret; - int event_id; - database_event_format f; - char *cur; - - ret = calloc(1, sizeof(struct textlog)); if (ret == NULL) abort(); - - ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); - ret->format = strdup(format); if (ret->format == NULL) abort(); - ret->database = database; - - event_id = event_id_from_name(database, event_name); - - ret->handler_id = register_handler_function(h, event_id, _event, ret); - - f = get_format(database, event_id); - - /* we won't get more than strlen(format) "chunks" */ - ret->f = malloc(sizeof(struct format_item) * strlen(format)); - if (ret->f == NULL) abort(); - - cur = ret->format; - - while (*cur) { - struct chunk c = next_chunk(&cur, f); - switch (c.type) { - case C_ERROR: goto error; - case C_STRING: - ret->f[ret->fsize].type = INSTRING; - ret->f[ret->fsize].s = c.s; - break; - case C_ARG_NAME: - ret->f[ret->fsize].type = c.it; - ret->f[ret->fsize].event_arg = c.event_arg; - break; - case C_EVENT_NAME: - ret->f[ret->fsize].type = INSTRING; - ret->f[ret->fsize].s = ret->event_name; - break; - } - ret->fsize++; - } - return ret; - -error: - printf("%s:%d: bad format '%s'\n", __FILE__, __LINE__, format); - abort(); } -void textlog_add_view(textlog *_l, view *v) +event get_event(int s, char *v, void *d) { - struct textlog *l = _l; - l->vsize++; - l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); - l->v[l->vsize-1] = v; + int type; + int32_t length; + + fullread(s, &length, 4); + fullread(s, &type, sizeof(int)); + length -= sizeof(int); + fullread(s, v, length); + + return new_event(type, length, v, d); +} + +static void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return NULL; +} + +int main(int n, char **v) +{ + extern int volatile gui_logd; + char *database_filename = NULL; + void *database; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int s; + int i; + char t; + int l; + event_handler *h; + textlog *textlog; + gui *g; + int gui_mode = 0; + view *out; + int gui_active = 1; + + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); + on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-ON")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-OFF")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-x")) { gui_mode = 1; continue; } + if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } + if (!strcmp(v[i], "-no-gui")) { gui_active = 0; continue; } + usage(); + } + + if (gui_active == 0) gui_mode = 0; + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(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); + + if (gui_active) { + g = gui_init(); + new_thread(gui_thread, g); + } + + if (gui_mode) { + widget *w, *win; +// w = new_textlist(g, 600, 20, 0); + w = new_textlist(g, 800, 50, BACKGROUND_COLOR); + win = new_toplevel_window(g, 800, 50*12, "textlog"); + widget_add_child(g, win, w, -1); + out = new_view_textlist(1000, 10, g, w); + //tout = new_view_textlist(7, 4, g, w); + } else { + out = new_view_stdout(); + } + + for (i = 0; i < number_of_events; i++) { + char *name, *desc; + database_get_generic_description(database, i, &name, &desc); + textlog = new_textlog(h, database, name, desc); +// "ENB_UL_CHANNEL_ESTIMATE", +// "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); + textlog_add_view(textlog, out); + free(name); + free(desc); + } + + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); + + s = get_connection("0.0.0.0", port); + + /* send the first message - activate selected traces */ + t = 0; + if (write(s, &t, 1) != 1) abort(); + l = 0; + for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + for (l = 0; l < number_of_events; l++) + if (is_on[l]) + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + + if (gui_active) + setup_event_selector(g, database, s, is_on); + + /* read messages */ + while (1) { + char v[T_BUFFER_MAX]; + event e; + e = get_event(s, v, database); + handle_event(h, e); + } + + return 0; } From e54f87a00e2e764c135854308ef794d6d453776a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 10:38:11 +0200 Subject: [PATCH 094/217] bugfix: forgot malloc return check --- common/utils/T/tracer/database.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index 62796149b3..f31c7580e9 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -459,7 +459,7 @@ int database_get_ids(void *_d, char ***ids) { database *d = _d; int i; - *ids = malloc(d->isize * sizeof(char **)); + *ids = malloc(d->isize * sizeof(char **)); if (*ids == NULL) abort(); for (i = 0; i < d->isize; i++) (*ids)[i] = d->i[i].name; return d->isize; } @@ -468,7 +468,7 @@ int database_get_groups(void *_d, char ***groups) { database *d = _d; int i; - *groups = malloc(d->gsize * sizeof(char **)); + *groups = malloc(d->gsize * sizeof(char **)); if (*groups == NULL) abort(); for (i = 0; i < d->gsize; i++) (*groups)[i] = d->g[i].name; return d->gsize; } From d4f5ab774520a9f9a8c80379a4ffb7fad1ce00b6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 10:48:12 +0200 Subject: [PATCH 095/217] clarify "pos" in database.c the list of IDs is stored alphabetically so when accessing the database with an ID one needs an indirection to get the correct record. "pos" was not clear. "id_to_pos" is clearer. --- common/utils/T/tracer/database.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index f31c7580e9..1914946656 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -28,7 +28,7 @@ typedef struct { int isize; group *g; int gsize; - int *pos; + int *id_to_pos; } database; typedef struct { @@ -326,10 +326,11 @@ void *parse_database(char *filename) free(p.name.data); free(p.value.data); - /* setup pos */ - r->pos = malloc(sizeof(int) * r->isize); if (r->pos == NULL) abort(); + /* setup id_to_pos */ + r->id_to_pos = malloc(sizeof(int) * r->isize); + if (r->id_to_pos == NULL) abort(); for (i = 0; i < r->isize; i++) - r->pos[r->i[i].id] = i; + r->id_to_pos[r->i[i].id] = i; return r; } @@ -420,7 +421,7 @@ void on_off(void *_d, char *item, int *a, int onoff) char *event_name_from_id(void *_database, int id) { database *d = _database; - return d->i[d->pos[id]].name; + return d->i[d->id_to_pos[id]].name; } int event_id_from_name(void *_database, char *name) @@ -442,9 +443,9 @@ database_event_format get_format(void *_database, int event_id) abort(); } - ret.type = d->i[d->pos[event_id]].arg_type; - ret.name = d->i[d->pos[event_id]].arg_name; - ret.count = d->i[d->pos[event_id]].asize; + ret.type = d->i[d->id_to_pos[event_id]].arg_type; + ret.name = d->i[d->id_to_pos[event_id]].arg_name; + ret.count = d->i[d->id_to_pos[event_id]].asize; return ret; } From 185e6a4e1eb3e2cb90f3e103808b59218f33d32d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 11:18:09 +0200 Subject: [PATCH 096/217] warn when memory usage of local tracer grows too much --- common/utils/T/tracer/forward.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c index 27b36c9a9b..15a23307b5 100644 --- a/common/utils/T/tracer/forward.c +++ b/common/utils/T/tracer/forward.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include typedef struct databuf { char *d; @@ -20,6 +22,8 @@ typedef struct { pthread_mutex_t datalock; pthread_cond_t datacond; databuf * volatile head, *tail; + uint64_t memusage; + uint64_t last_warning_memusage; } forward_data; static void *data_sender(void *_f) @@ -37,6 +41,7 @@ wait: buf = cur->d; size = cur->l; f->head = cur->next; + f->memusage -= size; if (f->head == NULL) f->tail = NULL; if (pthread_mutex_unlock(&f->datalock)) abort(); free(cur); @@ -122,6 +127,9 @@ void *forwarder(char *ip, int port) f->sc = -1; f->head = f->tail = NULL; + f->memusage = 0; + f->last_warning_memusage = 0; + printf("connecting to remote tracer %s:%d\n", ip, port); again: @@ -167,6 +175,19 @@ void forward(void *_forwarder, char *buf, int size) if (f->tail != NULL) f->tail->next = new; f->tail = new; + f->memusage += size+4; + /* warn every 100MB */ + if (f->memusage > f->last_warning_memusage && + f->memusage - f->last_warning_memusage > 100000000) { + f->last_warning_memusage += 100000000; + printf("WARNING: memory usage is over %"PRIu64"MB\n", + f->last_warning_memusage / 1000000); + } else + if (f->memusage < f->last_warning_memusage && + f->last_warning_memusage - f->memusage > 100000000) { + f->last_warning_memusage = (f->memusage/100000000) * 100000000; + } + if (pthread_cond_signal(&f->datacond)) abort(); if (pthread_mutex_unlock(&f->datalock)) abort(); } From 87acde28f7344cdb35082bbaefda9191ef695e4f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 11:26:12 +0200 Subject: [PATCH 097/217] - change group names in T_messages.txt for legacy logs - add group ALL --- common/utils/T/T_messages.txt | 260 +++++++++++++++++----------------- 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 58d4107625..87627cfe4a 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,486 +1,486 @@ #PHY logs ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms - GROUP = PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata ID = ENB_UL_CHANNEL_ESTIMATE DESC = eNodeB channel estimation in the time domain - GROUP = PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t ID = PUSCH_IQ DESC = eNodeB PUSCH received IQ data - GROUP = PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : buffer,pusch_comp ID = PUCCH_1AB_IQ DESC = eNodeB PUCCH received IQ data - GROUP = PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,I : int,Q ID = PUCCH_1_ENERGY DESC = eNodeB PUCCH 1 energy and threshold - GROUP = PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold #legacy logs ID = LEGACY_MAC_INFO DESC = MAC legacy logs - info level - GROUP = MAC:INFO:LEGACY + GROUP = ALL:LEGACY_MAC:INFO:LEGACY FORMAT = string,log ID = LEGACY_MAC_ERROR DESC = MAC legacy logs - error level - GROUP = MAC:ERROR:LEGACY + GROUP = ALL:LEGACY_MAC:ERROR:LEGACY FORMAT = string,log ID = LEGACY_MAC_WARNING DESC = MAC legacy logs - warning level - GROUP = MAC:WARNING:LEGACY + GROUP = ALL:LEGACY_MAC:WARNING:LEGACY FORMAT = string,log ID = LEGACY_MAC_DEBUG DESC = MAC legacy logs - debug level - GROUP = MAC:DEBUG:LEGACY + GROUP = ALL:LEGACY_MAC:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_MAC_TRACE DESC = MAC legacy logs - trace level - GROUP = MAC:TRACE:LEGACY + GROUP = ALL:LEGACY_MAC:TRACE:LEGACY FORMAT = string,log ID = LEGACY_PHY_INFO DESC = PHY legacy logs - info level - GROUP = PHY:INFO:LEGACY + GROUP = ALL:LEGACY_PHY:INFO:LEGACY FORMAT = string,log ID = LEGACY_PHY_ERROR DESC = PHY legacy logs - error level - GROUP = PHY:ERROR:LEGACY + GROUP = ALL:LEGACY_PHY:ERROR:LEGACY FORMAT = string,log ID = LEGACY_PHY_WARNING DESC = PHY legacy logs - warning level - GROUP = PHY:WARNING:LEGACY + GROUP = ALL:LEGACY_PHY:WARNING:LEGACY FORMAT = string,log ID = LEGACY_PHY_DEBUG DESC = PHY legacy logs - debug level - GROUP = PHY:DEBUG:LEGACY + GROUP = ALL:LEGACY_PHY:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_PHY_TRACE DESC = PHY legacy logs - trace level - GROUP = PHY:TRACE:LEGACY + GROUP = ALL:LEGACY_PHY:TRACE:LEGACY FORMAT = string,log ID = LEGACY_S1AP_INFO DESC = S1AP legacy logs - info level - GROUP = S1AP:INFO:LEGACY + GROUP = ALL:LEGACY_S1AP:INFO:LEGACY FORMAT = string,log ID = LEGACY_S1AP_ERROR DESC = S1AP legacy logs - error level - GROUP = S1AP:ERROR:LEGACY + GROUP = ALL:LEGACY_S1AP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_S1AP_WARNING DESC = S1AP legacy logs - warning level - GROUP = S1AP:WARNING:LEGACY + GROUP = ALL:LEGACY_S1AP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_S1AP_DEBUG DESC = S1AP legacy logs - debug level - GROUP = S1AP:DEBUG:LEGACY + GROUP = ALL:LEGACY_S1AP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_S1AP_TRACE DESC = S1AP legacy logs - trace level - GROUP = S1AP:TRACE:LEGACY + GROUP = ALL:LEGACY_S1AP:TRACE:LEGACY FORMAT = string,log ID = LEGACY_X2AP_INFO DESC = X2AP legacy logs - info level - GROUP = X2AP:INFO:LEGACY + GROUP = ALL:LEGACY_X2AP:INFO:LEGACY FORMAT = string,log ID = LEGACY_X2AP_ERROR DESC = X2AP legacy logs - error level - GROUP = X2AP:ERROR:LEGACY + GROUP = ALL:LEGACY_X2AP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_X2AP_WARNING DESC = X2AP legacy logs - warning level - GROUP = X2AP:WARNING:LEGACY + GROUP = ALL:LEGACY_X2AP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_X2AP_DEBUG DESC = X2AP legacy logs - debug level - GROUP = X2AP:DEBUG:LEGACY + GROUP = ALL:LEGACY_X2AP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_X2AP_TRACE DESC = X2AP legacy logs - trace level - GROUP = X2AP:TRACE:LEGACY + GROUP = ALL:LEGACY_X2AP:TRACE:LEGACY FORMAT = string,log ID = LEGACY_RRC_INFO DESC = RRC legacy logs - info level - GROUP = RRC:INFO:LEGACY + GROUP = ALL:LEGACY_RRC:INFO:LEGACY FORMAT = string,log ID = LEGACY_RRC_ERROR DESC = RRC legacy logs - error level - GROUP = RRC:ERROR:LEGACY + GROUP = ALL:LEGACY_RRC:ERROR:LEGACY FORMAT = string,log ID = LEGACY_RRC_WARNING DESC = RRC legacy logs - warning level - GROUP = RRC:WARNING:LEGACY + GROUP = ALL:LEGACY_RRC:WARNING:LEGACY FORMAT = string,log ID = LEGACY_RRC_DEBUG DESC = RRC legacy logs - debug level - GROUP = RRC:DEBUG:LEGACY + GROUP = ALL:LEGACY_RRC:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_RRC_TRACE DESC = RRC legacy logs - trace level - GROUP = RRC:TRACE:LEGACY + GROUP = ALL:LEGACY_RRC:TRACE:LEGACY FORMAT = string,log ID = LEGACY_RLC_INFO DESC = RLC legacy logs - info level - GROUP = RLC:INFO:LEGACY + GROUP = ALL:LEGACY_RLC:INFO:LEGACY FORMAT = string,log ID = LEGACY_RLC_ERROR DESC = RLC legacy logs - error level - GROUP = RLC:ERROR:LEGACY + GROUP = ALL:LEGACY_RLC:ERROR:LEGACY FORMAT = string,log ID = LEGACY_RLC_WARNING DESC = RLC legacy logs - warning level - GROUP = RLC:WARNING:LEGACY + GROUP = ALL:LEGACY_RLC:WARNING:LEGACY FORMAT = string,log ID = LEGACY_RLC_DEBUG DESC = RLC legacy logs - debug level - GROUP = RLC:DEBUG:LEGACY + GROUP = ALL:LEGACY_RLC:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_RLC_TRACE DESC = RLC legacy logs - trace level - GROUP = RLC:TRACE:LEGACY + GROUP = ALL:LEGACY_RLC:TRACE:LEGACY FORMAT = string,log ID = LEGACY_PDCP_INFO DESC = PDCP legacy logs - info level - GROUP = PDCP:INFO:LEGACY + GROUP = ALL:LEGACY_PDCP:INFO:LEGACY FORMAT = string,log ID = LEGACY_PDCP_ERROR DESC = PDCP legacy logs - error level - GROUP = PDCP:ERROR:LEGACY + GROUP = ALL:LEGACY_PDCP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_PDCP_WARNING DESC = PDCP legacy logs - warning level - GROUP = PDCP:WARNING:LEGACY + GROUP = ALL:LEGACY_PDCP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_PDCP_DEBUG DESC = PDCP legacy logs - debug level - GROUP = PDCP:DEBUG:LEGACY + GROUP = ALL:LEGACY_PDCP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_PDCP_TRACE DESC = PDCP legacy logs - trace level - GROUP = PDCP:TRACE:LEGACY + GROUP = ALL:LEGACY_PDCP:TRACE:LEGACY FORMAT = string,log ID = LEGACY_ENB_APP_INFO DESC = ENB_APP legacy logs - info level - GROUP = ENB_APP:INFO:LEGACY + GROUP = ALL:LEGACY_ENB_APP:INFO:LEGACY FORMAT = string,log ID = LEGACY_ENB_APP_ERROR DESC = ENB_APP legacy logs - error level - GROUP = ENB_APP:ERROR:LEGACY + GROUP = ALL:LEGACY_ENB_APP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_ENB_APP_WARNING DESC = ENB_APP legacy logs - warning level - GROUP = ENB_APP:WARNING:LEGACY + GROUP = ALL:LEGACY_ENB_APP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_ENB_APP_DEBUG DESC = ENB_APP legacy logs - debug level - GROUP = ENB_APP:DEBUG:LEGACY + GROUP = ALL:LEGACY_ENB_APP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_ENB_APP_TRACE DESC = ENB_APP legacy logs - trace level - GROUP = ENB_APP:TRACE:LEGACY + GROUP = ALL:LEGACY_ENB_APP:TRACE:LEGACY FORMAT = string,log ID = LEGACY_SCTP_INFO DESC = SCTP legacy logs - info level - GROUP = SCTP:INFO:LEGACY + GROUP = ALL:LEGACY_SCTP:INFO:LEGACY FORMAT = string,log ID = LEGACY_SCTP_ERROR DESC = SCTP legacy logs - error level - GROUP = SCTP:ERROR:LEGACY + GROUP = ALL:LEGACY_SCTP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_SCTP_WARNING DESC = SCTP legacy logs - warning level - GROUP = SCTP:WARNING:LEGACY + GROUP = ALL:LEGACY_SCTP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_SCTP_DEBUG DESC = SCTP legacy logs - debug level - GROUP = SCTP:DEBUG:LEGACY + GROUP = ALL:LEGACY_SCTP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_SCTP_TRACE DESC = SCTP legacy logs - trace level - GROUP = SCTP:TRACE:LEGACY + GROUP = ALL:LEGACY_SCTP:TRACE:LEGACY FORMAT = string,log ID = LEGACY_UDP__INFO DESC = UDP_ legacy logs - info level - GROUP = UDP_:INFO:LEGACY + GROUP = ALL:LEGACY_UDP_:INFO:LEGACY FORMAT = string,log ID = LEGACY_UDP__ERROR DESC = UDP_ legacy logs - error level - GROUP = UDP_:ERROR:LEGACY + GROUP = ALL:LEGACY_UDP_:ERROR:LEGACY FORMAT = string,log ID = LEGACY_UDP__WARNING DESC = UDP_ legacy logs - warning level - GROUP = UDP_:WARNING:LEGACY + GROUP = ALL:LEGACY_UDP_:WARNING:LEGACY FORMAT = string,log ID = LEGACY_UDP__DEBUG DESC = UDP_ legacy logs - debug level - GROUP = UDP_:DEBUG:LEGACY + GROUP = ALL:LEGACY_UDP_:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_UDP__TRACE DESC = UDP_ legacy logs - trace level - GROUP = UDP_:TRACE:LEGACY + GROUP = ALL:LEGACY_UDP_:TRACE:LEGACY FORMAT = string,log ID = LEGACY_NAS_INFO DESC = NAS legacy logs - info level - GROUP = NAS:INFO:LEGACY + GROUP = ALL:LEGACY_NAS:INFO:LEGACY FORMAT = string,log ID = LEGACY_NAS_ERROR DESC = NAS legacy logs - error level - GROUP = NAS:ERROR:LEGACY + GROUP = ALL:LEGACY_NAS:ERROR:LEGACY FORMAT = string,log ID = LEGACY_NAS_WARNING DESC = NAS legacy logs - warning level - GROUP = NAS:WARNING:LEGACY + GROUP = ALL:LEGACY_NAS:WARNING:LEGACY FORMAT = string,log ID = LEGACY_NAS_DEBUG DESC = NAS legacy logs - debug level - GROUP = NAS:DEBUG:LEGACY + GROUP = ALL:LEGACY_NAS:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_NAS_TRACE DESC = NAS legacy logs - trace level - GROUP = NAS:TRACE:LEGACY + GROUP = ALL:LEGACY_NAS:TRACE:LEGACY FORMAT = string,log ID = LEGACY_HW_INFO DESC = HW legacy logs - info level - GROUP = HW:INFO:LEGACY + GROUP = ALL:LEGACY_HW:INFO:LEGACY FORMAT = string,log ID = LEGACY_HW_ERROR DESC = HW legacy logs - error level - GROUP = HW:ERROR:LEGACY + GROUP = ALL:LEGACY_HW:ERROR:LEGACY FORMAT = string,log ID = LEGACY_HW_WARNING DESC = HW legacy logs - warning level - GROUP = HW:WARNING:LEGACY + GROUP = ALL:LEGACY_HW:WARNING:LEGACY FORMAT = string,log ID = LEGACY_HW_DEBUG DESC = HW legacy logs - debug level - GROUP = HW:DEBUG:LEGACY + GROUP = ALL:LEGACY_HW:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_HW_TRACE DESC = HW legacy logs - trace level - GROUP = HW:TRACE:LEGACY + GROUP = ALL:LEGACY_HW:TRACE:LEGACY FORMAT = string,log ID = LEGACY_EMU_INFO DESC = EMU legacy logs - info level - GROUP = EMU:INFO:LEGACY + GROUP = ALL:LEGACY_EMU:INFO:LEGACY FORMAT = string,log ID = LEGACY_EMU_ERROR DESC = EMU legacy logs - error level - GROUP = EMU:ERROR:LEGACY + GROUP = ALL:LEGACY_EMU:ERROR:LEGACY FORMAT = string,log ID = LEGACY_EMU_WARNING DESC = EMU legacy logs - warning level - GROUP = EMU:WARNING:LEGACY + GROUP = ALL:LEGACY_EMU:WARNING:LEGACY FORMAT = string,log ID = LEGACY_EMU_DEBUG DESC = EMU legacy logs - debug level - GROUP = EMU:DEBUG:LEGACY + GROUP = ALL:LEGACY_EMU:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_EMU_TRACE DESC = EMU legacy logs - trace level - GROUP = EMU:TRACE:LEGACY + GROUP = ALL:LEGACY_EMU:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OTG_INFO DESC = OTG legacy logs - info level - GROUP = OTG:INFO:LEGACY + GROUP = ALL:LEGACY_OTG:INFO:LEGACY FORMAT = string,log ID = LEGACY_OTG_ERROR DESC = OTG legacy logs - error level - GROUP = OTG:ERROR:LEGACY + GROUP = ALL:LEGACY_OTG:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OTG_WARNING DESC = OTG legacy logs - warning level - GROUP = OTG:WARNING:LEGACY + GROUP = ALL:LEGACY_OTG:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OTG_DEBUG DESC = OTG legacy logs - debug level - GROUP = OTG:DEBUG:LEGACY + GROUP = ALL:LEGACY_OTG:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OTG_TRACE DESC = OTG legacy logs - trace level - GROUP = OTG:TRACE:LEGACY + GROUP = ALL:LEGACY_OTG:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OCG_INFO DESC = OCG legacy logs - info level - GROUP = OCG:INFO:LEGACY + GROUP = ALL:LEGACY_OCG:INFO:LEGACY FORMAT = string,log ID = LEGACY_OCG_ERROR DESC = OCG legacy logs - error level - GROUP = OCG:ERROR:LEGACY + GROUP = ALL:LEGACY_OCG:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OCG_WARNING DESC = OCG legacy logs - warning level - GROUP = OCG:WARNING:LEGACY + GROUP = ALL:LEGACY_OCG:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OCG_DEBUG DESC = OCG legacy logs - debug level - GROUP = OCG:DEBUG:LEGACY + GROUP = ALL:LEGACY_OCG:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OCG_TRACE DESC = OCG legacy logs - trace level - GROUP = OCG:TRACE:LEGACY + GROUP = ALL:LEGACY_OCG:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OCM_INFO DESC = OCM legacy logs - info level - GROUP = OCM:INFO:LEGACY + GROUP = ALL:LEGACY_OCM:INFO:LEGACY FORMAT = string,log ID = LEGACY_OCM_ERROR DESC = OCM legacy logs - error level - GROUP = OCM:ERROR:LEGACY + GROUP = ALL:LEGACY_OCM:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OCM_WARNING DESC = OCM legacy logs - warning level - GROUP = OCM:WARNING:LEGACY + GROUP = ALL:LEGACY_OCM:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OCM_DEBUG DESC = OCM legacy logs - debug level - GROUP = OCM:DEBUG:LEGACY + GROUP = ALL:LEGACY_OCM:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OCM_TRACE DESC = OCM legacy logs - trace level - GROUP = OCM:TRACE:LEGACY + GROUP = ALL:LEGACY_OCM:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OIP_INFO DESC = OIP legacy logs - info level - GROUP = OIP:INFO:LEGACY + GROUP = ALL:LEGACY_OIP:INFO:LEGACY FORMAT = string,log ID = LEGACY_OIP_ERROR DESC = OIP legacy logs - error level - GROUP = OIP:ERROR:LEGACY + GROUP = ALL:LEGACY_OIP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OIP_WARNING DESC = OIP legacy logs - warning level - GROUP = OIP:WARNING:LEGACY + GROUP = ALL:LEGACY_OIP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OIP_DEBUG DESC = OIP legacy logs - debug level - GROUP = OIP:DEBUG:LEGACY + GROUP = ALL:LEGACY_OIP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OIP_TRACE DESC = OIP legacy logs - trace level - GROUP = OIP:TRACE:LEGACY + GROUP = ALL:LEGACY_OIP:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OMG_INFO DESC = OMG legacy logs - info level - GROUP = OMG:INFO:LEGACY + GROUP = ALL:LEGACY_OMG:INFO:LEGACY FORMAT = string,log ID = LEGACY_OMG_ERROR DESC = OMG legacy logs - error level - GROUP = OMG:ERROR:LEGACY + GROUP = ALL:LEGACY_OMG:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OMG_WARNING DESC = OMG legacy logs - warning level - GROUP = OMG:WARNING:LEGACY + GROUP = ALL:LEGACY_OMG:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OMG_DEBUG DESC = OMG legacy logs - debug level - GROUP = OMG:DEBUG:LEGACY + GROUP = ALL:LEGACY_OMG:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OMG_TRACE DESC = OMG legacy logs - trace level - GROUP = OMG:TRACE:LEGACY + GROUP = ALL:LEGACY_OMG:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OPT_INFO DESC = OPT legacy logs - info level - GROUP = OPT:INFO:LEGACY + GROUP = ALL:LEGACY_OPT:INFO:LEGACY FORMAT = string,log ID = LEGACY_OPT_ERROR DESC = OPT legacy logs - error level - GROUP = OPT:ERROR:LEGACY + GROUP = ALL:LEGACY_OPT:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OPT_WARNING DESC = OPT legacy logs - warning level - GROUP = OPT:WARNING:LEGACY + GROUP = ALL:LEGACY_OPT:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OPT_DEBUG DESC = OPT legacy logs - debug level - GROUP = OPT:DEBUG:LEGACY + GROUP = ALL:LEGACY_OPT:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OPT_TRACE DESC = OPT legacy logs - trace level - GROUP = OPT:TRACE:LEGACY + GROUP = ALL:LEGACY_OPT:TRACE:LEGACY FORMAT = string,log ID = LEGACY_GTPU_INFO DESC = GTPU legacy logs - info level - GROUP = GTPU:INFO:LEGACY + GROUP = ALL:LEGACY_GTPU:INFO:LEGACY FORMAT = string,log ID = LEGACY_GTPU_ERROR DESC = GTPU legacy logs - error level - GROUP = GTPU:ERROR:LEGACY + GROUP = ALL:LEGACY_GTPU:ERROR:LEGACY FORMAT = string,log ID = LEGACY_GTPU_WARNING DESC = GTPU legacy logs - warning level - GROUP = GTPU:WARNING:LEGACY + GROUP = ALL:LEGACY_GTPU:WARNING:LEGACY FORMAT = string,log ID = LEGACY_GTPU_DEBUG DESC = GTPU legacy logs - debug level - GROUP = GTPU:DEBUG:LEGACY + GROUP = ALL:LEGACY_GTPU:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_GTPU_TRACE DESC = GTPU legacy logs - trace level - GROUP = GTPU:TRACE:LEGACY + GROUP = ALL:LEGACY_GTPU:TRACE:LEGACY FORMAT = string,log ID = LEGACY_TMR_INFO DESC = TMR legacy logs - info level - GROUP = TMR:INFO:LEGACY + GROUP = ALL:LEGACY_TMR:INFO:LEGACY FORMAT = string,log ID = LEGACY_TMR_ERROR DESC = TMR legacy logs - error level - GROUP = TMR:ERROR:LEGACY + GROUP = ALL:LEGACY_TMR:ERROR:LEGACY FORMAT = string,log ID = LEGACY_TMR_WARNING DESC = TMR legacy logs - warning level - GROUP = TMR:WARNING:LEGACY + GROUP = ALL:LEGACY_TMR:WARNING:LEGACY FORMAT = string,log ID = LEGACY_TMR_DEBUG DESC = TMR legacy logs - debug level - GROUP = TMR:DEBUG:LEGACY + GROUP = ALL:LEGACY_TMR:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_TMR_TRACE DESC = TMR legacy logs - trace level - GROUP = TMR:TRACE:LEGACY + GROUP = ALL:LEGACY_TMR:TRACE:LEGACY FORMAT = string,log ID = LEGACY_OSA_INFO DESC = OSA legacy logs - info level - GROUP = OSA:INFO:LEGACY + GROUP = ALL:LEGACY_OSA:INFO:LEGACY FORMAT = string,log ID = LEGACY_OSA_ERROR DESC = OSA legacy logs - error level - GROUP = OSA:ERROR:LEGACY + GROUP = ALL:LEGACY_OSA:ERROR:LEGACY FORMAT = string,log ID = LEGACY_OSA_WARNING DESC = OSA legacy logs - warning level - GROUP = OSA:WARNING:LEGACY + GROUP = ALL:LEGACY_OSA:WARNING:LEGACY FORMAT = string,log ID = LEGACY_OSA_DEBUG DESC = OSA legacy logs - debug level - GROUP = OSA:DEBUG:LEGACY + GROUP = ALL:LEGACY_OSA:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_OSA_TRACE DESC = OSA legacy logs - trace level - GROUP = OSA:TRACE:LEGACY + GROUP = ALL:LEGACY_OSA:TRACE:LEGACY FORMAT = string,log # this is a bad hack but I won't fix (function util_print_hex_octets @@ -489,65 +489,65 @@ ID = LEGACY_OSA_TRACE # level and this funkyness is not easily dealable with, so be it...) ID = LEGACY_component_INFO DESC = component legacy logs - info level - GROUP = component:INFO:LEGACY + GROUP = ALL:LEGACY_component:INFO:LEGACY FORMAT = string,log ID = LEGACY_component_ERROR DESC = component legacy logs - error level - GROUP = component:ERROR:LEGACY + GROUP = ALL:LEGACY_component:ERROR:LEGACY FORMAT = string,log ID = LEGACY_component_WARNING DESC = component legacy logs - warning level - GROUP = component:WARNING:LEGACY + GROUP = ALL:LEGACY_component:WARNING:LEGACY FORMAT = string,log ID = LEGACY_component_DEBUG DESC = component legacy logs - debug level - GROUP = component:DEBUG:LEGACY + GROUP = ALL:LEGACY_component:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_component_TRACE DESC = component legacy logs - trace level - GROUP = component:TRACE:LEGACY + GROUP = ALL:LEGACY_component:TRACE:LEGACY FORMAT = string,log ID = LEGACY_componentP_INFO DESC = componentP legacy logs - info level - GROUP = componentP:INFO:LEGACY + GROUP = ALL:LEGACY_componentP:INFO:LEGACY FORMAT = string,log ID = LEGACY_componentP_ERROR DESC = componentP legacy logs - error level - GROUP = componentP:ERROR:LEGACY + GROUP = ALL:LEGACY_componentP:ERROR:LEGACY FORMAT = string,log ID = LEGACY_componentP_WARNING DESC = componentP legacy logs - warning level - GROUP = componentP:WARNING:LEGACY + GROUP = ALL:LEGACY_componentP:WARNING:LEGACY FORMAT = string,log ID = LEGACY_componentP_DEBUG DESC = componentP legacy logs - debug level - GROUP = componentP:DEBUG:LEGACY + GROUP = ALL:LEGACY_componentP:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_componentP_TRACE DESC = componentP legacy logs - trace level - GROUP = componentP:TRACE:LEGACY + GROUP = ALL:LEGACY_componentP:TRACE:LEGACY FORMAT = string,log #needed? ID = LEGACY_CLI_INFO DESC = CLI legacy logs - info level - GROUP = CLI:INFO:LEGACY + GROUP = ALL:LEGACY_CLI:INFO:LEGACY FORMAT = string,log ID = LEGACY_CLI_ERROR DESC = CLI legacy logs - error level - GROUP = CLI:ERROR:LEGACY + GROUP = ALL:LEGACY_CLI:ERROR:LEGACY FORMAT = string,log ID = LEGACY_CLI_WARNING DESC = CLI legacy logs - warning level - GROUP = CLI:WARNING:LEGACY + GROUP = ALL:LEGACY_CLI:WARNING:LEGACY FORMAT = string,log ID = LEGACY_CLI_DEBUG DESC = CLI legacy logs - debug level - GROUP = CLI:DEBUG:LEGACY + GROUP = ALL:LEGACY_CLI:DEBUG:LEGACY FORMAT = string,log ID = LEGACY_CLI_TRACE DESC = CLI legacy logs - trace level - GROUP = CLI:TRACE:LEGACY + GROUP = ALL:LEGACY_CLI:TRACE:LEGACY FORMAT = string,log #for debug/test - not used From deefb1854faa7e26eec45916517a37585a658772 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 15:21:52 +0200 Subject: [PATCH 098/217] delete children widget --- common/utils/T/tracer/gui/container.c | 20 +++++++ common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/gui_defs.h | 3 ++ common/utils/T/tracer/gui/widget.c | 77 ++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 3dfcef2e2c..3ec408ecd7 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -18,6 +18,7 @@ static void add_child(gui *g, widget *_this, widget *child, int position) { LOGD("ADD_CHILD container\n"); struct container_widget *this = _this; + this->hints_are_valid = 0; widget_add_child_internal(g, this, child, position); @@ -35,6 +36,24 @@ static void add_child(gui *g, widget *_this, widget *child, int position) this->nchildren++; } +static void del_child(gui *g, widget *_this, widget *child) +{ + LOGD("DEL_CHILD container\n"); + struct container_widget *this = _this; + int position = widget_get_child_position(g, _this, child); + + this->hints_are_valid = 0; + widget_del_child_internal(g, this, child); + + memmove(this->growable + position, this->growable + position+1, + (this->nchildren - position - 1) * sizeof(int)); + + this->growable = realloc(this->growable, (this->nchildren-1)*sizeof(int)); + if (this->growable == NULL) abort(); + + this->nchildren--; +} + static void compute_vertical_hints(struct gui *g, struct container_widget *this) { @@ -271,6 +290,7 @@ widget *new_container(gui *_gui, int vertical) w->common.paint = paint; w->common.add_child = add_child; + w->common.del_child = del_child; w->common.repack = repack; if (vertical) { diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index aa89a53c75..2561fe6d16 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -16,6 +16,7 @@ gui *gui_init(void); /* position = -1 to put at the end */ void widget_add_child(gui *gui, widget *parent, widget *child, int position); +void widget_del_child(gui *gui, widget *parent, widget *child); void widget_dirty(gui *gui, widget *this); widget *new_toplevel_window(gui *gui, int width, int height, char *title); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index afc590c7be..bca856d5ea 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -46,6 +46,7 @@ struct widget { struct widget *parent; void (*repack)(gui *g, widget *this); void (*add_child)(gui *g, widget *this, widget *child, int position); + void (*del_child)(gui *g, widget *this, widget *child); void (*allocate)(gui *g, widget *this, int x, int y, int width, int height); void (*hints)(gui *g, widget *this, int *width, int *height); void (*paint)(gui *g, widget *this); @@ -197,6 +198,8 @@ struct gui { widget *new_widget(struct gui *g, enum widget_type type, int size); void widget_add_child_internal( gui *_gui, widget *parent, widget *child, int position); +void widget_del_child_internal(gui *_gui, widget *parent, widget *child); +int widget_get_child_position(gui *_gui, widget *parent, widget *child); const char *widget_name(enum widget_type type); diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 8411a4602f..76e303fbe9 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -12,6 +12,7 @@ static void default_allocate( gui *gui, widget *_this, int x, int y, int width, int height); static void default_add_child( gui *_gui, widget *_this, widget *child, int position); +static void default_del_child(gui *_gui, widget *_this, widget *child); static void default_hints(gui *g, widget *this, int *width, int *height); static void default_button(gui *gui, widget *_this, int x, int y, int button, int up); @@ -47,6 +48,7 @@ widget *new_widget(struct gui *g, enum widget_type type, int size) ret->clear = default_clear; ret->repack = default_repack; ret->add_child = default_add_child; + ret->del_child = default_del_child; ret->allocate = default_allocate; ret->hints = default_hints; ret->button = default_button; @@ -121,6 +123,65 @@ repack: send_event(_gui, REPACK, p->id); } +void widget_del_child_internal(gui *_gui, widget *parent, widget *child) +{ + struct widget *p = parent; + struct widget *c = child; + struct widget_list *prev, *cur; + int i; + + c->parent = NULL; + + prev = NULL; + cur = p->children; + + while (cur != NULL && cur->item != c) { + prev = cur; + cur = cur->next; + } + + if (cur == NULL) ERR("child not found\n"); + + if (prev == NULL) { + /* child is at head */ + p->children = cur->next; + if (p->children != NULL) p->children->last = cur->last; + goto done; + } + + if (cur->next == NULL) { + /* child is last (and prev is != NULL) */ + prev->next = NULL; + p->children->last = prev; + goto done; + } + + /* child is between two existing items */ + prev->next = cur->next; + +done: + free(cur); + send_event(_gui, REPACK, p->id); +} + +int widget_get_child_position(gui *_gui, widget *parent, widget *child) +{ + struct widget *p = parent; + struct widget *c = child; + struct widget_list *cur; + int i = 0; + + cur = p->children; + + while (cur != NULL && cur->item != c) { + cur = cur->next; + i++; + } + + if (cur == NULL) return -1; + return i; +} + /*************************************************************************/ /* default functions */ /*************************************************************************/ @@ -140,12 +201,18 @@ static void default_repack(gui *gui, widget *_this) } static void default_add_child( - gui *_gui, widget *_this, widget *child, int position) + gui *_gui, widget *_this, widget *child, int position) { struct widget *this = _this; WARN("cannot add child to widget %s\n", widget_name(this->type)); } +static void default_del_child( gui *_gui, widget *_this, widget *child) +{ + struct widget *this = _this; + WARN("cannot del child from widget %s\n", widget_name(this->type)); +} + static void default_allocate( gui *gui, widget *_this, int x, int y, int width, int height) { @@ -180,6 +247,14 @@ void widget_add_child(gui *_gui, widget *parent, widget *child, int position) gunlock(_gui); } +void widget_del_child(gui *_gui, widget *parent, widget *child) +{ + struct widget *this = parent; + glock(_gui); + this->del_child(_gui, parent, child); + gunlock(_gui); +} + void widget_dirty(gui *_gui, widget *_this) { struct gui *g = _gui; From d4a4bba32ee501e88e88418590d7b2265e8c56a9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 15:55:24 +0200 Subject: [PATCH 099/217] minor fix - remove unused variable --- common/utils/T/tracer/gui/widget.c | 1 - 1 file changed, 1 deletion(-) diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 76e303fbe9..6277556333 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -128,7 +128,6 @@ void widget_del_child_internal(gui *_gui, widget *parent, widget *child) struct widget *p = parent; struct widget *c = child; struct widget_list *prev, *cur; - int i; c->parent = NULL; From 8f50b77e30502403708455e2313d5339f8922592 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 15:56:06 +0200 Subject: [PATCH 100/217] make label clickable (the user has to ask for it, it's non-clickable by default) --- common/utils/T/tracer/gui/gui.h | 4 ++++ common/utils/T/tracer/gui/label.c | 34 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 2561fe6d16..9d7f283ea1 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -26,6 +26,8 @@ widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); widget *new_textlist(gui *_gui, int width, int nlines, int background_color); +void label_set_clickable(gui *gui, widget *label, int clickable); + void container_set_child_growable(gui *_gui, widget *_this, widget *child, int growable); @@ -60,6 +62,8 @@ int new_color(gui *gui, char *color); * - scrollup { void *: NULL } * - scrolldown { void *: NULL } * - click { int [2]: line, button } + * - label: + * - click { int: button } (if enabled) */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/label.c b/common/utils/T/tracer/gui/label.c index 35b4f7b667..80d885f1d2 100644 --- a/common/utils/T/tracer/gui/label.c +++ b/common/utils/T/tracer/gui/label.c @@ -44,3 +44,37 @@ widget *new_label(gui *_gui, const char *label) return w; } + +static void button(gui *gui, widget *_this, int x, int y, int button, int up) +{ + LOGD("BUTTON label %p xy %d %d button %d up %d\n", _this, x, y, button, up); + + if (up != 0) return; + + gui_notify(gui, "click", _this, &button); +} + +/* we could use default_button, but it's in widget.c, so, well... */ +static void no_button(gui *gui, widget *_this, int x,int y,int button,int up) +{ + /* do nothing */ +} + +/*************************************************************************/ +/* public functions */ +/*************************************************************************/ + +void label_set_clickable(gui *_g, widget *_this, int clickable) +{ + struct gui *g = _g; + struct label_widget *this = _this; + + glock(g); + + if (clickable) + this->common.button = button; + else + this->common.button = no_button; + + gunlock(g); +} From e299a7e4d3f75355c263a3ccaa8dd4833dc5d919 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 16:04:16 +0200 Subject: [PATCH 101/217] bugfix - it may be that the container has only one child when we delete it --- common/utils/T/tracer/gui/container.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 3ec408ecd7..344f864382 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -49,7 +49,7 @@ static void del_child(gui *g, widget *_this, widget *child) (this->nchildren - position - 1) * sizeof(int)); this->growable = realloc(this->growable, (this->nchildren-1)*sizeof(int)); - if (this->growable == NULL) abort(); + if (this->nchildren != 1 && this->growable == NULL) abort(); this->nchildren--; } From a74f8659179c7d305e9449bf060f5432dbd5cff0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 17:13:38 +0200 Subject: [PATCH 102/217] more logical handling of x/y in button events click at x/y refers to the toplevel window and the widget knows its own x/y position, so let's keep the x/y of the click as is and let the down widget handle translation by itself something like that --- common/utils/T/tracer/gui/container.c | 4 ++-- common/utils/T/tracer/gui/textlist.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 344f864382..d3ce2a110b 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -237,7 +237,7 @@ static void horizontal_button(gui *_g, widget *_this, int x, int y, l = this->common.children; while (l) { if (l->item->x <= x && x < l->item->x + l->item->width) { - l->item->button(g, l->item, x - l->item->x, y, button, up); + l->item->button(g, l->item, x, y, button, up); break; } l = l->next; @@ -255,7 +255,7 @@ static void vertical_button(gui *_g, widget *_this, int x, int y, l = this->common.children; while (l) { if (l->item->y <= y && y < l->item->y + l->item->height) { - l->item->button(g, l->item, x, y - l->item->y, button, up); + l->item->button(g, l->item, x, y, button, up); break; } l = l->next; diff --git a/common/utils/T/tracer/gui/textlist.c b/common/utils/T/tracer/gui/textlist.c index 9244b8c9bf..50a21cd459 100644 --- a/common/utils/T/tracer/gui/textlist.c +++ b/common/utils/T/tracer/gui/textlist.c @@ -49,6 +49,8 @@ static void button(gui *_g, widget *_this, int x, int y, int button, int up) struct gui *g = _g; struct textlist_widget *this = _this; LOGD("BUTTON textlist %p xy %d %d button %d up %d\n", _this, x, y, button, up); + y -= this->common.y; + x -= this->common.x; /* scroll up */ if (button == 4 && up == 0) { gui_notify(g, "scrollup", _this, NULL); From 16e17d346f9b59ea152efb4e8111a8eeaff33a75 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 17:27:32 +0200 Subject: [PATCH 103/217] positioner widget - the child is positioned in the middle, does not grow --- common/utils/T/tracer/gui/Makefile | 2 +- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/gui_defs.h | 6 +- common/utils/T/tracer/gui/positioner.c | 92 ++++++++++++++++++++++++++ common/utils/T/tracer/gui/widget.c | 4 +- 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 common/utils/T/tracer/gui/positioner.c diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index adec8fdd79..b64af3bd18 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ - gui.o label.o event.o xy_plot.o textlist.o notify.o + gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 9d7f283ea1..92f336ada7 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -21,6 +21,7 @@ void widget_dirty(gui *gui, widget *this); widget *new_toplevel_window(gui *gui, int width, int height, char *title); widget *new_container(gui *gui, int vertical); +widget *new_positioner(gui *gui); widget *new_label(gui *gui, const char *text); widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index bca856d5ea..463d9bf8a0 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -30,7 +30,7 @@ extern int volatile gui_logd; /*************************************************************************/ enum widget_type { - TOPLEVEL_WINDOW, CONTAINER, TEXT_LIST, XY_PLOT, BUTTON, LABEL + TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL }; struct widget_list; @@ -77,6 +77,10 @@ struct container_widget { int nchildren; }; +struct positioner_widget { + struct widget common; +}; + struct textlist_widget { struct widget common; char **text; diff --git a/common/utils/T/tracer/gui/positioner.c b/common/utils/T/tracer/gui/positioner.c new file mode 100644 index 0000000000..5bd23e147e --- /dev/null +++ b/common/utils/T/tracer/gui/positioner.c @@ -0,0 +1,92 @@ +#include "gui.h" +#include "gui_defs.h" +#include +#include +#include + +static void add_child(gui *g, widget *_this, widget *child, int position) +{ + LOGD("ADD_CHILD positioner\n"); + struct positioner_widget *this = _this; + widget_add_child_internal(g, this, child, position); +} + +static void del_child(gui *g, widget *_this, widget *child) +{ + LOGD("DEL_CHILD positioner\n"); + struct positioner_widget *this = _this; + widget_del_child_internal(g, this, child); +} + +static void allocate( + gui *_g, widget *_this, int x, int y, int width, int height) +{ + LOGD("ALLOCATE positioner %p\n", _this); + struct gui *g = _g; + struct positioner_widget *this = _this; + struct widget_list *l = this->common.children; + int cwidth, cheight; + + this->common.x = x; + this->common.y = y; + this->common.width = width; + this->common.height = height; + + if (l != NULL) { + l->item->hints(g, l->item, &cwidth, &cheight); + l->item->allocate(g, l->item, x+(width-cwidth)/2, y+(height-cheight)/2, + cwidth, cheight); + } +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + LOGD("HINTS positioner %p\n", _w); + struct gui *g = _gui; + struct positioner_widget *this = _w; + struct widget_list *l = this->common.children; + if (l != NULL) + l->item->hints(g, l->item, width, height); + else { *width = *height = 1; } +} + +static void button(gui *_g, widget *_this, int x, int y, int button, int up) +{ + LOGD("BUTTON positioner %p xy %d %d button %d up %d\n", _this, x, y, button, up); + struct gui *g = _g; + struct positioner_widget *this = _this; + struct widget_list *l = this->common.children; + if (l != NULL) + l->item->button(g, l->item, x, y, button, up); +} + +static void paint(gui *_gui, widget *_this) +{ + LOGD("PAINT positioner\n"); + struct gui *g = _gui; + struct widget *this = _this; + struct widget_list *l = this->children; + if (l != NULL) + l->item->paint(g, l->item); +} + +widget *new_positioner(gui *_gui) +{ + struct gui *g = _gui; + struct positioner_widget *w; + + glock(g); + + w = new_widget(g, POSITIONER, sizeof(struct positioner_widget)); + + w->common.paint = paint; + w->common.add_child = add_child; + w->common.del_child = del_child; + w->common.allocate = allocate; + w->common.hints = hints; + w->common.button = button; + + gunlock(g); + + return w; +} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 6277556333..db8a754a70 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -264,7 +264,8 @@ void widget_dirty(gui *_gui, widget *_this) } static const char *names[] = { - "TOPLEVEL_WINDOW", "CONTAINER", "TEXT_LIST", "XY_PLOT", "BUTTON", "LABEL" + "TOPLEVEL_WINDOW", "CONTAINER", "POSITIONER", "TEXT_LIST", + "XY_PLOT", "BUTTON", "LABEL" }; const char *widget_name(enum widget_type type) { @@ -272,6 +273,7 @@ const char *widget_name(enum widget_type type) default: break; case TOPLEVEL_WINDOW: case CONTAINER: + case POSITIONER: case TEXT_LIST: case XY_PLOT: case BUTTON: From 277ddb139d8a83611d1959491cdd46c30eaeeb60 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 4 May 2016 17:54:00 +0200 Subject: [PATCH 104/217] middle button to toggle event reception in event selector window --- common/utils/T/tracer/event_selector.c | 65 +++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index 833939ff5d..bc1f25f4b7 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -16,6 +16,11 @@ struct event_selector { int nevents; int ngroups; int socket; + int paused; + /* those three widgets used to pause/unpause reception of events */ + widget *parent_widget; + widget *normal_widget; + widget *pause_widget; }; static void scroll(void *private, gui *g, @@ -54,6 +59,46 @@ static void click(void *private, gui *g, int i; char t; + /* notification_data depends on the kind of widget */ + if (w == this->pause_widget) { + line = 0; + button = d[0]; + } else { + line = d[0]; + button = d[1]; + } + + /* middle-button toggles - redo with SPACE when keyboard is processed */ + if (button == 2) { + if (this->paused == 0) { + widget_del_child(g, this->parent_widget, this->normal_widget); + widget_add_child(g, this->parent_widget, this->pause_widget, 0); + container_set_child_growable(g, this->parent_widget, + this->pause_widget, 1); + /* pause */ + t = 1; + socket_send(this->socket, &t, 1); + socket_send(this->socket, &this->nevents, sizeof(int)); + set_on = 0; + for (i = 0; i < this->nevents; i++) + socket_send(this->socket, &set_on, sizeof(int)); + } else { + widget_del_child(g, this->parent_widget, this->pause_widget); + widget_add_child(g, this->parent_widget, this->normal_widget, 0); + container_set_child_growable(g, this->parent_widget, + this->normal_widget, 1); + /* un-pause */ + t = 1; + socket_send(this->socket, &t, 1); + socket_send(this->socket, &this->nevents, sizeof(int)); + socket_send(this->socket, this->is_on, this->nevents * sizeof(int)); + } + this->paused = 1 - this->paused; + return; + } + + if (w == this->pause_widget) return; + if (button != 1 && button != 3) return; if (button == 1) set_on = 1; else set_on = 0; @@ -87,10 +132,12 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, { struct event_selector *ret; widget *win; + widget *win_container; widget *main_container; widget *container; widget *left, *right; widget *events, *groups; + widget *pause_container; char **ids; char **gps; int n; @@ -103,8 +150,12 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, green = new_color(g, "#2f9e2a"); win = new_toplevel_window(g, 470, 300, "event selector"); + win_container = new_container(g, VERTICAL); + widget_add_child(g, win, win_container, -1); + main_container = new_container(g, VERTICAL); - widget_add_child(g, win, main_container, -1); + widget_add_child(g, win_container, main_container, -1); + container_set_child_growable(g, win_container, main_container, 1); container = new_container(g, HORIZONTAL); widget_add_child(g, main_container, container, -1); @@ -132,6 +183,12 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, container_set_child_growable(g, left, events, 1); container_set_child_growable(g, right, groups, 1); + pause_container = new_positioner(g); + widget_add_child(g, pause_container, + new_label(g, + "events' reception paused - click middle button to resume"), -1); + label_set_clickable(g, pause_container, 1); + n = database_get_ids(database, &ids); for (i = 0; i < n; i++) { textlist_add(g, events, ids[i], -1, @@ -158,6 +215,10 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, ret->database = database; ret->socket = socket; + ret->parent_widget = win_container; + ret->normal_widget = main_container; + ret->pause_widget = pause_container; + register_notifier(g, "scrollup", events, scroll, ret); register_notifier(g, "scrolldown", events, scroll, ret); register_notifier(g, "click", events, click, ret); @@ -166,5 +227,7 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, register_notifier(g, "scrolldown", groups, scroll, ret); register_notifier(g, "click", groups, click, ret); + register_notifier(g, "click", pause_container, click, ret); + return ret; } From 32b2264fbda72ed4ecbfecf93c9962af05f8802f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 9 May 2016 12:13:18 +0200 Subject: [PATCH 105/217] support multiple plot per xy_plot --- common/utils/T/tracer/gui.c | 3 +- common/utils/T/tracer/gui/gui.h | 3 +- common/utils/T/tracer/gui/gui_defs.h | 10 +++- common/utils/T/tracer/gui/xy_plot.c | 80 +++++++++++++++++++--------- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/common/utils/T/tracer/gui.c b/common/utils/T/tracer/gui.c index 2963e4c348..46e06d2e1f 100644 --- a/common/utils/T/tracer/gui.c +++ b/common/utils/T/tracer/gui.c @@ -55,7 +55,7 @@ static void *input_signal_plotter(void *_) iqbuf[2*i+1]*iqbuf[2*i+1])); } - xy_plot_set_points(eNB_data.g, eNB_data.input_signal, + xy_plot_set_points(eNB_data.g, eNB_data.input_signal, 0, length, x, y); if (pthread_mutex_unlock(&eNB_data.input_signal_lock)) abort(); @@ -70,6 +70,7 @@ void t_gui_start(void) widget *plot = new_xy_plot(g, 512, 100, "eNB 0 input signal", 20); widget_add_child(g, win, plot, -1); xy_plot_set_range(g, plot, 0, 76800, 30, 70); + xy_plot_new_plot(g, plot, FOREGROUND_COLOR); eNB_data.input_signal = plot; eNB_data.input_signal_length = 76800 * 4; diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 92f336ada7..78507f7f4f 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -32,10 +32,11 @@ void label_set_clickable(gui *gui, widget *label, int clickable); void container_set_child_growable(gui *_gui, widget *_this, widget *child, int growable); +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_set_points(gui *gui, widget *this, - int npoints, float *x, float *y); + int plot, int npoints, float *x, float *y); void textlist_add(gui *gui, widget *this, const char *text, int position, int color); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 463d9bf8a0..dd76922179 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -95,11 +95,15 @@ struct textlist_widget { int background_color; }; -struct xy_plot_widget { - struct widget common; +struct xy_plot_plot { float *x; float *y; int npoints; + int color; +}; + +struct xy_plot_widget { + struct widget common; char *label; int label_width; int label_height; @@ -109,6 +113,8 @@ struct xy_plot_widget { float ymin, ymax; int wanted_width; int wanted_height; + struct xy_plot_plot *plots; + int nplots; }; struct button_widget { diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index c1ca608f49..ca17fb4eab 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -21,6 +21,7 @@ static void paint(gui *_gui, widget *_this) float allocated_ymin, allocated_ymax; float center; int i; + int n; # define FLIP(v) (-(v) + allocated_plot_height-1) @@ -134,23 +135,25 @@ static void paint(gui *_gui, widget *_this) + this->label_baseline, this->label); - /* points */ - float ax, bx, ay, by; - ax = (allocated_plot_width-1) / (allocated_xmax - allocated_xmin); - bx = -ax * allocated_xmin; - ay = (allocated_plot_height-1) / (allocated_ymax - allocated_ymin); - by = -ay * allocated_ymin; - for (i = 0; i < this->npoints; i++) { - int x, y; - x = ax * this->x[i] + bx; - y = ay * this->y[i] + by; - if (x >= 0 && x < allocated_plot_width && - y >= 0 && y < allocated_plot_height) - x_add_point(g->x, - this->common.x + this->vrule_width + x, - this->common.y + FLIP(y)); + for (n = 0; n < this->nplots; n++) { + /* points */ + float ax, bx, ay, by; + ax = (allocated_plot_width-1) / (allocated_xmax - allocated_xmin); + bx = -ax * allocated_xmin; + ay = (allocated_plot_height-1) / (allocated_ymax - allocated_ymin); + by = -ay * allocated_ymin; + for (i = 0; i < this->plots[n].npoints; i++) { + int x, y; + x = ax * this->plots[n].x[i] + bx; + y = ay * this->plots[n].y[i] + by; + if (x >= 0 && x < allocated_plot_width && + y >= 0 && y < allocated_plot_height) + x_add_point(g->x, + this->common.x + this->vrule_width + x, + this->common.y + FLIP(y)); + } + x_plot_points(g->x, g->xwin, this->plots[n].color); } - x_plot_points(g->x, g->xwin, FOREGROUND_COLOR); } static void hints(gui *_gui, widget *_w, int *width, int *height) @@ -186,6 +189,8 @@ widget *new_xy_plot(gui *_gui, int width, int height, char *label, w->xmax = 1; w->ymin = -1; w->ymax = 1; + w->plots = NULL; + w->nplots = 0; w->common.paint = paint; w->common.hints = hints; @@ -199,6 +204,31 @@ widget *new_xy_plot(gui *_gui, int width, int height, char *label, /* public functions */ /*************************************************************************/ +int xy_plot_new_plot(gui *_gui, widget *_this, int color) +{ + int ret; + struct gui *g = _gui; + struct xy_plot_widget *this = _this; + + glock(g); + + ret = this->nplots; + + this->nplots++; + this->plots = realloc(this->plots, + this->nplots * sizeof(struct xy_plot_plot)); + if (this->plots == NULL) abort(); + + this->plots[ret].x = NULL; + this->plots[ret].y = NULL; + this->plots[ret].npoints = 0; + this->plots[ret].color = color; + + gunlock(g); + + return ret; +} + void xy_plot_set_range(gui *_gui, widget *_this, float xmin, float xmax, float ymin, float ymax) { @@ -217,7 +247,7 @@ void xy_plot_set_range(gui *_gui, widget *_this, gunlock(g); } -void xy_plot_set_points(gui *_gui, widget *_this, +void xy_plot_set_points(gui *_gui, widget *_this, int plot, int npoints, float *x, float *y) { struct gui *g = _gui; @@ -225,16 +255,16 @@ void xy_plot_set_points(gui *_gui, widget *_this, glock(g); - if (npoints != this->npoints) { - free(this->x); - free(this->y); - this->x = calloc(sizeof(float), npoints); - this->y = calloc(sizeof(float), npoints); - this->npoints = npoints; + if (npoints != this->plots[plot].npoints) { + free(this->plots[plot].x); + free(this->plots[plot].y); + this->plots[plot].x = calloc(sizeof(float), npoints); + this->plots[plot].y = calloc(sizeof(float), npoints); + this->plots[plot].npoints = npoints; } - memcpy(this->x, x, npoints * sizeof(float)); - memcpy(this->y, y, npoints * sizeof(float)); + memcpy(this->plots[plot].x, x, npoints * sizeof(float)); + memcpy(this->plots[plot].y, y, npoints * sizeof(float)); send_event(g, DIRTY, this->common.id); From 8195e42d756a2d3b460411fcc23f76cf7c289524 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 9 May 2016 16:38:08 +0200 Subject: [PATCH 106/217] preliminary work on frame logger not tested --- common/utils/T/tracer/logger/Makefile | 2 +- common/utils/T/tracer/logger/framelog.c | 122 ++++++++++++++++++++++++ common/utils/T/tracer/logger/framelog.h | 13 +++ common/utils/T/tracer/view/view.h | 1 + 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/logger/framelog.c create mode 100644 common/utils/T/tracer/logger/framelog.h diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile index 1b4c3b1d28..f9416f0dff 100644 --- a/common/utils/T/tracer/logger/Makefile +++ b/common/utils/T/tracer/logger/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=textlog.o +OBJS=textlog.o framelog.o logger.a: $(OBJS) ar cr logger.a $(OBJS) diff --git a/common/utils/T/tracer/logger/framelog.c b/common/utils/T/tracer/logger/framelog.c new file mode 100644 index 0000000000..3a5f17e0bc --- /dev/null +++ b/common/utils/T/tracer/logger/framelog.c @@ -0,0 +1,122 @@ +#include "framelog.h" +#include "handler.h" +#include "database.h" +#include +#include +#include +#include + +struct framelog { + char *event_name; + void *database; + unsigned long handler_id; + int subframe_arg; + int buffer_arg; + /* list of views */ + view **v; + int vsize; + float *x; + float *buffer; + int blength; +}; + +static void _event(void *p, event e) +{ + struct framelog *l = p; + int i; + int subframe; + void *buffer; + int bsize; + int nsamples; + + subframe = e.e[l->subframe_arg].i; + buffer = e.e[l->buffer_arg].b; + bsize = e.e[l->buffer_arg].bsize; + + nsamples = bsize / (2*sizeof(int16_t)); + + if (l->blength != nsamples * 10) { + l->blength = nsamples * 10; + free(l->x); + free(l->buffer); + l->x = calloc(sizeof(float), l->blength); + if (l->x == NULL) abort(); + l->buffer = calloc(sizeof(float), l->blength); + if (l->buffer == NULL) abort(); + /* update 'x' */ + for (i = 0; i < l->blength; i++) + l->x[i] = i; + /* update 'length' of views */ + for (i = 0; i < l->vsize; i++) + l->v[i]->set(l->v[i], "length", l->blength); + } + + /* TODO: compute the LOGs in the plotter (too much useless computations) */ + for (i = 0; i < nsamples; i++) { + int I = ((int16_t *)buffer)[i*2]; + int Q = ((int16_t *)buffer)[i*2+1]; + l->buffer[subframe * nsamples + i] = 10*log10(1.0+(float)(I*I+Q*Q)); + } + + if (subframe == 9) + for (i = 0; i < l->vsize; i++) + l->v[i]->append(l->v[i], l->x, l->buffer, l->blength); +} + +framelog *new_framelog(event_handler *h, void *database, + char *event_name, char *subframe_varname, char *buffer_varname) +{ + struct framelog *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct framelog)); if (ret == NULL) abort(); + + ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->handler_id = register_handler_function(h, event_id, _event, ret); + + f = get_format(database, event_id); + + /* look for subframe and buffer args */ + ret->subframe_arg = -1; + ret->buffer_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], subframe_varname)) ret->subframe_arg = i; + if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i; + } + if (ret->subframe_arg == -1) { + printf("%s:%d: subframe argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, subframe_varname, event_name); + abort(); + } + 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->subframe_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, subframe_varname); + 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; +} + +void framelog_add_view(framelog *_l, view *v) +{ + struct framelog *l = _l; + l->vsize++; + l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); + l->v[l->vsize-1] = v; +} diff --git a/common/utils/T/tracer/logger/framelog.h b/common/utils/T/tracer/logger/framelog.h new file mode 100644 index 0000000000..a7b3d0d21d --- /dev/null +++ b/common/utils/T/tracer/logger/framelog.h @@ -0,0 +1,13 @@ +#ifndef _FRAMELOG_H_ +#define _FRAMELOG_H_ + +typedef void framelog; + +framelog *new_framelog(void *event_handler, void *database, + char *event_name, char *subframe_varname, char *buffer_varname); + +#include "view/view.h" + +void framelog_add_view(framelog *l, view *v); + +#endif /* _FRAMELOG_H_ */ diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index a5855b1098..9f3306538a 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -8,6 +8,7 @@ typedef struct view { void (*clear)(struct view *this); void (*append)(struct view *this, ...); + void (*set)(struct view *this, char *name, ...); } view; view *new_view_stdout(void); From 497c64a96482b25fc15925fe7d4134dcb2bc1bf4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 9 May 2016 18:26:03 +0200 Subject: [PATCH 107/217] XY view --- common/utils/T/tracer/view/Makefile | 2 +- common/utils/T/tracer/view/view.h | 2 + common/utils/T/tracer/view/xy.c | 116 ++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/view/xy.c diff --git a/common/utils/T/tracer/view/Makefile b/common/utils/T/tracer/view/Makefile index bcf49d15cb..10fd21cd28 100644 --- a/common/utils/T/tracer/view/Makefile +++ b/common/utils/T/tracer/view/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=stdout.o textlist.o +OBJS=stdout.o textlist.o xy.o view.a: $(OBJS) ar cr view.a $(OBJS) diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 9f3306538a..7a125cd567 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -13,5 +13,7 @@ typedef struct view { 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); #endif /* _VIEW_H_ */ diff --git a/common/utils/T/tracer/view/xy.c b/common/utils/T/tracer/view/xy.c new file mode 100644 index 0000000000..b027472a73 --- /dev/null +++ b/common/utils/T/tracer/view/xy.c @@ -0,0 +1,116 @@ +#include "view.h" +#include "../utils.h" +#include +#include +#include +#include +#include + +struct xy { + view common; + gui *g; + widget *w; + int plot; + float refresh_rate; + pthread_mutex_t lock; + int length; + float *x; + float *y; + int insert_point; +}; + +static void *xy_thread(void *_this) +{ + struct xy *this = _this; + + while (1) { + if (pthread_mutex_lock(&this->lock)) abort(); + xy_plot_set_points(this->g, this->w, this->plot, + this->length, this->x, this->y); + if (pthread_mutex_unlock(&this->lock)) abort(); + sleepms(1000/this->refresh_rate); + } + + return 0; +} + +static void clear(view *this) +{ + /* TODO */ +} + +static void append(view *_this, float *x, float *y, int length) +{ + struct xy *this = (struct xy *)_this; + int i; + int ip; + + if (pthread_mutex_lock(&this->lock)) abort(); + + ip = this->insert_point; + + /* TODO: optimize the copy */ + for (i = 0; i < length; i++) { + this->x[ip] = x[i]; + this->y[ip] = y[i]; + ip++; if (ip == this->length) ip = 0; + } + + this->insert_point = ip; + + if (pthread_mutex_unlock(&this->lock)) abort(); +} + +static void set(view *_this, char *name, ...) +{ + struct xy *this = (struct xy *)_this; + va_list ap; + + if (!strcmp(name, "length")) { + if (pthread_mutex_lock(&this->lock)) abort(); + + va_start(ap, name); + + free(this->x); + free(this->y); + this->length = va_arg(ap, int); + this->x = calloc(sizeof(float), this->length); if (this->x==NULL)abort(); + this->y = calloc(sizeof(float), this->length); if (this->y==NULL)abort(); + this->insert_point = 0; + + va_end(ap); + + if (pthread_mutex_unlock(&this->lock)) abort(); + return; + } + + printf("%s:%d: unkown setting '%s'\n", __FILE__, __LINE__, name); + abort(); +} + +view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, + int color) +{ + struct xy *ret = calloc(1, sizeof(struct xy)); + if (ret == NULL) abort(); + + ret->common.clear = clear; + ret->common.append = (void (*)(view *, ...))append; + ret->common.set = set; + + ret->refresh_rate = refresh_rate; + ret->g = g; + ret->w = w; + ret->plot = xy_plot_new_plot(g, w, color); + + ret->length = length; + ret->x = calloc(sizeof(float), length); if (ret->x == NULL) abort(); + ret->y = calloc(sizeof(float), length); if (ret->y == NULL) abort(); + ret->insert_point = 0; + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + + new_thread(xy_thread, ret); + + return (view *)ret; +} From b04a448b627337b867a27c8b8f7f2d197f55d11c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 10 May 2016 10:01:45 +0200 Subject: [PATCH 108/217] bugfix: calloc arguments' wrong order --- common/utils/T/tracer/gui/xy_plot.c | 4 ++-- common/utils/T/tracer/logger/framelog.c | 4 ++-- common/utils/T/tracer/view/xy.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index ca17fb4eab..4c1a9e1034 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -258,8 +258,8 @@ void xy_plot_set_points(gui *_gui, widget *_this, int plot, if (npoints != this->plots[plot].npoints) { free(this->plots[plot].x); free(this->plots[plot].y); - this->plots[plot].x = calloc(sizeof(float), npoints); - this->plots[plot].y = calloc(sizeof(float), npoints); + this->plots[plot].x = calloc(npoints, sizeof(float)); + this->plots[plot].y = calloc(npoints, sizeof(float)); this->plots[plot].npoints = npoints; } diff --git a/common/utils/T/tracer/logger/framelog.c b/common/utils/T/tracer/logger/framelog.c index 3a5f17e0bc..a52bbe7f48 100644 --- a/common/utils/T/tracer/logger/framelog.c +++ b/common/utils/T/tracer/logger/framelog.c @@ -39,9 +39,9 @@ static void _event(void *p, event e) l->blength = nsamples * 10; free(l->x); free(l->buffer); - l->x = calloc(sizeof(float), l->blength); + l->x = calloc(l->blength, sizeof(float)); if (l->x == NULL) abort(); - l->buffer = calloc(sizeof(float), l->blength); + l->buffer = calloc(l->blength, sizeof(float)); if (l->buffer == NULL) abort(); /* update 'x' */ for (i = 0; i < l->blength; i++) diff --git a/common/utils/T/tracer/view/xy.c b/common/utils/T/tracer/view/xy.c index b027472a73..1407a16a0e 100644 --- a/common/utils/T/tracer/view/xy.c +++ b/common/utils/T/tracer/view/xy.c @@ -74,8 +74,8 @@ static void set(view *_this, char *name, ...) free(this->x); free(this->y); this->length = va_arg(ap, int); - this->x = calloc(sizeof(float), this->length); if (this->x==NULL)abort(); - this->y = calloc(sizeof(float), this->length); if (this->y==NULL)abort(); + this->x = calloc(this->length, sizeof(float)); if (this->x==NULL)abort(); + this->y = calloc(this->length, sizeof(float)); if (this->y==NULL)abort(); this->insert_point = 0; va_end(ap); @@ -104,8 +104,8 @@ view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, ret->plot = xy_plot_new_plot(g, w, color); ret->length = length; - ret->x = calloc(sizeof(float), length); if (ret->x == NULL) abort(); - ret->y = calloc(sizeof(float), length); if (ret->y == NULL) abort(); + ret->x = calloc(length, sizeof(float)); if (ret->x == NULL) abort(); + ret->y = calloc(length, sizeof(float)); if (ret->y == NULL) abort(); ret->insert_point = 0; if (pthread_mutex_init(&ret->lock, NULL)) abort(); From 724b6622ddd56b21739b87db39f0ffec6115f854 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 10 May 2016 10:29:04 +0200 Subject: [PATCH 109/217] TTI logger --- common/utils/T/tracer/logger/Makefile | 2 +- common/utils/T/tracer/logger/ttilog.c | 111 ++++++++++++++++++++++++++ common/utils/T/tracer/logger/ttilog.h | 14 ++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/logger/ttilog.c create mode 100644 common/utils/T/tracer/logger/ttilog.h diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile index f9416f0dff..026a2e194a 100644 --- a/common/utils/T/tracer/logger/Makefile +++ b/common/utils/T/tracer/logger/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=textlog.o framelog.o +OBJS=textlog.o framelog.o ttilog.o logger.a: $(OBJS) ar cr logger.a $(OBJS) diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c new file mode 100644 index 0000000000..f031658ccb --- /dev/null +++ b/common/utils/T/tracer/logger/ttilog.c @@ -0,0 +1,111 @@ +#include "ttilog.h" +#include "event.h" +#include "database.h" +#include "handler.h" +#include +#include +#include + +struct ttilog { + char *event_name; + void *database; + unsigned long handler_id; + int frame_arg; + int subframe_arg; + int data_arg; + /* list of views */ + view **v; + int vsize; +}; + +static void _event(void *p, event e) +{ + struct ttilog *l = p; + int i; + int frame; + int subframe; + float value; + + frame = e.e[l->frame_arg].i; + subframe = e.e[l->subframe_arg].i; + switch (e.e[l->data_arg].type) { + case EVENT_INT: value = e.e[l->data_arg].i; + default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort(); + } + + for (i = 0; i < l->vsize; i++) + l->v[i]->append(l->v[i], frame, subframe, value); +} + +ttilog *new_ttilog(event_handler *h, void *database, + char *event_name, char *frame_varname, char *subframe_varname, + char *data_varname) +{ + struct ttilog *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct ttilog)); if (ret == NULL) abort(); + + ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->handler_id = register_handler_function(h, event_id, _event, ret); + + f = get_format(database, event_id); + + /* look for frame, subframe and data args */ + ret->frame_arg = -1; + ret->subframe_arg = -1; + ret->data_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], frame_varname)) ret->frame_arg = i; + if (!strcmp(f.name[i], subframe_varname)) ret->subframe_arg = i; + if (!strcmp(f.name[i], data_varname)) ret->data_arg = i; + } + if (ret->frame_arg == -1) { + printf("%s:%d: frame argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, frame_varname, event_name); + abort(); + } + if (ret->subframe_arg == -1) { + printf("%s:%d: subframe argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, subframe_varname, event_name); + abort(); + } + if (ret->data_arg == -1) { + printf("%s:%d: data argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, data_varname, event_name); + abort(); + } + if (strcmp(f.type[ret->frame_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, frame_varname); + abort(); + } + if (strcmp(f.type[ret->subframe_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, subframe_varname); + abort(); + } + if (strcmp(f.type[ret->data_arg], "int") != 0 && + strcmp(f.type[ret->data_arg], "float") != 0) { + printf("%s:%d: argument '%s' has wrong type" + " (should be 'int' or 'float')\n", + __FILE__, __LINE__, data_varname); + abort(); + } + + return ret; +} + +void ttilog_add_view(ttilog *_l, view *v) +{ + struct ttilog *l = _l; + l->vsize++; + l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); + l->v[l->vsize-1] = v; +} diff --git a/common/utils/T/tracer/logger/ttilog.h b/common/utils/T/tracer/logger/ttilog.h new file mode 100644 index 0000000000..614fc8db33 --- /dev/null +++ b/common/utils/T/tracer/logger/ttilog.h @@ -0,0 +1,14 @@ +#ifndef _TTILOG_H_ +#define _TTILOG_H_ + +typedef void ttilog; + +ttilog *new_ttilog(void *event_handler, void *database, + char *event_name, char *frame_varname, char *subframe_varname, + char *data_varname); + +#include "view/view.h" + +void ttilog_add_view(ttilog *l, view *v); + +#endif /* _TTILOG_H_ */ From 24af12247551d69798ee5c48d31a0f845d74ecfc Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 10 May 2016 11:19:56 +0200 Subject: [PATCH 110/217] bugfix: calloc may fail --- common/utils/T/tracer/gui/xy_plot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index 4c1a9e1034..f5d5f6bdbd 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -259,7 +259,9 @@ void xy_plot_set_points(gui *_gui, widget *_this, int plot, free(this->plots[plot].x); free(this->plots[plot].y); this->plots[plot].x = calloc(npoints, sizeof(float)); + if (this->plots[plot].x == NULL) abort(); this->plots[plot].y = calloc(npoints, sizeof(float)); + if (this->plots[plot].y == NULL) abort(); this->plots[plot].npoints = npoints; } From 029adbf3683fef7c23d24c639101d2fbe4748fef Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 10 May 2016 11:21:40 +0200 Subject: [PATCH 111/217] bugfix: forget to break and all gets heck! --- common/utils/T/tracer/logger/ttilog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c index f031658ccb..684caaaee5 100644 --- a/common/utils/T/tracer/logger/ttilog.c +++ b/common/utils/T/tracer/logger/ttilog.c @@ -29,7 +29,7 @@ static void _event(void *p, event e) frame = e.e[l->frame_arg].i; subframe = e.e[l->subframe_arg].i; switch (e.e[l->data_arg].type) { - case EVENT_INT: value = e.e[l->data_arg].i; + case EVENT_INT: value = e.e[l->data_arg].i; break; default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort(); } From 70ebbd7e194d1aa2ff91d6373dca93d57fa808ea Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 15:34:44 +0200 Subject: [PATCH 112/217] new function xy_plot_get_dimensions --- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/xy_plot.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 78507f7f4f..18f4ce3bfc 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -37,6 +37,7 @@ void xy_plot_set_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); void textlist_add(gui *gui, widget *this, const char *text, int position, int color); diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index f5d5f6bdbd..93b7f682bf 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -272,3 +272,16 @@ void xy_plot_set_points(gui *_gui, widget *_this, int plot, gunlock(g); } + +void xy_plot_get_dimensions(gui *_gui, widget *_this, int *width, int *height) +{ + struct gui *g = _gui; + struct xy_plot_widget *this = _this; + + glock(g); + + *width = this->common.width - this->vrule_width; + *height = this->common.height - this->label_height * 2; + + gunlock(g); +} From 43f99ff6fc025e02f0072e2ddb0fa91d555c76f3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 15:35:44 +0200 Subject: [PATCH 113/217] convert to dB in ttilog if requested --- common/utils/T/tracer/logger/ttilog.c | 7 ++++++- common/utils/T/tracer/logger/ttilog.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c index 684caaaee5..f9daa4102b 100644 --- a/common/utils/T/tracer/logger/ttilog.c +++ b/common/utils/T/tracer/logger/ttilog.c @@ -5,6 +5,7 @@ #include #include #include +#include struct ttilog { char *event_name; @@ -16,6 +17,7 @@ struct ttilog { /* list of views */ view **v; int vsize; + int convert_to_dB; }; static void _event(void *p, event e) @@ -33,13 +35,15 @@ static void _event(void *p, event e) default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort(); } + if (l->convert_to_dB) value = 10 * log10(value); + for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], frame, subframe, value); } ttilog *new_ttilog(event_handler *h, void *database, char *event_name, char *frame_varname, char *subframe_varname, - char *data_varname) + char *data_varname, int convert_to_dB) { struct ttilog *ret; int event_id; @@ -50,6 +54,7 @@ ttilog *new_ttilog(event_handler *h, void *database, ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); ret->database = database; + ret->convert_to_dB = convert_to_dB; event_id = event_id_from_name(database, event_name); diff --git a/common/utils/T/tracer/logger/ttilog.h b/common/utils/T/tracer/logger/ttilog.h index 614fc8db33..9e0c4fc356 100644 --- a/common/utils/T/tracer/logger/ttilog.h +++ b/common/utils/T/tracer/logger/ttilog.h @@ -5,7 +5,7 @@ typedef void ttilog; ttilog *new_ttilog(void *event_handler, void *database, char *event_name, char *frame_varname, char *subframe_varname, - char *data_varname); + char *data_varname, int convert_to_dB); #include "view/view.h" From db4882857b887de04e80b900f26c55c07821132e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 15:39:09 +0200 Subject: [PATCH 114/217] TTI view --- common/utils/T/tracer/view/Makefile | 2 +- common/utils/T/tracer/view/tti.c | 121 ++++++++++++++++++++++++++++ common/utils/T/tracer/view/view.h | 2 + 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/view/tti.c diff --git a/common/utils/T/tracer/view/Makefile b/common/utils/T/tracer/view/Makefile index 10fd21cd28..a922ec025d 100644 --- a/common/utils/T/tracer/view/Makefile +++ b/common/utils/T/tracer/view/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=stdout.o textlist.o xy.o +OBJS=stdout.o textlist.o xy.o tti.o view.a: $(OBJS) ar cr view.a $(OBJS) diff --git a/common/utils/T/tracer/view/tti.c b/common/utils/T/tracer/view/tti.c new file mode 100644 index 0000000000..ebf9fc657c --- /dev/null +++ b/common/utils/T/tracer/view/tti.c @@ -0,0 +1,121 @@ +#include "view.h" +#include "../utils.h" +#include +#include +#include +#include +#include + +struct tti { + view common; + gui *g; + widget *w; + 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]; + int last_insert_point; +}; + +static int far_enough(int i, int last_insert, int plot_width) +{ + 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; + p1 = last_insert; + p2 = (last_insert + hole_size_tti) % (1024*10); + if (p1 < p2) { + return !(i > p1 && i < p2); + } + return i > p2 && i <= p1; +} + +static void *tti_thread(void *_this) +{ + struct tti *this = _this; + int i; + int length; + int plot_width; + int plot_height; + + while (1) { + if (pthread_mutex_lock(&this->lock)) abort(); + xy_plot_get_dimensions(this->g, this->w, &plot_width, &plot_height); + length = 0; + /* TODO: optimize */ + for (i = 0; i < 1024*10; i++) + /* do not take points too close after last insertion point */ + if (this->valid[i] && + far_enough(i, this->last_insert_point, plot_width)) { + this->xout[length] = i; + this->yout[length] = this->data[i]; + length++; + } + xy_plot_set_points(this->g, this->w, this->plot, + length, this->xout, this->yout); + if (pthread_mutex_unlock(&this->lock)) abort(); + sleepms(1000/this->refresh_rate); + } + + return 0; +} + +static void clear(view *this) +{ + /* TODO */ +} + +static void append(view *_this, int frame, int subframe, double value) +{ + struct tti *this = (struct tti *)_this; + int i; + int index = frame * 10 + subframe; + + if (pthread_mutex_lock(&this->lock)) abort(); + + /* TODO: optimize */ + /* clear all between last insert point and current one + * 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); + while (i != index) { + this->valid[i] = 0; + i = (i + 1) % (1024*10); + } + + this->data[index] = value; + this->valid[index] = 1; + + this->last_insert_point = index; + + if (pthread_mutex_unlock(&this->lock)) abort(); +} + +view *new_view_tti(float refresh_rate, gui *g, widget *w, int color) +{ + struct tti *ret = calloc(1, sizeof(struct tti)); + if (ret == NULL) abort(); + + ret->common.clear = clear; + ret->common.append = (void (*)(view *, ...))append; + + ret->refresh_rate = refresh_rate; + ret->g = g; + ret->w = w; + ret->plot = xy_plot_new_plot(g, w, color); + + ret->last_insert_point = 0; + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + + new_thread(tti_thread, ret); + + return (view *)ret; +} diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 7a125cd567..529e598d09 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -15,5 +15,7 @@ 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); +view *new_view_tti(float refresh_rate, gui *g, widget *w, + int color); #endif /* _VIEW_H_ */ From 3e38cd2651dbb80b8a65ef059fabc6b2b9f0fddd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 16:35:27 +0200 Subject: [PATCH 115/217] add frame parameter to rx_pucch for the T logger --- openair1/PHY/LTE_TRANSPORT/proto.h | 1 + openair1/PHY/LTE_TRANSPORT/pucch.c | 3 ++- openair1/SCHED/phy_procedures_lte_eNb.c | 6 ++++++ openair1/SIMULATION/LTE_PHY/pucchsim.c | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 9afea790b3..4781737bea 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1665,6 +1665,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, uint16_t n2_pucch, uint8_t shortened_format, uint8_t *payload, + int frame, uint8_t subframe, uint8_t pucch1_thres); diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 07789e48e1..51b13c82c5 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -437,6 +437,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, uint16_t n2_pucch, uint8_t shortened_format, uint8_t *payload, + int frame, uint8_t subframe, uint8_t pucch1_thres) { @@ -793,7 +794,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, phy_vars_eNB->pucch1_stats_thres[UE_id][(subframe<<10)+phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe]] = sigma2_dB+pucch1_thres; phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe] = (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe]+1)&1023; - T(T_PUCCH_1_ENERGY, T_INT(phy_vars_eNB->Mod_id), T_INT(UE_id), T_INT(-1), T_INT(subframe), + T(T_PUCCH_1_ENERGY, T_INT(phy_vars_eNB->Mod_id), T_INT(UE_id), T_INT(frame), T_INT(subframe), T_INT(stat_max), T_INT(sigma2_dB+pucch1_thres)); /* diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index d16ac720eb..7bf32eba48 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -3180,6 +3180,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ 0, // n2_pucch 0, // shortened format, should be use_srs flag, later &SR_payload, + frame, subframe, PUCCH1_THRES); @@ -3241,6 +3242,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ 0, //n2_pucch 0, // shortened format pucch_payload0, + frame, subframe, PUCCH1a_THRES); @@ -3252,6 +3254,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ 0, //n2_pucch 0, // shortened format pucch_payload0, + frame, subframe, PUCCH1a_THRES); } @@ -3313,6 +3316,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ 0, //n2_pucch 0, // shortened format pucch_payload0, + frame, subframe, PUCCH1a_THRES); else { @@ -3344,6 +3348,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ 0, // n2_pucch 0, // shortened format pucch_payload0, + frame, subframe, PUCCH1a_THRES); else { @@ -3367,6 +3372,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ 0, //n2_pucch 0, // shortened format pucch_payload1, + frame, subframe, PUCCH1a_THRES); else { diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index 42de78ac74..54f96a61ef 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -610,6 +610,7 @@ int main(int argc, char **argv) n2_pucch, 0, //shortened_format, &pucch_payload_rx, //payload, + 0 /* frame not defined, let's pass 0 */, subframe, pucch1_thres); From aacb2ff7c229fc412a4da5313ad82bec45cd1649 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 18:26:30 +0200 Subject: [PATCH 116/217] send time in events this calls clock_gettime for each active T macro, hopefully it does not eat too much CPU can be deactivated by commenting one line in T_defs.h --- common/utils/T/T.h | 25 +++++++++++++++++++++++++ common/utils/T/T_defs.h | 3 +++ common/utils/T/tracer/textlog.c | 5 +++++ 3 files changed, 33 insertions(+) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 6797213d31..1e1a45779b 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -7,6 +7,10 @@ #include "T_defs.h" +#ifdef T_SEND_TIME +#include +#endif + /* T message IDs */ #include "T_IDs.h" @@ -187,6 +191,25 @@ extern T_cache_t *T_cache; } while (0) #endif +#ifdef T_SEND_TIME + +#define T_HEADER(x) \ + do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + struct timespec T_HEADER_time; \ + if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \ + memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \ + T_LOCAL_size += sizeof(struct timespec); \ + T_PUT_int(1, (int)(uintptr_t)(x)); \ + } while (0) + +#else /* #ifdef T_SEND_TIME */ + #define T_HEADER(x) \ do { \ if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ @@ -198,6 +221,8 @@ extern T_cache_t *T_cache; T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) +#endif /* #ifdef T_SEND_TIME */ + #define T1(t) \ do { \ if (T_ACTIVE(t)) { \ diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 97da76fe1f..faeff507e8 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -1,6 +1,9 @@ #ifndef _T_defs_H_ #define _T_defs_H_ +/* comment (and recompile everything) to not send time in events */ +#define T_SEND_TIME + /* maximum number of arguments for the T macro */ #define T_MAX_ARGS 16 diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index f3e6f7178c..f42a1de832 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -84,10 +84,15 @@ int fullread(int fd, void *_buf, int count) event get_event(int s, char *v, void *d) { + struct timespec t; int type; int32_t length; fullread(s, &length, 4); +#ifdef T_SEND_TIME + fullread(s, &t, sizeof(struct timespec)); + length -= sizeof(struct timespec); +#endif fullread(s, &type, sizeof(int)); length -= sizeof(int); fullread(s, v, length); From 1261ae753a982c573b5aa20466316bfb0e59c8ae Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 18:32:54 +0200 Subject: [PATCH 117/217] update remote_old.c to deal with time in events --- common/utils/T/tracer/remote_old.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/utils/T/tracer/remote_old.c b/common/utils/T/tracer/remote_old.c index 5c3a751baf..8a53e8f89d 100644 --- a/common/utils/T/tracer/remote_old.c +++ b/common/utils/T/tracer/remote_old.c @@ -94,7 +94,13 @@ void get_message(int s) int32_t size; int m; +#ifdef T_SEND_TIME + struct timespec t; +#endif if (GET(s, &size, 4) != 4) abort(); +#ifdef T_SEND_TIME + if (GET(s, &t, sizeof(struct timespec)) != sizeof(struct timespec)) abort(); +#endif if (GET(s, &m, sizeof(int)) != sizeof(int)) abort(); switch (m) { case T_first: { From d8ec913bcd5f2496d1143f50c05011f7c88a4e33 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 11 May 2016 18:33:40 +0200 Subject: [PATCH 118/217] minor bugfix - forgot an ifdef --- common/utils/T/tracer/textlog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index f42a1de832..eb9a83f525 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -84,7 +84,9 @@ int fullread(int fd, void *_buf, int count) event get_event(int s, char *v, void *d) { +#ifdef T_SEND_TIME struct timespec t; +#endif int type; int32_t length; From e5689a5bd17977bcbefdd3ef49d63654f9df9310 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 12 May 2016 10:59:59 +0200 Subject: [PATCH 119/217] introducing a generic logger "class" --- common/utils/T/tracer/logger/Makefile | 2 +- common/utils/T/tracer/logger/framelog.c | 32 ++++++++-------------- common/utils/T/tracer/logger/framelog.h | 13 --------- common/utils/T/tracer/logger/logger.c | 11 ++++++++ common/utils/T/tracer/logger/logger.h | 18 ++++++++++++ common/utils/T/tracer/logger/logger_defs.h | 14 ++++++++++ common/utils/T/tracer/logger/textlog.c | 29 +++++++------------- common/utils/T/tracer/logger/textlog.h | 13 --------- common/utils/T/tracer/logger/ttilog.c | 28 ++++++------------- common/utils/T/tracer/logger/ttilog.h | 14 ---------- common/utils/T/tracer/textlog.c | 6 ++-- 11 files changed, 77 insertions(+), 103 deletions(-) delete mode 100644 common/utils/T/tracer/logger/framelog.h create mode 100644 common/utils/T/tracer/logger/logger.c create mode 100644 common/utils/T/tracer/logger/logger.h create mode 100644 common/utils/T/tracer/logger/logger_defs.h delete mode 100644 common/utils/T/tracer/logger/textlog.h delete mode 100644 common/utils/T/tracer/logger/ttilog.h diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile index 026a2e194a..4e67dce3ad 100644 --- a/common/utils/T/tracer/logger/Makefile +++ b/common/utils/T/tracer/logger/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=textlog.o framelog.o ttilog.o +OBJS=logger.o textlog.o framelog.o ttilog.o logger.a: $(OBJS) ar cr logger.a $(OBJS) diff --git a/common/utils/T/tracer/logger/framelog.c b/common/utils/T/tracer/logger/framelog.c index a52bbe7f48..2b26a5b3a0 100644 --- a/common/utils/T/tracer/logger/framelog.c +++ b/common/utils/T/tracer/logger/framelog.c @@ -1,4 +1,5 @@ -#include "framelog.h" +#include "logger.h" +#include "logger_defs.h" #include "handler.h" #include "database.h" #include @@ -7,14 +8,10 @@ #include struct framelog { - char *event_name; + struct logger common; void *database; - unsigned long handler_id; int subframe_arg; int buffer_arg; - /* list of views */ - view **v; - int vsize; float *x; float *buffer; int blength; @@ -47,8 +44,8 @@ static void _event(void *p, event e) for (i = 0; i < l->blength; i++) l->x[i] = i; /* update 'length' of views */ - for (i = 0; i < l->vsize; i++) - l->v[i]->set(l->v[i], "length", l->blength); + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->set(l->common.v[i], "length", l->blength); } /* TODO: compute the LOGs in the plotter (too much useless computations) */ @@ -59,11 +56,11 @@ static void _event(void *p, event e) } if (subframe == 9) - for (i = 0; i < l->vsize; i++) - l->v[i]->append(l->v[i], l->x, l->buffer, l->blength); + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], l->x, l->buffer, l->blength); } -framelog *new_framelog(event_handler *h, void *database, +logger *new_framelog(event_handler *h, void *database, char *event_name, char *subframe_varname, char *buffer_varname) { struct framelog *ret; @@ -73,12 +70,13 @@ framelog *new_framelog(event_handler *h, void *database, ret = calloc(1, sizeof(struct framelog)); if (ret == NULL) abort(); - ret->event_name = strdup(event_name); if (ret->event_name == 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->handler_id = register_handler_function(h, event_id, _event, ret); + ret->common.handler_id = register_handler_function(h,event_id,_event,ret); f = get_format(database, event_id); @@ -112,11 +110,3 @@ framelog *new_framelog(event_handler *h, void *database, return ret; } - -void framelog_add_view(framelog *_l, view *v) -{ - struct framelog *l = _l; - l->vsize++; - l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); - l->v[l->vsize-1] = v; -} diff --git a/common/utils/T/tracer/logger/framelog.h b/common/utils/T/tracer/logger/framelog.h deleted file mode 100644 index a7b3d0d21d..0000000000 --- a/common/utils/T/tracer/logger/framelog.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _FRAMELOG_H_ -#define _FRAMELOG_H_ - -typedef void framelog; - -framelog *new_framelog(void *event_handler, void *database, - char *event_name, char *subframe_varname, char *buffer_varname); - -#include "view/view.h" - -void framelog_add_view(framelog *l, view *v); - -#endif /* _FRAMELOG_H_ */ diff --git a/common/utils/T/tracer/logger/logger.c b/common/utils/T/tracer/logger/logger.c new file mode 100644 index 0000000000..c27c612f82 --- /dev/null +++ b/common/utils/T/tracer/logger/logger.c @@ -0,0 +1,11 @@ +#include "logger.h" +#include "logger_defs.h" +#include + +void logger_add_view(logger *_l, view *v) +{ + struct logger *l = _l; + l->vsize++; + l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); + l->v[l->vsize-1] = v; +} diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h new file mode 100644 index 0000000000..f6905e153d --- /dev/null +++ b/common/utils/T/tracer/logger/logger.h @@ -0,0 +1,18 @@ +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +typedef void logger; + +logger *new_framelog(void *event_handler, void *database, + char *event_name, char *subframe_varname, char *buffer_varname); +logger *new_textlog(void *event_handler, void *database, + char *event_name, char *format); +logger *new_ttilog(void *event_handler, void *database, + char *event_name, char *frame_varname, char *subframe_varname, + char *data_varname, int convert_to_dB); + +#include "view/view.h" + +void logger_add_view(logger *l, view *v); + +#endif /* _LOGGER_H_ */ diff --git a/common/utils/T/tracer/logger/logger_defs.h b/common/utils/T/tracer/logger/logger_defs.h new file mode 100644 index 0000000000..e4279157ec --- /dev/null +++ b/common/utils/T/tracer/logger/logger_defs.h @@ -0,0 +1,14 @@ +#ifndef _LOGGER_DEFS_H_ +#define _LOGGER_DEFS_H_ + +#include "view/view.h" + +struct logger { + char *event_name; + unsigned long handler_id; + /* list of views */ + view **v; + int vsize; +}; + +#endif /* _LOGGER_DEFS_H_ */ diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index 264068c617..2efbc8b1aa 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -1,4 +1,5 @@ -#include "textlog.h" +#include "logger.h" +#include "logger_defs.h" #include "handler.h" #include "database.h" #include "view/view.h" @@ -22,16 +23,12 @@ struct format_item { }; struct textlog { - char *event_name; + struct logger common; char *format; void *database; - unsigned long handler_id; /* parsed format string */ struct format_item *f; int fsize; - /* list of views */ - view **v; - int vsize; /* local output buffer */ OBUF o; }; @@ -56,7 +53,8 @@ static void _event(void *p, event e) } PUTC(&l->o, 0); - for (i = 0; i < l->vsize; i++) l->v[i]->append(l->v[i], l->o.obuf); + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], l->o.obuf); } enum chunk_type { C_ERROR, C_STRING, C_ARG_NAME, C_EVENT_NAME }; @@ -127,7 +125,7 @@ error: return (struct chunk){type:C_ERROR}; } -textlog *new_textlog(event_handler *h, void *database, +logger *new_textlog(event_handler *h, void *database, char *event_name, char *format) { struct textlog *ret; @@ -137,13 +135,14 @@ textlog *new_textlog(event_handler *h, void *database, ret = calloc(1, sizeof(struct textlog)); if (ret == NULL) abort(); - ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); + ret->common.event_name = strdup(event_name); + if (ret->common.event_name == NULL) abort(); ret->format = strdup(format); if (ret->format == NULL) abort(); ret->database = database; event_id = event_id_from_name(database, event_name); - ret->handler_id = register_handler_function(h, event_id, _event, ret); + ret->common.handler_id = register_handler_function(h,event_id,_event,ret); f = get_format(database, event_id); @@ -167,7 +166,7 @@ textlog *new_textlog(event_handler *h, void *database, break; case C_EVENT_NAME: ret->f[ret->fsize].type = INSTRING; - ret->f[ret->fsize].s = ret->event_name; + ret->f[ret->fsize].s = ret->common.event_name; break; } ret->fsize++; @@ -179,11 +178,3 @@ error: printf("%s:%d: bad format '%s'\n", __FILE__, __LINE__, format); abort(); } - -void textlog_add_view(textlog *_l, view *v) -{ - struct textlog *l = _l; - l->vsize++; - l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); - l->v[l->vsize-1] = v; -} diff --git a/common/utils/T/tracer/logger/textlog.h b/common/utils/T/tracer/logger/textlog.h deleted file mode 100644 index b9e9a3e8e3..0000000000 --- a/common/utils/T/tracer/logger/textlog.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _TEXTLOG_H_ -#define _TEXTLOG_H_ - -typedef void textlog; - -textlog *new_textlog(void *event_handler, void *database, - char *event_name, char *format); - -#include "view/view.h" - -void textlog_add_view(textlog *l, view *v); - -#endif /* _TEXTLOG_H_ */ diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c index f9daa4102b..649c4b497a 100644 --- a/common/utils/T/tracer/logger/ttilog.c +++ b/common/utils/T/tracer/logger/ttilog.c @@ -1,4 +1,5 @@ -#include "ttilog.h" +#include "logger.h" +#include "logger_defs.h" #include "event.h" #include "database.h" #include "handler.h" @@ -8,15 +9,11 @@ #include struct ttilog { - char *event_name; + struct logger common; void *database; - unsigned long handler_id; int frame_arg; int subframe_arg; int data_arg; - /* list of views */ - view **v; - int vsize; int convert_to_dB; }; @@ -37,11 +34,11 @@ static void _event(void *p, event e) if (l->convert_to_dB) value = 10 * log10(value); - for (i = 0; i < l->vsize; i++) - l->v[i]->append(l->v[i], frame, subframe, value); + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], frame, subframe, value); } -ttilog *new_ttilog(event_handler *h, void *database, +logger *new_ttilog(event_handler *h, void *database, char *event_name, char *frame_varname, char *subframe_varname, char *data_varname, int convert_to_dB) { @@ -52,13 +49,14 @@ ttilog *new_ttilog(event_handler *h, void *database, ret = calloc(1, sizeof(struct ttilog)); if (ret == NULL) abort(); - ret->event_name = strdup(event_name); if (ret->event_name == NULL) abort(); + ret->common.event_name = strdup(event_name); + if (ret->common.event_name == NULL) abort(); ret->database = database; ret->convert_to_dB = convert_to_dB; event_id = event_id_from_name(database, event_name); - ret->handler_id = register_handler_function(h, event_id, _event, ret); + ret->common.handler_id = register_handler_function(h,event_id,_event,ret); f = get_format(database, event_id); @@ -106,11 +104,3 @@ ttilog *new_ttilog(event_handler *h, void *database, return ret; } - -void ttilog_add_view(ttilog *_l, view *v) -{ - struct ttilog *l = _l; - l->vsize++; - l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); - l->v[l->vsize-1] = v; -} diff --git a/common/utils/T/tracer/logger/ttilog.h b/common/utils/T/tracer/logger/ttilog.h deleted file mode 100644 index 9e0c4fc356..0000000000 --- a/common/utils/T/tracer/logger/ttilog.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _TTILOG_H_ -#define _TTILOG_H_ - -typedef void ttilog; - -ttilog *new_ttilog(void *event_handler, void *database, - char *event_name, char *frame_varname, char *subframe_varname, - char *data_varname, int convert_to_dB); - -#include "view/view.h" - -void ttilog_add_view(ttilog *l, view *v); - -#endif /* _TTILOG_H_ */ diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index eb9a83f525..eef202495d 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -7,7 +7,7 @@ #include "database.h" #include "event.h" #include "handler.h" -#include "logger/textlog.h" +#include "logger/logger.h" #include "view/view.h" #include "gui/gui.h" #include "utils.h" @@ -125,7 +125,7 @@ int main(int n, char **v) char t; int l; event_handler *h; - textlog *textlog; + logger *textlog; gui *g; int gui_mode = 0; view *out; @@ -192,7 +192,7 @@ int main(int n, char **v) textlog = new_textlog(h, database, name, desc); // "ENB_UL_CHANNEL_ESTIMATE", // "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); - textlog_add_view(textlog, out); + logger_add_view(textlog, out); free(name); free(desc); } From df5afaa93d27e11c35d766a35163fa1ed5a3f0ef Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 12 May 2016 13:00:19 +0200 Subject: [PATCH 120/217] store received time in events for later processing --- common/utils/T/tracer/event.c | 8 ++++++++ common/utils/T/tracer/event.h | 11 +++++++++++ common/utils/T/tracer/textlog.c | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c index 88668eaf7f..2071c90356 100644 --- a/common/utils/T/tracer/event.c +++ b/common/utils/T/tracer/event.c @@ -4,13 +4,21 @@ #include #include +#ifdef T_SEND_TIME +event new_event(struct timespec sending_time, int type, + int length, char *buffer, void *database) +#else event new_event(int type, int length, char *buffer, void *database) +#endif { database_event_format f; event e; int i; int offset; +#ifdef T_SEND_TIME + e.sending_time = sending_time; +#endif e.type = type; e.buffer = buffer; diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h index 88f6e4eeb4..0cecca3265 100644 --- a/common/utils/T/tracer/event.h +++ b/common/utils/T/tracer/event.h @@ -2,6 +2,9 @@ #define _EVENT_H_ #include "../T_defs.h" +#ifdef T_SEND_TIME +#include +#endif enum event_arg_type { EVENT_INT, @@ -23,12 +26,20 @@ typedef struct { } event_arg; typedef struct { +#ifdef T_SEND_TIME + struct timespec sending_time; +#endif int type; char *buffer; event_arg e[T_MAX_ARGS]; int ecount; } event; +#ifdef T_SEND_TIME +event new_event(struct timespec sending_time, int type, + int length, char *buffer, void *database); +#else event new_event(int type, int length, char *buffer, void *database); +#endif #endif /* _EVENT_H_ */ diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index eef202495d..ec08596fca 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -99,7 +99,11 @@ event get_event(int s, char *v, void *d) length -= sizeof(int); fullread(s, v, length); +#ifdef T_SEND_TIME + return new_event(t, type, length, v, d); +#else return new_event(type, length, v, d); +#endif } static void *gui_thread(void *_g) From 2eb0d4c90fbd4a4eb33acea7dc806f36793a46ce Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 12 May 2016 15:12:21 +0200 Subject: [PATCH 121/217] add time to textlog if available --- common/utils/T/tracer/logger/textlog.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index 2efbc8b1aa..4a69a9619a 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -37,9 +37,21 @@ static void _event(void *p, event e) { struct textlog *l = p; int i; +#ifdef T_SEND_TIME + struct tm *t; + char tt[64]; +#endif l->o.osize = 0; +#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.%3.3d: ", t->tm_hour, t->tm_min, t->tm_sec, + (int)((e.sending_time.tv_nsec/(1000000/2)+1)/2)); + PUTS(&l->o, tt); +#endif + for (i = 0; i < l->fsize; i++) switch(l->f[i].type) { case INSTRING: PUTS(&l->o, l->f[i].s); break; From 52fae6a830ab7bd89b07bea7db6af94d7f8880be Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 12 May 2016 15:18:35 +0200 Subject: [PATCH 122/217] minor "typo" --- common/utils/T/tracer/gui/gui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 18f4ce3bfc..ab4bf503f4 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -25,7 +25,7 @@ widget *new_positioner(gui *gui); widget *new_label(gui *gui, const char *text); widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); -widget *new_textlist(gui *_gui, int width, int nlines, int background_color); +widget *new_textlist(gui *gui, int width, int nlines, int background_color); void label_set_clickable(gui *gui, widget *label, int clickable); From 944dad4caa5a96965d99de1f442429a12bb92cbb Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 12 May 2016 17:03:07 +0200 Subject: [PATCH 123/217] GUI timeline widget --- common/utils/T/tracer/gui/Makefile | 3 +- common/utils/T/tracer/gui/gui.h | 10 ++ common/utils/T/tracer/gui/gui_defs.h | 19 +++- common/utils/T/tracer/gui/timeline.c | 150 +++++++++++++++++++++++++++ common/utils/T/tracer/gui/widget.c | 3 +- 5 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 common/utils/T/tracer/gui/timeline.c diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index b64af3bd18..7129d390b9 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -2,7 +2,8 @@ CC=gcc CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ - gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o + gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \ + timeline.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index ab4bf503f4..5902ea2831 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -26,6 +26,8 @@ widget *new_label(gui *gui, const char *text); widget *new_xy_plot(gui *gui, int width, int height, char *label, int vruler_width); widget *new_textlist(gui *gui, int width, int nlines, int background_color); +widget *new_timeline(gui *gui, int width, int number_of_sublines, + int subline_height); void label_set_clickable(gui *gui, widget *label, int clickable); @@ -52,6 +54,12 @@ void textlist_get_line(gui *gui, widget *this, int line, char **text, int *color); void textlist_set_color(gui *gui, widget *this, int line, int color); +void timeline_clear(gui *gui, widget *this); +void timeline_add_points(gui *gui, widget *this, int subline, int color, + int *x, int len); +void timeline_set_subline_background_color(gui *gui, widget *this, + int subline, int color); + void gui_loop(gui *gui); void glock(gui *gui); @@ -67,6 +75,8 @@ int new_color(gui *gui, char *color); * - click { int [2]: line, button } * - label: * - click { int: button } (if enabled) + * - timeline + * - resize { int: width } */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index dd76922179..8f15747490 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -30,7 +30,8 @@ extern int volatile gui_logd; /*************************************************************************/ enum widget_type { - TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL + TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL, + TIMELINE }; struct widget_list; @@ -117,6 +118,22 @@ struct xy_plot_widget { int nplots; }; +struct timeline_subline { + int *color; /* length = width of timeline widget + * value = -1 if no color + */ + int width; + int background; /* background color of the subline */ +}; + +struct timeline_widget { + struct widget common; + int n; /* number of sublines */ + struct timeline_subline *s; + int subline_height; + int wanted_width; +}; + struct button_widget { struct widget common; }; diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c new file mode 100644 index 0000000000..9e794dda4c --- /dev/null +++ b/common/utils/T/tracer/gui/timeline.c @@ -0,0 +1,150 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include + +static void paint(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + int i; + int j; + + for (i = 0; i < this->n; i++) { + x_fill_rectangle(g->x, g->xwin, this->s[i].background, + this->common.x, this->common.y + i * this->subline_height, + this->common.width, this->subline_height); + for (j = 0; j < this->s[i].width; j++) + if (this->s[i].color[j] != -1) + x_draw_line(g->x, g->xwin, this->s[i].color[j], + this->common.x + j, this->common.y + i * this->subline_height, + this->common.x + j, this->common.y + this->subline_height -1 + + i * this->subline_height); + } + + LOGD("PAINT timeline xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height); +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct timeline_widget *w = _w; + *width = w->wanted_width; + *height = w->n * w->subline_height; + LOGD("HINTS timeline wh %d %d\n", *width, *height); +} + +static void allocate(gui *_gui, widget *_this, + int x, int y, int width, int height) +{ + struct timeline_widget *this = _this; + int i; + int j; + this->common.x = x; + this->common.y = y; + this->common.width = width; + this->common.height = height; + LOGD("ALLOCATE timeline %p xywh %d %d %d %d\n", this, x, y, width, height); + for (i = 0; i < this->n; i++) { + this->s[i].width = width; + this->s[i].color = realloc(this->s[i].color, width * sizeof(int)); + if (this->s[i].color == NULL) abort(); + for (j = 0; j < width; j++) this->s[i].color[j] = -1; + } + gui_notify(_gui, "resize", _this, &width); +} + +/*************************************************************************/ +/* creation function */ +/*************************************************************************/ + +widget *new_timeline(gui *_gui, int width, int number_of_sublines, + int subline_height) +{ + struct gui *g = _gui; + struct timeline_widget *w; + int i; + int j; + + glock(g); + + w = new_widget(g, TIMELINE, sizeof(struct timeline_widget)); + + w->wanted_width = width; + w->n = number_of_sublines; + w->s = calloc(w->n, sizeof(struct timeline_subline)); if (w->s == NULL) OOM; + w->subline_height = subline_height; + + /* initialize colors */ + for (i = 0; i < w->n; i++) { + w->s[i].width = width; + w->s[i].color = calloc(width, sizeof(int)); + if (w->s[i].color == NULL) abort(); + for (j = 0; j < width; j++) w->s[i].color[j] = -1; + w->s[i].background = BACKGROUND_COLOR; + } + + w->common.paint = paint; + w->common.hints = hints; + w->common.allocate = allocate; + + gunlock(g); + + return w; +} + +/*************************************************************************/ +/* public functions */ +/*************************************************************************/ + +void timeline_clear(gui *_gui, widget *_this) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + int i; + int j; + + glock(g); + + for (i = 0; i < this->n; i++) + for (j = 0; j < this->s[i].width; j++) + this->s[i].color[j] = -1; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} + +void timeline_add_points(gui *_gui, widget *_this, int subline, int color, + int *x, int len) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + int i; + + glock(g); + + for (i = 0; i < len; i++) { + if (x[i] >= this->s[subline].width) { WARN("out of bounds\n"); continue; } + this->s[subline].color[x[i]] = color; + } + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} + +void timeline_set_subline_background_color(gui *_gui, widget *_this, + int subline, int color) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + + glock(g); + + this->s[subline].background = color; + + send_event(g, DIRTY, this->common.id); + + gunlock(g); +} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index db8a754a70..944d27548f 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -265,7 +265,7 @@ void widget_dirty(gui *_gui, widget *_this) static const char *names[] = { "TOPLEVEL_WINDOW", "CONTAINER", "POSITIONER", "TEXT_LIST", - "XY_PLOT", "BUTTON", "LABEL" + "XY_PLOT", "BUTTON", "LABEL", "TIMELINE" }; const char *widget_name(enum widget_type type) { @@ -278,6 +278,7 @@ const char *widget_name(enum widget_type type) case XY_PLOT: case BUTTON: case LABEL: + case TIMELINE: return names[type]; } return "UNKNOWN (error)"; From 69f14c37fa7e77e6ddd7a92304e94d3ca16fc5a9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 12 May 2016 17:26:42 +0200 Subject: [PATCH 124/217] timelog --- common/utils/T/tracer/logger/Makefile | 2 +- common/utils/T/tracer/logger/logger.h | 1 + common/utils/T/tracer/logger/timelog.c | 37 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/logger/timelog.c diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile index 4e67dce3ad..18f70e0bc5 100644 --- a/common/utils/T/tracer/logger/Makefile +++ b/common/utils/T/tracer/logger/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=logger.o textlog.o framelog.o ttilog.o +OBJS=logger.o textlog.o framelog.o ttilog.o timelog.o logger.a: $(OBJS) ar cr logger.a $(OBJS) diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index f6905e153d..a3c09b2c23 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -10,6 +10,7 @@ logger *new_textlog(void *event_handler, void *database, logger *new_ttilog(void *event_handler, void *database, char *event_name, char *frame_varname, char *subframe_varname, char *data_varname, int convert_to_dB); +logger *new_timelog(void *event_handler, void *database, char *event_name); #include "view/view.h" diff --git a/common/utils/T/tracer/logger/timelog.c b/common/utils/T/tracer/logger/timelog.c new file mode 100644 index 0000000000..5dadad8c27 --- /dev/null +++ b/common/utils/T/tracer/logger/timelog.c @@ -0,0 +1,37 @@ +#include "logger.h" +#include "logger_defs.h" +#include "event.h" +#include "database.h" +#include "handler.h" +#include +#include + +struct timelog { + struct logger common; +}; + +static void _event(void *p, event e) +{ + struct timelog *l = p; + int i; + + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], e.sending_time); +} + +logger *new_timelog(event_handler *h, void *database, char *event_name) +{ + struct timelog *ret; + int event_id; + + ret = calloc(1, sizeof(struct timelog)); if (ret == NULL) abort(); + + ret->common.event_name = strdup(event_name); + if (ret->common.event_name == NULL) abort(); + + event_id = event_id_from_name(database, event_name); + + ret->common.handler_id = register_handler_function(h,event_id,_event,ret); + + return ret; +} From 48f0c341a181e38888b4bce571f84fa0b5b01173 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 13 May 2016 15:27:23 +0200 Subject: [PATCH 125/217] maybe bugfix, maybe useless: return wanted size if allocated size is zero in get_dimensions for xy_plot --- common/utils/T/tracer/gui/xy_plot.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index 93b7f682bf..f4d2ff4b01 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -280,8 +280,13 @@ void xy_plot_get_dimensions(gui *_gui, widget *_this, int *width, int *height) glock(g); - *width = this->common.width - this->vrule_width; - *height = this->common.height - this->label_height * 2; + if (this->common.width == 0 || this->common.height == 0) { + *width = this->wanted_width; + *height = this->wanted_height; + } else { + *width = this->common.width - this->vrule_width; + *height = this->common.height - this->label_height * 2; + } gunlock(g); } From ee62356349d51d0e372e96938d89735cd2b51ca0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 13 May 2016 15:29:08 +0200 Subject: [PATCH 126/217] new function timeline_get_width --- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/timeline.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 5902ea2831..2a60e08e96 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -59,6 +59,7 @@ void timeline_add_points(gui *gui, widget *this, int subline, int color, int *x, int len); void timeline_set_subline_background_color(gui *gui, widget *this, int subline, int color); +void timeline_get_width(gui *gui, widget *this, int *width); void gui_loop(gui *gui); diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index 9e794dda4c..7c8469f928 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -148,3 +148,15 @@ void timeline_set_subline_background_color(gui *_gui, widget *_this, gunlock(g); } + +void timeline_get_width(gui *_gui, widget *_this, int *width) +{ + struct gui *g = _gui; + struct timeline_widget *this = _this; + + glock(g); + + *width = this->common.width == 0 ? this->wanted_width : this->common.width; + + gunlock(g); +} From 0cf4738d702e7002895e8fc4edb96e5fe7fd8eae Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 13 May 2016 19:00:21 +0200 Subject: [PATCH 127/217] time view, not tested at all --- common/utils/T/tracer/view/Makefile | 2 +- common/utils/T/tracer/view/time.c | 297 ++++++++++++++++++++++++++++ common/utils/T/tracer/view/view.h | 3 + 3 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 common/utils/T/tracer/view/time.c diff --git a/common/utils/T/tracer/view/Makefile b/common/utils/T/tracer/view/Makefile index a922ec025d..51b5114a0e 100644 --- a/common/utils/T/tracer/view/Makefile +++ b/common/utils/T/tracer/view/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=stdout.o textlist.o xy.o tti.o +OBJS=stdout.o textlist.o xy.o tti.o time.o view.a: $(OBJS) ar cr view.a $(OBJS) diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c new file mode 100644 index 0000000000..417760f9d5 --- /dev/null +++ b/common/utils/T/tracer/view/time.c @@ -0,0 +1,297 @@ +#include "view.h" +#include "../utils.h" +#include +#include +#include + +/****************************************************************************/ +/* timeview */ +/****************************************************************************/ + +struct plot { + long *nano; + int nanosize; + int nanomaxsize; + int line; + int color; +}; + +struct tick { + struct plot *p; /* one plot per subview, + * so size is 'subcount' + * (see in struct time below) + */ +}; + +struct time { + view common; + gui *g; + widget *w; + float refresh_rate; + pthread_mutex_t lock; + struct tick *t; /* t is a circular list + * a tick lasts one second + */ + int tsize; /* size of t */ + int tstart; /* starting index in t */ + time_t tstart_time; /* timestamp (in seconds) of starting in t */ + int subcount; /* number of subviews */ + struct timespec latest_time; /* time of latest received tick */ + int64_t pixel_length; /* unit: nanosecond (maximum 1 hour/pixel) */ +}; + +/* TODO: put that function somewhere else (utils.c) */ +static struct timespec time_add(struct timespec a, struct timespec b) +{ + struct timespec ret; + ret.tv_sec = a.tv_sec + b.tv_sec; + ret.tv_nsec = a.tv_nsec + b.tv_nsec; + if (ret.tv_nsec > 1000000000) { + ret.tv_sec++; + ret.tv_nsec -= 1000000000; + } + return ret; +} + +/* TODO: put that function somewhere else (utils.c) */ +static struct timespec time_sub(struct timespec a, struct timespec b) +{ + struct timespec ret; + if (a.tv_nsec < b.tv_nsec) { + ret.tv_nsec = (int64_t)a.tv_nsec - (int64_t)b.tv_nsec + 1000000000; + ret.tv_sec = a.tv_sec - b.tv_sec - 1; + } else { + ret.tv_nsec = a.tv_nsec - b.tv_nsec; + ret.tv_sec = a.tv_sec - b.tv_sec; + } + return ret; +} + +/* TODO: put that function somewhere else (utils.c) */ +static struct timespec nano_to_time(int64_t n) +{ + struct timespec ret; + ret.tv_sec = n / 1000000000; + ret.tv_nsec = n % 1000000000; + return ret; +} + +/* TODO: put that function somewhere else (utils.c) */ +static int time_cmp(struct timespec a, struct timespec b) +{ + if (a.tv_sec < b.tv_sec) return -1; + if (a.tv_sec > b.tv_sec) return 1; + if (a.tv_nsec < b.tv_nsec) return -1; + if (a.tv_nsec > b.tv_nsec) return 1; + return 0; +} + +static void *time_thread(void *_this) +{ + struct time *this = _this; + int width; + int l; + int i; + int t; + struct timespec tstart; + struct timespec tnext; + struct plot *p; + + while (1) { + if (pthread_mutex_lock(&this->lock)) abort(); + + timeline_get_width(this->g, this->w, &width); + + /* TODO: optimize/cleanup */ + + tnext = time_add(this->latest_time,(struct timespec){tv_sec:0,tv_nsec:1}); + tstart = time_sub(tnext, nano_to_time(this->pixel_length * width)); + + for (l = 0; l < this->subcount; l++) { + for (i = 0; i < width; i++) { + struct timespec tick_start, tick_end; + tick_start = time_add(tstart, nano_to_time(this->pixel_length * i)); + tick_end = time_add(tick_start, nano_to_time(this->pixel_length-1)); + /* if tick is before start, do nothing */ + if (time_cmp(tick_end, + (struct timespec){tv_sec:this->tstart_time,tv_nsec:0}) < 0) + continue; + /* if tick after end, do nothing */ + if (time_cmp(tick_start, + time_add((struct timespec){tv_sec:this->tstart_time,tv_nsec:0}, + nano_to_time(this->pixel_length * width))) >= 0) + continue; + /* look for a nano between tick_start and tick_end */ + /* TODO: optimize */ + for (t = 0; t < this->tsize; t++) { + int n; + time_t current_second = this->tstart_time + t; + time_t next_second = current_second + 1; + struct timespec current_time = + (struct timespec){tv_sec:current_second,tv_nsec:0}; + struct timespec next_time = + (struct timespec){tv_sec:next_second,tv_nsec:0}; + if (time_cmp(tick_end, current_time) < 0) continue; + if (time_cmp(tick_start, next_time) >= 0) continue; + p = &this->t[(this->tstart + t) % this->tsize].p[l]; + for (n = 0; n < p->nanosize; n++) { + struct timespec nano = + (struct timespec){tv_sec:current_second,tv_nsec:p->nano[n]}; + if (time_cmp(tick_start, nano) <= 0 && + time_cmp(nano, tick_end) < 0) + goto gotit; + } + } + continue; +gotit: + /* TODO: only one call */ + timeline_add_points(this->g, this->w, p->line, p->color, &i, 1); + } + } + + if (pthread_mutex_unlock(&this->lock)) abort(); + sleepms(1000 / this->refresh_rate); + } + + return 0; +} + +view *new_view_time(int number_of_seconds, float refresh_rate, + gui *g, widget *w) +{ + struct time *ret = calloc(1, sizeof(struct time)); + if (ret == NULL) abort(); + + ret->refresh_rate = refresh_rate; + ret->g = g; + ret->w = w; + + ret->t = calloc(number_of_seconds, sizeof(struct tick)); + if (ret->t == NULL) abort(); + ret->tsize = number_of_seconds; + ret->tstart = 0; + ret->tstart_time = 0; + ret->subcount = 0; + ret->pixel_length = 10 * 1000000; /* 10ms */ + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + + new_thread(time_thread, ret); + + return (view *)ret; +} + +/****************************************************************************/ +/* subtimeview */ +/****************************************************************************/ + +struct subtime { + view common; + struct time *parent; + int line; + int color; + int subview; +}; + +static void append(view *_this, struct timespec t) +{ + struct subtime *this = (struct subtime *)_this; + struct time *time = this->parent; + time_t start_time, end_time; + int i, l; + int tpos; + struct plot *p; + + if (pthread_mutex_lock(&time->lock)) abort(); + + start_time = time->tstart_time; + end_time = time->tstart_time + time->tsize - 1; + + /* useless test? */ + if (t.tv_sec < start_time) abort(); + + /* tick out of current window? if yes, move window */ + /* if too far, free all */ + if (end_time - t.tv_sec > time->tsize) { + for (l = 0; l < time->tsize; l++) + for (i = 0; i < time->subcount; i++) { + free(time->t[l].p[i].nano); + time->t[l].p[i].nano = NULL; + time->t[l].p[i].nanosize = 0; + time->t[l].p[i].nanomaxsize = 0; + } + time->tstart = 0; + time->tstart_time = t.tv_sec - (time->tsize-1); + start_time = time->tstart_time; + end_time = time->tstart_time + time->tsize - 1; + } + while (t.tv_sec > end_time) { + for (i = 0; i < time->subcount; i++) { + free(time->t[time->tstart].p[i].nano); + time->t[time->tstart].p[i].nano = NULL; + time->t[time->tstart].p[i].nanosize = 0; + time->t[time->tstart].p[i].nanomaxsize = 0; + } + time->tstart = (time->tstart+1) % time->tsize; + time->tstart_time++; + start_time++; + end_time++; + } + + tpos = (time->tstart + (t.tv_sec - time->tstart_time)) % time->tsize; + p = &time->t[tpos].p[this->subview]; + + /* can we get a new event with <= time than last in list? */ + if (p->nanosize != 0 && t.tv_nsec <= p->nano[p->nanosize-1]) + { printf("%s:%d: possible?\n", __FILE__, __LINE__); abort(); } + + if (p->nanosize == p->nanomaxsize) { + p->nanomaxsize += 4096; + p->nano = realloc(p->nano, p->nanomaxsize * sizeof(long)); + if (p->nano == NULL) abort(); + } + + p->nano[p->nanosize] = t.tv_nsec; + p->nanosize++; + + if (time->latest_time.tv_sec < t.tv_sec || + (time->latest_time.tv_sec == t.tv_sec && + time->latest_time.tv_nsec < t.tv_nsec)) + time->latest_time = t; + + if (pthread_mutex_unlock(&time->lock)) abort(); +} + +view *new_subview_time(view *_time, int line, int color) +{ + int i; + struct time *time = (struct time *)_time; + struct subtime *ret = calloc(1, sizeof(struct subtime)); + if (ret == NULL) abort(); + + ret->common.append = (void (*)(view *, ...))append; + + if (pthread_mutex_lock(&time->lock)) abort(); + + ret->parent = time; + ret->line = line; + ret->color = color; + ret->subview = time->subcount; + + for (i = 0; i < time->tsize; i++) { + time->t[i].p = realloc(time->t[i].p, + (time->subcount + 1) * sizeof(struct plot)); + if (time->t[i].p == NULL) abort(); + time->t[i].p[time->subcount].nano = NULL; + time->t[i].p[time->subcount].nanosize = 0; + time->t[i].p[time->subcount].nanomaxsize = 0; + time->t[i].p[time->subcount].line = line; + time->t[i].p[time->subcount].color = color; + } + + time->subcount++; + + if (pthread_mutex_unlock(&time->lock)) abort(); + + return (view *)ret; +} diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 529e598d09..8d8036721c 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -17,5 +17,8 @@ view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, int color); view *new_view_tti(float refresh_rate, gui *g, widget *w, int color); +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); #endif /* _VIEW_H_ */ From f49489a63228be00663320a4021f00e50c5b6f20 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 15 May 2016 23:15:06 +0200 Subject: [PATCH 128/217] add _silent functions for gui/timeline.c, the way view/time.c uses it requires those optimizations --- common/utils/T/tracer/gui/gui.h | 3 +++ common/utils/T/tracer/gui/timeline.c | 34 ++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 2a60e08e96..bb1a495849 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -55,8 +55,11 @@ void textlist_get_line(gui *gui, widget *this, int line, void textlist_set_color(gui *gui, widget *this, int line, int color); void timeline_clear(gui *gui, widget *this); +void timeline_clear_silent(gui *gui, widget *this); void timeline_add_points(gui *gui, widget *this, int subline, int color, int *x, int len); +void timeline_add_points_silent(gui *gui, widget *this, int subline, + int color, int *x, int len); void timeline_set_subline_background_color(gui *gui, widget *this, int subline, int color); void timeline_get_width(gui *gui, widget *this, int *width); diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index 7c8469f928..0902078071 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -97,7 +97,7 @@ widget *new_timeline(gui *_gui, int width, int number_of_sublines, /* public functions */ /*************************************************************************/ -void timeline_clear(gui *_gui, widget *_this) +static void _timeline_clear(gui *_gui, widget *_this, int silent) { struct gui *g = _gui; struct timeline_widget *this = _this; @@ -110,13 +110,24 @@ void timeline_clear(gui *_gui, widget *_this) for (j = 0; j < this->s[i].width; j++) this->s[i].color[j] = -1; - send_event(g, DIRTY, this->common.id); + if (silent == 0) + send_event(g, DIRTY, this->common.id); gunlock(g); } -void timeline_add_points(gui *_gui, widget *_this, int subline, int color, - int *x, int len) +void timeline_clear(gui *_gui, widget *_this) +{ + _timeline_clear(_gui, _this, 0); +} + +void timeline_clear_silent(gui *_gui, widget *_this) +{ + _timeline_clear(_gui, _this, 1); +} + +static void _timeline_add_points(gui *_gui, widget *_this, int subline, + int color, int *x, int len, int silent) { struct gui *g = _gui; struct timeline_widget *this = _this; @@ -129,11 +140,24 @@ void timeline_add_points(gui *_gui, widget *_this, int subline, int color, this->s[subline].color[x[i]] = color; } - send_event(g, DIRTY, this->common.id); + if (silent == 0) + send_event(g, DIRTY, this->common.id); gunlock(g); } +void timeline_add_points(gui *_gui, widget *_this, int subline, int color, + int *x, int len) +{ + _timeline_add_points(_gui, _this, subline, color, x, len, 0); +} + +void timeline_add_points_silent(gui *_gui, widget *_this, int subline, + int color, int *x, int len) +{ + _timeline_add_points(_gui, _this, subline, color, x, len, 1); +} + void timeline_set_subline_background_color(gui *_gui, widget *_this, int subline, int color) { From 30ffc8d20e9d3b2963e719f062b16e404146c4c0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 15 May 2016 23:17:23 +0200 Subject: [PATCH 129/217] bugfix and optimizations in view/time.c not very efficient, to be refined --- common/utils/T/tracer/view/time.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index 417760f9d5..0ef609e59a 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -101,6 +101,7 @@ static void *time_thread(void *_this) if (pthread_mutex_lock(&this->lock)) abort(); timeline_get_width(this->g, this->w, &width); + timeline_clear_silent(this->g, this->w); /* TODO: optimize/cleanup */ @@ -112,15 +113,6 @@ static void *time_thread(void *_this) struct timespec tick_start, tick_end; tick_start = time_add(tstart, nano_to_time(this->pixel_length * i)); tick_end = time_add(tick_start, nano_to_time(this->pixel_length-1)); - /* if tick is before start, do nothing */ - if (time_cmp(tick_end, - (struct timespec){tv_sec:this->tstart_time,tv_nsec:0}) < 0) - continue; - /* if tick after end, do nothing */ - if (time_cmp(tick_start, - time_add((struct timespec){tv_sec:this->tstart_time,tv_nsec:0}, - nano_to_time(this->pixel_length * width))) >= 0) - continue; /* look for a nano between tick_start and tick_end */ /* TODO: optimize */ for (t = 0; t < this->tsize; t++) { @@ -145,10 +137,12 @@ static void *time_thread(void *_this) continue; gotit: /* TODO: only one call */ - timeline_add_points(this->g, this->w, p->line, p->color, &i, 1); + timeline_add_points_silent(this->g, this->w, p->line, p->color, &i, 1); } } + widget_dirty(this->g, this->w); + if (pthread_mutex_unlock(&this->lock)) abort(); sleepms(1000 / this->refresh_rate); } @@ -212,7 +206,7 @@ static void append(view *_this, struct timespec t) /* tick out of current window? if yes, move window */ /* if too far, free all */ - if (end_time - t.tv_sec > time->tsize) { + if (t.tv_sec > end_time && t.tv_sec - end_time > time->tsize) { for (l = 0; l < time->tsize; l++) for (i = 0; i < time->subcount; i++) { free(time->t[l].p[i].nano); From 421aac43a03263b3564cbc83b82e19bb3642728f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 12:26:53 +0200 Subject: [PATCH 130/217] add skip_delay parameter to the framelog not very clean, might be reworked at some point the idea is to compute much less 'log' than what was done --- common/utils/T/tracer/logger/framelog.c | 30 +++++++++++++++++++++++++ common/utils/T/tracer/logger/logger.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/common/utils/T/tracer/logger/framelog.c b/common/utils/T/tracer/logger/framelog.c index 2b26a5b3a0..0889f2b80c 100644 --- a/common/utils/T/tracer/logger/framelog.c +++ b/common/utils/T/tracer/logger/framelog.c @@ -15,6 +15,11 @@ struct framelog { float *x; float *buffer; int blength; + int skip_delay; /* one frame over 'skip_delay' is truly processed + * 0 to disable (process all data) + */ + int skip_current; /* internal data for the skip mechanism */ + int skip_on; /* internal data for the skip mechanism */ }; static void _event(void *p, event e) @@ -30,6 +35,18 @@ static void _event(void *p, event e) buffer = e.e[l->buffer_arg].b; bsize = e.e[l->buffer_arg].bsize; + if (l->skip_delay != 0) { + if (subframe == 0) { + l->skip_current++; + if (l->skip_current >= l->skip_delay) { + l->skip_on = 0; + l->skip_current = 0; + } else + l->skip_on = 1; + } + } + if (l->skip_on) return; + nsamples = bsize / (2*sizeof(int16_t)); if (l->blength != nsamples * 10) { @@ -110,3 +127,16 @@ logger *new_framelog(event_handler *h, void *database, return ret; } + +/****************************************************************************/ +/* public functions */ +/****************************************************************************/ + +void framelog_set_skip(logger *_this, int skip_delay) +{ + struct framelog *l = _this; + /* TODO: protect with a lock? */ + l->skip_delay = skip_delay; + l->skip_current = 0; + l->skip_on = 0; +} diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index a3c09b2c23..ec04e60819 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -12,6 +12,8 @@ logger *new_ttilog(void *event_handler, void *database, char *data_varname, int convert_to_dB); logger *new_timelog(void *event_handler, void *database, char *event_name); +void framelog_set_skip(logger *_this, int skip_delay); + #include "view/view.h" void logger_add_view(logger *l, view *v); From b50fb79dd7af1dbf76ff54f7aafa01bca1bd40da Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 12:29:25 +0200 Subject: [PATCH 131/217] starting to work on the enb monitor/debugger --- common/utils/T/tracer/Makefile | 1 + common/utils/T/tracer/Makefile.remote | 4 + common/utils/T/tracer/enb.c | 226 ++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 common/utils/T/tracer/enb.c diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index b06ff4dd4d..43b7e55c16 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -6,6 +6,7 @@ local: remote: make -f Makefile.remote make -f Makefile.remote textlog + make -f Makefile.remote enb clean: make -f Makefile.local clean diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 3eadcc27da..4a8d29261a 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -15,6 +15,10 @@ textlog: utils.o textlog.o database.o event.o handler.o \ event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o textlog $^ $(LIBS) +enb: utils.o enb.o database.o event.o handler.o \ + event_selector.o view/view.a gui/gui.a logger/logger.a + $(CC) $(CFLAGS) -o enb $^ $(LIBS) + .PHONY: gui/gui.a view/view.a logger/logger.a gui/gui.a: diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c new file mode 100644 index 0000000000..837f826663 --- /dev/null +++ b/common/utils/T/tracer/enb.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include "database.h" +#include "event.h" +#include "handler.h" +#include "logger/logger.h" +#include "view/view.h" +#include "gui/gui.h" +#include "utils.h" +#include "../T_defs.h" +#include "event_selector.h" + +#define DEFAULT_REMOTE_PORT 2021 + +int get_connection(char *addr, int port) +{ + struct sockaddr_in a; + socklen_t alen; + int s, t; + + printf("waiting for connection on %s:%d\n", addr, port); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + + printf("connected\n"); + + return t; +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -on turn log ON for given GROUP or ID\n" +" -off turn log OFF for given GROUP or ID\n" +" -ON turn all logs ON\n" +" -OFF turn all logs OFF\n" +" note: you may pass several -on/-off/-ON/-OFF,\n" +" they will be processed in order\n" +" by default, all is off\n" +" -p use given port (default %d)\n" +" -debug-gui activate GUI debug logs\n", + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) { printf("read socket problem\n"); abort(); } + count -= l; + buf += l; + ret += l; + } + return ret; +} + +event get_event(int s, char *v, void *d) +{ +#ifdef T_SEND_TIME + struct timespec t; +#endif + int type; + int32_t length; + + fullread(s, &length, 4); +#ifdef T_SEND_TIME + fullread(s, &t, sizeof(struct timespec)); + length -= sizeof(struct timespec); +#endif + fullread(s, &type, sizeof(int)); + length -= sizeof(int); + fullread(s, v, length); + +#ifdef T_SEND_TIME + return new_event(t, type, length, v, d); +#else + return new_event(type, length, v, d); +#endif +} + +static void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return NULL; +} + +static void enb_main_gui(gui *g, event_handler *h, void *database) +{ + widget *main_window; + widget *top_container; + widget *line; + widget *input_signal_plot; + logger *input_signal_log; + view *input_signal_view; + + main_window = new_toplevel_window(g, 800, 600, "eNB 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); + input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20); + widget_add_child(g, line, input_signal_plot, -1); + xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70); + input_signal_log = new_framelog(h, database, + "ENB_INPUT_SIGNAL", "subframe", "rxdata"); + /* a skip value of 10 means to process 1 frame over 10, that is + * more or less 10 frames per second + */ + framelog_set_skip(input_signal_log, 10); + input_signal_view = new_view_xy(7680*10, 10, + g, input_signal_plot, new_color(g, "#0c0c72")); + logger_add_view(input_signal_log, input_signal_view); +} + +int main(int n, char **v) +{ + extern int volatile gui_logd; + char *database_filename = NULL; + void *database; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int s; + int i; + char t; + int l; + event_handler *h; + gui *g; + + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); + on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-ON")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-OFF")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + h = new_handler(database); + + g = gui_init(); + new_thread(gui_thread, g); + + enb_main_gui(g, h, database); + + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); + + s = get_connection("0.0.0.0", port); + + /* send the first message - activate selected traces */ + t = 0; + if (write(s, &t, 1) != 1) abort(); + l = 0; + for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + for (l = 0; l < number_of_events; l++) + if (is_on[l]) + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + + setup_event_selector(g, database, s, is_on); + + /* read messages */ + while (1) { + char v[T_BUFFER_MAX]; + event e; + e = get_event(s, v, database); + handle_event(h, e); + } + + return 0; +} From 7d1665fe42121b1cf481764d4ee8f9f3be7f23d7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 15:06:45 +0200 Subject: [PATCH 132/217] add a timelog to enb.c --- common/utils/T/tracer/enb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 837f826663..974db118ca 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -119,6 +119,11 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) widget *input_signal_plot; logger *input_signal_log; view *input_signal_view; + widget *timeline_plot; + logger *input_signal_timelog; + view *input_signal_timeview; + view *input_signal_subview; + int i; main_window = new_toplevel_window(g, 800, 600, "eNB tracer"); top_container = new_container(g, VERTICAL); @@ -138,6 +143,20 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) input_signal_view = new_view_xy(7680*10, 10, g, input_signal_plot, new_color(g, "#0c0c72")); logger_add_view(input_signal_log, input_signal_view); + + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + timeline_plot = new_timeline(g, 512, 16, 5); + widget_add_child(g, line, timeline_plot, -1); + container_set_child_growable(g, line, timeline_plot, 1); + for (i = 0; i < 16; i++) + timeline_set_subline_background_color(g, timeline_plot, i, + new_color(g, i & 1 ? "#ddd" : "#eee")); + input_signal_timelog = new_timelog(h, database, "ENB_INPUT_SIGNAL"); + input_signal_timeview = new_view_time(3600, 10, g, timeline_plot); + input_signal_subview = new_subview_time(input_signal_timeview, + 0, FOREGROUND_COLOR); + logger_add_view(input_signal_timelog, input_signal_subview); } int main(int n, char **v) From 2e7ab60d703a741383f3873449a60ab744d844c4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 16:18:29 +0200 Subject: [PATCH 133/217] zoom in/out in timeline --- common/utils/T/tracer/gui/gui.h | 2 ++ common/utils/T/tracer/gui/timeline.c | 16 ++++++++++++++++ common/utils/T/tracer/view/time.c | 27 ++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index bb1a495849..e470d2d366 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -81,6 +81,8 @@ int new_color(gui *gui, char *color); * - click { int: button } (if enabled) * - timeline * - resize { int: width } + * - scrollup { void *: NULL } + * - scrolldown { void *: NULL } */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index 0902078071..e627567aaf 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -54,6 +54,21 @@ static void allocate(gui *_gui, widget *_this, gui_notify(_gui, "resize", _this, &width); } +static void button(gui *_g, widget *_this, int x, int y, int button, int up) +{ + struct gui *g = _g; + struct timeline_widget *this = _this; + LOGD("BUTTON timeline %p xy %d %d button %d up %d\n", _this, x, y, button, up); + /* scroll up */ + if (button == 4 && up == 0) { + gui_notify(g, "scrollup", _this, NULL); + } + /* scroll down */ + if (button == 5 && up == 0) { + gui_notify(g, "scrolldown", _this, NULL); + } +} + /*************************************************************************/ /* creation function */ /*************************************************************************/ @@ -87,6 +102,7 @@ widget *new_timeline(gui *_gui, int width, int number_of_sublines, w->common.paint = paint; w->common.hints = hints; w->common.allocate = allocate; + w->common.button = button; gunlock(g); diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index 0ef609e59a..9d6607b32b 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -3,6 +3,7 @@ #include #include #include +#include /****************************************************************************/ /* timeview */ @@ -37,7 +38,7 @@ struct time { time_t tstart_time; /* timestamp (in seconds) of starting in t */ int subcount; /* number of subviews */ struct timespec latest_time; /* time of latest received tick */ - int64_t pixel_length; /* unit: nanosecond (maximum 1 hour/pixel) */ + double pixel_length; /* unit: nanosecond (maximum 1 hour/pixel) */ }; /* TODO: put that function somewhere else (utils.c) */ @@ -150,6 +151,27 @@ gotit: return 0; } +static void scroll(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + struct time *this = private; + double mul = 1.2; + double pixel_length; + + if (pthread_mutex_lock(&this->lock)) abort(); + + if (!strcmp(notification, "scrollup")) mul = 1 / mul; + + pixel_length = this->pixel_length * mul; + if (pixel_length < 1) pixel_length = 1; + if (pixel_length > (double)3600 * 1000000000) + pixel_length = (double)3600 * 1000000000; + + this->pixel_length = pixel_length; + + if (pthread_mutex_unlock(&this->lock)) abort(); +} + view *new_view_time(int number_of_seconds, float refresh_rate, gui *g, widget *w) { @@ -168,6 +190,9 @@ view *new_view_time(int number_of_seconds, float refresh_rate, ret->subcount = 0; ret->pixel_length = 10 * 1000000; /* 10ms */ + register_notifier(g, "scrollup", w, scroll, ret); + register_notifier(g, "scrolldown", w, scroll, ret); + if (pthread_mutex_init(&ret->lock, NULL)) abort(); new_thread(time_thread, ret); From f8ae07d3884608241d3ad6cccb154b000e39171b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 17:05:14 +0200 Subject: [PATCH 134/217] bugfixes in view/time.c --- common/utils/T/tracer/view/time.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index 9d6607b32b..efa0f61c52 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -97,6 +97,7 @@ static void *time_thread(void *_this) struct timespec tstart; struct timespec tnext; struct plot *p; + int64_t pixel_length; while (1) { if (pthread_mutex_lock(&this->lock)) abort(); @@ -106,14 +107,17 @@ static void *time_thread(void *_this) /* TODO: optimize/cleanup */ + /* use rounded pixel_length */ + pixel_length = this->pixel_length; + tnext = time_add(this->latest_time,(struct timespec){tv_sec:0,tv_nsec:1}); - tstart = time_sub(tnext, nano_to_time(this->pixel_length * width)); + tstart = time_sub(tnext, nano_to_time(pixel_length * width)); for (l = 0; l < this->subcount; l++) { for (i = 0; i < width; i++) { struct timespec tick_start, tick_end; - tick_start = time_add(tstart, nano_to_time(this->pixel_length * i)); - tick_end = time_add(tick_start, nano_to_time(this->pixel_length-1)); + tick_start = time_add(tstart, nano_to_time(pixel_length * i)); + tick_end = time_add(tick_start, nano_to_time(pixel_length-1)); /* look for a nano between tick_start and tick_end */ /* TODO: optimize */ for (t = 0; t < this->tsize; t++) { @@ -131,7 +135,7 @@ static void *time_thread(void *_this) struct timespec nano = (struct timespec){tv_sec:current_second,tv_nsec:p->nano[n]}; if (time_cmp(tick_start, nano) <= 0 && - time_cmp(nano, tick_end) < 0) + time_cmp(nano, tick_end) <= 0) goto gotit; } } @@ -157,11 +161,15 @@ static void scroll(void *private, gui *g, struct time *this = private; double mul = 1.2; double pixel_length; + int64_t old_px_len_rounded; if (pthread_mutex_lock(&this->lock)) abort(); + old_px_len_rounded = this->pixel_length; + if (!strcmp(notification, "scrollup")) mul = 1 / mul; +again: pixel_length = this->pixel_length * mul; if (pixel_length < 1) pixel_length = 1; if (pixel_length > (double)3600 * 1000000000) @@ -169,6 +177,16 @@ static void scroll(void *private, gui *g, this->pixel_length = pixel_length; + /* due to rounding, we may need to zoom by more than 1.2 with + * very close lookup, otherwise the user zooming command won't + * be visible (say length is 2.7, zoom in, new length is 2.25, + * and rounding is 2, same value, no change, no feedback to user => bad) + * TODO: make all this cleaner + */ + if (pixel_length != 1 && pixel_length != (double)3600 * 1000000000 && + (int64_t)pixel_length == old_px_len_rounded) + goto again; + if (pthread_mutex_unlock(&this->lock)) abort(); } From 5822e94e5f33ab6f4519ac7582a0f423399caf88 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 17:33:45 +0200 Subject: [PATCH 135/217] starting work on DL/UL DCI graphical logging --- common/utils/T/T_messages.txt | 8 +++++ common/utils/T/tracer/enb.c | 40 ++++++++++++++++++------- openair1/SCHED/phy_procedures_lte_eNb.c | 4 +++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 87627cfe4a..1691f4517e 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,4 +1,12 @@ #PHY logs +ID = ENB_UL_TICK + DESC = eNodeB uplink tick - one tick per ms at start of uplink processing + GROUP = ALL:PHY:GRAPHIC + FORMAT = int,eNB_ID : int,frame : int,subframe +ID = ENB_DL_TICK + DESC = eNodeB downlink tick - one tick per ms at start of downlink processing + GROUP = ALL:PHY:GRAPHIC + FORMAT = int,eNB_ID : int,frame : int,subframe ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms GROUP = ALL:PHY:GRAPHIC:HEAVY diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 974db118ca..c3172a612f 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -120,9 +120,9 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) logger *input_signal_log; view *input_signal_view; widget *timeline_plot; - logger *input_signal_timelog; - view *input_signal_timeview; - view *input_signal_subview; + logger *timelog; + view *timeview; + view *subview; int i; main_window = new_toplevel_window(g, 800, 600, "eNB tracer"); @@ -144,19 +144,35 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) g, input_signal_plot, new_color(g, "#0c0c72")); logger_add_view(input_signal_log, input_signal_view); + /* downlink UE DCIs */ line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); - timeline_plot = new_timeline(g, 512, 16, 5); + timeline_plot = new_timeline(g, 512, 4, 5); widget_add_child(g, line, timeline_plot, -1); container_set_child_growable(g, line, timeline_plot, 1); - for (i = 0; i < 16; i++) + for (i = 0; i < 4; i++) timeline_set_subline_background_color(g, timeline_plot, i, new_color(g, i & 1 ? "#ddd" : "#eee")); - input_signal_timelog = new_timelog(h, database, "ENB_INPUT_SIGNAL"); - input_signal_timeview = new_view_time(3600, 10, g, timeline_plot); - input_signal_subview = new_subview_time(input_signal_timeview, - 0, FOREGROUND_COLOR); - logger_add_view(input_signal_timelog, input_signal_subview); + timelog = new_timelog(h, database, "ENB_DL_TICK"); + timeview = new_view_time(3600, 10, g, timeline_plot); + subview = new_subview_time(timeview, 0, FOREGROUND_COLOR); + logger_add_view(timelog, subview); + widget_add_child(g, line, new_label(g,"DL TICK/DCI/ACK/NACK "), 0); + + /* uplink UE DCIs */ + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + timeline_plot = new_timeline(g, 512, 4, 5); + widget_add_child(g, line, timeline_plot, -1); + container_set_child_growable(g, line, timeline_plot, 1); + for (i = 0; i < 4; i++) + timeline_set_subline_background_color(g, timeline_plot, i, + new_color(g, i & 1 ? "#ddd" : "#eee")); + timelog = new_timelog(h, database, "ENB_UL_TICK"); + timeview = new_view_time(3600, 10, g, timeline_plot); + subview = new_subview_time(timeview, 0, FOREGROUND_COLOR); + logger_add_view(timelog, subview); + widget_add_child(g, line, new_label(g,"UL TICK/DCI/ACK/NACK "), 0); } int main(int n, char **v) @@ -216,6 +232,10 @@ int main(int n, char **v) enb_main_gui(g, h, database); + on_off(database, "ENB_INPUT_SIGNAL", is_on, 1); + on_off(database, "ENB_UL_TICK", is_on, 1); + on_off(database, "ENB_DL_TICK", is_on, 1); + for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 7bf32eba48..2566adc4c6 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -651,6 +651,8 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e phy_vars_eNB->Mod_id, frame, subframe); #endif + T(T_ENB_DL_TICK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe)); + for (i=0; iMod_id,frame, subframe); #endif + T(T_ENB_UL_TICK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe)); + T(T_ENB_INPUT_SIGNAL, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), T_BUFFER(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti], phy_vars_eNB->lte_frame_parms.samples_per_tti * 4)); From bc3aa8581fbfe89586d86d1b0955baa6f36bbe31 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 17:36:08 +0200 Subject: [PATCH 136/217] add group ENB to T_messages.txt --- common/utils/T/T_messages.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 1691f4517e..37db1cad27 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,31 +1,31 @@ #PHY logs ID = ENB_UL_TICK DESC = eNodeB uplink tick - one tick per ms at start of uplink processing - GROUP = ALL:PHY:GRAPHIC + GROUP = ALL:PHY:GRAPHIC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe ID = ENB_DL_TICK DESC = eNodeB downlink tick - one tick per ms at start of downlink processing - GROUP = ALL:PHY:GRAPHIC + GROUP = ALL:PHY:GRAPHIC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms - GROUP = ALL:PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata ID = ENB_UL_CHANNEL_ESTIMATE DESC = eNodeB channel estimation in the time domain - GROUP = ALL:PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t ID = PUSCH_IQ DESC = eNodeB PUSCH received IQ data - GROUP = ALL:PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : buffer,pusch_comp ID = PUCCH_1AB_IQ DESC = eNodeB PUCCH received IQ data - GROUP = ALL:PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,I : int,Q ID = PUCCH_1_ENERGY DESC = eNodeB PUCCH 1 energy and threshold - GROUP = ALL:PHY:GRAPHIC:HEAVY + GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold #legacy logs From b0ee0f4c8206613621ac98242a2050c941f4681c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 18:10:36 +0200 Subject: [PATCH 137/217] add UE downlink DCI logging --- common/utils/T/T_messages.txt | 4 ++++ common/utils/T/tracer/enb.c | 26 +++++++++++-------------- openair1/SCHED/phy_procedures_lte_eNb.c | 3 +++ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 37db1cad27..e86cfa43a6 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -7,6 +7,10 @@ ID = ENB_DL_TICK DESC = eNodeB downlink tick - one tick per ms at start of downlink processing GROUP = ALL:PHY:GRAPHIC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe +ID = ENB_DLSCH_UE_DCI + DESC = eNodeB downlink UE specific DCI as sent by the PHY layer + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index c3172a612f..8ebc1bdf12 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -147,32 +147,27 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) /* downlink UE DCIs */ line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); - timeline_plot = new_timeline(g, 512, 4, 5); + timeline_plot = new_timeline(g, 512, 8, 5); widget_add_child(g, line, timeline_plot, -1); container_set_child_growable(g, line, timeline_plot, 1); - for (i = 0; i < 4; i++) + widget_add_child(g, line, new_label(g,"DL/UL TICK/DCI/ACK/NACK "), 0); + for (i = 0; i < 8; i++) timeline_set_subline_background_color(g, timeline_plot, i, new_color(g, i & 1 ? "#ddd" : "#eee")); - timelog = new_timelog(h, database, "ENB_DL_TICK"); timeview = new_view_time(3600, 10, g, timeline_plot); + /* tick logging */ + timelog = new_timelog(h, database, "ENB_DL_TICK"); subview = new_subview_time(timeview, 0, FOREGROUND_COLOR); logger_add_view(timelog, subview); - widget_add_child(g, line, new_label(g,"DL TICK/DCI/ACK/NACK "), 0); + /* DCI logging */ + timelog = new_timelog(h, database, "ENB_DLSCH_UE_DCI"); + subview = new_subview_time(timeview, 1, new_color(g, "#228")); + logger_add_view(timelog, subview); /* uplink UE DCIs */ - line = new_container(g, HORIZONTAL); - widget_add_child(g, top_container, line, -1); - timeline_plot = new_timeline(g, 512, 4, 5); - widget_add_child(g, line, timeline_plot, -1); - container_set_child_growable(g, line, timeline_plot, 1); - for (i = 0; i < 4; i++) - timeline_set_subline_background_color(g, timeline_plot, i, - new_color(g, i & 1 ? "#ddd" : "#eee")); timelog = new_timelog(h, database, "ENB_UL_TICK"); - timeview = new_view_time(3600, 10, g, timeline_plot); - subview = new_subview_time(timeview, 0, FOREGROUND_COLOR); + subview = new_subview_time(timeview, 4, FOREGROUND_COLOR); logger_add_view(timelog, subview); - widget_add_child(g, line, new_label(g,"UL TICK/DCI/ACK/NACK "), 0); } int main(int n, char **v) @@ -235,6 +230,7 @@ int main(int n, char **v) on_off(database, "ENB_INPUT_SIGNAL", is_on, 1); on_off(database, "ENB_UL_TICK", is_on, 1); on_off(database, "ENB_DL_TICK", is_on, 1); + on_off(database, "ENB_DLSCH_UE_DCI", is_on, 1); for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 2566adc4c6..29b632ecb9 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1162,6 +1162,9 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e else UE_id = i; + T(T_ENB_DLSCH_UE_DCI, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), + T_INT(DCI_pdu->dci_alloc[i].rnti), T_INT(DCI_pdu->dci_alloc[i].format)); + if (UE_id>=0) { if ((frame%100)==0) { LOG_D(PHY,"Frame %3d, SF %d \n",frame,subframe); From 0e033810166878f6a71253be60fbbda0ec6add97 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 17 May 2016 18:48:11 +0200 Subject: [PATCH 138/217] log ack/nack at phy level (process_harq_feedback) --- common/utils/T/T_messages.txt | 8 ++++++++ common/utils/T/tracer/enb.c | 10 ++++++++++ openair1/SCHED/phy_procedures_lte_eNb.c | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index e86cfa43a6..e437f7f2b9 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -11,6 +11,14 @@ ID = ENB_DLSCH_UE_DCI DESC = eNodeB downlink UE specific DCI as sent by the PHY layer GROUP = ALL:PHY:GRAPHIC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format +ID = ENB_DLSCH_UE_ACK + DESC = eNodeB downlink UE ACK as seen by the PHY layer in process_HARQ_feedback + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti +ID = ENB_DLSCH_UE_NACK + DESC = eNodeB downlink UE NACK as seen by the PHY layer in process_HARQ_feedback + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 8ebc1bdf12..5cd59a811c 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -163,6 +163,14 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) timelog = new_timelog(h, database, "ENB_DLSCH_UE_DCI"); subview = new_subview_time(timeview, 1, new_color(g, "#228")); logger_add_view(timelog, subview); + /* ACK */ + timelog = new_timelog(h, database, "ENB_DLSCH_UE_ACK"); + subview = new_subview_time(timeview, 2, new_color(g, "#282")); + logger_add_view(timelog, subview); + /* NACK */ + timelog = new_timelog(h, database, "ENB_DLSCH_UE_NACK"); + subview = new_subview_time(timeview, 3, new_color(g, "#f22")); + logger_add_view(timelog, subview); /* uplink UE DCIs */ timelog = new_timelog(h, database, "ENB_UL_TICK"); @@ -231,6 +239,8 @@ int main(int n, char **v) on_off(database, "ENB_UL_TICK", is_on, 1); on_off(database, "ENB_DL_TICK", is_on, 1); on_off(database, "ENB_DLSCH_UE_DCI", is_on, 1); + on_off(database, "ENB_DLSCH_UE_ACK", is_on, 1); + on_off(database, "ENB_DLSCH_UE_NACK", is_on, 1); for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 29b632ecb9..e251bddbee 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2051,6 +2051,8 @@ void process_HARQ_feedback(uint8_t UE_id, dlsch->rnti,dl_harq_pid[m],M,m,mp,dlsch_harq_proc->round); #endif + T(T_ENB_DLSCH_UE_NACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), T_INT(dlsch->rnti)); + if (dlsch_harq_proc->round == 0) ue_stats->dlsch_NAK_round0++; @@ -2083,6 +2085,9 @@ void process_HARQ_feedback(uint8_t UE_id, LOG_D(PHY,"[eNB %d][PDSCH %x/%d] ACK Received in round %d, resetting process\n",phy_vars_eNB->Mod_id, dlsch->rnti,dl_harq_pid[m],dlsch_harq_proc->round); #endif + + T(T_ENB_DLSCH_UE_ACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), T_INT(dlsch->rnti)); + ue_stats->dlsch_ACK[dl_harq_pid[m]][dlsch_harq_proc->round]++; // Received ACK so set round to 0 and set dlsch_harq_pid IDLE From 262ab7090cff3415183ee0cd96f660a8c2f66131 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 14:55:48 +0200 Subject: [PATCH 139/217] bugfix/improve/simplify view/time.c --- common/utils/T/tracer/enb.c | 10 +- common/utils/T/tracer/view/time.c | 179 ++++++++++-------------------- common/utils/T/tracer/view/view.h | 2 +- 3 files changed, 65 insertions(+), 126 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 5cd59a811c..19cac762af 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -157,24 +157,24 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) timeview = new_view_time(3600, 10, g, timeline_plot); /* tick logging */ timelog = new_timelog(h, database, "ENB_DL_TICK"); - subview = new_subview_time(timeview, 0, FOREGROUND_COLOR); + subview = new_subview_time(timeview, 0, FOREGROUND_COLOR, 3600*1000); logger_add_view(timelog, subview); /* DCI logging */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_DCI"); - subview = new_subview_time(timeview, 1, new_color(g, "#228")); + subview = new_subview_time(timeview, 1, new_color(g, "#228"), 3600*1000); logger_add_view(timelog, subview); /* ACK */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_ACK"); - subview = new_subview_time(timeview, 2, new_color(g, "#282")); + subview = new_subview_time(timeview, 2, new_color(g, "#282"), 3600*1000); logger_add_view(timelog, subview); /* NACK */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_NACK"); - subview = new_subview_time(timeview, 3, new_color(g, "#f22")); + subview = new_subview_time(timeview, 3, new_color(g, "#f22"), 3600*1000); logger_add_view(timelog, subview); /* uplink UE DCIs */ timelog = new_timelog(h, database, "ENB_UL_TICK"); - subview = new_subview_time(timeview, 4, FOREGROUND_COLOR); + subview = new_subview_time(timeview, 4, FOREGROUND_COLOR, 3600*1000); logger_add_view(timelog, subview); } diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index efa0f61c52..43f30cc403 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -10,35 +10,24 @@ /****************************************************************************/ struct plot { - long *nano; - int nanosize; - int nanomaxsize; + struct timespec *tick; + int ticksize; + int tickmaxsize; + int tickstart; int line; int color; }; -struct tick { - struct plot *p; /* one plot per subview, - * so size is 'subcount' - * (see in struct time below) - */ -}; - struct time { view common; gui *g; widget *w; float refresh_rate; pthread_mutex_t lock; - struct tick *t; /* t is a circular list - * a tick lasts one second - */ - int tsize; /* size of t */ - int tstart; /* starting index in t */ - time_t tstart_time; /* timestamp (in seconds) of starting in t */ - int subcount; /* number of subviews */ - struct timespec latest_time; /* time of latest received tick */ + struct plot *p; + int psize; double pixel_length; /* unit: nanosecond (maximum 1 hour/pixel) */ + struct timespec latest_time; }; /* TODO: put that function somewhere else (utils.c) */ @@ -87,13 +76,33 @@ static int time_cmp(struct timespec a, struct timespec b) return 0; } +static int interval_empty(struct time *this, int sub, + struct timespec start, struct timespec end) +{ + int a, b, mid; + int i; + + if (this->p[sub].ticksize == 0) return 1; + + /* look for a tick larger than start and smaller than end */ + a = 0; + b = this->p[sub].ticksize - 1; + while (b >= a) { + mid = (a+b) / 2; + i = (this->p[sub].tickstart + mid) % this->p[sub].ticksize; + if (time_cmp(this->p[sub].tick[i], start) < 0) a = mid + 1; + else if (time_cmp(this->p[sub].tick[i], end) > 0) b = mid - 1; + else return 0; + } + return 1; +} + static void *time_thread(void *_this) { struct time *this = _this; int width; int l; int i; - int t; struct timespec tstart; struct timespec tnext; struct plot *p; @@ -105,7 +114,7 @@ static void *time_thread(void *_this) timeline_get_width(this->g, this->w, &width); timeline_clear_silent(this->g, this->w); - /* TODO: optimize/cleanup */ + /* TODO: optimize? */ /* use rounded pixel_length */ pixel_length = this->pixel_length; @@ -113,34 +122,14 @@ static void *time_thread(void *_this) tnext = time_add(this->latest_time,(struct timespec){tv_sec:0,tv_nsec:1}); tstart = time_sub(tnext, nano_to_time(pixel_length * width)); - for (l = 0; l < this->subcount; l++) { + for (l = 0; l < this->psize; l++) { for (i = 0; i < width; i++) { struct timespec tick_start, tick_end; tick_start = time_add(tstart, nano_to_time(pixel_length * i)); tick_end = time_add(tick_start, nano_to_time(pixel_length-1)); - /* look for a nano between tick_start and tick_end */ - /* TODO: optimize */ - for (t = 0; t < this->tsize; t++) { - int n; - time_t current_second = this->tstart_time + t; - time_t next_second = current_second + 1; - struct timespec current_time = - (struct timespec){tv_sec:current_second,tv_nsec:0}; - struct timespec next_time = - (struct timespec){tv_sec:next_second,tv_nsec:0}; - if (time_cmp(tick_end, current_time) < 0) continue; - if (time_cmp(tick_start, next_time) >= 0) continue; - p = &this->t[(this->tstart + t) % this->tsize].p[l]; - for (n = 0; n < p->nanosize; n++) { - struct timespec nano = - (struct timespec){tv_sec:current_second,tv_nsec:p->nano[n]}; - if (time_cmp(tick_start, nano) <= 0 && - time_cmp(nano, tick_end) <= 0) - goto gotit; - } - } - continue; -gotit: + if (interval_empty(this, l, tick_start, tick_end)) + continue; + p = &this->p[l]; /* TODO: only one call */ timeline_add_points_silent(this->g, this->w, p->line, p->color, &i, 1); } @@ -200,13 +189,11 @@ view *new_view_time(int number_of_seconds, float refresh_rate, ret->g = g; ret->w = w; - ret->t = calloc(number_of_seconds, sizeof(struct tick)); - if (ret->t == NULL) abort(); - ret->tsize = number_of_seconds; - ret->tstart = 0; - ret->tstart_time = 0; - ret->subcount = 0; - ret->pixel_length = 10 * 1000000; /* 10ms */ + ret->p = NULL; + ret->psize = 0; + + /* default pixel length: 10ms */ + ret->pixel_length = 10 * 1000000; register_notifier(g, "scrollup", w, scroll, ret); register_notifier(g, "scrolldown", w, scroll, ret); @@ -234,74 +221,26 @@ static void append(view *_this, struct timespec t) { struct subtime *this = (struct subtime *)_this; struct time *time = this->parent; - time_t start_time, end_time; - int i, l; - int tpos; - struct plot *p; + struct plot *p = &time->p[this->subview]; if (pthread_mutex_lock(&time->lock)) abort(); - start_time = time->tstart_time; - end_time = time->tstart_time + time->tsize - 1; - - /* useless test? */ - if (t.tv_sec < start_time) abort(); - - /* tick out of current window? if yes, move window */ - /* if too far, free all */ - if (t.tv_sec > end_time && t.tv_sec - end_time > time->tsize) { - for (l = 0; l < time->tsize; l++) - for (i = 0; i < time->subcount; i++) { - free(time->t[l].p[i].nano); - time->t[l].p[i].nano = NULL; - time->t[l].p[i].nanosize = 0; - time->t[l].p[i].nanomaxsize = 0; - } - time->tstart = 0; - time->tstart_time = t.tv_sec - (time->tsize-1); - start_time = time->tstart_time; - end_time = time->tstart_time + time->tsize - 1; - } - while (t.tv_sec > end_time) { - for (i = 0; i < time->subcount; i++) { - free(time->t[time->tstart].p[i].nano); - time->t[time->tstart].p[i].nano = NULL; - time->t[time->tstart].p[i].nanosize = 0; - time->t[time->tstart].p[i].nanomaxsize = 0; - } - time->tstart = (time->tstart+1) % time->tsize; - time->tstart_time++; - start_time++; - end_time++; + if (p->ticksize < p->tickmaxsize) { + p->tick[p->ticksize] = t; + p->ticksize++; + } else { + p->tick[p->tickstart] = t; + p->tickstart = (p->tickstart + 1) % p->ticksize; } - tpos = (time->tstart + (t.tv_sec - time->tstart_time)) % time->tsize; - p = &time->t[tpos].p[this->subview]; - - /* can we get a new event with <= time than last in list? */ - if (p->nanosize != 0 && t.tv_nsec <= p->nano[p->nanosize-1]) - { printf("%s:%d: possible?\n", __FILE__, __LINE__); abort(); } - - if (p->nanosize == p->nanomaxsize) { - p->nanomaxsize += 4096; - p->nano = realloc(p->nano, p->nanomaxsize * sizeof(long)); - if (p->nano == NULL) abort(); - } - - p->nano[p->nanosize] = t.tv_nsec; - p->nanosize++; - - if (time->latest_time.tv_sec < t.tv_sec || - (time->latest_time.tv_sec == t.tv_sec && - time->latest_time.tv_nsec < t.tv_nsec)) + if (time_cmp(time->latest_time, t) < 0) time->latest_time = t; if (pthread_mutex_unlock(&time->lock)) abort(); } -view *new_subview_time(view *_time, int line, int color) +view *new_subview_time(view *_time, int line, int color, int size) { - int i; struct time *time = (struct time *)_time; struct subtime *ret = calloc(1, sizeof(struct subtime)); if (ret == NULL) abort(); @@ -313,20 +252,20 @@ view *new_subview_time(view *_time, int line, int color) ret->parent = time; ret->line = line; ret->color = color; - ret->subview = time->subcount; + ret->subview = time->psize; - for (i = 0; i < time->tsize; i++) { - time->t[i].p = realloc(time->t[i].p, - (time->subcount + 1) * sizeof(struct plot)); - if (time->t[i].p == NULL) abort(); - time->t[i].p[time->subcount].nano = NULL; - time->t[i].p[time->subcount].nanosize = 0; - time->t[i].p[time->subcount].nanomaxsize = 0; - time->t[i].p[time->subcount].line = line; - time->t[i].p[time->subcount].color = color; - } + time->p = realloc(time->p, + (time->psize + 1) * sizeof(struct plot)); + if (time->p == NULL) abort(); + time->p[time->psize].tick = calloc(size, sizeof(struct timespec)); + if (time->p[time->psize].tick == NULL) abort(); + time->p[time->psize].ticksize = 0; + time->p[time->psize].tickmaxsize = size; + time->p[time->psize].tickstart = 0; + time->p[time->psize].line = line; + time->p[time->psize].color = color; - time->subcount++; + time->psize++; if (pthread_mutex_unlock(&time->lock)) abort(); diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 8d8036721c..4b91291b1c 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -19,6 +19,6 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color); 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); +view *new_subview_time(view *time, int line, int color, int size); #endif /* _VIEW_H_ */ From 4511fe7778dafe3cdeacff72cddd7bc15a4f4b42 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 15:28:28 +0200 Subject: [PATCH 140/217] add key modifiers to button event --- common/utils/T/tracer/gui/container.c | 8 ++++---- common/utils/T/tracer/gui/gui.h | 5 +++++ common/utils/T/tracer/gui/gui_defs.h | 3 ++- common/utils/T/tracer/gui/label.c | 6 ++++-- common/utils/T/tracer/gui/positioner.c | 5 +++-- common/utils/T/tracer/gui/textlist.c | 3 ++- common/utils/T/tracer/gui/timeline.c | 3 ++- common/utils/T/tracer/gui/toplevel_window.c | 5 +++-- common/utils/T/tracer/gui/widget.c | 8 ++++---- common/utils/T/tracer/gui/x.c | 12 ++++++++++-- 10 files changed, 39 insertions(+), 19 deletions(-) diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index d3ce2a110b..8de4347933 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -227,7 +227,7 @@ static void horizontal_hints(gui *_gui, widget *_w, int *width, int *height) } static void horizontal_button(gui *_g, widget *_this, int x, int y, - int button, int up) + int key_modifiers, int button, int up) { LOGD("BUTTON container horizontal %p xy %d %d button %d up %d\n", _this, x, y, button, up); struct gui *g = _g; @@ -237,7 +237,7 @@ static void horizontal_button(gui *_g, widget *_this, int x, int y, l = this->common.children; while (l) { if (l->item->x <= x && x < l->item->x + l->item->width) { - l->item->button(g, l->item, x, y, button, up); + l->item->button(g, l->item, x, y, key_modifiers, button, up); break; } l = l->next; @@ -245,7 +245,7 @@ static void horizontal_button(gui *_g, widget *_this, int x, int y, } static void vertical_button(gui *_g, widget *_this, int x, int y, - int button, int up) + int key_modifiers, int button, int up) { LOGD("BUTTON container vertical %p xy %d %d button %d up %d\n", _this, x, y, button, up); struct gui *g = _g; @@ -255,7 +255,7 @@ static void vertical_button(gui *_g, widget *_this, int x, int y, l = this->common.children; while (l) { if (l->item->y <= y && y < l->item->y + l->item->height) { - l->item->button(g, l->item, x, y, button, up); + l->item->button(g, l->item, x, y, key_modifiers, button, up); break; } l = l->next; diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index e470d2d366..5ae623f559 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -12,6 +12,11 @@ typedef void widget; #define BACKGROUND_COLOR 0 #define FOREGROUND_COLOR 1 +/* key modifiers */ +#define KEY_SHIFT (1<<0) +#define KEY_CONTROL (1<<1) +#define KEY_ALT (1<<2) + gui *gui_init(void); /* position = -1 to put at the end */ diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 8f15747490..5b8469ad9a 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -53,7 +53,8 @@ struct widget { void (*paint)(gui *g, widget *this); void (*clear)(gui *g, widget *this); /* user input */ - void (*button)(gui *g, widget *this, int x, int y, int button, int up); + void (*button)(gui *g, widget *this, int x, int y, int key_modifiers, + int button, int up); }; struct widget_list { diff --git a/common/utils/T/tracer/gui/label.c b/common/utils/T/tracer/gui/label.c index 80d885f1d2..bbe6e98eaf 100644 --- a/common/utils/T/tracer/gui/label.c +++ b/common/utils/T/tracer/gui/label.c @@ -45,7 +45,8 @@ widget *new_label(gui *_gui, const char *label) return w; } -static void button(gui *gui, widget *_this, int x, int y, int button, int up) +static void button(gui *gui, widget *_this, int x, int y, + int key_modifiers, int button, int up) { LOGD("BUTTON label %p xy %d %d button %d up %d\n", _this, x, y, button, up); @@ -55,7 +56,8 @@ static void button(gui *gui, widget *_this, int x, int y, int button, int up) } /* we could use default_button, but it's in widget.c, so, well... */ -static void no_button(gui *gui, widget *_this, int x,int y,int button,int up) +static void no_button(gui *gui, widget *_this, int x, int y, + int key_modifiers, int button, int up) { /* do nothing */ } diff --git a/common/utils/T/tracer/gui/positioner.c b/common/utils/T/tracer/gui/positioner.c index 5bd23e147e..673ffb32de 100644 --- a/common/utils/T/tracer/gui/positioner.c +++ b/common/utils/T/tracer/gui/positioner.c @@ -50,14 +50,15 @@ static void hints(gui *_gui, widget *_w, int *width, int *height) else { *width = *height = 1; } } -static void button(gui *_g, widget *_this, int x, int y, int button, int up) +static void button(gui *_g, widget *_this, int x, int y, + int key_modifiers, int button, int up) { LOGD("BUTTON positioner %p xy %d %d button %d up %d\n", _this, x, y, button, up); struct gui *g = _g; struct positioner_widget *this = _this; struct widget_list *l = this->common.children; if (l != NULL) - l->item->button(g, l->item, x, y, button, up); + l->item->button(g, l->item, x, y, key_modifiers, button, up); } static void paint(gui *_gui, widget *_this) diff --git a/common/utils/T/tracer/gui/textlist.c b/common/utils/T/tracer/gui/textlist.c index 50a21cd459..6803d2301d 100644 --- a/common/utils/T/tracer/gui/textlist.c +++ b/common/utils/T/tracer/gui/textlist.c @@ -44,7 +44,8 @@ static void allocate( LOGD("ALLOCATE textlist %p xywh %d %d %d %d nlines %d\n", this, x, y, width, height, this->allocated_nlines); } -static void button(gui *_g, widget *_this, int x, int y, int button, int up) +static void button(gui *_g, widget *_this, int x, int y, + int key_modifiers, int button, int up) { struct gui *g = _g; struct textlist_widget *this = _this; diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index e627567aaf..43cbcc525f 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -54,7 +54,8 @@ static void allocate(gui *_gui, widget *_this, gui_notify(_gui, "resize", _this, &width); } -static void button(gui *_g, widget *_this, int x, int y, int button, int up) +static void button(gui *_g, widget *_this, int x, int y, + int key_modifiers, int button, int up) { struct gui *g = _g; struct timeline_widget *this = _this; diff --git a/common/utils/T/tracer/gui/toplevel_window.c b/common/utils/T/tracer/gui/toplevel_window.c index 03d5091bc7..d2436c84f9 100644 --- a/common/utils/T/tracer/gui/toplevel_window.c +++ b/common/utils/T/tracer/gui/toplevel_window.c @@ -55,13 +55,14 @@ static void paint(gui *_gui, widget *_this) g->xwin = NULL; /* TODO: remove? it's just in case */ } -static void button(gui *_g, widget *_this, int x, int y, int button, int up) +static void button(gui *_g, widget *_this, int x, int y, + int key_modifiers, int button, int up) { struct gui *g = _g; struct toplevel_window_widget *this = _this; g->xwin = this->x; this->common.children->item->button(_g, this->common.children->item, - x, y, button, up); + x, y, key_modifiers, button, up); g->xwin = NULL; /* TODO: remove? it's just in case */ } diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 944d27548f..1d2b03a25f 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -14,8 +14,8 @@ static void default_add_child( gui *_gui, widget *_this, widget *child, int position); static void default_del_child(gui *_gui, widget *_this, widget *child); static void default_hints(gui *g, widget *this, int *width, int *height); -static void default_button(gui *gui, widget *_this, int x, int y, int button, - int up); +static void default_button(gui *gui, widget *_this, int x, int y, + int key_modifiers, int button, int up); static void toplevel_list_append(struct gui *g, struct widget *e) { @@ -228,8 +228,8 @@ static void default_hints(gui *g, widget *this, int *width, int *height) *height = 1; } -static void default_button(gui *gui, widget *_this, int x, int y, int button, - int up) +static void default_button(gui *gui, widget *_this, int x, int y, + int key_modifiers, int button, int up) { /* nothing */ } diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index bbc51e8a94..0a2d145039 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -171,13 +171,21 @@ void x_events(gui *_gui) break; case ButtonPress: if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { - w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, + 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) { - w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, + 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; From 5c5f54709cc99370d7c71a8c03dc0643821be9a6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 15:47:40 +0200 Subject: [PATCH 141/217] gui/timeline.c scroll up/down event to include x, y, key_modifiers --- common/utils/T/tracer/gui/gui.h | 4 ++-- common/utils/T/tracer/gui/timeline.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 5ae623f559..464ac94463 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -86,8 +86,8 @@ int new_color(gui *gui, char *color); * - click { int: button } (if enabled) * - timeline * - resize { int: width } - * - scrollup { void *: NULL } - * - scrolldown { void *: NULL } + * - scrollup { int [3]: x, y, key_modifiers } + * - scrolldown { int [3]: x, y, key_modifiers } */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index 43cbcc525f..afcb681f9d 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -58,15 +58,21 @@ static void button(gui *_g, widget *_this, int x, int y, int key_modifiers, int button, int up) { struct gui *g = _g; - struct timeline_widget *this = _this; + int d[3]; LOGD("BUTTON timeline %p xy %d %d button %d up %d\n", _this, x, y, button, up); /* scroll up */ if (button == 4 && up == 0) { - gui_notify(g, "scrollup", _this, NULL); + d[0] = x; + d[1] = y; + d[2] = key_modifiers; + gui_notify(g, "scrollup", _this, d); } /* scroll down */ if (button == 5 && up == 0) { - gui_notify(g, "scrolldown", _this, NULL); + d[0] = x; + d[1] = y; + d[2] = key_modifiers; + gui_notify(g, "scrolldown", _this, d); } } From e4fd229641ec94526f7855d2259f7039369f3f52 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 16:00:10 +0200 Subject: [PATCH 142/217] gui/timeline.c click event --- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/timeline.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 464ac94463..6d36cddfd6 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -88,6 +88,7 @@ int new_color(gui *gui, char *color); * - resize { int: width } * - scrollup { int [3]: x, y, key_modifiers } * - scrolldown { int [3]: x, y, key_modifiers } + * - click { int: button } */ /* same type as in gui_defs.h */ diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index afcb681f9d..2f1e6121f4 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -74,6 +74,10 @@ static void button(gui *_g, widget *_this, int x, int y, d[2] = key_modifiers; gui_notify(g, "scrolldown", _this, d); } + /* button 1/2/3 */ + if ((button == 1 || button == 2 || button == 3) && up == 0) { + gui_notify(g, "click", _this, &button); + } } /*************************************************************************/ From 34e3945249cc2b9c25e1f93561cd71f5a141aa74 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 17:23:28 +0200 Subject: [PATCH 143/217] bugfix - one needs to translate to local coordinates --- common/utils/T/tracer/gui/timeline.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/gui/timeline.c b/common/utils/T/tracer/gui/timeline.c index 2f1e6121f4..d2373ff60a 100644 --- a/common/utils/T/tracer/gui/timeline.c +++ b/common/utils/T/tracer/gui/timeline.c @@ -58,19 +58,20 @@ static void button(gui *_g, widget *_this, int x, int y, int key_modifiers, int button, int up) { struct gui *g = _g; + struct timeline_widget *w = _this; int d[3]; LOGD("BUTTON timeline %p xy %d %d button %d up %d\n", _this, x, y, button, up); /* scroll up */ if (button == 4 && up == 0) { - d[0] = x; - d[1] = y; + d[0] = x - w->common.x; + d[1] = y - w->common.y; d[2] = key_modifiers; gui_notify(g, "scrollup", _this, d); } /* scroll down */ if (button == 5 && up == 0) { - d[0] = x; - d[1] = y; + d[0] = x - w->common.x; + d[1] = y - w->common.y; d[2] = key_modifiers; gui_notify(g, "scrolldown", _this, d); } From 392a818b7b31c74b0b119f1648b40601910eeac1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 17:37:28 +0200 Subject: [PATCH 144/217] view/time.c autoscroll and zoom --- common/utils/T/tracer/view/time.c | 33 +++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index 43f30cc403..546491edab 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -28,6 +28,8 @@ struct time { int psize; double pixel_length; /* unit: nanosecond (maximum 1 hour/pixel) */ struct timespec latest_time; + struct timespec start_time; + int autoscroll; }; /* TODO: put that function somewhere else (utils.c) */ @@ -119,8 +121,15 @@ static void *time_thread(void *_this) /* use rounded pixel_length */ pixel_length = this->pixel_length; - tnext = time_add(this->latest_time,(struct timespec){tv_sec:0,tv_nsec:1}); - tstart = time_sub(tnext, nano_to_time(pixel_length * width)); + if (this->autoscroll) { + tnext = time_add(this->latest_time, + (struct timespec){tv_sec:0,tv_nsec:1}); + tstart = time_sub(tnext, nano_to_time(pixel_length * width)); + this->start_time = tstart; + } else { + tstart = this->start_time; + tnext = time_add(tstart, nano_to_time(pixel_length * width)); + } for (l = 0; l < this->psize; l++) { for (i = 0; i < width; i++) { @@ -148,9 +157,12 @@ static void scroll(void *private, gui *g, char *notification, widget *w, void *notification_data) { struct time *this = private; + int *d = notification_data; + int x = d[0]; double mul = 1.2; double pixel_length; int64_t old_px_len_rounded; + struct timespec t; if (pthread_mutex_lock(&this->lock)) abort(); @@ -176,9 +188,23 @@ again: (int64_t)pixel_length == old_px_len_rounded) goto again; + t = time_add(this->start_time, nano_to_time(x * old_px_len_rounded)); + this->start_time = time_sub(t, nano_to_time(x * (int64_t)pixel_length)); + if (pthread_mutex_unlock(&this->lock)) abort(); } +static void click(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + struct time *this = private; + int *d = notification_data; + int button = *d; + + if (button == 1) this->autoscroll = 0; + if (button == 3) this->autoscroll = 1; +} + view *new_view_time(int number_of_seconds, float refresh_rate, gui *g, widget *w) { @@ -192,11 +218,14 @@ view *new_view_time(int number_of_seconds, float refresh_rate, ret->p = NULL; ret->psize = 0; + ret->autoscroll = 1; + /* default pixel length: 10ms */ ret->pixel_length = 10 * 1000000; register_notifier(g, "scrollup", w, scroll, ret); register_notifier(g, "scrolldown", w, scroll, ret); + register_notifier(g, "click", w, click, ret); if (pthread_mutex_init(&ret->lock, NULL)) abort(); From 55a4b2cef4baafd3a30d98c9f1bda42c6b2f72d6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 May 2016 18:01:06 +0200 Subject: [PATCH 145/217] scroll view/time.c if control+mouse wheel --- common/utils/T/tracer/view/time.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index 546491edab..b307d3a592 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -159,15 +159,34 @@ static void scroll(void *private, gui *g, struct time *this = private; int *d = notification_data; int x = d[0]; + int key_modifiers = d[2]; double mul = 1.2; double pixel_length; int64_t old_px_len_rounded; struct timespec t; + int scroll_px; + int width; if (pthread_mutex_lock(&this->lock)) abort(); old_px_len_rounded = this->pixel_length; + /* scroll if control+wheel, zoom otherwise */ + + if (key_modifiers & KEY_CONTROL) { + timeline_get_width(this->g, this->w, &width); + if (width < 2) width = 2; + scroll_px = 100; + if (scroll_px > width - 1) scroll_px = width - 1; + if (!strcmp(notification, "scrolldown")) + this->start_time = time_add(this->start_time, + nano_to_time(scroll_px * old_px_len_rounded)); + else + this->start_time = time_sub(this->start_time, + nano_to_time(scroll_px * old_px_len_rounded)); + goto end; + } + if (!strcmp(notification, "scrollup")) mul = 1 / mul; again: @@ -191,6 +210,7 @@ again: t = time_add(this->start_time, nano_to_time(x * old_px_len_rounded)); this->start_time = time_sub(t, nano_to_time(x * (int64_t)pixel_length)); +end: if (pthread_mutex_unlock(&this->lock)) abort(); } From 131b1bda2373ca1892ed3c36445546d56c2b5dad Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 May 2016 14:57:07 +0200 Subject: [PATCH 146/217] remove dead code --- common/utils/T/tracer/handler.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/common/utils/T/tracer/handler.c b/common/utils/T/tracer/handler.c index 15722f5e5f..1ee9db1ade 100644 --- a/common/utils/T/tracer/handler.c +++ b/common/utils/T/tracer/handler.c @@ -25,28 +25,6 @@ struct _event_handler { unsigned long next_id; }; -#if 0 -#include -void handle_event(event_handler *h, event e) -{ - int i; - printf("event %s (%d)\n", event_name_from_id(h->database, e.type), e.type); - for (i = 0; i < e.ecount; i++) { - switch (e.e[i].type) { - case EVENT_INT: - printf(" %d: INT %d\n", i, *(int *)&e.buffer[e.e[i].offset]); - break; - case EVENT_STRING: - printf(" %d: STRING '%s'\n", i, &e.buffer[e.e[i].offset]); - break; - case EVENT_BUFFER: - printf(" %d: BUFFER size %d\n", i, *(int *)&e.buffer[e.e[i].offset]); - break; - } - } -} -#endif - void handle_event(event_handler *_h, event e) { struct _event_handler *h = _h; From f38476aee48fb808b453ebd029150f984b0b0e81 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 May 2016 15:27:14 +0200 Subject: [PATCH 147/217] import VCD into the T --- common/utils/T/T.h | 40 ++ common/utils/T/T_defs.h | 12 + common/utils/T/T_messages.txt | 762 +++++++++++++++++++++++++ common/utils/T/tracer/event.c | 4 + common/utils/T/tracer/event.h | 2 + common/utils/T/tracer/logger/textlog.c | 4 +- common/utils/T/tracer/logger/ttilog.c | 1 + common/utils/T/tracer/utils.c | 7 + common/utils/T/tracer/utils.h | 1 + openair2/UTIL/LOG/vcd_signal_dumper.h | 12 + 10 files changed, 844 insertions(+), 1 deletion(-) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 1e1a45779b..58e0d5a885 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -32,6 +32,14 @@ T_LOCAL_size += sizeof(int); \ } while (0) +#define T_PUT_ulong(argnum, val) \ + do { \ + unsigned long T_PUT_var = (val); \ + T_CHECK_SIZE(sizeof(unsigned long), argnum); \ + memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(unsigned long)); \ + T_LOCAL_size += sizeof(unsigned long); \ + } while (0) + #define T_PUT_float(argnum, val) \ do { \ float T_PUT_var = (val); \ @@ -535,6 +543,38 @@ extern T_cache_t *T_cache; #define T30(...) T_CALL_ERROR #define T32(...) T_CALL_ERROR +/* special cases for VCD logs */ + +#define T_VCD_VARIABLE(var, val) \ + do { \ + if (T_ACTIVE(((var) + VCD_FIRST_VARIABLE))) { \ + if ((var) > VCD_NUM_VARIABLES) { \ + printf("%s:%d:%s: VCD data out of synch for the T, contact" \ + " the authors!\n", __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + T_LOCAL_DATA \ + T_HEADER(T_ID((var) + VCD_FIRST_VARIABLE)); \ + T_PUT_ulong(1, (val)); \ + T_SEND(); \ + } \ + } while (0) + +#define T_VCD_FUNCTION(fun, val) \ + do { \ + if (T_ACTIVE(((fun) + VCD_FIRST_FUNCTION))) { \ + if ((fun) > VCD_NUM_FUNCTIONS) { \ + printf("%s:%d:%s: VCD data out of synch for the T, contact" \ + " the authors!\n", __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + T_LOCAL_DATA \ + T_HEADER(T_ID((fun) + VCD_FIRST_FUNCTION)); \ + T_PUT_int(1, (val)); \ + T_SEND(); \ + } \ + } while (0) + #ifndef T_USE_SHARED_MEMORY #include diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index faeff507e8..ffd35ad9af 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -21,4 +21,16 @@ typedef struct { #define T_SHM_FILENAME "/T_shm_segment" +/* number of VCD functions (to be kept up to date! see in T_messages.txt) */ +#define VCD_NUM_FUNCTIONS 139 + +/* number of VCD variables (to be kept up to date! see in T_messages.txt) */ +#define VCD_NUM_VARIABLES 45 + +/* first VCD function (to be kept up to date! see in T_messages.txt) */ +#define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) + +/* first VCD variable (to be kept up to date! see in T_messages.txt) */ +#define VCD_FIRST_VARIABLE ((uintptr_t)T_VCD_VARIABLE_FRAME_NUMBER_TX_ENB) + #endif /* _T_defs_H_ */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index e437f7f2b9..9f1587db0c 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -573,3 +573,765 @@ ID = LEGACY_CLI_TRACE #for debug/test - not used ID = first ID = buf_test + +#VCD variables and functions + +#be careful! this must be synchronized with the code! +#also keep up to date VCD_NUM_VARIABLES and VCD_NUM_FUNCTIONS in T_defs.h + +#to synchronize: copy/paste from openair2/UTIL/LOG/vcd_signal_dumper.h +#the variables and functions name, replace "SIGNAL_DUMPER_VARIABLES" by +#"VARIABLE" and "SIGNAL_DUMPER_FUNCTIONS" by "FUNCTION" (check that +#everything is fine! for example we have +#VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG that has VARIABLE without S) +#and then process with sed + +#to generate variables: +#sed -e "s/ VCD_VARIABLE_\(.*\)/ID = VCD_VARIABLE_\1\n DESC = VCD variable \1\n GROUP = ALL:VCD:ENB\n FORMAT = ulong,value/" < VCD >> T_messages.txt + +#to generate functions: +#sed -e "s/ VCD_FUNCTION_\(.*\)/ID = VCD_FUNCTION_\1\n DESC = VCD function \1\n GROUP = ALL:VCD:ENB\n FORMAT = int,value/" < VCD.functions >> T_messages.txt + +#you may want to manually edit groups for UE instead of eNB + +#then count functions and variables and update VCD_NUM_FUNCTIONS and +#VCD_NUM_VARIABLES in T_defs.h + +#also verify that VCD_FIRST_FUNCTION and VCD_FIRST_VARIABLE are correct +#in T_defs.h. They have to point to the first function and variable +#as defined below. Note also that the order of the VCD functions +#and variables must be the same as in the code. + +#variables + +ID = VCD_VARIABLE_FRAME_NUMBER_TX_ENB + DESC = VCD variable FRAME_NUMBER_TX_ENB + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_FRAME_NUMBER_RX_ENB + DESC = VCD variable FRAME_NUMBER_RX_ENB + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RUNTIME_TX_ENB + DESC = VCD variable RUNTIME_TX_ENB + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RUNTIME_RX_ENB + DESC = VCD variable RUNTIME_RX_ENB + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_FRAME_NUMBER_TX_UE + DESC = VCD variable FRAME_NUMBER_TX_UE + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_FRAME_NUMBER_RX_UE + DESC = VCD variable FRAME_NUMBER_RX_UE + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_SLOT_NUMBER_TX_UE + DESC = VCD variable SLOT_NUMBER_TX_UE + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_SLOT_NUMBER_RX_UE + DESC = VCD variable SLOT_NUMBER_RX_UE + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX_UE + DESC = VCD variable SUBFRAME_NUMBER_TX_UE + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX_UE + DESC = VCD variable SUBFRAME_NUMBER_RX_UE + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_MISSED_SLOTS_ENB + DESC = VCD variable MISSED_SLOTS_ENB + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_DAQ_MBOX + DESC = VCD variable DAQ_MBOX + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_UE_OFFSET_MBOX + DESC = VCD variable UE_OFFSET_MBOX + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_UE_RX_OFFSET + DESC = VCD variable UE_RX_OFFSET + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_DIFF + DESC = VCD variable DIFF + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_HW_SUBFRAME + DESC = VCD variable HW_SUBFRAME + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_HW_FRAME + DESC = VCD variable HW_FRAME + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_HW_SUBFRAME_RX + DESC = VCD variable HW_SUBFRAME_RX + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_HW_FRAME_RX + DESC = VCD variable HW_FRAME_RX + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TXCNT + DESC = VCD variable TXCNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RXCNT + DESC = VCD variable RXCNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TRX_TS + DESC = VCD variable TRX_TS + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TRX_TST + DESC = VCD variable TRX_TST + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TX_TS + DESC = VCD variable TX_TS + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RX_TS + DESC = VCD variable RX_TS + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RX_HWCNT + DESC = VCD variable RX_HWCNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RX_LHWCNT + DESC = VCD variable RX_LHWCNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TX_HWCNT + DESC = VCD variable TX_HWCNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TX_LHWCNT + DESC = VCD variable TX_LHWCNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RX_PCK + DESC = VCD variable RX_PCK + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TX_PCK + DESC = VCD variable TX_PCK + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RX_SEQ_NUM + DESC = VCD variable RX_SEQ_NUM + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_RX_SEQ_NUM_PRV + DESC = VCD variable RX_SEQ_NUM_PRV + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_TX_SEQ_NUM + DESC = VCD variable TX_SEQ_NUM + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_CNT + DESC = VCD variable CNT + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_DUMMY_DUMP + DESC = VCD variable DUMMY_DUMP + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_ITTI_SEND_MSG + DESC = VCD variable ITTI_SEND_MSG + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_ITTI_POLL_MSG + DESC = VCD variable ITTI_POLL_MSG + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_ITTI_RECV_MSG + DESC = VCD variable ITTI_RECV_MSG + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_ITTI_ALLOC_MSG + DESC = VCD variable ITTI_ALLOC_MSG + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_MP_ALLOC + DESC = VCD variable MP_ALLOC + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_MP_FREE + DESC = VCD variable MP_FREE + GROUP = ALL:VCD:ENB + FORMAT = ulong,value +ID = VCD_VARIABLE_UE_INST_CNT_RX + DESC = VCD variable UE_INST_CNT_RX + GROUP = ALL:VCD:UE + FORMAT = ulong,value +ID = VCD_VARIABLE_UE_INST_CNT_TX + DESC = VCD variable UE_INST_CNT_TX + GROUP = ALL:VCD:UE + FORMAT = ulong,value + +#functions + +ID = VCD_FUNCTION_RT_SLEEP + DESC = VCD function RT_SLEEP + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_TRX_READ + DESC = VCD function TRX_READ + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_TRX_WRITE + DESC = VCD function TRX_WRITE + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX0 + DESC = VCD function eNB_PROC_TX0 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX0 + DESC = VCD function eNB_PROC_RX0 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX1 + DESC = VCD function eNB_PROC_TX1 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX1 + DESC = VCD function eNB_PROC_RX1 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX2 + DESC = VCD function eNB_PROC_TX2 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX2 + DESC = VCD function eNB_PROC_RX2 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX3 + DESC = VCD function eNB_PROC_TX3 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX3 + DESC = VCD function eNB_PROC_RX3 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX4 + DESC = VCD function eNB_PROC_TX4 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX4 + DESC = VCD function eNB_PROC_RX4 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX5 + DESC = VCD function eNB_PROC_TX5 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX5 + DESC = VCD function eNB_PROC_RX5 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX6 + DESC = VCD function eNB_PROC_TX6 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX6 + DESC = VCD function eNB_PROC_RX6 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX7 + DESC = VCD function eNB_PROC_TX7 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX7 + DESC = VCD function eNB_PROC_RX7 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX8 + DESC = VCD function eNB_PROC_TX8 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX8 + DESC = VCD function eNB_PROC_RX8 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_TX9 + DESC = VCD function eNB_PROC_TX9 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_RX9 + DESC = VCD function eNB_PROC_RX9 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_UE_THREAD_TX + DESC = VCD function UE_THREAD_TX + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_THREAD_RX + DESC = VCD function UE_THREAD_RX + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_eNB_TX + DESC = VCD function eNB_TX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_RX + DESC = VCD function eNB_RX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_TRX + DESC = VCD function eNB_TRX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_TM + DESC = VCD function eNB_TM + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_RX_SLEEP + DESC = VCD function eNB_RX_SLEEP + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_TX_SLEEP + DESC = VCD function eNB_TX_SLEEP + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_eNB_PROC_SLEEP + DESC = VCD function eNB_PROC_SLEEP + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_TRX_READ_RF + DESC = VCD function TRX_READ_RF + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_TRX_WRITE_RF + DESC = VCD function TRX_WRITE_RF + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_UE_SYNCH + DESC = VCD function UE_SYNCH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_SLOT_FEP + DESC = VCD function UE_SLOT_FEP + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_RRC_MEASUREMENTS + DESC = VCD function UE_RRC_MEASUREMENTS + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_GAIN_CONTROL + DESC = VCD function UE_GAIN_CONTROL + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_ADJUST_SYNCH + DESC = VCD function UE_ADJUST_SYNCH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_MEASUREMENT_PROCEDURES + DESC = VCD function UE_MEASUREMENT_PROCEDURES + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_PDCCH_PROCEDURES + DESC = VCD function UE_PDCCH_PROCEDURES + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_PBCH_PROCEDURES + DESC = VCD function UE_PBCH_PROCEDURES + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_TX + DESC = VCD function PHY_PROCEDURES_ENB_TX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX + DESC = VCD function PHY_PROCEDURES_ENB_RX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_UE_TX + DESC = VCD function PHY_PROCEDURES_UE_TX + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_UE_RX + DESC = VCD function PHY_PROCEDURES_UE_RX + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_LTE + DESC = VCD function PHY_PROCEDURES_ENB_LTE + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_UE_LTE + DESC = VCD function PHY_PROCEDURES_UE_LTE + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_PDSCH_THREAD + DESC = VCD function PDSCH_THREAD + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD0 + DESC = VCD function DLSCH_THREAD0 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD1 + DESC = VCD function DLSCH_THREAD1 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD2 + DESC = VCD function DLSCH_THREAD2 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD3 + DESC = VCD function DLSCH_THREAD3 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD4 + DESC = VCD function DLSCH_THREAD4 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD5 + DESC = VCD function DLSCH_THREAD5 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD6 + DESC = VCD function DLSCH_THREAD6 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_THREAD7 + DESC = VCD function DLSCH_THREAD7 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING0 + DESC = VCD function DLSCH_DECODING0 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING1 + DESC = VCD function DLSCH_DECODING1 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING2 + DESC = VCD function DLSCH_DECODING2 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING3 + DESC = VCD function DLSCH_DECODING3 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING4 + DESC = VCD function DLSCH_DECODING4 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING5 + DESC = VCD function DLSCH_DECODING5 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING6 + DESC = VCD function DLSCH_DECODING6 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_DECODING7 + DESC = VCD function DLSCH_DECODING7 + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RX_PDCCH + DESC = VCD function RX_PDCCH + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DCI_DECODING + DESC = VCD function DCI_DECODING + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RX_PHICH + DESC = VCD function RX_PHICH + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_UE_CONFIG_SIB2 + DESC = VCD function PHY_UE_CONFIG_SIB2 + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_PHY_CONFIG_SIB1_ENB + DESC = VCD function PHY_CONFIG_SIB1_ENB + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_CONFIG_SIB2_ENB + DESC = VCD function PHY_CONFIG_SIB2_ENB + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_CONFIG_DEDICATED_ENB + DESC = VCD function PHY_CONFIG_DEDICATED_ENB + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_UE_COMPUTE_PRACH + DESC = VCD function PHY_UE_COMPUTE_PRACH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_PHY_ENB_ULSCH_DECODING + DESC = VCD function PHY_ENB_ULSCH_DECODING + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_ENB_SFGEN + DESC = VCD function PHY_ENB_SFGEN + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_ENB_PRACH_RX + DESC = VCD function PHY_ENB_PRACH_RX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_ENB_PDCCH_TX + DESC = VCD function PHY_ENB_PDCCH_TX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PHY_ENB_RS_TX + DESC = VCD function PHY_ENB_RS_TX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_UE_GENERATE_PRACH + DESC = VCD function UE_GENERATE_PRACH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_ULSCH_MODULATION + DESC = VCD function UE_ULSCH_MODULATION + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_ULSCH_ENCODING + DESC = VCD function UE_ULSCH_ENCODING + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_ULSCH_SCRAMBLING + DESC = VCD function UE_ULSCH_SCRAMBLING + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_ENB_DLSCH_MODULATION + DESC = VCD function ENB_DLSCH_MODULATION + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ENB_DLSCH_ENCODING + DESC = VCD function ENB_DLSCH_ENCODING + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ENB_DLSCH_SCRAMBLING + DESC = VCD function ENB_DLSCH_SCRAMBLING + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_MACPHY_INIT + DESC = VCD function MACPHY_INIT + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_MACPHY_EXIT + DESC = VCD function MACPHY_EXIT + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER + DESC = VCD function ENB_DLSCH_ULSCH_SCHEDULER + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_FILL_RAR + DESC = VCD function FILL_RAR + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_TERMINATE_RA_PROC + DESC = VCD function TERMINATE_RA_PROC + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_INITIATE_RA_PROC + DESC = VCD function INITIATE_RA_PROC + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_CANCEL_RA_PROC + DESC = VCD function CANCEL_RA_PROC + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_GET_DCI_SDU + DESC = VCD function GET_DCI_SDU + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_GET_DLSCH_SDU + DESC = VCD function GET_DLSCH_SDU + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RX_SDU + DESC = VCD function RX_SDU + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_MRBCH_PHY_SYNC_FAILURE + DESC = VCD function MRBCH_PHY_SYNC_FAILURE + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_SR_INDICATION + DESC = VCD function SR_INDICATION + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_DLSCH_PREPROCESSOR + DESC = VCD function DLSCH_PREPROCESSOR + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_SCHEDULE_DLSCH + DESC = VCD function SCHEDULE_DLSCH + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_FILL_DLSCH_DCI + DESC = VCD function FILL_DLSCH_DCI + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_OUT_OF_SYNC_IND + DESC = VCD function OUT_OF_SYNC_IND + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_UE_DECODE_SI + DESC = VCD function UE_DECODE_SI + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_DECODE_CCCH + DESC = VCD function UE_DECODE_CCCH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_DECODE_BCCH + DESC = VCD function UE_DECODE_BCCH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_SEND_SDU + DESC = VCD function UE_SEND_SDU + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_GET_SDU + DESC = VCD function UE_GET_SDU + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_GET_RACH + DESC = VCD function UE_GET_RACH + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_PROCESS_RAR + DESC = VCD function UE_PROCESS_RAR + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_SCHEDULER + DESC = VCD function UE_SCHEDULER + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_GET_SR + DESC = VCD function UE_GET_SR + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_UE_SEND_MCH_SDU + DESC = VCD function UE_SEND_MCH_SDU + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_RLC_DATA_REQ + DESC = VCD function RLC_DATA_REQ + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_MAC_RLC_STATUS_IND + DESC = VCD function MAC_RLC_STATUS_IND + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_MAC_RLC_DATA_REQ + DESC = VCD function MAC_RLC_DATA_REQ + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_MAC_RLC_DATA_IND + DESC = VCD function MAC_RLC_DATA_IND + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RLC_UM_TRY_REASSEMBLY + DESC = VCD function RLC_UM_TRY_REASSEMBLY + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RLC_UM_CHECK_TIMER_DAR_TIME_OUT + DESC = VCD function RLC_UM_CHECK_TIMER_DAR_TIME_OUT + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RLC_UM_RECEIVE_PROCESS_DAR + DESC = VCD function RLC_UM_RECEIVE_PROCESS_DAR + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PDCP_RUN + DESC = VCD function PDCP_RUN + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PDCP_DATA_REQ + DESC = VCD function PDCP_DATA_REQ + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PDCP_DATA_IND + DESC = VCD function PDCP_DATA_IND + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PDCP_APPLY_SECURITY + DESC = VCD function PDCP_APPLY_SECURITY + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_PDCP_VALIDATE_SECURITY + DESC = VCD function PDCP_VALIDATE_SECURITY + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RRC_RX_TX + DESC = VCD function RRC_RX_TX + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RRC_MAC_CONFIG + DESC = VCD function RRC_MAC_CONFIG + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_RRC_UE_DECODE_SIB1 + DESC = VCD function RRC_UE_DECODE_SIB1 + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_RRC_UE_DECODE_SI + DESC = VCD function RRC_UE_DECODE_SI + GROUP = ALL:VCD:UE + FORMAT = int,value +ID = VCD_FUNCTION_GTPV1U_ENB_TASK + DESC = VCD function GTPV1U_ENB_TASK + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_GTPV1U_PROCESS_UDP_REQ + DESC = VCD function GTPV1U_PROCESS_UDP_REQ + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_GTPV1U_PROCESS_TUNNEL_DATA_REQ + DESC = VCD function GTPV1U_PROCESS_TUNNEL_DATA_REQ + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_UDP_ENB_TASK + DESC = VCD function UDP_ENB_TASK + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_EMU_TRANSPORT + DESC = VCD function EMU_TRANSPORT + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_LOG_RECORD + DESC = VCD function LOG_RECORD + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ITTI_ENQUEUE_MESSAGE + DESC = VCD function ITTI_ENQUEUE_MESSAGE + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ITTI_DUMP_ENQUEUE_MESSAGE + DESC = VCD function ITTI_DUMP_ENQUEUE_MESSAGE + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC + DESC = VCD function ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_ITTI_RELAY_THREAD + DESC = VCD function ITTI_RELAY_THREAD + GROUP = ALL:VCD:ENB + FORMAT = int,value +ID = VCD_FUNCTION_TEST + DESC = VCD function TEST + GROUP = ALL:VCD:ENB + FORMAT = int,value diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c index 2071c90356..1d9f3a4081 100644 --- a/common/utils/T/tracer/event.c +++ b/common/utils/T/tracer/event.c @@ -36,6 +36,10 @@ event new_event(int type, int length, char *buffer, void *database) e.e[i].type = EVENT_INT; e.e[i].i = *(int *)(&buffer[offset]); offset += 4; + } else if (!strcmp(f.type[i], "ulong")) { + e.e[i].type = EVENT_ULONG; + e.e[i].ul = *(unsigned long *)(&buffer[offset]); + offset += sizeof(unsigned long); } else if (!strcmp(f.type[i], "string")) { e.e[i].type = EVENT_STRING; e.e[i].s = &buffer[offset]; diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h index 0cecca3265..32abee4ead 100644 --- a/common/utils/T/tracer/event.h +++ b/common/utils/T/tracer/event.h @@ -8,6 +8,7 @@ enum event_arg_type { EVENT_INT, + EVENT_ULONG, EVENT_STRING, EVENT_BUFFER }; @@ -17,6 +18,7 @@ typedef struct { //int offset; union { int i; + unsigned long ul; char *s; struct { int bsize; diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index 4a69a9619a..ea7f9c8a93 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -10,7 +10,7 @@ enum format_item_type { INSTRING, - INT, STRING, BUFFER }; + INT, ULONG, STRING, BUFFER }; struct format_item { enum format_item_type type; @@ -56,6 +56,7 @@ static void _event(void *p, event e) switch(l->f[i].type) { case INSTRING: PUTS(&l->o, l->f[i].s); break; case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; + case ULONG: PUTUL(&l->o, e.e[l->f[i].event_arg].ul); break; case STRING: PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break; case BUFFER: PUTS(&l->o, "{buffer size:"); @@ -86,6 +87,7 @@ static int find_argument(char *name, database_event_format f, if (i == f.count) return 0; *event_arg = i; if (!strcmp(f.type[i], "int")) *it = INT; + else if (!strcmp(f.type[i], "ulong")) *it = ULONG; else if (!strcmp(f.type[i], "string")) *it = STRING; else if (!strcmp(f.type[i], "buffer")) *it = BUFFER; else return 0; diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c index 649c4b497a..172d0eeb2d 100644 --- a/common/utils/T/tracer/logger/ttilog.c +++ b/common/utils/T/tracer/logger/ttilog.c @@ -29,6 +29,7 @@ static void _event(void *p, event e) subframe = e.e[l->subframe_arg].i; switch (e.e[l->data_arg].type) { case EVENT_INT: value = e.e[l->data_arg].i; break; + case EVENT_ULONG: value = e.e[l->data_arg].ul; break; default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort(); } diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index f4bcd1243c..95b4084822 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -115,3 +115,10 @@ void PUTI(OBUF *o, int i) sprintf(s, "%d", i); PUTS(o, s); } + +void PUTUL(OBUF *o, unsigned long l) +{ + char s[128]; + sprintf(s, "%ld", l); + PUTS(o, s); +} diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index dd96d39941..f7e3a6d256 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -36,5 +36,6 @@ void PUTC(OBUF *o, char c); void PUTS(OBUF *o, char *s); void PUTS_CLEAN(OBUF *o, char *s); void PUTI(OBUF *o, int i); +void PUTUL(OBUF *o, unsigned long i); #endif /* _UTILS_H_ */ diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h index 9ca55846fd..8ba56d4bd2 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.h +++ b/openair2/UTIL/LOG/vcd_signal_dumper.h @@ -312,6 +312,16 @@ void vcd_signal_dumper_dump_function_by_name(vcd_signal_dump_functions function extern int ouput_vcd; +#if T_TRACER + +#define VCD_SIGNAL_DUMPER_INIT(x) /* nothing */ +#define VCD_SIGNAL_DUMPER_CLOSE() /* nothing */ +#define VCD_SIGNAL_DUMPER_CREATE_HEADER() /* nothing */ +#define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(var, val) T_VCD_VARIABLE(var, val) +#define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(var, val) T_VCD_FUNCTION(var, val) + +#else /* T_TRACER */ + #if defined(ENABLE_VCD) #define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT) vcd_signal_dumper_init(aRgUmEnT) #define VCD_SIGNAL_DUMPER_CLOSE() vcd_signal_dumper_close() @@ -326,5 +336,7 @@ extern int ouput_vcd; #define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2) #endif +#endif /* T_TRACER */ + #endif /* !defined (VCD_SIGNAL_DUMPER_H_) */ From 5dec2748ecb6c033b65bc25734e99470b6bbb6a3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 May 2016 16:11:44 +0200 Subject: [PATCH 148/217] add a basic VCD plotter --- common/utils/T/tracer/Makefile | 4 +- common/utils/T/tracer/Makefile.remote | 13 +- common/utils/T/tracer/vcd.c | 240 ++++++++++++++++++++++++++ 3 files changed, 248 insertions(+), 9 deletions(-) create mode 100644 common/utils/T/tracer/vcd.c diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 43b7e55c16..8cbc0d58d2 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -4,9 +4,7 @@ local: make -f Makefile.local remote: - make -f Makefile.remote - make -f Makefile.remote textlog - make -f Makefile.remote enb + make -f Makefile.remote tracer_remote textlog enb vcd clean: make -f Makefile.local clean diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index 4a8d29261a..c539a2c388 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -5,11 +5,8 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. LIBS=-lX11 -lm -PROG=tracer_remote -OBJS=remote_old.o plot.o database.o gui.o utils.o - -$(PROG): gui/gui.a $(OBJS) - $(CC) $(CFLAGS) -o $(PROG) $(OBJS) gui/gui.a $(LIBS) +tracer_remote: remote_old.o plot.o database.o gui.o utils.o gui/gui.a + $(CC) $(CFLAGS) -o tracer_remote $^ $(LIBS) textlog: utils.o textlog.o database.o event.o handler.o \ event_selector.o view/view.a gui/gui.a logger/logger.a @@ -19,6 +16,10 @@ enb: utils.o enb.o database.o event.o handler.o \ event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o enb $^ $(LIBS) +vcd: utils.o vcd.o database.o event.o handler.o \ + event_selector.o view/view.a gui/gui.a logger/logger.a + $(CC) $(CFLAGS) -o vcd $^ $(LIBS) + .PHONY: gui/gui.a view/view.a logger/logger.a gui/gui.a: @@ -34,7 +35,7 @@ logger/logger.a: $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f *.o $(PROG) core textlog + rm -f *.o core tracer_remote textlog enb vcd cd gui && make clean cd view && make clean cd logger && make clean diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c new file mode 100644 index 0000000000..a80f30121d --- /dev/null +++ b/common/utils/T/tracer/vcd.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include +#include +#include +#include "database.h" +#include "event.h" +#include "handler.h" +#include "logger/logger.h" +#include "view/view.h" +#include "gui/gui.h" +#include "utils.h" +#include "../T_defs.h" +#include "event_selector.h" + +#define DEFAULT_REMOTE_PORT 2021 + +int get_connection(char *addr, int port) +{ + struct sockaddr_in a; + socklen_t alen; + int s, t; + + printf("waiting for connection on %s:%d\n", addr, port); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + + printf("connected\n"); + + return t; +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -on turn log ON for given GROUP or ID\n" +" -off turn log OFF for given GROUP or ID\n" +" -ON turn all logs ON\n" +" -OFF turn all logs OFF\n" +" note: you may pass several -on/-off/-ON/-OFF,\n" +" they will be processed in order\n" +" by default, all is off\n" +" -p use given port (default %d)\n" +" -debug-gui activate GUI debug logs\n", + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) { printf("read socket problem\n"); abort(); } + count -= l; + buf += l; + ret += l; + } + return ret; +} + +event get_event(int s, char *v, void *d) +{ +#ifdef T_SEND_TIME + struct timespec t; +#endif + int type; + int32_t length; + + fullread(s, &length, 4); +#ifdef T_SEND_TIME + fullread(s, &t, sizeof(struct timespec)); + length -= sizeof(struct timespec); +#endif + fullread(s, &type, sizeof(int)); + length -= sizeof(int); + fullread(s, v, length); + +#ifdef T_SEND_TIME + return new_event(t, type, length, v, d); +#else + return new_event(type, length, v, d); +#endif +} + +static void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return NULL; +} + +static void vcd_main_gui(gui *g, event_handler *h, void *database, int *is_on) +{ + int i, j; + int n; + int nb_functions = 0; + char **ids; + widget *win; + widget *container; + widget *w; + view *timeview; + view *subview; + logger *timelog; + + /* get number of vcd functions - look for all events VCD_FUNCTION_xxx */ + n = database_get_ids(database, &ids); + for (i = 0; i < n; i++) { + if (strncmp(ids[i], "VCD_FUNCTION_", 13) != 0) continue; + nb_functions++; + } + + win = new_toplevel_window(g, 1000, 5 * nb_functions, "VCD tracer"); + container = new_container(g, VERTICAL); + widget_add_child(g, win, container, -1); + + w = new_timeline(g, 1000, nb_functions, 5); + widget_add_child(g, container, w, -1); + for (i = 0; i < nb_functions; i++) + timeline_set_subline_background_color(g, w, i, + new_color(g, i & 1 ? "#ddd" : "#eee")); + timeview = new_view_time(3600, 10, g, w); + i = 0; + for (j = 0; j < n; j++) { + if (strncmp(ids[j], "VCD_FUNCTION_", 13) != 0) continue; + on_off(database, ids[j], is_on, 1); + timelog = new_timelog(h, database, ids[j]); + subview = new_subview_time(timeview, i, FOREGROUND_COLOR, 3600*1000); + logger_add_view(timelog, subview); + i++; + } + + free(ids); +} + +int main(int n, char **v) +{ + extern int volatile gui_logd; + char *database_filename = NULL; + void *database; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int s; + int i; + char t; + int l; + event_handler *h; + gui *g; + + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); + on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); + on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-ON")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } + if (!strcmp(v[i], "-OFF")) + { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } + if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + h = new_handler(database); + + g = gui_init(); + new_thread(gui_thread, g); + + vcd_main_gui(g, h, database, is_on); + + for (i = 0; i < on_off_n; i++) + on_off(database, on_off_name[i], is_on, on_off_action[i]); + + s = get_connection("0.0.0.0", port); + + /* send the first message - activate selected traces */ + t = 0; + if (write(s, &t, 1) != 1) abort(); + l = 0; + for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + for (l = 0; l < number_of_events; l++) + if (is_on[l]) + if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); + + setup_event_selector(g, database, s, is_on); + + /* read messages */ + while (1) { + char v[T_BUFFER_MAX]; + event e; + e = get_event(s, v, database); + handle_event(h, e); + } + + return 0; +} From 181470728766bacc5b6ae29832c32fcfbb3ed2a3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 May 2016 16:15:37 +0200 Subject: [PATCH 149/217] add groups VCD_VARIABLE and VCD_FUNCTION --- common/utils/T/T_messages.txt | 364 +++++++++++++++++----------------- 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 9f1587db0c..df9ed1edec 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -606,732 +606,732 @@ ID = buf_test ID = VCD_VARIABLE_FRAME_NUMBER_TX_ENB DESC = VCD variable FRAME_NUMBER_TX_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_FRAME_NUMBER_RX_ENB DESC = VCD variable FRAME_NUMBER_RX_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RUNTIME_TX_ENB DESC = VCD variable RUNTIME_TX_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RUNTIME_RX_ENB DESC = VCD variable RUNTIME_RX_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_FRAME_NUMBER_TX_UE DESC = VCD variable FRAME_NUMBER_TX_UE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_FRAME_NUMBER_RX_UE DESC = VCD variable FRAME_NUMBER_RX_UE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_SLOT_NUMBER_TX_UE DESC = VCD variable SLOT_NUMBER_TX_UE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_SLOT_NUMBER_RX_UE DESC = VCD variable SLOT_NUMBER_RX_UE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX_UE DESC = VCD variable SUBFRAME_NUMBER_TX_UE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX_UE DESC = VCD variable SUBFRAME_NUMBER_RX_UE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_MISSED_SLOTS_ENB DESC = VCD variable MISSED_SLOTS_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_DAQ_MBOX DESC = VCD variable DAQ_MBOX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_UE_OFFSET_MBOX DESC = VCD variable UE_OFFSET_MBOX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_UE_RX_OFFSET DESC = VCD variable UE_RX_OFFSET - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_DIFF DESC = VCD variable DIFF - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_HW_SUBFRAME DESC = VCD variable HW_SUBFRAME - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_HW_FRAME DESC = VCD variable HW_FRAME - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_HW_SUBFRAME_RX DESC = VCD variable HW_SUBFRAME_RX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_HW_FRAME_RX DESC = VCD variable HW_FRAME_RX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TXCNT DESC = VCD variable TXCNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RXCNT DESC = VCD variable RXCNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TRX_TS DESC = VCD variable TRX_TS - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TRX_TST DESC = VCD variable TRX_TST - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TX_TS DESC = VCD variable TX_TS - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RX_TS DESC = VCD variable RX_TS - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RX_HWCNT DESC = VCD variable RX_HWCNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RX_LHWCNT DESC = VCD variable RX_LHWCNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TX_HWCNT DESC = VCD variable TX_HWCNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TX_LHWCNT DESC = VCD variable TX_LHWCNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RX_PCK DESC = VCD variable RX_PCK - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TX_PCK DESC = VCD variable TX_PCK - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RX_SEQ_NUM DESC = VCD variable RX_SEQ_NUM - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RX_SEQ_NUM_PRV DESC = VCD variable RX_SEQ_NUM_PRV - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_TX_SEQ_NUM DESC = VCD variable TX_SEQ_NUM - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_CNT DESC = VCD variable CNT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_DUMMY_DUMP DESC = VCD variable DUMMY_DUMP - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_ITTI_SEND_MSG DESC = VCD variable ITTI_SEND_MSG - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_ITTI_POLL_MSG DESC = VCD variable ITTI_POLL_MSG - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_ITTI_RECV_MSG DESC = VCD variable ITTI_RECV_MSG - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_ITTI_ALLOC_MSG DESC = VCD variable ITTI_ALLOC_MSG - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_MP_ALLOC DESC = VCD variable MP_ALLOC - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_MP_FREE DESC = VCD variable MP_FREE - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_UE_INST_CNT_RX DESC = VCD variable UE_INST_CNT_RX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_UE_INST_CNT_TX DESC = VCD variable UE_INST_CNT_TX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value #functions ID = VCD_FUNCTION_RT_SLEEP DESC = VCD function RT_SLEEP - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_TRX_READ DESC = VCD function TRX_READ - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_TRX_WRITE DESC = VCD function TRX_WRITE - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX0 DESC = VCD function eNB_PROC_TX0 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX0 DESC = VCD function eNB_PROC_RX0 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX1 DESC = VCD function eNB_PROC_TX1 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX1 DESC = VCD function eNB_PROC_RX1 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX2 DESC = VCD function eNB_PROC_TX2 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX2 DESC = VCD function eNB_PROC_RX2 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX3 DESC = VCD function eNB_PROC_TX3 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX3 DESC = VCD function eNB_PROC_RX3 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX4 DESC = VCD function eNB_PROC_TX4 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX4 DESC = VCD function eNB_PROC_RX4 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX5 DESC = VCD function eNB_PROC_TX5 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX5 DESC = VCD function eNB_PROC_RX5 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX6 DESC = VCD function eNB_PROC_TX6 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX6 DESC = VCD function eNB_PROC_RX6 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX7 DESC = VCD function eNB_PROC_TX7 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX7 DESC = VCD function eNB_PROC_RX7 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX8 DESC = VCD function eNB_PROC_TX8 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX8 DESC = VCD function eNB_PROC_RX8 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_TX9 DESC = VCD function eNB_PROC_TX9 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_RX9 DESC = VCD function eNB_PROC_RX9 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_THREAD_TX DESC = VCD function UE_THREAD_TX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_THREAD_RX DESC = VCD function UE_THREAD_RX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_TX DESC = VCD function eNB_TX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_RX DESC = VCD function eNB_RX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_TRX DESC = VCD function eNB_TRX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_TM DESC = VCD function eNB_TM - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_RX_SLEEP DESC = VCD function eNB_RX_SLEEP - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_TX_SLEEP DESC = VCD function eNB_TX_SLEEP - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_PROC_SLEEP DESC = VCD function eNB_PROC_SLEEP - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_TRX_READ_RF DESC = VCD function TRX_READ_RF - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_TRX_WRITE_RF DESC = VCD function TRX_WRITE_RF - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_SYNCH DESC = VCD function UE_SYNCH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_SLOT_FEP DESC = VCD function UE_SLOT_FEP - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_RRC_MEASUREMENTS DESC = VCD function UE_RRC_MEASUREMENTS - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_GAIN_CONTROL DESC = VCD function UE_GAIN_CONTROL - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_ADJUST_SYNCH DESC = VCD function UE_ADJUST_SYNCH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_MEASUREMENT_PROCEDURES DESC = VCD function UE_MEASUREMENT_PROCEDURES - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_PDCCH_PROCEDURES DESC = VCD function UE_PDCCH_PROCEDURES - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_PBCH_PROCEDURES DESC = VCD function UE_PBCH_PROCEDURES - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_TX DESC = VCD function PHY_PROCEDURES_ENB_TX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX DESC = VCD function PHY_PROCEDURES_ENB_RX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_UE_TX DESC = VCD function PHY_PROCEDURES_UE_TX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_UE_RX DESC = VCD function PHY_PROCEDURES_UE_RX - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_LTE DESC = VCD function PHY_PROCEDURES_ENB_LTE - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_UE_LTE DESC = VCD function PHY_PROCEDURES_UE_LTE - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PDSCH_THREAD DESC = VCD function PDSCH_THREAD - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD0 DESC = VCD function DLSCH_THREAD0 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD1 DESC = VCD function DLSCH_THREAD1 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD2 DESC = VCD function DLSCH_THREAD2 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD3 DESC = VCD function DLSCH_THREAD3 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD4 DESC = VCD function DLSCH_THREAD4 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD5 DESC = VCD function DLSCH_THREAD5 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD6 DESC = VCD function DLSCH_THREAD6 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_THREAD7 DESC = VCD function DLSCH_THREAD7 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING0 DESC = VCD function DLSCH_DECODING0 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING1 DESC = VCD function DLSCH_DECODING1 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING2 DESC = VCD function DLSCH_DECODING2 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING3 DESC = VCD function DLSCH_DECODING3 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING4 DESC = VCD function DLSCH_DECODING4 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING5 DESC = VCD function DLSCH_DECODING5 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING6 DESC = VCD function DLSCH_DECODING6 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_DECODING7 DESC = VCD function DLSCH_DECODING7 - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RX_PDCCH DESC = VCD function RX_PDCCH - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DCI_DECODING DESC = VCD function DCI_DECODING - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RX_PHICH DESC = VCD function RX_PHICH - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_UE_CONFIG_SIB2 DESC = VCD function PHY_UE_CONFIG_SIB2 - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_CONFIG_SIB1_ENB DESC = VCD function PHY_CONFIG_SIB1_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_CONFIG_SIB2_ENB DESC = VCD function PHY_CONFIG_SIB2_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_CONFIG_DEDICATED_ENB DESC = VCD function PHY_CONFIG_DEDICATED_ENB - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_UE_COMPUTE_PRACH DESC = VCD function PHY_UE_COMPUTE_PRACH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_ENB_ULSCH_DECODING DESC = VCD function PHY_ENB_ULSCH_DECODING - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_ENB_SFGEN DESC = VCD function PHY_ENB_SFGEN - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_ENB_PRACH_RX DESC = VCD function PHY_ENB_PRACH_RX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_ENB_PDCCH_TX DESC = VCD function PHY_ENB_PDCCH_TX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_ENB_RS_TX DESC = VCD function PHY_ENB_RS_TX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_GENERATE_PRACH DESC = VCD function UE_GENERATE_PRACH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_ULSCH_MODULATION DESC = VCD function UE_ULSCH_MODULATION - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_ULSCH_ENCODING DESC = VCD function UE_ULSCH_ENCODING - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_ULSCH_SCRAMBLING DESC = VCD function UE_ULSCH_SCRAMBLING - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ENB_DLSCH_MODULATION DESC = VCD function ENB_DLSCH_MODULATION - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ENB_DLSCH_ENCODING DESC = VCD function ENB_DLSCH_ENCODING - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ENB_DLSCH_SCRAMBLING DESC = VCD function ENB_DLSCH_SCRAMBLING - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_MACPHY_INIT DESC = VCD function MACPHY_INIT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_MACPHY_EXIT DESC = VCD function MACPHY_EXIT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER DESC = VCD function ENB_DLSCH_ULSCH_SCHEDULER - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_FILL_RAR DESC = VCD function FILL_RAR - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_TERMINATE_RA_PROC DESC = VCD function TERMINATE_RA_PROC - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_INITIATE_RA_PROC DESC = VCD function INITIATE_RA_PROC - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_CANCEL_RA_PROC DESC = VCD function CANCEL_RA_PROC - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_GET_DCI_SDU DESC = VCD function GET_DCI_SDU - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_GET_DLSCH_SDU DESC = VCD function GET_DLSCH_SDU - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RX_SDU DESC = VCD function RX_SDU - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_MRBCH_PHY_SYNC_FAILURE DESC = VCD function MRBCH_PHY_SYNC_FAILURE - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_SR_INDICATION DESC = VCD function SR_INDICATION - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_DLSCH_PREPROCESSOR DESC = VCD function DLSCH_PREPROCESSOR - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_SCHEDULE_DLSCH DESC = VCD function SCHEDULE_DLSCH - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_FILL_DLSCH_DCI DESC = VCD function FILL_DLSCH_DCI - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_OUT_OF_SYNC_IND DESC = VCD function OUT_OF_SYNC_IND - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_DECODE_SI DESC = VCD function UE_DECODE_SI - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_DECODE_CCCH DESC = VCD function UE_DECODE_CCCH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_DECODE_BCCH DESC = VCD function UE_DECODE_BCCH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_SEND_SDU DESC = VCD function UE_SEND_SDU - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_GET_SDU DESC = VCD function UE_GET_SDU - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_GET_RACH DESC = VCD function UE_GET_RACH - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_PROCESS_RAR DESC = VCD function UE_PROCESS_RAR - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_SCHEDULER DESC = VCD function UE_SCHEDULER - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_GET_SR DESC = VCD function UE_GET_SR - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UE_SEND_MCH_SDU DESC = VCD function UE_SEND_MCH_SDU - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RLC_DATA_REQ DESC = VCD function RLC_DATA_REQ - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_MAC_RLC_STATUS_IND DESC = VCD function MAC_RLC_STATUS_IND - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_MAC_RLC_DATA_REQ DESC = VCD function MAC_RLC_DATA_REQ - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_MAC_RLC_DATA_IND DESC = VCD function MAC_RLC_DATA_IND - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RLC_UM_TRY_REASSEMBLY DESC = VCD function RLC_UM_TRY_REASSEMBLY - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RLC_UM_CHECK_TIMER_DAR_TIME_OUT DESC = VCD function RLC_UM_CHECK_TIMER_DAR_TIME_OUT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RLC_UM_RECEIVE_PROCESS_DAR DESC = VCD function RLC_UM_RECEIVE_PROCESS_DAR - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PDCP_RUN DESC = VCD function PDCP_RUN - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PDCP_DATA_REQ DESC = VCD function PDCP_DATA_REQ - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PDCP_DATA_IND DESC = VCD function PDCP_DATA_IND - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PDCP_APPLY_SECURITY DESC = VCD function PDCP_APPLY_SECURITY - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PDCP_VALIDATE_SECURITY DESC = VCD function PDCP_VALIDATE_SECURITY - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RRC_RX_TX DESC = VCD function RRC_RX_TX - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RRC_MAC_CONFIG DESC = VCD function RRC_MAC_CONFIG - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RRC_UE_DECODE_SIB1 DESC = VCD function RRC_UE_DECODE_SIB1 - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_RRC_UE_DECODE_SI DESC = VCD function RRC_UE_DECODE_SI - GROUP = ALL:VCD:UE + GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_GTPV1U_ENB_TASK DESC = VCD function GTPV1U_ENB_TASK - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_GTPV1U_PROCESS_UDP_REQ DESC = VCD function GTPV1U_PROCESS_UDP_REQ - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_GTPV1U_PROCESS_TUNNEL_DATA_REQ DESC = VCD function GTPV1U_PROCESS_TUNNEL_DATA_REQ - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_UDP_ENB_TASK DESC = VCD function UDP_ENB_TASK - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_EMU_TRANSPORT DESC = VCD function EMU_TRANSPORT - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_LOG_RECORD DESC = VCD function LOG_RECORD - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ITTI_ENQUEUE_MESSAGE DESC = VCD function ITTI_ENQUEUE_MESSAGE - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ITTI_DUMP_ENQUEUE_MESSAGE DESC = VCD function ITTI_DUMP_ENQUEUE_MESSAGE - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC DESC = VCD function ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_ITTI_RELAY_THREAD DESC = VCD function ITTI_RELAY_THREAD - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_TEST DESC = VCD function TEST - GROUP = ALL:VCD:ENB + GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value From c24855b2292fc8d0f533a10eb84e83b6158e357b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 May 2016 16:17:24 +0200 Subject: [PATCH 150/217] reverse button 1 and 3 to start and stop autoscroll in view/time.c it seems more natural to stop autoscroll with button 3 and start it with button 1 --- common/utils/T/tracer/view/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/view/time.c b/common/utils/T/tracer/view/time.c index b307d3a592..287e7b1c7b 100644 --- a/common/utils/T/tracer/view/time.c +++ b/common/utils/T/tracer/view/time.c @@ -221,8 +221,8 @@ static void click(void *private, gui *g, int *d = notification_data; int button = *d; - if (button == 1) this->autoscroll = 0; - if (button == 3) this->autoscroll = 1; + if (button == 3) this->autoscroll = 0; + if (button == 1) this->autoscroll = 1; } view *new_view_time(int number_of_seconds, float refresh_rate, From 25546ae9203aa72d2bb3a45f9976659cd57f8abe Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 May 2016 16:49:58 +0200 Subject: [PATCH 151/217] cleanup: better to on/off traces outside of gui creation --- common/utils/T/tracer/vcd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index a80f30121d..e1fae049bd 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -111,7 +111,7 @@ static void *gui_thread(void *_g) return NULL; } -static void vcd_main_gui(gui *g, event_handler *h, void *database, int *is_on) +static void vcd_main_gui(gui *g, event_handler *h, void *database) { int i, j; int n; @@ -144,7 +144,6 @@ static void vcd_main_gui(gui *g, event_handler *h, void *database, int *is_on) i = 0; for (j = 0; j < n; j++) { if (strncmp(ids[j], "VCD_FUNCTION_", 13) != 0) continue; - on_off(database, ids[j], is_on, 1); timelog = new_timelog(h, database, ids[j]); subview = new_subview_time(timeview, i, FOREGROUND_COLOR, 3600*1000); logger_add_view(timelog, subview); @@ -209,7 +208,9 @@ int main(int n, char **v) g = gui_init(); new_thread(gui_thread, g); - vcd_main_gui(g, h, database, is_on); + vcd_main_gui(g, h, database); + + on_off(database, "VCD_FUNCTION", is_on, 1); for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); From 50c00218c7ca785c2ff50c2d1446541c113c26fb Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 23 May 2016 16:18:00 +0200 Subject: [PATCH 152/217] space widget, to add some space in the gui --- common/utils/T/tracer/gui/Makefile | 2 +- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/gui_defs.h | 8 ++++++- common/utils/T/tracer/gui/space.c | 36 ++++++++++++++++++++++++++++ common/utils/T/tracer/gui/widget.c | 4 ++-- 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 common/utils/T/tracer/gui/space.c diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index 7129d390b9..fb3a9486d8 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \ - timeline.o + timeline.o space.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 6d36cddfd6..208a3c2a54 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -33,6 +33,7 @@ widget *new_xy_plot(gui *gui, int width, int height, char *label, widget *new_textlist(gui *gui, int width, int nlines, int background_color); widget *new_timeline(gui *gui, int width, int number_of_sublines, int subline_height); +widget *new_space(gui *gui, int width, int height); void label_set_clickable(gui *gui, widget *label, int clickable); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index 5b8469ad9a..dc3559c82c 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -31,7 +31,7 @@ extern int volatile gui_logd; enum widget_type { TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL, - TIMELINE + TIMELINE, SPACE }; struct widget_list; @@ -148,6 +148,12 @@ struct label_widget { int baseline; /* as given by the graphic's backend */ }; +struct space_widget { + struct widget common; + int wanted_width; + int wanted_height; +}; + /*************************************************************************/ /* events */ /*************************************************************************/ diff --git a/common/utils/T/tracer/gui/space.c b/common/utils/T/tracer/gui/space.c new file mode 100644 index 0000000000..c98600b88d --- /dev/null +++ b/common/utils/T/tracer/gui/space.c @@ -0,0 +1,36 @@ +#include "gui.h" +#include "gui_defs.h" +#include + +static void paint(gui *_gui, widget *_w) +{ + /* nothing */ +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct space_widget *w = _w; + LOGD("HINTS space %p\n", w); + *width = w->wanted_width; + *height = w->wanted_height; +} + +widget *new_space(gui *_gui, int width, int height) +{ + struct gui *g = _gui; + struct space_widget *w; + + glock(g); + + w = new_widget(g, SPACE, sizeof(struct space_widget)); + + w->wanted_width = width; + w->wanted_height = height; + + w->common.paint = paint; + w->common.hints = hints; + + gunlock(g); + + return w; +} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 1d2b03a25f..149f4be7f5 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -265,12 +265,11 @@ void widget_dirty(gui *_gui, widget *_this) static const char *names[] = { "TOPLEVEL_WINDOW", "CONTAINER", "POSITIONER", "TEXT_LIST", - "XY_PLOT", "BUTTON", "LABEL", "TIMELINE" + "XY_PLOT", "BUTTON", "LABEL", "TIMELINE", "SPACE" }; const char *widget_name(enum widget_type type) { switch (type) { - default: break; case TOPLEVEL_WINDOW: case CONTAINER: case POSITIONER: @@ -279,6 +278,7 @@ const char *widget_name(enum widget_type type) case BUTTON: case LABEL: case TIMELINE: + case SPACE: return names[type]; } return "UNKNOWN (error)"; From d08a2b1a60622a4f95282c5b6d055dfe7e81beb9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 24 May 2016 15:38:44 +0200 Subject: [PATCH 153/217] image widget many assumptions about X backed were made, to be refined if does not work properly in some setups --- common/utils/T/tracer/Makefile.remote | 2 +- common/utils/T/tracer/gui/Makefile | 2 +- common/utils/T/tracer/gui/gui.h | 1 + common/utils/T/tracer/gui/gui_defs.h | 9 ++- common/utils/T/tracer/gui/image.c | 112 ++++++++++++++++++++++++++ common/utils/T/tracer/gui/widget.c | 3 +- common/utils/T/tracer/gui/x.c | 57 +++++++++++++ common/utils/T/tracer/gui/x.h | 6 ++ common/utils/T/tracer/gui/x_defs.h | 6 ++ 9 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 common/utils/T/tracer/gui/image.c diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index c539a2c388..be8a77250c 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. #CFLAGS += -O3 -ffast-math -fomit-frame-pointer -LIBS=-lX11 -lm +LIBS=-lX11 -lm -lpng tracer_remote: remote_old.o plot.o database.o gui.o utils.o gui/gui.a $(CC) $(CFLAGS) -o tracer_remote $^ $(LIBS) diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index fb3a9486d8..370020a8b5 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \ - timeline.o space.o + timeline.o space.o image.o gui.a: $(OBJS) ar cr gui.a $(OBJS) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 208a3c2a54..8ab0f06373 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -34,6 +34,7 @@ widget *new_textlist(gui *gui, int width, int nlines, int background_color); widget *new_timeline(gui *gui, int width, int number_of_sublines, int subline_height); widget *new_space(gui *gui, int width, int height); +widget *new_image(gui *gui, unsigned char *data, int length); void label_set_clickable(gui *gui, widget *label, int clickable); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index dc3559c82c..ec72bb0e2b 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -31,7 +31,7 @@ extern int volatile gui_logd; enum widget_type { TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL, - TIMELINE, SPACE + TIMELINE, SPACE, IMAGE }; struct widget_list; @@ -154,6 +154,13 @@ struct space_widget { int wanted_height; }; +struct image_widget { + struct widget common; + int width; + int height; + void *x; /* opaque X data (type x_image), used in x.c */ +}; + /*************************************************************************/ /* events */ /*************************************************************************/ diff --git a/common/utils/T/tracer/gui/image.c b/common/utils/T/tracer/gui/image.c new file mode 100644 index 0000000000..70618239aa --- /dev/null +++ b/common/utils/T/tracer/gui/image.c @@ -0,0 +1,112 @@ +#include "gui.h" +#include "gui_defs.h" +#include "x.h" +#include +#include +#include + +static void paint(gui *_gui, widget *_w) +{ + struct gui *g = _gui; + struct image_widget *w = _w; + x_draw_image(g->x, g->xwin, w->x, w->common.x, w->common.y); +} + +static void hints(gui *_gui, widget *_w, int *width, int *height) +{ + struct image_widget *w = _w; + LOGD("HINTS image %p\n", w); + *width = w->width; + *height = w->height; +} + +struct png_reader { + unsigned char *data; + int size; + int pos; +}; + +static void png_readfn(png_structp png_ptr, png_bytep data, png_size_t length) +{ + struct png_reader *r = png_get_io_ptr(png_ptr); + if (length > r->size - r->pos) png_error(png_ptr, "bad png image"); + memcpy(data, r->data + r->pos, length); + r->pos += length; +} + +static void load_image(struct gui *g, struct image_widget *w, + unsigned char *data, int length) +{ + png_structp png_ptr; + png_infop info_ptr; + png_bytepp image; + int width, height, bit_depth, color_type, channels; + unsigned char *img_data; + struct png_reader r; + int i; + + /* unpack PNG data */ + + r.data = data; + r.size = length; + r.pos = 0; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) abort(); + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) abort(); + + if (setjmp(png_jmpbuf(png_ptr))) abort(); + + png_set_read_fn(png_ptr, &r, png_readfn); + + png_read_png(png_ptr, info_ptr, + PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_PACKING | + PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_BGR, NULL); + + image = png_get_rows(png_ptr, info_ptr); + + width = png_get_image_width(png_ptr, info_ptr); + height = png_get_image_height(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + color_type = png_get_color_type(png_ptr, info_ptr); + channels = png_get_channels(png_ptr, info_ptr); + + if (width < 1 || width > 1000 || height < 1 || height > 1000 || + bit_depth != 8 || color_type != PNG_COLOR_TYPE_RGBA || channels != 4) + { printf("bad image\n"); abort(); } + + img_data = malloc(4 * width * height); if (img_data == NULL) abort(); + for (i = 0; i < height; i++) + memcpy(img_data+i*4*width, image[i], width*4); + + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + /* create the X image */ + w->x = x_create_image(g->x, img_data, width, height); + + free(img_data); + + w->width = width; + w->height = height; +} + +widget *new_image(gui *_gui, unsigned char *data, int length) +{ + struct gui *g = _gui; + struct image_widget *w; + + glock(g); + + w = new_widget(g, IMAGE, sizeof(struct image_widget)); + + load_image(g, w, data, length); + + w->common.paint = paint; + w->common.hints = hints; + + gunlock(g); + + return w; +} diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 149f4be7f5..362d2e1e48 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -265,7 +265,7 @@ void widget_dirty(gui *_gui, widget *_this) static const char *names[] = { "TOPLEVEL_WINDOW", "CONTAINER", "POSITIONER", "TEXT_LIST", - "XY_PLOT", "BUTTON", "LABEL", "TIMELINE", "SPACE" + "XY_PLOT", "BUTTON", "LABEL", "TIMELINE", "SPACE", "IMAGE" }; const char *widget_name(enum widget_type type) { @@ -279,6 +279,7 @@ const char *widget_name(enum widget_type type) case LABEL: case TIMELINE: case SPACE: + case IMAGE: return names[type]; } return "UNKNOWN (error)"; diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 0a2d145039..5fb41b4f92 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -2,6 +2,7 @@ #include "x_defs.h" #include "gui_defs.h" #include +#include #include #include #include @@ -111,6 +112,52 @@ x_window *x_create_window(x_connection *_x, int width, int height, return ret; } +x_image *x_create_image(x_connection *_x, unsigned char *data, + int width, int height) +{ + struct x_connection *x = _x; + struct x_image *ret; + XImage *ximage; + XVisualInfo *vs; + XVisualInfo template; + int nvs; + Visual *v; + + ret = calloc(1, sizeof(struct x_image)); if (ret == NULL) OOM; + + template.class = TrueColor; + template.depth = 24; + template.red_mask = 0xff0000; + 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); + if (vs == NULL || nvs == 0) 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); + 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); + + /* 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) { struct widget_list *cur; @@ -312,6 +359,16 @@ void x_draw_clipped_string(x_connection *_c, x_window *_w, int color, XSetClipMask(c->d, c->colors[color], None); } +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); +} + void x_draw(x_connection *_c, x_window *_w) { struct x_connection *c = _c; diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index c1f8d33d89..aca9868ae0 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -5,12 +5,16 @@ typedef void x_connection; typedef void x_window; +typedef void x_image; x_connection *x_open(void); x_window *x_create_window(x_connection *x, int width, int height, char *title); +x_image *x_create_image(x_connection *x, unsigned char *data, + int width, int height); + int x_connection_fd(x_connection *x); void x_flush(x_connection *x); @@ -42,6 +46,8 @@ void x_draw_clipped_string(x_connection *_c, x_window *_w, int color, int x, int y, const char *t, int clipx, int clipy, int clipwidth, int clipheight); +void x_draw_image(x_connection *c, x_window *w, x_image *img, int x, int y); + /* specials functions to plot many points * you call several times x_add_point() then x_plot_points() */ diff --git a/common/utils/T/tracer/gui/x_defs.h b/common/utils/T/tracer/gui/x_defs.h index 41817d06ce..e5874a1a3b 100644 --- a/common/utils/T/tracer/gui/x_defs.h +++ b/common/utils/T/tracer/gui/x_defs.h @@ -23,4 +23,10 @@ struct x_window { int resize, new_width, new_height; }; +struct x_image { + Pixmap p; + int width; + int height; +}; + #endif /* _X_DEFS_H_ */ From 9cedfbcf1baaebfb7253baa9547f5b628e90a31f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 24 May 2016 15:43:55 +0200 Subject: [PATCH 154/217] add openair logo to enb.c --- common/utils/T/tracer/enb.c | 4 + common/utils/T/tracer/openair_logo.h | 395 +++++++++++++++++++++++++ common/utils/T/tracer/openair_logo.png | Bin 0 -> 4664 bytes 3 files changed, 399 insertions(+) create mode 100644 common/utils/T/tracer/openair_logo.h create mode 100644 common/utils/T/tracer/openair_logo.png diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 19cac762af..a2b00c7930 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -13,6 +13,7 @@ #include "utils.h" #include "../T_defs.h" #include "event_selector.h" +#include "openair_logo.h" #define DEFAULT_REMOTE_PORT 2021 @@ -116,6 +117,7 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) widget *main_window; widget *top_container; widget *line; + widget *logo; widget *input_signal_plot; logger *input_signal_log; view *input_signal_view; @@ -131,6 +133,8 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); + logo = new_image(g, openair_logo_png, openair_logo_png_len); + widget_add_child(g, line, logo, -1); input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20); widget_add_child(g, line, input_signal_plot, -1); xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70); diff --git a/common/utils/T/tracer/openair_logo.h b/common/utils/T/tracer/openair_logo.h new file mode 100644 index 0000000000..4a98c3d871 --- /dev/null +++ b/common/utils/T/tracer/openair_logo.h @@ -0,0 +1,395 @@ +/* this file (minus this comment) was obtained by running: + * xxd -i openair_logo.png > openair_logo.h + */ +unsigned char openair_logo_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x28, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x08, 0x78, 0x5f, 0x43, 0x00, 0x00, 0x00, + 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, + 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, + 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, + 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe0, 0x05, 0x17, + 0x0e, 0x30, 0x2a, 0xd1, 0xdd, 0x83, 0x5b, 0x00, 0x00, 0x11, 0xc5, 0x49, + 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0x9b, 0x79, 0x70, 0x94, 0xe7, 0x7d, + 0xc7, 0x3f, 0xcf, 0xf3, 0xbe, 0xbb, 0x2b, 0xed, 0xea, 0xbe, 0xef, 0x03, + 0x24, 0x10, 0x08, 0x8c, 0xb9, 0x31, 0x06, 0x73, 0xd4, 0xd8, 0x4e, 0x38, + 0x62, 0x63, 0x77, 0x92, 0x90, 0xcb, 0x9d, 0x34, 0x19, 0x27, 0xce, 0xa4, + 0xed, 0x8c, 0xd3, 0x78, 0xd2, 0x64, 0xd2, 0x36, 0x9d, 0x34, 0xa9, 0xdb, + 0xa6, 0x99, 0xb6, 0x49, 0x67, 0x82, 0xe3, 0x24, 0x76, 0x9a, 0x34, 0x76, + 0x5c, 0x1f, 0x18, 0x8f, 0x31, 0xc4, 0xc6, 0x06, 0xcc, 0x69, 0x21, 0xb0, + 0x05, 0x08, 0x1d, 0x80, 0x2e, 0x74, 0xae, 0xa4, 0xbd, 0xb4, 0xbb, 0xef, + 0xfb, 0x3c, 0xfd, 0x63, 0x57, 0x2b, 0xd6, 0x12, 0x58, 0x60, 0x32, 0x74, + 0xb0, 0x9f, 0x99, 0x1d, 0x69, 0x9f, 0xe7, 0xf9, 0x3d, 0xd7, 0xf7, 0x77, + 0x3f, 0xcf, 0x0a, 0xad, 0xb5, 0xe6, 0x43, 0x5a, 0x94, 0xd6, 0xf4, 0x07, + 0xc3, 0xf8, 0xa3, 0x51, 0x3a, 0x47, 0xfc, 0xf4, 0x05, 0x82, 0x0c, 0xf8, + 0x43, 0x98, 0x52, 0x50, 0xec, 0x49, 0xa5, 0x38, 0xdd, 0x4d, 0x71, 0xba, + 0x87, 0x34, 0x97, 0x93, 0x74, 0x97, 0x13, 0x21, 0xc4, 0x1f, 0x7d, 0x4d, + 0xe2, 0xc3, 0x0a, 0xc8, 0xde, 0xce, 0x3e, 0xde, 0xea, 0x1e, 0x60, 0x45, + 0x51, 0x2e, 0x45, 0x9e, 0x14, 0x72, 0x52, 0x9c, 0xa4, 0x3b, 0x1d, 0x38, + 0x0d, 0x03, 0x04, 0x44, 0x6d, 0x9b, 0x50, 0xc4, 0xc2, 0x1f, 0x8e, 0x30, + 0x1c, 0x0a, 0xd1, 0xed, 0x1d, 0xa1, 0x36, 0x3f, 0x97, 0x19, 0x05, 0xb9, + 0x1f, 0x01, 0x72, 0x3d, 0xcb, 0x68, 0x24, 0xca, 0x7f, 0x34, 0xb6, 0x30, + 0x37, 0x27, 0x83, 0x7b, 0x67, 0x96, 0x5e, 0x15, 0x6d, 0x63, 0x47, 0x0f, + 0x03, 0x23, 0x3e, 0x6e, 0x9f, 0x5d, 0x4d, 0x8a, 0xc3, 0xf1, 0x11, 0x20, + 0x1f, 0xb4, 0xbc, 0x7c, 0xbe, 0x97, 0x0e, 0x9f, 0x9f, 0x7b, 0x67, 0x94, + 0x51, 0xe0, 0x76, 0x5d, 0xd3, 0x18, 0xc1, 0x48, 0x84, 0x53, 0x1d, 0xdd, + 0xe4, 0x78, 0xdc, 0x54, 0x17, 0x15, 0x7c, 0x04, 0xc8, 0xb5, 0x96, 0x86, + 0xfe, 0x61, 0x0e, 0x5c, 0x1c, 0xe4, 0xe1, 0xf9, 0x33, 0xaf, 0xcb, 0x78, + 0xa7, 0x2e, 0x74, 0x91, 0x9b, 0x91, 0x46, 0x41, 0x56, 0xe6, 0x75, 0x5d, + 0xa7, 0xfc, 0x30, 0x80, 0xb1, 0xaf, 0x67, 0x90, 0x97, 0xcf, 0xf7, 0x4d, + 0x0b, 0x8c, 0xd1, 0x70, 0x04, 0x7f, 0x38, 0xfa, 0xbe, 0xfd, 0xe6, 0x54, + 0x94, 0xd2, 0x33, 0xe8, 0x65, 0x60, 0x78, 0xe4, 0xba, 0xae, 0xd5, 0xbc, + 0xd9, 0xc1, 0x08, 0x5a, 0x36, 0xfb, 0x7b, 0x86, 0xf8, 0xd6, 0x92, 0x59, + 0x97, 0xed, 0xd3, 0xe1, 0x0b, 0xf2, 0xf8, 0x89, 0xb3, 0x48, 0x65, 0x33, + 0x33, 0xc3, 0x83, 0x43, 0x08, 0x46, 0x82, 0x21, 0xd2, 0x1d, 0x06, 0x1b, + 0xea, 0x66, 0x90, 0xeb, 0x71, 0x4f, 0x49, 0xb7, 0x60, 0x66, 0x15, 0x0d, + 0x67, 0x5a, 0xc8, 0xf0, 0xb8, 0x71, 0x5e, 0x27, 0x9b, 0x72, 0xd3, 0xab, + 0xac, 0x7f, 0x6a, 0x38, 0xcb, 0xa6, 0xaa, 0x22, 0xe6, 0x66, 0xa7, 0x4f, + 0x6a, 0x3b, 0x37, 0x1a, 0x64, 0xe7, 0xb9, 0x6e, 0xb2, 0x9d, 0x0e, 0xb6, + 0xd6, 0x96, 0xe3, 0x32, 0x92, 0x15, 0x86, 0x65, 0x2b, 0x1a, 0x3b, 0xba, + 0x51, 0xb6, 0xa2, 0xb6, 0x28, 0x8f, 0xac, 0x29, 0x80, 0x09, 0x85, 0xc3, + 0xf4, 0x0d, 0x0e, 0x53, 0x59, 0x52, 0xf8, 0x91, 0x84, 0xbc, 0x5f, 0x79, + 0x77, 0xc8, 0x87, 0x37, 0x6c, 0x4d, 0x09, 0x46, 0x87, 0x2f, 0xc4, 0x4f, + 0xdf, 0x69, 0xe3, 0x6f, 0x97, 0xcd, 0x21, 0xd5, 0x34, 0xa6, 0x3e, 0x1c, + 0x43, 0xb2, 0xb8, 0xaa, 0x8c, 0xa8, 0x6d, 0xd3, 0xd8, 0x7a, 0x9e, 0xb9, + 0x95, 0xa5, 0xb8, 0x5d, 0xc9, 0xce, 0x40, 0xaa, 0xcb, 0xc5, 0xa8, 0xdf, + 0x8f, 0x52, 0xf9, 0x48, 0x79, 0x1d, 0x2c, 0x80, 0xbe, 0x89, 0xcb, 0x5f, + 0xee, 0x3b, 0xa9, 0xb5, 0x9a, 0x5c, 0xdf, 0x1f, 0x0a, 0xeb, 0x07, 0x77, + 0x1f, 0x9b, 0x54, 0xef, 0x1d, 0x0b, 0xeb, 0xd6, 0xa1, 0x11, 0x7d, 0xde, + 0x3b, 0xaa, 0xfd, 0xe1, 0x48, 0x52, 0x9b, 0xd2, 0x4a, 0xbf, 0x71, 0xfc, + 0x1d, 0x1d, 0x89, 0x46, 0x27, 0xd1, 0x05, 0x82, 0x21, 0x7d, 0xa6, 0xa5, + 0xed, 0xba, 0xac, 0xf9, 0xa6, 0x95, 0x90, 0xd1, 0x88, 0x45, 0x65, 0x7a, + 0x2a, 0x4c, 0x11, 0x5c, 0x3f, 0xdd, 0xd2, 0xc5, 0xbf, 0xae, 0x9a, 0x9f, + 0x54, 0xf7, 0xc3, 0xa3, 0xa7, 0x29, 0x48, 0x71, 0xb0, 0xa2, 0x30, 0x07, + 0x5b, 0xc0, 0xa1, 0xf6, 0x0e, 0xa4, 0xb2, 0x59, 0x3b, 0xa7, 0x36, 0xa6, + 0xdb, 0x11, 0xac, 0x9c, 0x3f, 0x87, 0xd3, 0xed, 0xe7, 0xa9, 0x9f, 0x59, + 0x9d, 0x44, 0xeb, 0x4e, 0x4d, 0x21, 0x1c, 0x8d, 0x60, 0xdb, 0x0a, 0xc3, + 0x90, 0xfc, 0x67, 0x63, 0x1b, 0xbf, 0x69, 0xef, 0x27, 0x64, 0xab, 0xd8, + 0xf4, 0xd2, 0x60, 0xd7, 0xc7, 0x17, 0x91, 0xe3, 0x8a, 0x1d, 0xf7, 0xe3, + 0xef, 0x9c, 0xe3, 0x17, 0x67, 0x7b, 0xc9, 0x4e, 0x75, 0xf1, 0xcd, 0x85, + 0xd5, 0xdc, 0x5e, 0x98, 0x79, 0xf3, 0xab, 0xac, 0xe1, 0x48, 0x74, 0x4a, + 0x55, 0x15, 0xb2, 0x6d, 0xbc, 0x91, 0x28, 0xd9, 0xae, 0x09, 0x23, 0xfc, + 0x58, 0x43, 0x33, 0x9b, 0x67, 0x94, 0x32, 0x37, 0x67, 0xa2, 0x7f, 0x6d, + 0x5e, 0x36, 0x43, 0xfe, 0x20, 0x0d, 0x2d, 0xed, 0x2c, 0xac, 0x89, 0x01, + 0x60, 0x48, 0x49, 0xa6, 0xc7, 0x43, 0x24, 0x1a, 0x9d, 0x64, 0xc4, 0x0b, + 0x72, 0x73, 0x09, 0x04, 0x83, 0x64, 0xa4, 0xa7, 0xd1, 0x36, 0x1a, 0xa4, + 0x69, 0x38, 0xcc, 0x33, 0x1b, 0xea, 0x09, 0x5a, 0x0a, 0x1b, 0xf0, 0x98, + 0x12, 0xb4, 0x66, 0xcb, 0x8b, 0x87, 0x79, 0x7b, 0x34, 0xc2, 0xf7, 0x97, + 0xd5, 0xd0, 0x33, 0xea, 0xe7, 0xae, 0x17, 0x8e, 0xf0, 0xe4, 0x5d, 0x8b, + 0xd8, 0x5a, 0x99, 0x73, 0x73, 0x03, 0x32, 0x12, 0x89, 0x92, 0xee, 0x9c, + 0xbc, 0xbd, 0x5f, 0x9e, 0xee, 0x60, 0x55, 0xf1, 0x44, 0xfa, 0xe3, 0xdf, + 0x1a, 0x5b, 0x59, 0x92, 0x9f, 0x93, 0x04, 0xc6, 0x78, 0xc9, 0x49, 0x73, + 0x13, 0xcc, 0x48, 0xa7, 0x7f, 0xc8, 0x4b, 0x7e, 0x4e, 0x36, 0x00, 0x69, + 0xee, 0x54, 0x02, 0x81, 0x20, 0xce, 0xf7, 0xc4, 0x1f, 0x99, 0xe9, 0xe9, + 0xf8, 0xfc, 0x7e, 0x74, 0x9a, 0x07, 0x7f, 0xd4, 0x26, 0xc3, 0x65, 0x72, + 0xbc, 0x6f, 0x04, 0xbf, 0xd2, 0x3c, 0x30, 0xa3, 0x18, 0x97, 0x21, 0x19, + 0x0c, 0x8e, 0x71, 0xc6, 0x1f, 0x66, 0x43, 0x65, 0x11, 0x9f, 0x9f, 0x55, + 0x0c, 0xc0, 0x17, 0xeb, 0x2b, 0x89, 0xe8, 0x0f, 0x41, 0x1c, 0xd2, 0x13, + 0x1c, 0x23, 0x63, 0x0a, 0x57, 0xf4, 0xe5, 0x0b, 0xbd, 0xdc, 0x56, 0x18, + 0xe3, 0x46, 0x0d, 0x1c, 0xe9, 0x1f, 0x66, 0x5d, 0x59, 0x5e, 0xcc, 0xab, + 0xd2, 0x9a, 0xed, 0xa7, 0x3a, 0xd9, 0x7e, 0xaa, 0x13, 0x3b, 0xee, 0x7c, + 0x96, 0x15, 0xe4, 0xd1, 0x76, 0xa1, 0x73, 0xc2, 0x88, 0xa7, 0xb8, 0x18, + 0x1e, 0xf5, 0x4d, 0x0e, 0xe8, 0x0c, 0x09, 0x08, 0x34, 0x10, 0x88, 0x5a, + 0x78, 0x43, 0x21, 0x5e, 0xec, 0x18, 0x62, 0x5f, 0xe7, 0x20, 0x8b, 0x9f, + 0x39, 0xc0, 0x6f, 0xdb, 0x07, 0x70, 0x4a, 0x81, 0x00, 0x0c, 0x21, 0xe8, + 0x1d, 0xf1, 0xb1, 0xf8, 0x99, 0xb7, 0xd8, 0xb8, 0xf3, 0x18, 0x47, 0x07, + 0xfc, 0x37, 0x3f, 0x20, 0x1e, 0xc3, 0x24, 0xcb, 0x35, 0x19, 0x90, 0xd9, + 0x59, 0x69, 0x38, 0xa4, 0x48, 0xe4, 0xb5, 0xee, 0xad, 0x2e, 0x4e, 0xb4, + 0xf5, 0x06, 0x23, 0xbc, 0x70, 0xae, 0x8f, 0x1d, 0xe7, 0xfb, 0x39, 0xed, + 0x0d, 0x24, 0xea, 0x73, 0x33, 0x33, 0x12, 0xff, 0x3b, 0x4c, 0x13, 0xa7, + 0x39, 0x59, 0xf2, 0xa4, 0x90, 0x38, 0x1c, 0x26, 0x42, 0x08, 0xfe, 0xe2, + 0xd6, 0x99, 0xfc, 0x6e, 0xc3, 0xad, 0xbc, 0xb6, 0x65, 0x09, 0xbb, 0x3e, + 0xb1, 0x8c, 0xfb, 0xcb, 0xb3, 0xf8, 0x61, 0xc3, 0xb9, 0x84, 0x37, 0x27, + 0x80, 0x5c, 0x4f, 0x2a, 0xdf, 0x5e, 0x3c, 0x83, 0x40, 0x34, 0xca, 0xf6, + 0xa6, 0xee, 0x9b, 0xdf, 0x86, 0xdc, 0x5e, 0x9c, 0x33, 0x75, 0x5c, 0x72, + 0x5b, 0xfd, 0x84, 0x9a, 0x71, 0x3a, 0xf8, 0xd3, 0x99, 0x25, 0x89, 0xef, + 0xa5, 0x1e, 0x17, 0x2f, 0x7c, 0x6c, 0xd1, 0x24, 0x9a, 0x9a, 0xea, 0xca, + 0x89, 0x83, 0x97, 0x92, 0xd2, 0x92, 0xa2, 0xc9, 0x2e, 0xb2, 0x69, 0x90, + 0x95, 0x99, 0x81, 0xd2, 0x9a, 0x1d, 0x6d, 0x17, 0x39, 0xe8, 0x0d, 0xb1, + 0xa1, 0x2c, 0x17, 0x8d, 0x26, 0x60, 0xd9, 0xb8, 0x1d, 0x4e, 0x24, 0x60, + 0x4a, 0xc1, 0xc5, 0xe0, 0x18, 0xd2, 0x30, 0x59, 0x5d, 0x94, 0x85, 0x29, + 0x48, 0x30, 0xc8, 0xa4, 0xc0, 0x30, 0x14, 0x0a, 0xd2, 0xd1, 0xd1, 0x85, + 0xdf, 0xef, 0xc7, 0x30, 0x0c, 0x72, 0x73, 0x73, 0x28, 0x2b, 0x2b, 0x9b, + 0x34, 0x79, 0x67, 0x67, 0x27, 0x7d, 0x7d, 0x7d, 0xc9, 0x11, 0xa6, 0x10, + 0xa4, 0xa5, 0xa5, 0x51, 0x56, 0x56, 0x4e, 0x6a, 0x6a, 0xca, 0x24, 0x9a, + 0xf6, 0xf6, 0x76, 0xbc, 0x5e, 0xef, 0x94, 0x87, 0xa4, 0x94, 0xa2, 0xb8, + 0xb8, 0x98, 0xd2, 0xd2, 0x58, 0xf6, 0xb5, 0xbf, 0xbf, 0x9f, 0x8e, 0x8e, + 0x0e, 0x4a, 0x4b, 0x4b, 0x29, 0x2c, 0x2c, 0xbc, 0xd4, 0x45, 0xa7, 0xb9, + 0xb9, 0x99, 0x40, 0x20, 0x80, 0xd3, 0xe9, 0xa4, 0xbe, 0xbe, 0xfe, 0xaa, + 0xee, 0x28, 0x0e, 0x5c, 0x1c, 0xe6, 0xf8, 0xa0, 0x8f, 0x95, 0x85, 0x59, + 0xdc, 0x9a, 0x37, 0xd9, 0x66, 0x74, 0x07, 0xc2, 0x3c, 0xdd, 0x7a, 0x11, + 0x29, 0x04, 0x1b, 0xca, 0x73, 0xa9, 0xcb, 0xf2, 0x4c, 0xd0, 0x0d, 0x8c, + 0xa2, 0x92, 0x24, 0x42, 0x50, 0x90, 0xe2, 0x64, 0x79, 0x61, 0x26, 0xe5, + 0x69, 0xc9, 0xfb, 0x7d, 0x77, 0x60, 0x84, 0x47, 0xde, 0x3a, 0xc3, 0xbb, + 0xc3, 0x21, 0x9c, 0x02, 0x8a, 0xd3, 0xdd, 0xfc, 0xe4, 0x8e, 0x7a, 0xe6, + 0x67, 0xbb, 0xd9, 0xd1, 0xda, 0xc3, 0x3f, 0x34, 0xb4, 0x33, 0x10, 0xb6, + 0x89, 0xda, 0x36, 0x17, 0x02, 0x63, 0x6c, 0xa8, 0x28, 0x61, 0xd7, 0xc6, + 0x5b, 0x92, 0x25, 0xe4, 0xb5, 0xd7, 0x5e, 0xa7, 0xb1, 0xb1, 0x71, 0xd2, + 0x22, 0x0d, 0xc3, 0x60, 0xf3, 0xe6, 0x4d, 0x54, 0x55, 0x55, 0x01, 0xd0, + 0xd2, 0xd2, 0xca, 0x73, 0xcf, 0x3d, 0x87, 0x69, 0x5e, 0x5e, 0xb8, 0xe6, + 0xcd, 0x9b, 0xc7, 0x9d, 0x77, 0xfe, 0x49, 0xe2, 0xfb, 0xd1, 0xa3, 0x47, + 0xd9, 0xbb, 0xf7, 0x0d, 0x0c, 0x63, 0xea, 0x00, 0xcc, 0xb6, 0x6d, 0x56, + 0xac, 0x58, 0x4e, 0x69, 0x69, 0x29, 0xd1, 0x68, 0x94, 0x27, 0x9e, 0xf8, + 0x05, 0x4e, 0xa7, 0x13, 0x87, 0xc3, 0xc1, 0xb6, 0x6d, 0x9f, 0x26, 0x3b, + 0x3b, 0x3b, 0x01, 0xdc, 0xf1, 0xe3, 0x8d, 0xf4, 0xf4, 0xf4, 0x90, 0x99, + 0x99, 0x49, 0x7d, 0x7d, 0xfd, 0xb4, 0xc1, 0xd8, 0xdb, 0x33, 0xc4, 0xdd, + 0x3b, 0x8e, 0xe1, 0x36, 0x0d, 0xa2, 0x4a, 0x73, 0xf4, 0xfe, 0x15, 0xcc, + 0x8e, 0x1f, 0xf8, 0x78, 0x39, 0xef, 0x0f, 0xf1, 0xe8, 0xa1, 0xb3, 0xb8, + 0x0c, 0x41, 0x5e, 0x8a, 0x83, 0xba, 0x2c, 0x0f, 0xbb, 0x3b, 0x07, 0xf9, + 0xe4, 0xee, 0x46, 0xa6, 0xca, 0x67, 0x8c, 0xb3, 0xc2, 0x7d, 0xd5, 0x85, + 0x6c, 0x5f, 0x3b, 0xb1, 0x96, 0xfa, 0xbc, 0x4c, 0x76, 0x6e, 0x5e, 0xc6, + 0x38, 0xaf, 0x0b, 0x21, 0x12, 0x7d, 0x37, 0xcd, 0x2c, 0x66, 0xe3, 0x8c, + 0x62, 0x34, 0xfa, 0x92, 0x71, 0x26, 0x98, 0xca, 0xb4, 0x6d, 0x9b, 0x17, + 0x5e, 0x78, 0x91, 0xd6, 0xd6, 0x56, 0x84, 0x10, 0x54, 0x54, 0x94, 0x53, + 0x54, 0x54, 0x44, 0x24, 0x12, 0xa5, 0xad, 0xad, 0x8d, 0x40, 0x20, 0xc0, + 0xef, 0x7f, 0xff, 0x2c, 0x5b, 0xb7, 0xde, 0x47, 0x75, 0x75, 0x35, 0x3e, + 0x9f, 0x0f, 0x21, 0x04, 0x4a, 0x29, 0x66, 0xcc, 0x98, 0x41, 0x41, 0x41, + 0x01, 0x5a, 0x2b, 0x6c, 0x5b, 0xd1, 0xd3, 0xd3, 0x43, 0x57, 0x57, 0x17, + 0x8d, 0x8d, 0x8d, 0x8c, 0x8e, 0xfa, 0xb8, 0xf7, 0xde, 0x2d, 0x48, 0x29, + 0xf1, 0x7a, 0x87, 0x13, 0x34, 0x75, 0x75, 0x75, 0x64, 0x65, 0x65, 0x72, + 0x69, 0xc6, 0x46, 0x29, 0x4d, 0x69, 0x69, 0x4c, 0x12, 0xfd, 0x7e, 0x7f, + 0xa2, 0x2d, 0x1c, 0x0e, 0xb3, 0x67, 0xcf, 0x6b, 0x3c, 0xf0, 0xc0, 0xd6, + 0x0f, 0xac, 0xc2, 0xbe, 0xf6, 0xe6, 0x69, 0x52, 0xe2, 0xa9, 0x11, 0x01, + 0xfc, 0xd5, 0xfe, 0x33, 0xec, 0xdc, 0x98, 0xac, 0x9e, 0xf4, 0x7b, 0xfe, + 0x02, 0x0c, 0x86, 0xa3, 0x68, 0x1d, 0x33, 0xf8, 0x6b, 0x8b, 0x73, 0x58, + 0x51, 0x98, 0x89, 0xa5, 0x35, 0x96, 0xd2, 0x9c, 0x1c, 0xf2, 0xb1, 0xab, + 0x63, 0x90, 0xff, 0x6e, 0xe9, 0xe1, 0x1d, 0xaf, 0x8f, 0x5d, 0x1b, 0x97, + 0x90, 0x11, 0xf7, 0xec, 0x44, 0x1c, 0x88, 0x29, 0xf3, 0x55, 0x22, 0x19, + 0x84, 0x24, 0xd5, 0x37, 0x3a, 0x3a, 0x4a, 0x47, 0x47, 0x07, 0x86, 0x61, + 0x24, 0x38, 0x7b, 0x7c, 0xa0, 0x45, 0x8b, 0x16, 0xf2, 0xd4, 0x53, 0xbf, + 0x46, 0x6b, 0xcd, 0xab, 0xaf, 0xee, 0xe6, 0xcb, 0x5f, 0xfe, 0x52, 0xa2, + 0x4d, 0x29, 0x45, 0x4d, 0xcd, 0x4c, 0xe6, 0xcd, 0x9b, 0x97, 0xc4, 0xe9, + 0x3b, 0x77, 0xbe, 0x4c, 0x6b, 0x6b, 0x2b, 0xed, 0xed, 0xed, 0x84, 0xc3, + 0x61, 0x52, 0x53, 0x53, 0x13, 0x34, 0xb6, 0x6d, 0x53, 0x5f, 0x3f, 0x97, + 0xca, 0xca, 0xca, 0xcb, 0x27, 0xd7, 0x2e, 0xd9, 0x84, 0x94, 0x92, 0xf3, + 0xe7, 0xcf, 0x71, 0xe2, 0xc4, 0x49, 0x6e, 0xb9, 0x65, 0xfe, 0x35, 0x83, + 0xb1, 0xb7, 0xdb, 0xcb, 0x05, 0x7f, 0x08, 0x43, 0x08, 0x6c, 0xad, 0x31, + 0xa5, 0xe0, 0x8d, 0x8b, 0x5e, 0xce, 0x8e, 0x04, 0xa9, 0xcd, 0x74, 0x5f, + 0x39, 0xd9, 0x17, 0x3f, 0x38, 0x4b, 0x69, 0xee, 0x2c, 0xcb, 0xe1, 0xeb, + 0xf3, 0x93, 0xd7, 0xfe, 0x9d, 0xc3, 0x67, 0xf9, 0xf1, 0xc9, 0x0b, 0x9c, + 0x1d, 0x0e, 0x72, 0xa0, 0x77, 0x98, 0x7b, 0xca, 0xf3, 0x3e, 0x58, 0xfa, + 0x5d, 0x29, 0x85, 0x6d, 0xdb, 0x00, 0x14, 0x16, 0x16, 0x24, 0x1d, 0x48, + 0x76, 0x76, 0x36, 0x5a, 0x6b, 0x84, 0x10, 0x04, 0x83, 0xc1, 0xe9, 0xa4, + 0x61, 0x88, 0x46, 0x63, 0xa9, 0xeb, 0x71, 0x8f, 0x63, 0x2a, 0xee, 0xb8, + 0x9a, 0x62, 0x18, 0x06, 0xfb, 0xf7, 0xef, 0x23, 0x18, 0x0c, 0x5d, 0x5b, + 0x6a, 0x08, 0x78, 0xaa, 0xb9, 0x1b, 0x43, 0x08, 0x94, 0xd6, 0x3c, 0xb2, + 0xa0, 0x8a, 0x90, 0x65, 0xe3, 0x90, 0x82, 0xff, 0x6a, 0xba, 0xf0, 0x81, + 0x25, 0x2f, 0x60, 0xd9, 0x89, 0x7d, 0xa5, 0x1a, 0x1f, 0xdc, 0x69, 0x35, + 0x93, 0x8d, 0xab, 0x9e, 0x16, 0xe7, 0x4e, 0x78, 0x16, 0x31, 0xf2, 0xa1, + 0xa1, 0x21, 0x4e, 0x9d, 0x3a, 0x4d, 0x53, 0x53, 0x13, 0x81, 0x40, 0x80, + 0x68, 0x34, 0xca, 0xaa, 0x55, 0xb7, 0x93, 0x92, 0x92, 0x32, 0x69, 0x0c, + 0x9f, 0x2f, 0xc0, 0xe8, 0xe8, 0x08, 0x4a, 0x69, 0xb4, 0x56, 0x64, 0x66, + 0x66, 0x5d, 0x36, 0x29, 0xe7, 0x74, 0x3a, 0xb1, 0x2c, 0x8b, 0xb1, 0xb1, + 0x30, 0x47, 0x8e, 0x1c, 0x61, 0xcd, 0x9a, 0x3b, 0xae, 0xfe, 0xc0, 0xa2, + 0x36, 0x7b, 0xba, 0x06, 0x01, 0x58, 0x55, 0x9c, 0xcd, 0xb7, 0x17, 0xcd, + 0xe4, 0x7f, 0xdb, 0xfb, 0x38, 0xe7, 0x0b, 0xf1, 0x87, 0xae, 0x21, 0x7c, + 0x51, 0x8b, 0x74, 0xc7, 0xd5, 0x3b, 0x9b, 0xaf, 0x74, 0x0c, 0xf0, 0xfd, + 0xb7, 0xdb, 0x38, 0x39, 0xe4, 0xc7, 0xd2, 0x9a, 0xf5, 0x45, 0x39, 0xac, + 0x29, 0xc9, 0xb9, 0x71, 0xd9, 0x5e, 0xd3, 0x34, 0xd9, 0xbd, 0x7b, 0x0f, + 0xcf, 0x3f, 0xff, 0x02, 0x5a, 0x6b, 0xa4, 0x94, 0x78, 0x3c, 0x1e, 0x0a, + 0x0b, 0x0b, 0x58, 0xb1, 0xe2, 0x36, 0xaa, 0xab, 0xab, 0xa6, 0xa4, 0x79, + 0xe9, 0xa5, 0x9d, 0xd8, 0xb6, 0x8d, 0x10, 0x82, 0x50, 0x28, 0xc4, 0x37, + 0xbe, 0xf1, 0x08, 0x69, 0x69, 0x9e, 0x29, 0xe7, 0x28, 0x2c, 0x2c, 0xc4, + 0xb2, 0xa2, 0xf4, 0xf4, 0x5c, 0xe4, 0xd0, 0xa1, 0x43, 0xd4, 0xd6, 0xd6, + 0x5c, 0x75, 0x46, 0xf5, 0x77, 0x2d, 0x17, 0xe9, 0x0e, 0x86, 0xf1, 0x98, + 0x06, 0x5b, 0xab, 0x0b, 0x11, 0x02, 0x3e, 0x5b, 0x5b, 0xc2, 0x3f, 0xbc, + 0xdd, 0xca, 0x69, 0x6f, 0x90, 0xe3, 0x03, 0x3e, 0x56, 0x17, 0x67, 0x4f, + 0xef, 0xae, 0x02, 0xc1, 0x33, 0x6d, 0xbd, 0x3c, 0xfc, 0x66, 0x13, 0xde, + 0xb0, 0x85, 0x43, 0x0a, 0x72, 0x53, 0x1c, 0x7c, 0x69, 0x4e, 0x19, 0x3f, + 0x5c, 0x31, 0xeb, 0xc6, 0xa7, 0xdf, 0x23, 0x91, 0x08, 0x85, 0x85, 0x05, + 0x14, 0x17, 0x17, 0x53, 0x55, 0x55, 0x4d, 0x7e, 0x7e, 0x1e, 0x59, 0x59, + 0x97, 0xe7, 0x78, 0xa5, 0x14, 0x95, 0x95, 0xe5, 0xa4, 0xa6, 0xba, 0x01, + 0x4d, 0x24, 0x12, 0xc1, 0x71, 0x05, 0xee, 0x34, 0x4d, 0x93, 0x75, 0xeb, + 0xd6, 0xf2, 0xb3, 0x9f, 0x6d, 0xc7, 0xe5, 0x72, 0xb1, 0x63, 0xc7, 0x0e, + 0xdc, 0x6e, 0xcf, 0x55, 0xad, 0xf1, 0x9b, 0x87, 0x9a, 0x71, 0x9b, 0x06, + 0x52, 0x08, 0xb6, 0xd5, 0xc6, 0x82, 0xc0, 0xad, 0x33, 0x0a, 0x78, 0xac, + 0xb1, 0x1d, 0x5b, 0x6b, 0xfe, 0xe6, 0xf0, 0x59, 0xde, 0xf8, 0xc4, 0xb2, + 0x69, 0x8d, 0xe5, 0x34, 0x04, 0x0f, 0xbd, 0xd1, 0x84, 0xad, 0x35, 0x45, + 0x6e, 0x27, 0xdf, 0x5b, 0x5a, 0xcb, 0x1d, 0x25, 0xd9, 0x54, 0xa7, 0xa7, + 0x5e, 0xb7, 0xf8, 0xc9, 0xbc, 0x56, 0xfd, 0x6e, 0x59, 0x16, 0x9b, 0x36, + 0x6d, 0xa4, 0xae, 0xae, 0x6e, 0xda, 0x34, 0xb6, 0x6d, 0xb3, 0x72, 0xe5, + 0x4a, 0xca, 0xcb, 0xcb, 0xa7, 0x7b, 0x35, 0x40, 0x4e, 0x4e, 0x0e, 0xb7, + 0xdf, 0xbe, 0x92, 0xc3, 0x87, 0x8f, 0x10, 0x0c, 0x86, 0x08, 0x04, 0x82, + 0xd3, 0x8e, 0x3d, 0x9e, 0x38, 0xdd, 0xc5, 0x98, 0xad, 0x30, 0xa5, 0xc0, + 0xed, 0x30, 0x78, 0x68, 0x6f, 0x13, 0x11, 0x15, 0xfb, 0x6e, 0x6b, 0x8d, + 0x21, 0x04, 0x07, 0xfb, 0x46, 0x38, 0xd2, 0x37, 0xc2, 0xd2, 0x82, 0xf7, + 0xbf, 0x1b, 0xb7, 0x94, 0xe6, 0xcf, 0xea, 0x4a, 0xf8, 0x59, 0x53, 0x17, + 0xde, 0x70, 0x94, 0x53, 0x5e, 0x3f, 0x5f, 0x98, 0x5d, 0x72, 0x5d, 0x03, + 0xda, 0xf7, 0x95, 0xff, 0xf1, 0xcd, 0x4f, 0x75, 0xb1, 0x68, 0x59, 0xd6, + 0x55, 0x4f, 0xa8, 0x94, 0xba, 0x6a, 0x9a, 0x65, 0xcb, 0x96, 0x91, 0x99, + 0x99, 0x79, 0x59, 0x5b, 0x36, 0xa5, 0xf4, 0x2a, 0xc5, 0x6f, 0x5b, 0x2f, + 0xe2, 0x90, 0x02, 0x4b, 0x69, 0x2e, 0x8c, 0x86, 0xf8, 0xe5, 0xe9, 0x4e, + 0x7e, 0xd3, 0xdc, 0xcd, 0x93, 0xa7, 0xbb, 0xe8, 0x0f, 0x45, 0xb0, 0xb5, + 0xc6, 0x63, 0x1a, 0x7c, 0xbf, 0xa1, 0x6d, 0x7a, 0x0c, 0xa5, 0x35, 0x8f, + 0xad, 0x98, 0xcd, 0x9a, 0x92, 0x6c, 0x94, 0x86, 0x1f, 0x9f, 0xbc, 0xc0, + 0xd7, 0xf6, 0x9d, 0xba, 0xae, 0x80, 0x98, 0x2e, 0x97, 0x0b, 0xb7, 0xdb, + 0x4d, 0x28, 0x14, 0x62, 0xff, 0xfe, 0xfd, 0x54, 0x54, 0x54, 0x90, 0x91, + 0x91, 0x81, 0x52, 0x8a, 0x86, 0x86, 0x06, 0x94, 0x52, 0x28, 0xa5, 0xa8, + 0xad, 0xad, 0xbd, 0x2e, 0x13, 0xda, 0xb6, 0x9d, 0x18, 0x33, 0x89, 0x33, + 0xa4, 0xbc, 0xa2, 0x71, 0x5f, 0xbe, 0x7c, 0x39, 0xbb, 0x76, 0xed, 0x9a, + 0xb6, 0x0d, 0xe9, 0x0a, 0x84, 0x69, 0x18, 0x18, 0x45, 0x03, 0x1f, 0xab, + 0xc8, 0xe3, 0x89, 0x75, 0xf3, 0xb0, 0x2f, 0xe1, 0x29, 0xa7, 0x14, 0xdc, + 0xf3, 0xd2, 0x31, 0x1a, 0x07, 0x7d, 0x34, 0x0e, 0xf8, 0xe8, 0x0c, 0x8c, + 0x31, 0x5d, 0x05, 0xf1, 0xfc, 0x3d, 0x0b, 0xb9, 0xfb, 0xa5, 0x63, 0x1c, + 0xee, 0x1d, 0xe1, 0xc9, 0xe6, 0x6e, 0x66, 0x65, 0x7a, 0xf8, 0xfa, 0xfc, + 0x8a, 0xeb, 0x03, 0x48, 0x5a, 0x5a, 0x1a, 0x6b, 0xd6, 0xac, 0x61, 0xd7, + 0xae, 0x5d, 0x04, 0x83, 0x21, 0xb6, 0x6f, 0x7f, 0x9c, 0x9c, 0x9c, 0x1c, + 0xa2, 0xd1, 0x28, 0x3e, 0x5f, 0x2c, 0xab, 0x59, 0x5a, 0x5a, 0xc2, 0x86, + 0x0d, 0x77, 0x5e, 0xf3, 0x24, 0x4a, 0x29, 0xb4, 0xd6, 0x98, 0xa6, 0xc9, + 0x9e, 0x3d, 0x7f, 0x98, 0x14, 0xe5, 0xdb, 0xb6, 0xcd, 0xad, 0xb7, 0x2e, + 0x60, 0xc9, 0x92, 0x25, 0x57, 0x88, 0xfe, 0xeb, 0x69, 0x69, 0x69, 0xa5, + 0xa5, 0xe5, 0x2c, 0xa6, 0x69, 0xbe, 0xaf, 0xa4, 0xfd, 0xe2, 0x74, 0x17, + 0xc1, 0xa8, 0x4d, 0x8a, 0x69, 0xf0, 0x99, 0xda, 0x62, 0x3c, 0x53, 0x5c, + 0xd3, 0x7e, 0xb1, 0xae, 0x94, 0xaf, 0xef, 0x3b, 0x4d, 0xdf, 0x58, 0x84, + 0xd7, 0xbb, 0xbc, 0xcc, 0xca, 0x72, 0x27, 0x45, 0xe0, 0x57, 0x04, 0xe5, + 0xee, 0x85, 0xdc, 0xb3, 0xf3, 0x18, 0x6f, 0xf7, 0x8f, 0xf2, 0xd7, 0x07, + 0xcf, 0x20, 0x05, 0x7c, 0x6d, 0x5e, 0xc5, 0xf5, 0x51, 0x59, 0x75, 0x75, + 0xb3, 0xf9, 0xea, 0x57, 0x1f, 0x62, 0xe9, 0xd2, 0x25, 0xa4, 0xa4, 0xa4, + 0x30, 0x32, 0x32, 0x42, 0x30, 0x18, 0xa4, 0x20, 0xbf, 0x80, 0xcd, 0x9b, + 0x37, 0xb3, 0x6d, 0xdb, 0xb6, 0x84, 0x0b, 0xab, 0xb5, 0x4e, 0xfa, 0x4c, + 0xa7, 0xac, 0x5e, 0xbd, 0x8a, 0xf4, 0xf4, 0x74, 0xb4, 0xd6, 0xf8, 0xfd, + 0x7e, 0x86, 0x87, 0x87, 0x27, 0x7d, 0xc6, 0x42, 0xa1, 0xf8, 0xf8, 0x5c, + 0x76, 0xfc, 0x4d, 0x9b, 0x3e, 0x4e, 0x41, 0x41, 0x21, 0x4a, 0x69, 0xe6, + 0xce, 0x9d, 0x73, 0x45, 0xf5, 0xf5, 0x83, 0x86, 0x76, 0x4c, 0x29, 0x71, + 0x9b, 0x92, 0x75, 0xa5, 0x53, 0xbb, 0xa3, 0xab, 0x8b, 0xb3, 0xc9, 0x70, + 0x9a, 0x18, 0x42, 0xf2, 0xdd, 0xa3, 0x2d, 0xa4, 0x1a, 0x12, 0xa5, 0x35, + 0x4a, 0x5f, 0x1a, 0xb5, 0x6b, 0xb4, 0x26, 0xa9, 0x0e, 0x20, 0xc5, 0x94, + 0xbc, 0xbe, 0x65, 0x29, 0x15, 0x69, 0x29, 0xb8, 0xa4, 0xc1, 0x77, 0x8e, + 0xb4, 0xf0, 0x54, 0x73, 0xf7, 0x07, 0x06, 0x44, 0x04, 0x7c, 0x83, 0xda, + 0xb6, 0x2d, 0x94, 0xb6, 0x30, 0xe2, 0x1b, 0x0c, 0xf8, 0x7d, 0x18, 0x12, + 0x4c, 0xd3, 0x41, 0x24, 0x12, 0xc6, 0xb2, 0x22, 0x68, 0xad, 0xd0, 0x4a, + 0x13, 0xb5, 0xa2, 0xd8, 0xd1, 0x28, 0x5a, 0xdb, 0x48, 0x19, 0x7b, 0x07, + 0x8b, 0x56, 0x09, 0x29, 0x40, 0xab, 0x58, 0xdf, 0xd8, 0xc9, 0xc6, 0x0f, + 0x55, 0xe3, 0x30, 0x4d, 0x82, 0xa1, 0x20, 0xca, 0xb6, 0xe3, 0xdb, 0x14, + 0xb1, 0xbf, 0xf1, 0x76, 0x29, 0x24, 0x86, 0x61, 0xa0, 0xb4, 0xc6, 0x8a, + 0x07, 0x97, 0x42, 0x08, 0x4c, 0xc3, 0x84, 0xf1, 0xb4, 0x9e, 0x10, 0x18, + 0x86, 0x41, 0x34, 0x12, 0xa1, 0x7c, 0xc6, 0x2d, 0xe4, 0x16, 0x4f, 0xed, + 0x6a, 0xaa, 0x78, 0xaa, 0xc3, 0x52, 0x0a, 0x43, 0x88, 0x49, 0xaf, 0x49, + 0xde, 0x6b, 0x17, 0xb4, 0x86, 0x90, 0xad, 0x48, 0x77, 0x18, 0x58, 0xf1, + 0x58, 0xcc, 0x8c, 0x67, 0x60, 0xc7, 0x01, 0xba, 0xb4, 0x6e, 0x2a, 0x63, + 0xaf, 0xb4, 0x66, 0xcc, 0x56, 0x89, 0xd4, 0xc9, 0x35, 0xab, 0x2c, 0xad, + 0x35, 0x1a, 0x85, 0x56, 0x8a, 0xa8, 0x6d, 0x61, 0x2b, 0x1b, 0x69, 0x08, + 0x94, 0x6d, 0x13, 0x0a, 0x85, 0xd0, 0xda, 0x46, 0x29, 0x3b, 0x01, 0x88, + 0x40, 0x23, 0x24, 0x08, 0x25, 0x50, 0xda, 0x42, 0xdb, 0x3a, 0x0e, 0x88, + 0x1d, 0xe7, 0x6a, 0x95, 0x00, 0x05, 0x0d, 0x4a, 0x2b, 0x34, 0x60, 0x45, + 0x42, 0x71, 0x90, 0x6c, 0x40, 0xa1, 0x11, 0x08, 0x4d, 0xec, 0xb0, 0x75, + 0x6c, 0xe3, 0xb6, 0x15, 0x0b, 0xad, 0xa5, 0x14, 0x38, 0xa4, 0x40, 0x6b, + 0x8d, 0x1d, 0x89, 0xa0, 0xb1, 0x27, 0x0e, 0x30, 0xae, 0x54, 0x0c, 0xe3, + 0xf2, 0xef, 0xa0, 0x9a, 0x87, 0x03, 0xbc, 0xd5, 0x3b, 0xcc, 0x67, 0x67, + 0x95, 0xd0, 0x19, 0x18, 0x23, 0x64, 0xd9, 0xcc, 0xcd, 0x4e, 0xa3, 0x71, + 0xd0, 0xc7, 0x81, 0x8b, 0xc3, 0x6c, 0xae, 0xcc, 0xe7, 0xc5, 0xf3, 0xfd, + 0x49, 0xa0, 0x6c, 0xab, 0x2d, 0xe6, 0xed, 0x81, 0x00, 0x07, 0x2e, 0x0e, + 0x23, 0x85, 0x60, 0xcc, 0xb2, 0x79, 0x78, 0x5e, 0x05, 0xbe, 0xa8, 0xcd, + 0x33, 0xad, 0x17, 0xb1, 0xb5, 0xa6, 0x30, 0xd5, 0xc5, 0x03, 0x33, 0x63, + 0xd9, 0x67, 0x5f, 0xd4, 0xe2, 0xe9, 0xd6, 0x5e, 0xc6, 0xec, 0x18, 0xf3, + 0x95, 0xa7, 0xa7, 0xb0, 0xa5, 0xb2, 0x00, 0x0d, 0x3c, 0x7f, 0xae, 0x97, + 0x8d, 0x15, 0x05, 0x49, 0x69, 0xf5, 0x86, 0x81, 0x51, 0x8e, 0xf4, 0x8d, + 0xf0, 0xa9, 0xda, 0x62, 0x32, 0xe2, 0xae, 0xfe, 0xab, 0x9d, 0x83, 0x34, + 0x0f, 0x07, 0x10, 0x42, 0xa0, 0xd1, 0x3c, 0x5c, 0x5f, 0x81, 0xe9, 0x49, + 0xff, 0xe3, 0xbe, 0xe6, 0xbe, 0x96, 0xf2, 0x64, 0xdb, 0x20, 0x0f, 0xbe, + 0xf6, 0x2e, 0xa6, 0x10, 0x68, 0x31, 0x2e, 0x4d, 0xc9, 0xf9, 0x10, 0xeb, + 0x74, 0x2b, 0xa8, 0xe6, 0x09, 0xce, 0x32, 0x24, 0xed, 0x9f, 0x59, 0x4d, + 0x99, 0x27, 0x85, 0xc3, 0x7d, 0x23, 0x7c, 0xfb, 0x48, 0x0b, 0x0f, 0xd6, + 0x95, 0x72, 0xf7, 0x8e, 0xa3, 0x8c, 0x46, 0x2d, 0x5a, 0x3e, 0x7d, 0x07, + 0x7b, 0xbb, 0x87, 0x78, 0xe4, 0x60, 0x33, 0x1b, 0x2b, 0xf2, 0x69, 0x19, + 0x09, 0xf2, 0x6a, 0xd7, 0x20, 0x29, 0x52, 0xb2, 0xb2, 0x28, 0x0b, 0xa7, + 0x94, 0x2c, 0x7f, 0xf6, 0x20, 0xf7, 0x56, 0x15, 0x52, 0xea, 0x71, 0x11, + 0xb0, 0x6c, 0x94, 0xd6, 0xfc, 0xf3, 0xf1, 0x73, 0xfc, 0xaa, 0xb9, 0x8b, + 0xcf, 0xcf, 0x2a, 0xe1, 0xad, 0xde, 0x61, 0xbe, 0x79, 0xf0, 0x0c, 0x87, + 0xef, 0xbf, 0x8d, 0x57, 0x3a, 0x06, 0x78, 0xf4, 0x50, 0x33, 0x5f, 0x98, + 0x55, 0x42, 0x44, 0xa9, 0xc4, 0x0a, 0xf7, 0xf5, 0x78, 0xb9, 0x6f, 0xc7, + 0x31, 0xd6, 0x57, 0x14, 0xb0, 0x67, 0x4b, 0xcc, 0x26, 0x3e, 0xb4, 0xb7, + 0x89, 0xc6, 0x21, 0x1f, 0x8b, 0xf3, 0x33, 0xf8, 0xd6, 0xaf, 0xdf, 0xe4, + 0xdf, 0x57, 0xd5, 0xf1, 0xc9, 0x9a, 0x62, 0xee, 0x7a, 0xee, 0x30, 0x0f, + 0xcc, 0x2a, 0xa1, 0xd4, 0xe3, 0xfa, 0xff, 0x73, 0x41, 0x35, 0xd4, 0x77, + 0x1e, 0xad, 0xed, 0x84, 0x29, 0x95, 0x02, 0x22, 0xfd, 0x7d, 0x3c, 0x98, + 0x37, 0xc6, 0x54, 0x1a, 0x42, 0x03, 0xa6, 0xe1, 0x20, 0x33, 0xaf, 0x2a, + 0x26, 0x85, 0xf1, 0x92, 0xe3, 0x72, 0x90, 0xeb, 0x72, 0xc6, 0xf2, 0x5f, + 0x42, 0xc4, 0x32, 0xbb, 0x1a, 0xdc, 0xa6, 0x41, 0x87, 0x7f, 0x8c, 0xfb, + 0x77, 0x35, 0xf0, 0xe9, 0x9a, 0x12, 0x52, 0x0d, 0x49, 0x45, 0x7a, 0x0a, + 0xff, 0xb2, 0x72, 0x36, 0x5f, 0x79, 0xa3, 0x89, 0x2c, 0x97, 0x83, 0x7f, + 0x5c, 0x1e, 0xf3, 0x20, 0x53, 0x0d, 0x83, 0x47, 0x17, 0x56, 0xb3, 0x38, + 0x7f, 0xe2, 0x86, 0xd0, 0x90, 0x82, 0xca, 0xf4, 0x54, 0x7e, 0xb0, 0x62, + 0x16, 0x27, 0x87, 0x7c, 0x2c, 0x79, 0xe6, 0x20, 0x61, 0x5b, 0x21, 0x04, + 0xcc, 0xca, 0xf4, 0xf0, 0xd8, 0x6d, 0xb3, 0xdf, 0x93, 0x55, 0x3e, 0xc5, + 0xdd, 0xd5, 0x85, 0x1c, 0xea, 0x1b, 0xe1, 0xc4, 0xa0, 0x8f, 0x5b, 0x72, + 0xd3, 0x79, 0xb6, 0xbd, 0x97, 0x03, 0x5b, 0x97, 0x53, 0x93, 0xe1, 0xe6, + 0xbb, 0x8b, 0x67, 0x22, 0x85, 0xc0, 0x56, 0x1a, 0xa7, 0xcb, 0x9c, 0x34, + 0xdf, 0x0d, 0x05, 0x44, 0x6b, 0xcd, 0xbb, 0x47, 0x77, 0x20, 0x44, 0xb2, + 0x8e, 0x5f, 0xec, 0x30, 0x58, 0x96, 0x26, 0x2e, 0xe3, 0xb1, 0xd9, 0x94, + 0x54, 0x2d, 0x20, 0xbf, 0xb6, 0x66, 0x7a, 0x1e, 0x1e, 0xf0, 0xb9, 0x59, + 0x25, 0xfc, 0xbe, 0xbd, 0x37, 0x61, 0x23, 0x2f, 0x05, 0x57, 0x5d, 0xe2, + 0x38, 0x08, 0x01, 0x9f, 0xd9, 0x73, 0x82, 0x2c, 0xa7, 0xc9, 0xcf, 0xd7, + 0xcd, 0x63, 0x6e, 0x76, 0x5a, 0xa2, 0x6d, 0xdb, 0xee, 0x13, 0x1c, 0xe8, + 0x1d, 0xe6, 0xb7, 0x1b, 0x16, 0x50, 0xe2, 0x71, 0x21, 0x85, 0xa0, 0xc9, + 0xeb, 0x67, 0xc1, 0xd3, 0x07, 0xf8, 0xca, 0xdc, 0x72, 0x1e, 0xaa, 0x2f, + 0xe7, 0xad, 0xde, 0x61, 0xce, 0xf9, 0x43, 0x3c, 0xbe, 0xb6, 0x9e, 0x4f, + 0xed, 0x3e, 0xc1, 0x13, 0x67, 0xba, 0xf8, 0xd1, 0xca, 0x3a, 0x10, 0x24, + 0xe6, 0xce, 0x4f, 0x8d, 0x31, 0x4d, 0xc4, 0x56, 0x58, 0x4a, 0xf3, 0xd9, + 0x3d, 0x27, 0xc8, 0x74, 0x99, 0x3c, 0x7b, 0xd7, 0x42, 0x4a, 0x3c, 0xae, + 0x1b, 0x0d, 0x88, 0xcd, 0x82, 0xdb, 0x92, 0xef, 0x3a, 0x1c, 0x52, 0xf2, + 0xc0, 0x2b, 0xc7, 0x71, 0x3b, 0x8c, 0xcb, 0x82, 0x98, 0xda, 0x66, 0xe2, + 0xe8, 0x7a, 0xe7, 0x12, 0x23, 0xae, 0xb9, 0xaf, 0xba, 0x90, 0x4f, 0x54, + 0x4d, 0xfd, 0xf3, 0x80, 0x5b, 0xf3, 0x32, 0x58, 0x5a, 0x90, 0xc9, 0xc3, + 0x6f, 0x9e, 0x22, 0xd5, 0x94, 0x57, 0x58, 0x0f, 0xfc, 0x74, 0xf5, 0x5c, + 0xee, 0x28, 0xc9, 0x9e, 0x04, 0xde, 0x2d, 0x39, 0x69, 0x1c, 0xeb, 0x1f, + 0x65, 0x6d, 0x49, 0x76, 0x62, 0xce, 0x9a, 0x4c, 0x37, 0x87, 0xb7, 0xae, + 0x20, 0x1a, 0x77, 0xc1, 0x7f, 0x7e, 0xaa, 0x0b, 0x0d, 0xfc, 0xf9, 0xde, + 0x26, 0xc6, 0x6c, 0xc5, 0x73, 0xe7, 0xfa, 0xf8, 0xd1, 0xca, 0x3a, 0x2c, + 0xa5, 0x13, 0xf6, 0x64, 0x77, 0xe7, 0x20, 0x11, 0x5b, 0x71, 0x77, 0x79, + 0x1e, 0x86, 0x10, 0xfc, 0xe4, 0x3d, 0xf3, 0xdd, 0x50, 0x40, 0x84, 0x30, + 0x48, 0xcf, 0x2a, 0x4c, 0xca, 0x0a, 0x9c, 0x1c, 0xf0, 0xf1, 0x87, 0x61, + 0x41, 0x86, 0xf3, 0xf2, 0x07, 0x27, 0x7c, 0x01, 0x60, 0xe2, 0x11, 0x42, + 0x54, 0x29, 0x3e, 0x57, 0x5b, 0x9a, 0xc4, 0xe9, 0x46, 0xec, 0x16, 0x28, + 0xa6, 0x02, 0x6d, 0xc5, 0x57, 0xeb, 0x2b, 0xf9, 0xd5, 0x99, 0x6e, 0xda, + 0x46, 0x43, 0x97, 0x5c, 0xc3, 0xc6, 0xae, 0x62, 0xc7, 0x4b, 0x9a, 0xc3, + 0xe0, 0xa9, 0xb3, 0x3d, 0xbc, 0xde, 0x3d, 0x44, 0xd0, 0xb2, 0xf9, 0xde, + 0xb2, 0xda, 0x78, 0x1f, 0x78, 0x74, 0xd1, 0x0c, 0x0e, 0xf4, 0x8d, 0x70, + 0xff, 0x2b, 0xc7, 0x79, 0xe9, 0xe3, 0x8b, 0x11, 0x62, 0xc2, 0xeb, 0x72, + 0x48, 0x89, 0x37, 0x1c, 0x65, 0x77, 0xd7, 0x20, 0x2f, 0xde, 0xb3, 0x88, + 0x35, 0x71, 0xd0, 0x2a, 0x9e, 0xdc, 0xcb, 0xce, 0xf3, 0xfd, 0x7c, 0x69, + 0x4e, 0x19, 0x5b, 0x5e, 0x6e, 0x60, 0x7d, 0x49, 0x0e, 0xff, 0xd3, 0x76, + 0x91, 0xbf, 0x5b, 0x52, 0x83, 0x21, 0x63, 0xde, 0xdf, 0x53, 0x67, 0xbb, + 0x79, 0xbd, 0x7b, 0x08, 0x0d, 0xfc, 0xfd, 0xd2, 0x9a, 0x1b, 0xfb, 0xd8, + 0xba, 0xfb, 0x5c, 0x23, 0xde, 0x81, 0x8e, 0xa4, 0x2b, 0xd1, 0xa1, 0x31, + 0x8b, 0x36, 0x5f, 0x68, 0x12, 0x87, 0x26, 0x24, 0xc8, 0x99, 0xca, 0xac, + 0x05, 0xeb, 0x93, 0x62, 0x14, 0xad, 0xa1, 0x3e, 0x27, 0x2d, 0xe1, 0xde, + 0xf6, 0x06, 0xc3, 0xb4, 0xfb, 0xc6, 0x58, 0x51, 0x98, 0xc9, 0x91, 0xbe, + 0x11, 0x8a, 0xdd, 0x2e, 0xca, 0xd2, 0x52, 0xe8, 0xf0, 0x8f, 0xe1, 0x8b, + 0x5a, 0x09, 0x55, 0xd4, 0x3c, 0x1c, 0xc0, 0x90, 0x82, 0x99, 0x19, 0xb1, + 0x80, 0xf0, 0xdd, 0x21, 0x3f, 0xfd, 0xa1, 0x08, 0x3a, 0x0e, 0xf2, 0xfa, + 0xd2, 0x5c, 0x3a, 0xfc, 0x63, 0x78, 0xc3, 0x51, 0x16, 0xe5, 0x67, 0x60, + 0x6b, 0xcd, 0xde, 0x6e, 0x2f, 0x4b, 0xf2, 0x33, 0x18, 0xb3, 0x15, 0x9d, + 0xfe, 0x31, 0x16, 0xc5, 0xf5, 0x7f, 0xd0, 0xb2, 0x39, 0xd8, 0x3b, 0xc2, + 0xfa, 0x4b, 0x62, 0x9e, 0x53, 0xde, 0x00, 0xa0, 0x99, 0x93, 0x9d, 0xc6, + 0x89, 0x41, 0x1f, 0xde, 0x70, 0x94, 0xaa, 0x74, 0x37, 0x95, 0xe9, 0xb1, + 0x98, 0xee, 0x68, 0xff, 0x28, 0xfe, 0xa8, 0x15, 0x8b, 0xbd, 0x80, 0xf5, + 0xa5, 0x39, 0x37, 0x0e, 0x10, 0xad, 0x15, 0x67, 0x4f, 0xbc, 0xc6, 0x88, + 0x37, 0x39, 0x98, 0x0a, 0x59, 0x2a, 0xe9, 0xbe, 0x39, 0x39, 0x6e, 0xd6, + 0xe4, 0xe4, 0x55, 0x50, 0x33, 0x7f, 0xed, 0x15, 0x52, 0xe4, 0xd3, 0xa8, + 0x13, 0x53, 0xd5, 0x8b, 0x2b, 0x46, 0xe9, 0xd3, 0x1b, 0xe3, 0x72, 0xf7, + 0x8d, 0x5c, 0x79, 0xbd, 0x22, 0x6e, 0xd0, 0xc4, 0x0d, 0xfe, 0x39, 0x82, + 0x6d, 0x45, 0x92, 0x0e, 0x5f, 0x69, 0x58, 0xb7, 0xe3, 0x18, 0x41, 0xdb, + 0xc6, 0x10, 0x32, 0xa1, 0x52, 0x0c, 0x29, 0xd1, 0x42, 0x60, 0x0a, 0x81, + 0x34, 0x0d, 0x4c, 0xd3, 0x81, 0x94, 0x02, 0xa7, 0x90, 0x08, 0xa1, 0x71, + 0x08, 0x89, 0x29, 0x63, 0xed, 0xa6, 0x10, 0x98, 0x52, 0x20, 0xa5, 0xc0, + 0x10, 0x02, 0x87, 0x20, 0x51, 0x6f, 0x88, 0x98, 0xd7, 0x64, 0x08, 0x19, + 0x7b, 0x7e, 0x13, 0x57, 0x6d, 0x26, 0x02, 0x43, 0x82, 0x21, 0x0d, 0x0c, + 0x21, 0x30, 0x0c, 0x30, 0x90, 0x31, 0x3a, 0x34, 0x86, 0x90, 0x13, 0xb4, + 0xd2, 0x48, 0x3c, 0xe7, 0x31, 0x20, 0x56, 0x2f, 0x04, 0x32, 0x3e, 0xe6, + 0xf8, 0xbc, 0x32, 0x51, 0x1f, 0x03, 0x25, 0x36, 0xbf, 0x8e, 0xed, 0x47, + 0xc4, 0xd6, 0x27, 0x11, 0xf1, 0xf5, 0x80, 0x88, 0xc7, 0x5f, 0x37, 0xd4, + 0x86, 0x18, 0xa6, 0x33, 0xe9, 0x7b, 0xfb, 0x68, 0x88, 0x8e, 0x90, 0xcd, + 0x98, 0x52, 0x18, 0x09, 0x30, 0xc0, 0x90, 0x1a, 0x25, 0xc1, 0x29, 0x80, + 0xa8, 0x85, 0x29, 0x15, 0xd2, 0x90, 0x38, 0xa5, 0xc0, 0x14, 0xe0, 0x94, + 0x32, 0x01, 0x84, 0x63, 0x1c, 0x10, 0xc3, 0xc0, 0x21, 0x62, 0x34, 0x86, + 0x90, 0x38, 0x25, 0x48, 0x62, 0x6d, 0x46, 0xbc, 0xdf, 0xa5, 0x60, 0x99, + 0x02, 0x4c, 0x43, 0xc7, 0x0e, 0x4e, 0x09, 0x0c, 0x14, 0x26, 0xe3, 0x6d, + 0xb1, 0x88, 0xdf, 0x21, 0x05, 0x52, 0xc6, 0x40, 0x70, 0x48, 0x89, 0x8c, + 0x03, 0x62, 0x0a, 0x81, 0x21, 0x63, 0xb4, 0x52, 0x49, 0x0c, 0x19, 0x4b, + 0xed, 0x1b, 0x82, 0x58, 0x7f, 0x40, 0x09, 0x1d, 0x03, 0x4c, 0x80, 0x8a, + 0x83, 0x65, 0xa0, 0xd1, 0x0a, 0xb4, 0x88, 0x8d, 0xa3, 0x15, 0xfc, 0x1f, + 0xd7, 0xc0, 0x3b, 0xab, 0xdb, 0x65, 0xb1, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +unsigned int openair_logo_png_len = 4664; diff --git a/common/utils/T/tracer/openair_logo.png b/common/utils/T/tracer/openair_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8b3dcfe46ef222f6b21f7d7517914b3e6019873f GIT binary patch literal 4664 zcmV-8636X{P)w%1 zG?$ZfmlGkxAAL>Y!wSgW&OYAi9$-aLE=8Uca#Eb6I~_O;0|Z2En^45UAC52_3eoKy zp*BC483nl?0dhUdXe7#iG`27|Cxd%umR=QYV@D4IBR+1QT}_I^@ev>&w7h)2mkytw zduNnU;C5Zp7{N${Qytypc-&MM6?_E9wU&ndVGdjznQS{pM7Z(lh8~V0h%ZuGPHR!3bJ5`+J7?){j!rqn^f-|3+vXQ5q;h}s{P?eQk&9Bzj6E>9f?LK(FKAb zeWs=Dx~%!8m5|YhMP+&_Oc7i^-O|Osu9}}z_rs&7DM)d!qA&+rz@hdIq_SB%r#7bB z5v-g)htuunsh?S$MC(pXAsmfh+X};w{AXhuziIC$WUJWp(qPxe7m?$N9rxq!oZ}Z~ zd&y39@y&(R++LV@^Q)}kNOVe76|!x-kto@&2_yViLo=IalrlGGqJM2(Hbed(4K3{~ ztcd|&NJ*y0LnIoVWW)<{a|r~4WTdCjHX5X9ILtE}>Iqs38}OJCv}VhThk1K6!uOZe z&@<}it{0B*3Zv?;6JTRjemmwJpj&a5xWz!&Q)iRceO9MTgUBV!6z^yLe^+*TOlMhzV4A7))yUd*e~n(e1L*?y`MJMMgz z739%&p>x8Br??m%^-T`w3<(G{5QtiMLm^)57-C=NAd85)d1|z(1u8$q(`#J3mB#;Mnfz|Ut-Q8n3A;YAjQh*8_+i7jgf}OETu&C5i8)9v3fsY|$i|n(E4lgO`%hlA_5jvT2Z&nSs)p z9c>pm=nb)X(b0w9@5e9WoeA)Eq=)7|{!j(X;2yV=p&!#^~% zGZ40k+BO#gV{E7>Vb{i6k|pG|*IuWwv2oHO4Z~pb=1o*pRRPe_(#mtsJ%?#tUbyDX zo5!7Z{z>Bd(W6J%yY~$YW9k6Rwry6dSWanaDbZ+@C!Y8PPNx%x!@;&~pC&syI|1DB z9qDpi0{uRuQANY7V?+@|lp|iLQL0*c3x-1X7 zI|upX?nb7{XNHfB!67x86r}bu~Vp45%=sw9Ed6NRU#RLB-J-MI!Z@J2ZmuJID34cMT-{l)KkAkYt5^# z?&iy1{!*e%DMd}qOyv4}`D(<+NVi*Sd_wOSZ3|(7l2zaWw8$$?`);zMHijZaFkb?hey6}M|FJRe;eWe;7 z+-WtFjjNs(=T3MQG4i3IAx@n-O;b}7fk1$0G|H+~x08~RGHDE-FTm*N2uf+RR%B*o zT{bD_bULvti?OjVM~)m}&6+!|{=lL(d%6YzSXG?Ow-?Rif7|;w=L_+Nt|5F;i*(1; zJDaa`4DkK8+c-Jo$I_bhMLDb~$+>aaUeh$$y?YPOKmP(+YowHTJRS-Q3s|w@Hma+u zrlfi4rJdNejSzxRD8x6u@d#;Yo+;-jEG)#bqV)7!4fEf?tyhVhsN zTdNBZ0zO+?!auy-%4u(q;{!fc7iUlJt^&a`ZM{7FW)t49g+mH*QyhG0P8mO3G3&;s z-y@L-g@pwa7Z+1iRZV_=9$8tJ=Xj+Qm6heBrn&)5Boe`K1@1IWlXdIX^0S|9$K`Ud zW5*8MZqHS%@tcR5ahnEG2)5P6g21ga3V5us9b0Su=I~kG_{6eljpZ~1553WZtu;k% zC*NCI%N-@zRHvt2xA@7tR{d^S7MnJ0q^_=R+BCLpvvTE1%FD~Ado@5#P7b%^j-)7;IIr@QD6MX28$r8SSOn9Z7!Y?Ou{pS-}=_MN(} zfS4|q3%A=%C=_D<{{2)`RFIL8fl`Wwh6a>UD5a>at-UT2+P0k-Gl?^#yrOYmzI-{m zcI}$B4e1JmX&4wq10So%jOwyS{iHCtYO!#T?B(6wr_u&oSYn@(I`G&EUQ^sTEd16cV6=( zN-4C~n5M~|J%5-K<=eK+t+y^<$&w{ki2mzoX=$aU#0vbWZBHkPNQ+q$AOE(Y_81b#q<41plqux=Iwz1 z2QCgHg<#CGd3at0zNpPJtrxMirZCmT12bdUXJ6Ff>DFGx>=^Tvr>C%`vH%S{f3BB} z6$MFY^@f2_j`WT2soG*P;;#Oyor5$F2M|J_(L7vVf$2&AIwE~XG@ zF)mHX`4H=LE2!oP&N3wJpIJ?rCxyd(BYgWv3lG+na`%p-j7BY5K79v!yN7t>U^5#l z@@W|f@@m&0DN?esC<~{QEPwVO_f{2B>TwaUY?Rjg^YL^1s=15L&nn@q-eJCZ@C=9V zzl~Qq26*&PGhdihLPV*=3itJRxo^iY)>jm;XG_c`KD4)q#vvbz^E3F?uixa~SJm;! znquyH?l2F`DxuWl`u}r5HPm+=t?h&#FDeLR>q##9gFGMS2SVvT`ObP~veRg`mmn zXTj44_{!XJ9;z?rt=?hI`9nOuww_PzKEV@by7=r1d0&T@t>nr)ynQq!fLzi5`#;#(=OPa&rsk1%2-aSOn zviaV!+ISy$bkPhB^o?-;E5~{1Dnzgtp+A!FX(Q)jz*y?Y1^{Qc6J8~fP0`&=X5fsUjr(V;PmHeYBG zhbAP*naZpM>yu&>t)V_AE#cnw2E(-b##m99$&tPhirp^C(o*Q~kKv12302fQ9Keu* znHjNw@ZBLl{h<%0*4?`Z-|)JWC$61 zeiK)1CIUl(Aq@;6Fbpt|F*-DckQ21hNId5;AXYB~GCt<`yfRTA10^=Uj_pUp)+Z71 z^?-=SUpLf-7^XAnd;4gJj*!imQWyy^z>pdx!6|^Kg((%%kT|8l6yTIH0fb{55W~PB zVl;-3I3-A8ZAQG`rC^x?Ohd;GP6-SYCgW|fh~FUvQpP}VNQsOCVhVvFW3*C93>i!9 u8-iGWKnWcKOn{1mWuVatw1|zP75pF9z&oqkWwD9?0000 Date: Tue, 24 May 2016 16:25:49 +0200 Subject: [PATCH 155/217] minor: gui/image.c log paint --- common/utils/T/tracer/gui/image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/utils/T/tracer/gui/image.c b/common/utils/T/tracer/gui/image.c index 70618239aa..64d305747e 100644 --- a/common/utils/T/tracer/gui/image.c +++ b/common/utils/T/tracer/gui/image.c @@ -9,6 +9,7 @@ static void paint(gui *_gui, widget *_w) { struct gui *g = _gui; struct image_widget *w = _w; + LOGD("PAINT image %p\n", w); x_draw_image(g->x, g->xwin, w->x, w->common.x, w->common.y); } From 120951d732f9b9de4f1aa8ac0ce484425b24628b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 24 May 2016 17:02:38 +0200 Subject: [PATCH 156/217] minor color change in enb.c --- common/utils/T/tracer/enb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index a2b00c7930..239c2d8ad8 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -157,7 +157,7 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) widget_add_child(g, line, new_label(g,"DL/UL TICK/DCI/ACK/NACK "), 0); for (i = 0; i < 8; i++) timeline_set_subline_background_color(g, timeline_plot, i, - new_color(g, i & 1 ? "#ddd" : "#eee")); + new_color(g, i==0 || i==4 ? "#aaf" : i & 1 ? "#ddd" : "#eee")); timeview = new_view_time(3600, 10, g, timeline_plot); /* tick logging */ timelog = new_timelog(h, database, "ENB_DL_TICK"); From 187e7906cb7a671a01241ace04f80aa07e6eb81f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 10:30:25 +0200 Subject: [PATCH 157/217] use Xft to draw strings --- common/utils/T/tracer/Makefile.remote | 2 +- common/utils/T/tracer/gui/Makefile | 2 +- common/utils/T/tracer/gui/gui.h | 2 + common/utils/T/tracer/gui/label.c | 5 +- common/utils/T/tracer/gui/textlist.c | 5 +- common/utils/T/tracer/gui/x.c | 71 +++++++++++++++++++-------- common/utils/T/tracer/gui/x.h | 9 ++-- common/utils/T/tracer/gui/x_defs.h | 5 ++ common/utils/T/tracer/gui/xy_plot.c | 14 +++--- 9 files changed, 77 insertions(+), 38 deletions(-) diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index be8a77250c..e4b2e171af 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. #CFLAGS += -O3 -ffast-math -fomit-frame-pointer -LIBS=-lX11 -lm -lpng +LIBS=-lX11 -lm -lpng -lXft tracer_remote: remote_old.o plot.o database.o gui.o utils.o gui/gui.a $(CC) $(CFLAGS) -o tracer_remote $^ $(LIBS) diff --git a/common/utils/T/tracer/gui/Makefile b/common/utils/T/tracer/gui/Makefile index 370020a8b5..53f2077eac 100644 --- a/common/utils/T/tracer/gui/Makefile +++ b/common/utils/T/tracer/gui/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wall -g -pthread +CFLAGS=-Wall -g -pthread -I/usr/include/X11/Xft -I/usr/include/freetype2 OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \ gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \ diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 8ab0f06373..673514f138 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -12,6 +12,8 @@ typedef void widget; #define BACKGROUND_COLOR 0 #define FOREGROUND_COLOR 1 +#define DEFAULT_FONT 0 + /* key modifiers */ #define KEY_SHIFT (1<<0) #define KEY_CONTROL (1<<1) diff --git a/common/utils/T/tracer/gui/label.c b/common/utils/T/tracer/gui/label.c index bbe6e98eaf..f649fa5201 100644 --- a/common/utils/T/tracer/gui/label.c +++ b/common/utils/T/tracer/gui/label.c @@ -10,7 +10,7 @@ static void paint(gui *_gui, widget *_w) struct gui *g = _gui; struct label_widget *l = _w; LOGD("PAINT label '%s'\n", l->t); - x_draw_string(g->x, g->xwin, l->color, + x_draw_string(g->x, g->xwin, DEFAULT_FONT, l->color, l->common.x, l->common.y + l->baseline, l->t); } @@ -35,7 +35,8 @@ widget *new_label(gui *_gui, const char *label) if (w->t == NULL) OOM; w->color = FOREGROUND_COLOR; - x_text_get_dimensions(g->x, label, &w->width, &w->height, &w->baseline); + x_text_get_dimensions(g->x, DEFAULT_FONT, label, + &w->width, &w->height, &w->baseline); w->common.paint = paint; w->common.hints = hints; diff --git a/common/utils/T/tracer/gui/textlist.c b/common/utils/T/tracer/gui/textlist.c index 6803d2301d..896cba5b9e 100644 --- a/common/utils/T/tracer/gui/textlist.c +++ b/common/utils/T/tracer/gui/textlist.c @@ -16,7 +16,7 @@ static void paint(gui *_gui, widget *_this) this->common.width, this->common.height); for (i = 0, j = this->starting_line; i < this->allocated_nlines && j < this->text_count; i++, j++) - x_draw_clipped_string(g->x, g->xwin, this->color[j], + x_draw_clipped_string(g->x, g->xwin, DEFAULT_FONT, this->color[j], this->common.x, this->common.y + i * this->line_height + this->baseline, this->text[j], @@ -79,7 +79,8 @@ widget *new_textlist(gui *_gui, int width, int nlines, int bgcol) w = new_widget(g, TEXT_LIST, sizeof(struct textlist_widget)); w->wanted_nlines = nlines; - x_text_get_dimensions(g->x, ".", &dummy, &w->line_height, &w->baseline); + x_text_get_dimensions(g->x, DEFAULT_FONT, ".", + &dummy, &w->line_height, &w->baseline); w->background_color = bgcol; w->wanted_width = width; diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 5fb41b4f92..6f87de4420 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -33,12 +33,34 @@ 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); + + 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) + ERR("could not allocate color '%s'\n", color); + return x->ncolors - 1; } +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) { struct x_connection *ret; @@ -53,6 +75,8 @@ x_connection *x_open(void) x_new_color(ret, "white"); /* background color */ x_new_color(ret, "black"); /* foreground color */ + x_new_font(ret, "sans-8"); + return ret; } @@ -78,6 +102,11 @@ x_window *x_create_window(x_connection *_x, int width, int height, XFillRectangle(x->d, ret->p, x->colors[BACKGROUND_COLOR], 0, 0, width, height); + ret->xft = XftDrawCreate(x->d, ret->p, + DefaultVisual(x->d, DefaultScreen(x->d)), + DefaultColormap(x->d, DefaultScreen(x->d))); + if (ret->xft == NULL) ERR("XftDrawCreate failed\n"); + /* enable backing store */ { XSetWindowAttributes att; @@ -261,11 +290,17 @@ void x_events(gui *_gui) w->common.allocate(g, w, 0, 0, xw->new_width, xw->new_height); xw->width = xw->new_width; xw->height = xw->new_height; + 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))); XFillRectangle(x->d, xw->p, x->colors[BACKGROUND_COLOR], 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))); + if (xw->xft == NULL) ERR("XftDrawCreate failed\n"); + //xw->repaint = 1; } } @@ -290,24 +325,17 @@ void x_flush(x_connection *_x) XFlush(x->d); } -void x_text_get_dimensions(x_connection *_c, const char *t, +void x_text_get_dimensions(x_connection *_c, int font, const char *t, int *width, int *height, int *baseline) { struct x_connection *c = _c; - int dir; - int ascent; - int descent; - XCharStruct overall; + XGlyphInfo ext; - /* TODO: don't use XQueryTextExtents (X roundtrip) */ - XQueryTextExtents(c->d, XGContextFromGC(c->colors[1]), t, strlen(t), - &dir, &ascent, &descent, &overall); + XftTextExtents8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext); -//LOGD("dir %d ascent %d descent %d lbearing %d rbearing %d width %d ascent %d descent %d\n", dir, ascent, descent, overall.lbearing, overall.rbearing, overall.width, overall.ascent, overall.descent); - - *width = overall.width; - *height = ascent + descent; - *baseline = ascent; + *width = ext.width; + *height = c->fonts[font]->height; + *baseline = c->fonts[font]->ascent; } /***********************************************************************/ @@ -338,25 +366,26 @@ void x_fill_rectangle(x_connection *_c, x_window *_w, int color, XFillRectangle(c->d, w->p, c->colors[color], x, y, width, height); } -void x_draw_string(x_connection *_c, x_window *_w, int color, +void x_draw_string(x_connection *_c, x_window *_w, int font, int color, int x, int y, const char *t) { struct x_connection *c = _c; struct x_window *w = _w; int tlen = strlen(t); - XDrawString(c->d, w->p, c->colors[color], x, y, t, tlen); + XftDrawString8(w->xft, &c->xft_colors[color], c->fonts[font], + x, y, (const unsigned char *)t, tlen); } -void x_draw_clipped_string(x_connection *_c, x_window *_w, int color, - int x, int y, const char *t, +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) { - struct x_connection *c = _c; + struct x_window *w = _w; XRectangle clip = { clipx, clipy, clipwidth, clipheight }; - XSetClipRectangles(c->d, c->colors[color], 0, 0, &clip, 1, Unsorted); - x_draw_string(_c, _w, color, x, y, t); - XSetClipMask(c->d, c->colors[color], None); + 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) diff --git a/common/utils/T/tracer/gui/x.h b/common/utils/T/tracer/gui/x.h index aca9868ae0..d749d9acc4 100644 --- a/common/utils/T/tracer/gui/x.h +++ b/common/utils/T/tracer/gui/x.h @@ -20,12 +20,13 @@ int x_connection_fd(x_connection *x); void x_flush(x_connection *x); int x_new_color(x_connection *x, char *color); +int x_new_font(x_connection *x, char *font); /* for x_events, we pass the gui */ #include "gui.h" void x_events(gui *gui); -void x_text_get_dimensions(x_connection *, const char *t, +void x_text_get_dimensions(x_connection *, int font, const char *t, int *width, int *height, int *baseline); /* drawing functions */ @@ -39,11 +40,11 @@ void x_draw_rectangle(x_connection *c, x_window *w, int color, void x_fill_rectangle(x_connection *c, x_window *w, int color, int x, int y, int width, int height); -void x_draw_string(x_connection *_c, x_window *_w, int color, +void x_draw_string(x_connection *_c, x_window *_w, int font, int color, int x, int y, const char *t); -void x_draw_clipped_string(x_connection *_c, x_window *_w, int color, - int x, int y, const char *t, +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); void x_draw_image(x_connection *c, x_window *w, x_image *img, int x, int y); diff --git a/common/utils/T/tracer/gui/x_defs.h b/common/utils/T/tracer/gui/x_defs.h index e5874a1a3b..d0595ef51d 100644 --- a/common/utils/T/tracer/gui/x_defs.h +++ b/common/utils/T/tracer/gui/x_defs.h @@ -2,14 +2,18 @@ #define _X_DEFS_H_ #include +#include struct x_connection { Display *d; GC *colors; + XftColor *xft_colors; int ncolors; XPoint *pts; int pts_size; int pts_maxsize; + XftFont **fonts; + int nfonts; }; struct x_window { @@ -17,6 +21,7 @@ struct x_window { Pixmap p; int width; int height; + XftDraw *xft; /* below: internal data used for X events handling */ int redraw; int repaint; diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index f4d2ff4b01..7d20a027a1 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -79,8 +79,8 @@ static void paint(gui *_gui, widget *_this) this->common.x + this->vrule_width + x, this->common.y + this->common.height - this->label_height * 2 - 5); sprintf(v, "%g", k * ticstep); - x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy); - x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy); + x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR, this->common.x + this->vrule_width + x - vwidth/2, this->common.y + this->common.height - this->label_height * 2 + this->label_baseline, @@ -116,20 +116,20 @@ static void paint(gui *_gui, widget *_this) (allocated_ymax - allocated_ymin) * (allocated_plot_height - 1); sprintf(v, "%g", k * ticstep); - x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy); + x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy); x_draw_line(g->x, g->xwin, FOREGROUND_COLOR, this->common.x + this->vrule_width, this->common.y + FLIP(y), this->common.x + this->vrule_width + 5, this->common.y + FLIP(y)); - x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR, this->common.x + this->vrule_width - vwidth - 2, this->common.y + FLIP(y) - this->label_height/2+this->label_baseline, v); } /* label at bottom, in the middle */ - x_draw_string(g->x, g->xwin, FOREGROUND_COLOR, + x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR, this->common.x + (this->common.width - this->label_width) / 2, this->common.y + this->common.height - this->label_height + this->label_baseline, @@ -177,8 +177,8 @@ widget *new_xy_plot(gui *_gui, int width, int height, char *label, w->label = strdup(label); if (w->label == NULL) OOM; /* TODO: be sure calling X there is valid wrt "global model" (we are * not in the "gui thread") */ - x_text_get_dimensions(g->x, label, &w->label_width, &w->label_height, - &w->label_baseline); + x_text_get_dimensions(g->x, DEFAULT_FONT, label, + &w->label_width, &w->label_height, &w->label_baseline); LOGD("XY PLOT label wh %d %d\n", w->label_width, w->label_height); w->wanted_width = width; From 806b6a95953fcd2d7771e7c10b041d3fa52e0afd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 13:55:37 +0200 Subject: [PATCH 158/217] remove remote_old.c --- common/utils/T/tracer/Makefile.remote | 3 - common/utils/T/tracer/remote_old.c | 459 -------------------------- 2 files changed, 462 deletions(-) delete mode 100644 common/utils/T/tracer/remote_old.c diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index e4b2e171af..b6ff0f3cad 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -5,9 +5,6 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. LIBS=-lX11 -lm -lpng -lXft -tracer_remote: remote_old.o plot.o database.o gui.o utils.o gui/gui.a - $(CC) $(CFLAGS) -o tracer_remote $^ $(LIBS) - textlog: utils.o textlog.o database.o event.o handler.o \ event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o textlog $^ $(LIBS) diff --git a/common/utils/T/tracer/remote_old.c b/common/utils/T/tracer/remote_old.c deleted file mode 100644 index 8a53e8f89d..0000000000 --- a/common/utils/T/tracer/remote_old.c +++ /dev/null @@ -1,459 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defs.h" -#include "database.h" - -#define DEFAULT_REMOTE_PORT 2020 - -#define T_ID(x) x -#include "../T_IDs.h" -#include "../T_defs.h" - -#define BLUE "#0c0c72" -#define RED "#d72828" - -void *ul_plot; -void *chest_plot; -void *pusch_iq_plot; -void *pucch_iq_plot; -void *pucch_plot; - -#define GET fullread - -int fullread(int fd, void *_buf, int count) -{ - char *buf = _buf; - int ret = 0; - int l; - while (count) { - l = read(fd, buf, count); - if (l <= 0) { printf("read socket problem\n"); abort(); } - count -= l; - buf += l; - ret += l; - } - return ret; -} - -int get_connection(char *addr, int port) -{ - struct sockaddr_in a; - socklen_t alen; - int s, t; - - printf("waiting for connection on %s:%d\n", addr, port); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } - t = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) - { perror("setsockopt"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(addr); - - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("bind"); exit(1); } - alen = sizeof(a); - t = accept(s, (struct sockaddr *)&a, &alen); - if (t == -1) { perror("accept"); exit(1); } - close(s); - - printf("connected\n"); - - return t; -} - -void get_string(int s, char *out) -{ - while (1) { - if (GET(s, out, 1) != 1) abort(); - if (*out == 0) break; - out++; - } -} - -void get_message(int s) -{ -#define S(x, y) do { \ - char str[T_BUFFER_MAX]; \ - get_string(s, str); \ - printf("["x"]["y"] %s", str); \ - } while (0) - - int32_t size; - int m; -#ifdef T_SEND_TIME - struct timespec t; -#endif - if (GET(s, &size, 4) != 4) abort(); -#ifdef T_SEND_TIME - if (GET(s, &t, sizeof(struct timespec)) != sizeof(struct timespec)) abort(); -#endif - if (GET(s, &m, sizeof(int)) != sizeof(int)) abort(); - switch (m) { - case T_first: { - char str[T_BUFFER_MAX]; - get_string(s, str); - printf("%s", str); - break; - } - case T_LEGACY_MAC_INFO: S("MAC", "INFO"); break; - case T_LEGACY_MAC_ERROR: S("MAC", "ERROR"); break; - case T_LEGACY_MAC_WARNING: S("MAC", "WARNING"); break; - case T_LEGACY_MAC_DEBUG: S("MAC", "DEBUG"); break; - case T_LEGACY_MAC_TRACE: S("MAC", "TRACE"); break; - case T_LEGACY_PHY_INFO: S("PHY", "INFO"); break; - case T_LEGACY_PHY_ERROR: S("PHY", "ERROR"); break; - case T_LEGACY_PHY_WARNING: S("PHY", "WARNING"); break; - case T_LEGACY_PHY_DEBUG: S("PHY", "DEBUG"); break; - case T_LEGACY_PHY_TRACE: S("PHY", "TRACE"); break; - case T_LEGACY_S1AP_INFO: S("S1AP", "INFO"); break; - case T_LEGACY_S1AP_ERROR: S("S1AP", "ERROR"); break; - case T_LEGACY_S1AP_WARNING: S("S1AP", "WARNING"); break; - case T_LEGACY_S1AP_DEBUG: S("S1AP", "DEBUG"); break; - case T_LEGACY_S1AP_TRACE: S("S1AP", "TRACE"); break; - case T_LEGACY_RRC_INFO: S("RRC", "INFO"); break; - case T_LEGACY_RRC_ERROR: S("RRC", "ERROR"); break; - case T_LEGACY_RRC_WARNING: S("RRC", "WARNING"); break; - case T_LEGACY_RRC_DEBUG: S("RRC", "DEBUG"); break; - case T_LEGACY_RRC_TRACE: S("RRC", "TRACE"); break; - case T_LEGACY_RLC_INFO: S("RLC", "INFO"); break; - case T_LEGACY_RLC_ERROR: S("RLC", "ERROR"); break; - case T_LEGACY_RLC_WARNING: S("RLC", "WARNING"); break; - case T_LEGACY_RLC_DEBUG: S("RLC", "DEBUG"); break; - case T_LEGACY_RLC_TRACE: S("RLC", "TRACE"); break; - case T_LEGACY_PDCP_INFO: S("PDCP", "INFO"); break; - case T_LEGACY_PDCP_ERROR: S("PDCP", "ERROR"); break; - case T_LEGACY_PDCP_WARNING: S("PDCP", "WARNING"); break; - case T_LEGACY_PDCP_DEBUG: S("PDCP", "DEBUG"); break; - case T_LEGACY_PDCP_TRACE: S("PDCP", "TRACE"); break; - case T_LEGACY_ENB_APP_INFO: S("ENB_APP", "INFO"); break; - case T_LEGACY_ENB_APP_ERROR: S("ENB_APP", "ERROR"); break; - case T_LEGACY_ENB_APP_WARNING: S("ENB_APP", "WARNING"); break; - case T_LEGACY_ENB_APP_DEBUG: S("ENB_APP", "DEBUG"); break; - case T_LEGACY_ENB_APP_TRACE: S("ENB_APP", "TRACE"); break; - case T_LEGACY_SCTP_INFO: S("SCTP", "INFO"); break; - case T_LEGACY_SCTP_ERROR: S("SCTP", "ERROR"); break; - case T_LEGACY_SCTP_WARNING: S("SCTP", "WARNING"); break; - case T_LEGACY_SCTP_DEBUG: S("SCTP", "DEBUG"); break; - case T_LEGACY_SCTP_TRACE: S("SCTP", "TRACE"); break; - case T_LEGACY_UDP__INFO: S("UDP", "INFO"); break; - case T_LEGACY_UDP__ERROR: S("UDP", "ERROR"); break; - case T_LEGACY_UDP__WARNING: S("UDP", "WARNING"); break; - case T_LEGACY_UDP__DEBUG: S("UDP", "DEBUG"); break; - case T_LEGACY_UDP__TRACE: S("UDP", "TRACE"); break; - case T_LEGACY_NAS_INFO: S("NAS", "INFO"); break; - case T_LEGACY_NAS_ERROR: S("NAS", "ERROR"); break; - case T_LEGACY_NAS_WARNING: S("NAS", "WARNING"); break; - case T_LEGACY_NAS_DEBUG: S("NAS", "DEBUG"); break; - case T_LEGACY_NAS_TRACE: S("NAS", "TRACE"); break; - case T_LEGACY_HW_INFO: S("HW", "INFO"); break; - case T_LEGACY_HW_ERROR: S("HW", "ERROR"); break; - case T_LEGACY_HW_WARNING: S("HW", "WARNING"); break; - case T_LEGACY_HW_DEBUG: S("HW", "DEBUG"); break; - case T_LEGACY_HW_TRACE: S("HW", "TRACE"); break; - case T_LEGACY_EMU_INFO: S("EMU", "INFO"); break; - case T_LEGACY_EMU_ERROR: S("EMU", "ERROR"); break; - case T_LEGACY_EMU_WARNING: S("EMU", "WARNING"); break; - case T_LEGACY_EMU_DEBUG: S("EMU", "DEBUG"); break; - case T_LEGACY_EMU_TRACE: S("EMU", "TRACE"); break; - case T_LEGACY_OTG_INFO: S("OTG", "INFO"); break; - case T_LEGACY_OTG_ERROR: S("OTG", "ERROR"); break; - case T_LEGACY_OTG_WARNING: S("OTG", "WARNING"); break; - case T_LEGACY_OTG_DEBUG: S("OTG", "DEBUG"); break; - case T_LEGACY_OTG_TRACE: S("OTG", "TRACE"); break; - case T_LEGACY_OCG_INFO: S("OCG", "INFO"); break; - case T_LEGACY_OCG_ERROR: S("OCG", "ERROR"); break; - case T_LEGACY_OCG_WARNING: S("OCG", "WARNING"); break; - case T_LEGACY_OCG_DEBUG: S("OCG", "DEBUG"); break; - case T_LEGACY_OCG_TRACE: S("OCG", "TRACE"); break; - case T_LEGACY_OCM_INFO: S("OCM", "INFO"); break; - case T_LEGACY_OCM_ERROR: S("OCM", "ERROR"); break; - case T_LEGACY_OCM_WARNING: S("OCM", "WARNING"); break; - case T_LEGACY_OCM_DEBUG: S("OCM", "DEBUG"); break; - case T_LEGACY_OCM_TRACE: S("OCM", "TRACE"); break; - case T_LEGACY_OMG_INFO: S("OMG", "INFO"); break; - case T_LEGACY_OMG_ERROR: S("OMG", "ERROR"); break; - case T_LEGACY_OMG_WARNING: S("OMG", "WARNING"); break; - case T_LEGACY_OMG_DEBUG: S("OMG", "DEBUG"); break; - case T_LEGACY_OMG_TRACE: S("OMG", "TRACE"); break; - case T_LEGACY_OIP_INFO: S("OIP", "INFO"); break; - case T_LEGACY_OIP_ERROR: S("OIP", "ERROR"); break; - case T_LEGACY_OIP_WARNING: S("OIP", "WARNING"); break; - case T_LEGACY_OIP_DEBUG: S("OIP", "DEBUG"); break; - case T_LEGACY_OIP_TRACE: S("OIP", "TRACE"); break; - case T_LEGACY_GTPU_INFO: S("GTPU", "INFO"); break; - case T_LEGACY_GTPU_ERROR: S("GTPU", "ERROR"); break; - case T_LEGACY_GTPU_WARNING: S("GTPU", "WARNING"); break; - case T_LEGACY_GTPU_DEBUG: S("GTPU", "DEBUG"); break; - case T_LEGACY_GTPU_TRACE: S("GTPU", "TRACE"); break; - case T_LEGACY_TMR_INFO: S("TMR", "INFO"); break; - case T_LEGACY_TMR_ERROR: S("TMR", "ERROR"); break; - case T_LEGACY_TMR_WARNING: S("TMR", "WARNING"); break; - case T_LEGACY_TMR_DEBUG: S("TMR", "DEBUG"); break; - case T_LEGACY_TMR_TRACE: S("TMR", "TRACE"); break; - case T_LEGACY_OSA_INFO: S("OSA", "INFO"); break; - case T_LEGACY_OSA_ERROR: S("OSA", "ERROR"); break; - case T_LEGACY_OSA_WARNING: S("OSA", "WARNING"); break; - case T_LEGACY_OSA_DEBUG: S("OSA", "DEBUG"); break; - case T_LEGACY_OSA_TRACE: S("OSA", "TRACE"); break; - case T_LEGACY_component_INFO: S("XXX", "INFO"); break; - case T_LEGACY_component_ERROR: S("XXX", "ERROR"); break; - case T_LEGACY_component_WARNING: S("XXX", "WARNING"); break; - case T_LEGACY_component_DEBUG: S("XXX", "DEBUG"); break; - case T_LEGACY_component_TRACE: S("XXX", "TRACE"); break; - case T_LEGACY_componentP_INFO: S("XXX", "INFO"); break; - case T_LEGACY_componentP_ERROR: S("XXX", "ERROR"); break; - case T_LEGACY_componentP_WARNING: S("XXX", "WARNING"); break; - case T_LEGACY_componentP_DEBUG: S("XXX", "DEBUG"); break; - case T_LEGACY_componentP_TRACE: S("XXX", "TRACE"); break; - case T_LEGACY_CLI_INFO: S("CLI", "INFO"); break; - case T_LEGACY_CLI_ERROR: S("CLI", "ERROR"); break; - case T_LEGACY_CLI_WARNING: S("CLI", "WARNING"); break; - case T_LEGACY_CLI_DEBUG: S("CLI", "DEBUG"); break; - case T_LEGACY_CLI_TRACE: S("CLI", "TRACE"); break; - case T_ENB_INPUT_SIGNAL: { - unsigned char buf[T_BUFFER_MAX]; - int size; - int eNB, frame, subframe, antenna; - GET(s, &eNB, sizeof(int)); - GET(s, &frame, sizeof(int)); - GET(s, &subframe, sizeof(int)); - GET(s, &antenna, sizeof(int)); - GET(s, &size, sizeof(int)); - GET(s, buf, size); -#if 0 - printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna " - "%d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x " - "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2], - buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10], - buf[11],buf[12],buf[13],buf[14],buf[15]); -#endif - if (size != 4 * 7680) - {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed " - "(received %d bytes = %d samples)\n", size, size/4);abort();} - if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680, 0); - t_gui_set_input_signal(eNB, frame, subframe, antenna, size, buf); - break; - } - case T_ENB_UL_CHANNEL_ESTIMATE: { - unsigned char buf[T_BUFFER_MAX]; - int size; - int eNB, UE, frame, subframe, antenna; - GET(s, &eNB, sizeof(int)); - GET(s, &UE, sizeof(int)); - GET(s, &frame, sizeof(int)); - GET(s, &subframe, sizeof(int)); - GET(s, &antenna, sizeof(int)); - GET(s, &size, sizeof(int)); - GET(s, buf, size); - if (size != 512*4) - {printf("bad T_ENB_UL_CHANNEL_ESTIMATE, only 512 samples allowed\n"); - abort();} - if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0, 0); - break; - } - case T_PUSCH_IQ: { - unsigned char buf[T_BUFFER_MAX]; - int size; - int eNB, UE, frame, subframe, nb_rb; - GET(s, &eNB, sizeof(int)); - GET(s, &UE, sizeof(int)); - GET(s, &frame, sizeof(int)); - GET(s, &subframe, sizeof(int)); - GET(s, &nb_rb, sizeof(int)); - GET(s, &size, sizeof(int)); - GET(s, buf, size); - if (size != 12*25*14*4) - {printf("bad T_PUSCH_IQ, we want 25 RBs and 14 symbols/TTI\n"); - abort();} - if (pusch_iq_plot) { - uint32_t *src, *dst; - int i, l; - dst = (uint32_t*)buf; - for (l = 0; l < 14; l++) { - src = (uint32_t*)buf + l * 12 * 25; - for (i = 0; i < nb_rb*12; i++) *dst++ = *src++; - } - iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14, 0); - } - break; - } - case T_PUCCH_1AB_IQ: { - int eNB, UE, frame, subframe, I, Q; - GET(s, &eNB, sizeof(int)); - GET(s, &UE, sizeof(int)); - GET(s, &frame, sizeof(int)); - GET(s, &subframe, sizeof(int)); - GET(s, &I, sizeof(int)); - GET(s, &Q, sizeof(int)); - if (pucch_iq_plot) iq_plot_add_iq_point_loop(pucch_iq_plot,I*10,Q*10, 0); - break; - } - case T_PUCCH_1_ENERGY: { - int eNB, UE, frame, subframe, e, t; - GET(s, &eNB, sizeof(int)); - GET(s, &UE, sizeof(int)); - GET(s, &frame, sizeof(int)); - GET(s, &subframe, sizeof(int)); - GET(s, &e, sizeof(int)); - GET(s, &t, sizeof(int)); -//printf("t %d e %d\n", t, (int)(10*log10(e))); - if (pucch_plot) { - iq_plot_add_energy_point_loop(pucch_plot, t, 0); - iq_plot_add_energy_point_loop(pucch_plot, 10*log10(e), 1); - } - break; - } - case T_buf_test: { - unsigned char buf[T_BUFFER_MAX]; - int size; - GET(s, &size, sizeof(int)); - GET(s, buf, size); - printf("got buffer size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x" - " %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7], - buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]); - break; - } - default: printf("unkown message type %d\n", m); abort(); - } -} - -void usage(void) -{ - printf( -"tracer - remote side\n" -"options:\n" -" -d this option is mandatory\n" -" -li print IDs in the database\n" -" -lg print GROUPs in the database\n" -" -dump dump the database\n" -" -x run with XFORMS (revisited)\n" -" -T run with T GUI\n" -" -on turn log ON for given GROUP or ID\n" -" -off turn log OFF for given GROUP or ID\n" -" -ON turn all logs ON\n" -" -OFF turn all logs OFF\n" -"note: you may pass several -on/-off/-ON/-OFF, they will be processed in order\n" -" by default, all is off\n" -" -r remote side: use given port (default %d)\n", - DEFAULT_REMOTE_PORT - ); - exit(1); -} - -int main(int n, char **v) -{ - char *database_filename = NULL; - void *database; - int s; - int l; - char t; - int i; - int do_list_ids = 0; - int do_list_groups = 0; - int do_dump_database = 0; - int do_xforms = 0; - int do_T_gui = 0; - char **on_off_name; - int *on_off_action; - int on_off_n = 0; - int is_on[T_NUMBER_OF_IDS]; - int port = DEFAULT_REMOTE_PORT; - - memset(is_on, 0, sizeof(is_on)); - - on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); - on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); - - for (i = 1; i < n; i++) { - if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-d")) - { if (i > n-2) usage(); database_filename = v[++i]; continue; } - if (!strcmp(v[i], "-li")) { do_list_ids = 1; continue; } - if (!strcmp(v[i], "-lg")) { do_list_groups = 1; continue; } - if (!strcmp(v[i], "-dump")) { do_dump_database = 1; continue; } - if (!strcmp(v[i], "-x")) { do_xforms = 1; continue; } - if (!strcmp(v[i], "-T")) { do_T_gui = 1; continue; } - if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); - on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; } - if (!strcmp(v[i], "-off")) { if (i > n-2) usage(); - on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; } - if (!strcmp(v[i], "-ON")) - { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; } - if (!strcmp(v[i], "-OFF")) - { on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; } - if (!strcmp(v[i], "-r")) { if (i > n-2) usage(); - port = atoi(v[++i]); continue; } - printf("ERROR: unknown option %s\n", v[i]); - usage(); - } - - /* TODO: setup 'secure' connection with remote part */ - - if (database_filename == NULL) { - printf("ERROR: provide a database file (-d)\n"); - exit(1); - } - - database = parse_database(database_filename); - - if (do_list_ids + do_list_groups + do_dump_database > 1) usage(); - if (do_list_ids) { list_ids(database); return 0; } - if (do_list_groups) { list_groups(database); return 0; } - if (do_dump_database) { dump_database(database); return 0; } - - for (i = 0; i < on_off_n; i++) - on_off(database, on_off_name[i], is_on, on_off_action[i]); - - if (do_xforms) { - ul_plot = make_plot(512, 100, "UL Input Signal", 1, - 7680*10, PLOT_VS_TIME, BLUE); - chest_plot = make_plot(512, 100, "UL Channel Estimate UE 0", 1, - 512, PLOT_VS_TIME, BLUE); - pusch_iq_plot = make_plot(100, 100, "PUSCH IQ", 1, - 12*25*14, PLOT_IQ_POINTS, BLUE); - pucch_iq_plot = make_plot(100, 100, "PUCCH IQ", 1, - 1000, PLOT_IQ_POINTS, BLUE); - pucch_plot = make_plot(512, 100, "PUCCH 1 energy (SR)", 2, - /* threshold */ - 10240, PLOT_MINMAX, RED, - /* pucch 1 */ - 10240, PLOT_MINMAX, BLUE); - } - if (do_T_gui) { - t_gui_start(); - } - - s = get_connection("127.0.0.1", port); - - /* send the first message - activate selected traces */ - t = 0; - if (write(s, &t, 1) != 1) abort(); - l = 0; - for (i = 0; i < T_NUMBER_OF_IDS; i++) if (is_on[i]) l++; - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - for (l = 0; l < T_NUMBER_OF_IDS; l++) - if (is_on[l]) - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - - /* read messages */ - while (1) { - get_message(s); - } - return 0; -} From 2e64d54e9e5ac1f07aee4399d225d8c6366dfd32 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 14:13:53 +0200 Subject: [PATCH 159/217] the tracee (lte-softmodem) now sends the content of T_messages.txt as special events. If we store all received events to a file, this dump is now self-contained. Helps to analyze traces. Some functions have also been factorized in the process, too much duplication. (Also tracer/Makefile was forgotten in previous commit, included in this one...) --- common/utils/T/Makefile | 7 ++- common/utils/T/T.c | 28 ++++++++++ common/utils/T/T_defs.h | 7 +++ common/utils/T/tracer/Makefile | 2 +- common/utils/T/tracer/Makefile.remote | 6 +-- common/utils/T/tracer/config.c | 55 ++++++++++++++++++++ common/utils/T/tracer/config.h | 8 +++ common/utils/T/tracer/enb.c | 74 ++------------------------- common/utils/T/tracer/event.c | 39 ++++++++++++++ common/utils/T/tracer/event.h | 2 + common/utils/T/tracer/textlog.c | 74 ++------------------------- common/utils/T/tracer/utils.c | 47 +++++++++++++++++ common/utils/T/tracer/utils.h | 2 + common/utils/T/tracer/vcd.c | 74 ++------------------------- 14 files changed, 207 insertions(+), 218 deletions(-) create mode 100644 common/utils/T/tracer/config.c create mode 100644 common/utils/T/tracer/config.h diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 9694273c19..6690e7d38d 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -24,11 +24,16 @@ $(PROG): $(OBJS) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< +T.o: T_messages.txt.h + +T_messages.txt.h: T_messages.txt + xxd -i T_messages.txt > T_messages.txt.h + T_IDs.h: $(GENIDS) T_messages.txt ./$(GENIDS) T_messages.txt T_IDs.h main.o: T.h T_IDs.h T_defs.h clean: - rm -f *.o $(PROG) $(GENIDS) core T_IDs.h + rm -f *.o $(PROG) $(GENIDS) core T_IDs.h T_messages.txt.h cd tracer && make clean diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 541cd239b7..1a5ff0a54c 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -1,4 +1,5 @@ #include "T.h" +#include "T_messages.txt.h" #include #include #include @@ -125,6 +126,8 @@ void T_connect_to_tracer(char *addr, int port) #ifdef T_USE_SHARED_MEMORY int T_shm_fd; #endif + unsigned char *buf; + int len; if (strcmp(addr, "127.0.0.1") != 0) { printf("error: local tracer must be on same host\n"); @@ -169,4 +172,29 @@ again: new_thread(T_send_thread, NULL); #endif new_thread(T_receive_thread, NULL); + + /* trace T_message.txt + * Send several messages -1 with content followed by message -2. + * We can't use the T macro directly, events -1 and -2 are special. + */ + buf = T_messages_txt; + len = T_messages_txt_len; + while (len) { + int send_size = len; + if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int)) + send_size = T_PAYLOAD_MAXSIZE - sizeof(int); + do { + T_LOCAL_DATA + T_HEADER(T_ID(-1)); + T_PUT_buffer(1, ((T_buffer){addr:(buf), length:(len)})); + T_SEND(); + } while (0); + buf += send_size; + len -= send_size; + } + do { + T_LOCAL_DATA + T_HEADER(T_ID(-2)); + T_SEND(); + } while (0); } diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index ffd35ad9af..b4fd47c0a5 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -13,6 +13,13 @@ /* size of the local cache for messages (must be pow(2,something)) */ #define T_CACHE_SIZE (8192 * 2) +/* maximum number of bytes a message can contain */ +#ifdef T_SEND_TIME +# define T_PAYLOAD_MAXSIZE (T_BUFFER_MAX-sizeof(int)-sizeof(struct timespec)) +#else +# define T_PAYLOAD_MAXSIZE (T_BUFFER_MAX-sizeof(int)) +#endif + typedef struct { volatile int busy; char buffer[T_BUFFER_MAX]; diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 8cbc0d58d2..5044c2e8b3 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -4,7 +4,7 @@ local: make -f Makefile.local remote: - make -f Makefile.remote tracer_remote textlog enb vcd + make -f Makefile.remote textlog enb vcd clean: make -f Makefile.local clean diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote index b6ff0f3cad..b2663f8651 100644 --- a/common/utils/T/tracer/Makefile.remote +++ b/common/utils/T/tracer/Makefile.remote @@ -5,15 +5,15 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. LIBS=-lX11 -lm -lpng -lXft -textlog: utils.o textlog.o database.o event.o handler.o \ +textlog: utils.o textlog.o database.o event.o handler.o config.o \ event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o textlog $^ $(LIBS) -enb: utils.o enb.o database.o event.o handler.o \ +enb: utils.o enb.o database.o event.o handler.o config.o \ event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o enb $^ $(LIBS) -vcd: utils.o vcd.o database.o event.o handler.o \ +vcd: utils.o vcd.o database.o event.o handler.o config.o \ event_selector.o view/view.a gui/gui.a logger/logger.a $(CC) $(CFLAGS) -o vcd $^ $(LIBS) diff --git a/common/utils/T/tracer/config.c b/common/utils/T/tracer/config.c new file mode 100644 index 0000000000..333c28ce43 --- /dev/null +++ b/common/utils/T/tracer/config.c @@ -0,0 +1,55 @@ +#include "config.h" +#include +#include +#include + +static char *local; +static int local_size; +static char *remote; +static int remote_size; + +static char *PUT(char *to, int tosize, char c) +{ + if ((tosize & 4095) == 0) { + to = realloc(to, tosize + 4096); if (to == NULL) abort(); + } + to[tosize] = c; + return to; +} + +void append_received_config_chunk(char *buf, int length) +{ + int buflen = *(int *)buf; + if (buflen != length - sizeof(int)) { + printf("ERROR: bad trace -1, should not happen...\n"); + abort(); + } + buf += sizeof(int); + while (buflen) { + remote = PUT(remote, remote_size, *buf); + remote_size++; + buf++; + buflen--; + } +} + +void store_config_file(char *filename) +{ + int c; + FILE *f = fopen(filename, "r"); + if (f == NULL) { perror(filename); abort(); } + while (1) { + c = fgetc(f); if (c == EOF) break; + local = PUT(local, local_size, c); + local_size++; + } + fclose(f); +} + +void verify_config(void) +{ + if (local_size != remote_size || memcmp(local, remote, local_size) != 0) { + printf("ERROR: local and remote T_messages.txt not identical\n"); + abort(); + } +} diff --git a/common/utils/T/tracer/config.h b/common/utils/T/tracer/config.h new file mode 100644 index 0000000000..88b207e9f6 --- /dev/null +++ b/common/utils/T/tracer/config.h @@ -0,0 +1,8 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +void append_received_config_chunk(char *buf, int length); +void store_config_file(char *filename); +void verify_config(void); + +#endif /* _CONFIG_H_ */ diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 239c2d8ad8..97ff6f490f 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -1,8 +1,6 @@ #include #include #include -#include -#include #include #include "database.h" #include "event.h" @@ -14,39 +12,10 @@ #include "../T_defs.h" #include "event_selector.h" #include "openair_logo.h" +#include "config.h" #define DEFAULT_REMOTE_PORT 2021 -int get_connection(char *addr, int port) -{ - struct sockaddr_in a; - socklen_t alen; - int s, t; - - printf("waiting for connection on %s:%d\n", addr, port); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } - t = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) - { perror("setsockopt"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(addr); - - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("bind"); exit(1); } - alen = sizeof(a); - t = accept(s, (struct sockaddr *)&a, &alen); - if (t == -1) { perror("accept"); exit(1); } - close(s); - - printf("connected\n"); - - return t; -} - void usage(void) { printf( @@ -66,45 +35,6 @@ void usage(void) exit(1); } -int fullread(int fd, void *_buf, int count) -{ - char *buf = _buf; - int ret = 0; - int l; - while (count) { - l = read(fd, buf, count); - if (l <= 0) { printf("read socket problem\n"); abort(); } - count -= l; - buf += l; - ret += l; - } - return ret; -} - -event get_event(int s, char *v, void *d) -{ -#ifdef T_SEND_TIME - struct timespec t; -#endif - int type; - int32_t length; - - fullread(s, &length, 4); -#ifdef T_SEND_TIME - fullread(s, &t, sizeof(struct timespec)); - length -= sizeof(struct timespec); -#endif - fullread(s, &type, sizeof(int)); - length -= sizeof(int); - fullread(s, v, length); - -#ifdef T_SEND_TIME - return new_event(t, type, length, v, d); -#else - return new_event(type, length, v, d); -#endif -} - static void *gui_thread(void *_g) { gui *g = _g; @@ -228,6 +158,8 @@ int main(int n, char **v) database = parse_database(database_filename); + store_config_file(database_filename); + number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); if (is_on == NULL) abort(); diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c index 1d9f3a4081..e626b4a7d6 100644 --- a/common/utils/T/tracer/event.c +++ b/common/utils/T/tracer/event.c @@ -1,9 +1,48 @@ #include "event.h" #include "database.h" +#include "utils.h" +#include "config.h" #include #include #include +event get_event(int socket, char *event_buffer, void *database) +{ +#ifdef T_SEND_TIME + struct timespec t; +#endif + int type; + int32_t length; + + /* Events type -1 and -2 are special: the tracee sends its version + * of T_messages.txt using those events. + * We have to check that the local version of T_messages.txt is identical + * to the one the tracee uses. We don't report those events to the + * application. + */ + +again: + fullread(socket, &length, 4); +#ifdef T_SEND_TIME + fullread(socket, &t, sizeof(struct timespec)); + length -= sizeof(struct timespec); +#endif + fullread(socket, &type, sizeof(int)); + length -= sizeof(int); + fullread(socket, event_buffer, length); + + if (type == -1) append_received_config_chunk(event_buffer, length); + if (type == -2) verify_config(); + + if (type == -1 || type == -2) goto again; + +#ifdef T_SEND_TIME + return new_event(t, type, length, event_buffer, database); +#else + return new_event(type, length, event_buffer, database); +#endif +} + #ifdef T_SEND_TIME event new_event(struct timespec sending_time, int type, int length, char *buffer, void *database) diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h index 32abee4ead..6272baf1a8 100644 --- a/common/utils/T/tracer/event.h +++ b/common/utils/T/tracer/event.h @@ -37,6 +37,8 @@ typedef struct { int ecount; } event; +event get_event(int s, char *v, void *d); + #ifdef T_SEND_TIME event new_event(struct timespec sending_time, int type, int length, char *buffer, void *database); diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index ec08596fca..9b1b486460 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -1,8 +1,6 @@ #include #include #include -#include -#include #include #include "database.h" #include "event.h" @@ -13,39 +11,10 @@ #include "utils.h" #include "../T_defs.h" #include "event_selector.h" +#include "config.h" #define DEFAULT_REMOTE_PORT 2021 -int get_connection(char *addr, int port) -{ - struct sockaddr_in a; - socklen_t alen; - int s, t; - - printf("waiting for connection on %s:%d\n", addr, port); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } - t = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) - { perror("setsockopt"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(addr); - - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("bind"); exit(1); } - alen = sizeof(a); - t = accept(s, (struct sockaddr *)&a, &alen); - if (t == -1) { perror("accept"); exit(1); } - close(s); - - printf("connected\n"); - - return t; -} - void usage(void) { printf( @@ -67,45 +36,6 @@ void usage(void) exit(1); } -int fullread(int fd, void *_buf, int count) -{ - char *buf = _buf; - int ret = 0; - int l; - while (count) { - l = read(fd, buf, count); - if (l <= 0) { printf("read socket problem\n"); abort(); } - count -= l; - buf += l; - ret += l; - } - return ret; -} - -event get_event(int s, char *v, void *d) -{ -#ifdef T_SEND_TIME - struct timespec t; -#endif - int type; - int32_t length; - - fullread(s, &length, 4); -#ifdef T_SEND_TIME - fullread(s, &t, sizeof(struct timespec)); - length -= sizeof(struct timespec); -#endif - fullread(s, &type, sizeof(int)); - length -= sizeof(int); - fullread(s, v, length); - -#ifdef T_SEND_TIME - return new_event(t, type, length, v, d); -#else - return new_event(type, length, v, d); -#endif -} - static void *gui_thread(void *_g) { gui *g = _g; @@ -167,6 +97,8 @@ int main(int n, char **v) database = parse_database(database_filename); + store_config_file(database_filename); + number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); if (is_on == NULL) abort(); diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index 95b4084822..aac80e9fa5 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include void new_thread(void *(*f)(void *), void *data) { @@ -78,6 +80,51 @@ void socket_send(int socket, void *buffer, int size) } } +int get_connection(char *addr, int port) +{ + struct sockaddr_in a; + socklen_t alen; + int s, t; + + printf("waiting for connection on %s:%d\n", addr, port); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + t = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) + { perror("setsockopt"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } + if (listen(s, 5)) { perror("bind"); exit(1); } + alen = sizeof(a); + t = accept(s, (struct sockaddr *)&a, &alen); + if (t == -1) { perror("accept"); exit(1); } + close(s); + + printf("connected\n"); + + return t; +} + +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) { printf("read socket problem\n"); abort(); } + count -= l; + buf += l; + ret += l; + } + return ret; +} + /****************************************************************************/ /* buffer */ /****************************************************************************/ diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index f7e3a6d256..cdee2e0bc9 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -21,6 +21,8 @@ list *list_append(list *l, void *data); /****************************************************************************/ void socket_send(int socket, void *buffer, int size); +int get_connection(char *addr, int port); +int fullread(int fd, void *_buf, int count); /****************************************************************************/ /* buffer */ diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index e1fae049bd..4d36db59df 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -1,8 +1,6 @@ #include #include #include -#include -#include #include #include "database.h" #include "event.h" @@ -13,39 +11,10 @@ #include "utils.h" #include "../T_defs.h" #include "event_selector.h" +#include "config.h" #define DEFAULT_REMOTE_PORT 2021 -int get_connection(char *addr, int port) -{ - struct sockaddr_in a; - socklen_t alen; - int s, t; - - printf("waiting for connection on %s:%d\n", addr, port); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } - t = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) - { perror("setsockopt"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(addr); - - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("bind"); exit(1); } - alen = sizeof(a); - t = accept(s, (struct sockaddr *)&a, &alen); - if (t == -1) { perror("accept"); exit(1); } - close(s); - - printf("connected\n"); - - return t; -} - void usage(void) { printf( @@ -65,45 +34,6 @@ void usage(void) exit(1); } -int fullread(int fd, void *_buf, int count) -{ - char *buf = _buf; - int ret = 0; - int l; - while (count) { - l = read(fd, buf, count); - if (l <= 0) { printf("read socket problem\n"); abort(); } - count -= l; - buf += l; - ret += l; - } - return ret; -} - -event get_event(int s, char *v, void *d) -{ -#ifdef T_SEND_TIME - struct timespec t; -#endif - int type; - int32_t length; - - fullread(s, &length, 4); -#ifdef T_SEND_TIME - fullread(s, &t, sizeof(struct timespec)); - length -= sizeof(struct timespec); -#endif - fullread(s, &type, sizeof(int)); - length -= sizeof(int); - fullread(s, v, length); - -#ifdef T_SEND_TIME - return new_event(t, type, length, v, d); -#else - return new_event(type, length, v, d); -#endif -} - static void *gui_thread(void *_g) { gui *g = _g; @@ -199,6 +129,8 @@ int main(int n, char **v) database = parse_database(database_filename); + store_config_file(database_filename); + number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); if (is_on == NULL) abort(); From 45728df27cc89b9bdd00b0eae8ed1002bc44d404 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 16:47:43 +0200 Subject: [PATCH 160/217] bugfix: wrong index --- common/utils/T/tracer/database.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/database.c b/common/utils/T/tracer/database.c index 1914946656..f0908948e2 100644 --- a/common/utils/T/tracer/database.c +++ b/common/utils/T/tracer/database.c @@ -484,17 +484,18 @@ void database_get_generic_description(void *_d, int id, char **name, char **desc) { database *d = _d; + int pos = d->id_to_pos[id]; OBUF o; int i; - *name = strdup(d->i[id].name); + *name = strdup(d->i[pos].name); if (*name == NULL) abort(); o.osize = o.omaxsize = 0; o.obuf = NULL; PUTS(&o, *name); - for (i = 0; i < d->i[id].asize; i++) { + for (i = 0; i < d->i[pos].asize; i++) { PUTC(&o, ' '); - PUTS(&o, d->i[id].arg_name[i]); + PUTS(&o, d->i[pos].arg_name[i]); PUTS(&o, " ["); - PUTS(&o, d->i[id].arg_name[i]); + PUTS(&o, d->i[pos].arg_name[i]); PUTS(&o, "]"); } PUTC(&o, 0); From 2138a47e41c15535b9b4676e98a090b742178f85 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 16:51:33 +0200 Subject: [PATCH 161/217] more work on enb.c plus add rrc connection setup complete tracing --- common/utils/T/T_messages.txt | 6 +++ common/utils/T/tracer/enb.c | 91 +++++++++++++++++++++++++++++++++-- openair2/RRC/LITE/rrc_eNB.c | 3 ++ 3 files changed, 96 insertions(+), 4 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index df9ed1edec..ed3609a062 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -40,6 +40,12 @@ ID = PUCCH_1_ENERGY GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold +#RRC logs +ID = ENB_RRC_CONNECTION_SETUP_COMPLETE + DESC = RRC connection setup complete + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti + #legacy logs ID = LEGACY_MAC_INFO DESC = MAC legacy logs - info level diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 97ff6f490f..a675c2eae7 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -14,6 +14,10 @@ #include "openair_logo.h" #include "config.h" +typedef struct { + view *rrcview; +} enb_gui; + #define DEFAULT_REMOTE_PORT 2021 void usage(void) @@ -42,11 +46,11 @@ static void *gui_thread(void *_g) return NULL; } -static void enb_main_gui(gui *g, event_handler *h, void *database) +static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) { widget *main_window; widget *top_container; - widget *line; + widget *line, *col; widget *logo; widget *input_signal_plot; logger *input_signal_log; @@ -55,6 +59,8 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) logger *timelog; view *timeview; view *subview; + widget *text; + view *textview; int i; main_window = new_toplevel_window(g, 800, 600, "eNB tracer"); @@ -79,12 +85,13 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) logger_add_view(input_signal_log, input_signal_view); /* downlink UE DCIs */ + widget_add_child(g, top_container, + new_label(g,"DL/UL TICK/DCI/ACK/NACK "), -1); line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); timeline_plot = new_timeline(g, 512, 8, 5); widget_add_child(g, line, timeline_plot, -1); container_set_child_growable(g, line, timeline_plot, 1); - widget_add_child(g, line, new_label(g,"DL/UL TICK/DCI/ACK/NACK "), 0); for (i = 0; i < 8; i++) timeline_set_subline_background_color(g, timeline_plot, i, new_color(g, i==0 || i==4 ? "#aaf" : i & 1 ? "#ddd" : "#eee")); @@ -110,6 +117,78 @@ static void enb_main_gui(gui *g, event_handler *h, void *database) timelog = new_timelog(h, database, "ENB_UL_TICK"); subview = new_subview_time(timeview, 4, FOREGROUND_COLOR, 3600*1000); logger_add_view(timelog, subview); + + /* phy/mac/rlc/pdcp/rrc textlog */ + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + container_set_child_growable(g, top_container, line, 1); + + /* phy */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + container_set_child_growable(g, line, col, 1); + widget_add_child(g, col, new_label(g, "PHY"), -1); + text = new_textlist(g, 100, 10, new_color(g, "#afa")); + widget_add_child(g, col, text, -1); + container_set_child_growable(g, col, text, 1); + textview = new_view_textlist(10000, 10, g, text); + + /* mac */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + container_set_child_growable(g, line, col, 1); + widget_add_child(g, col, new_label(g, "MAC"), -1); + text = new_textlist(g, 100, 10, new_color(g, "#adf")); + widget_add_child(g, col, text, -1); + container_set_child_growable(g, col, text, 1); + textview = new_view_textlist(10000, 10, g, text); + + /* rlc */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + container_set_child_growable(g, line, col, 1); + widget_add_child(g, col, new_label(g, "RLC"), -1); + text = new_textlist(g, 100, 10, new_color(g, "#aff")); + widget_add_child(g, col, text, -1); + container_set_child_growable(g, col, text, 1); + textview = new_view_textlist(10000, 10, g, text); + + /* pdcp */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + container_set_child_growable(g, line, col, 1); + widget_add_child(g, col, new_label(g, "PDCP"), -1); + text = new_textlist(g, 100, 10, new_color(g, "#ed9")); + widget_add_child(g, col, text, -1); + container_set_child_growable(g, col, text, 1); + textview = new_view_textlist(10000, 10, g, text); + + /* rrc */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + container_set_child_growable(g, line, col, 1); + widget_add_child(g, col, new_label(g, "RRC"), -1); + text = new_textlist(g, 100, 10, new_color(g, "#fdb")); + widget_add_child(g, col, text, -1); + container_set_child_growable(g, col, text, 1); + textview = new_view_textlist(10000, 10, g, text); + e->rrcview = textview; +} + +void view_add_log(view *v, char *log, event_handler *h, void *database, + int *is_on) +{ + logger *textlog; + char *name, *desc; + + database_get_generic_description(database, + event_id_from_name(database, log), &name, &desc); + textlog = new_textlog(h, database, name, desc); + logger_add_view(textlog, v); + free(name); + free(desc); + + on_off(database, log, is_on, 1); } int main(int n, char **v) @@ -129,6 +208,7 @@ int main(int n, char **v) int l; event_handler *h; gui *g; + enb_gui eg; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -169,7 +249,7 @@ int main(int n, char **v) g = gui_init(); new_thread(gui_thread, g); - enb_main_gui(g, h, database); + enb_main_gui(&eg, g, h, database); on_off(database, "ENB_INPUT_SIGNAL", is_on, 1); on_off(database, "ENB_UL_TICK", is_on, 1); @@ -178,6 +258,9 @@ int main(int n, char **v) on_off(database, "ENB_DLSCH_UE_ACK", is_on, 1); on_off(database, "ENB_DLSCH_UE_NACK", is_on, 1); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE", h, database, + is_on); + for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 1d0b5f2902..dbc9e09f16 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -849,6 +849,9 @@ rrc_eNB_process_RRCConnectionSetupComplete( PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing RRCConnectionSetupComplete from UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #if defined(ENABLE_USE_MME) if (EPC_MODE_ENABLED == 1) { From 0feda7fdfe3a7f2807281a9e0b81c59af5893bec Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 17:38:44 +0200 Subject: [PATCH 162/217] add some RRC logs - adding T macros here and there - modify the T_messages.txt - modify enb.c to trace them in the RRC view --- common/utils/T/T_messages.txt | 48 +++++++++++++++++++++++++++++++++++ common/utils/T/tracer/enb.c | 28 ++++++++++++++++++-- openair2/RRC/LITE/rrc_eNB.c | 42 ++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index ed3609a062..0271cb82b5 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -45,6 +45,54 @@ ID = ENB_RRC_CONNECTION_SETUP_COMPLETE DESC = RRC connection setup complete GROUP = ALL:RRC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_SECURITY_MODE_COMMAND + DESC = RRC security mode command + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UE_CAPABILITY_ENQUIRY + DESC = RRC UE capability enquiry + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_REJECT + DESC = RRC connection reject + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT + DESC = RRC connection reestablishment reject + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_RELEASE + DESC = RRC connection release + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_RECONFIGURATION + DESC = RRC connection reconfiguration + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_MEASUREMENT_REPORT + DESC = RRC measurement report + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_HANDOVER_PREPARATION_INFORMATION + DESC = RRC handover preparation information + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE + DESC = RRC connection reconfiguration complete + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_SETUP + DESC = RRC connection setup + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UL_CCCH_DATA_IN + DESC = RRC uplink CCCH data in + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UL_DCCH_DATA_IN + DESC = RRC uplink DCCH data in + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti #legacy logs ID = LEGACY_MAC_INFO diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index a675c2eae7..a0431b7175 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -258,8 +258,32 @@ int main(int n, char **v) on_off(database, "ENB_DLSCH_UE_ACK", is_on, 1); on_off(database, "ENB_DLSCH_UE_NACK", is_on, 1); - view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE", h, database, - is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMMAND", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UE_CAPABILITY_ENQUIRY", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REJECT", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_RELEASE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_RECONFIGURATION", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_MEASUREMENT_REPORT", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_HANDOVER_PREPARATION_INFORMATION", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UL_CCCH_DATA_IN", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UL_DCCH_DATA_IN", + h, database, is_on); for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index dbc9e09f16..11c27c1aa2 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -882,6 +882,9 @@ rrc_eNB_generate_SecurityModeCommand( uint8_t buffer[100]; uint8_t size; + T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + size = do_SecurityModeCommand( ctxt_pP, buffer, @@ -946,6 +949,9 @@ rrc_eNB_generate_UECapabilityEnquiry( uint8_t buffer[100]; uint8_t size; + T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + size = do_UECapabilityEnquiry( ctxt_pP, buffer, @@ -998,6 +1004,9 @@ rrc_eNB_generate_RRCConnectionReject( int cnt; #endif + T(T_ENB_RRC_CONNECTION_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionReject(ctxt_pP->module_id, (uint8_t*) eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.Payload); @@ -1041,6 +1050,9 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( int cnt; #endif + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishmentReject(ctxt_pP->module_id, (uint8_t*) eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.Payload); @@ -1083,6 +1095,9 @@ rrc_eNB_generate_RRCConnectionRelease( uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; + T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + memset(buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); @@ -1190,6 +1205,9 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( cba_RNTI->size = 2; cba_RNTI->bits_unused = 0; + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + // associate UEs to the CBa groups as a function of their UE id if (rrc_inst->num_active_cba_groups) { cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; @@ -1829,6 +1847,9 @@ rrc_eNB_process_MeasurementReport( ) //----------------------------------------------------------------------------- { + T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_I(RRC, "[eNB %d] Frame %d: Process Measurement Report From UE %x (Measurement Id %d)\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId); @@ -1898,6 +1919,9 @@ rrc_eNB_generate_HandoverPreparationInformation( RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); */ + T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + handoverInfo->as_config.antennaInfoCommon.antennaPortsCount = 0; //Not used 0- but check value handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify! @@ -1988,6 +2012,9 @@ rrc_eNB_process_handoverPreparationInformation( ) //----------------------------------------------------------------------------- { + T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n", @@ -2063,6 +2090,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ) //----------------------------------------------------------------------------- { + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; @@ -3015,6 +3045,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #if defined(ENABLE_SECURITY) /* Derive the keys from kenb */ @@ -3275,6 +3308,9 @@ rrc_eNB_generate_RRCConnectionSetup( SRB_ToAddMod_t *SRB1_config; int cnt; + T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + SRB_configList = &ue_context_pP->ue_context.SRB_configList; eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup(ctxt_pP, @@ -3548,6 +3584,9 @@ rrc_eNB_decode_ccch( struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint64_t random_value = 0; + T(T_ENB_RRC_UL_CCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t)); LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n", @@ -3883,6 +3922,9 @@ rrc_eNB_decode_dcch( int i; struct rrc_eNB_ue_context_s* ue_context_p = NULL; + T(T_ENB_RRC_UL_DCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + if ((Srb_id != 1) && (Srb_id != 2)) { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%d, should not have ...\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), From 32302fc233a8167df3618eae0a266f7c4130605c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 25 May 2016 17:59:13 +0200 Subject: [PATCH 163/217] add legacy logs to enb.c --- common/utils/T/tracer/enb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index a0431b7175..11e90769b4 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -16,6 +16,7 @@ typedef struct { view *rrcview; + view *legacy; } enb_gui; #define DEFAULT_REMOTE_PORT 2021 @@ -173,6 +174,13 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); e->rrcview = textview; + + /* legacy logs (LOG_I, LOG_D, ...) */ + widget_add_child(g, top_container, new_label(g, "LEGACY"), -1); + text = new_textlist(g, 100, 10, new_color(g, "#eeb")); + widget_add_child(g, top_container, text, -1); + container_set_child_growable(g, top_container, text, 1); + e->legacy = new_view_textlist(10000, 10, g, text); } void view_add_log(view *v, char *log, event_handler *h, void *database, @@ -251,6 +259,17 @@ int main(int n, char **v) enb_main_gui(&eg, g, h, database); + for (i = 0; i < number_of_events; i++) { + logger *textlog; + char *name, *desc; + database_get_generic_description(database, i, &name, &desc); + if (strncmp(name, "LEGACY_", 7) != 0) continue; + textlog = new_textlog(h, database, name, desc); + logger_add_view(textlog, eg.legacy); + free(name); + free(desc); + } + on_off(database, "ENB_INPUT_SIGNAL", is_on, 1); on_off(database, "ENB_UL_TICK", is_on, 1); on_off(database, "ENB_DL_TICK", is_on, 1); From eeefd61433ce5d0491b42e9e94303d6126bcb19c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 17:26:29 +0200 Subject: [PATCH 164/217] let's print nanosecond in times of textlog instead of closest millisecond --- common/utils/T/tracer/logger/textlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index ea7f9c8a93..a9503b9510 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -47,8 +47,8 @@ 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.%3.3d: ", t->tm_hour, t->tm_min, t->tm_sec, - (int)((e.sending_time.tv_nsec/(1000000/2)+1)/2)); + 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 From fc1c621a18f29742ed70f3950d71cc3c329b2c51 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 17:27:43 +0200 Subject: [PATCH 165/217] better colors in enb.c --- common/utils/T/tracer/enb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 11e90769b4..dd84971e6b 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -95,11 +95,11 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) container_set_child_growable(g, line, timeline_plot, 1); for (i = 0; i < 8; i++) timeline_set_subline_background_color(g, timeline_plot, i, - new_color(g, i==0 || i==4 ? "#aaf" : i & 1 ? "#ddd" : "#eee")); + new_color(g, i==0 || i==4 ? "#aaf" : "#eee")); timeview = new_view_time(3600, 10, g, timeline_plot); /* tick logging */ timelog = new_timelog(h, database, "ENB_DL_TICK"); - subview = new_subview_time(timeview, 0, FOREGROUND_COLOR, 3600*1000); + subview = new_subview_time(timeview, 0, new_color(g, "#77c"), 3600*1000); logger_add_view(timelog, subview); /* DCI logging */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_DCI"); @@ -116,7 +116,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) /* uplink UE DCIs */ timelog = new_timelog(h, database, "ENB_UL_TICK"); - subview = new_subview_time(timeview, 4, FOREGROUND_COLOR, 3600*1000); + subview = new_subview_time(timeview, 4, new_color(g, "#77c"), 3600*1000); logger_add_view(timelog, subview); /* phy/mac/rlc/pdcp/rrc textlog */ From 4a80fd37049d7cc5834841237c55d7628cc6d257 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 18:35:08 +0200 Subject: [PATCH 166/217] add includes so that oaisim compiles with the T --- common/utils/itti/intertask_interface.c | 4 ++++ common/utils/itti/intertask_interface_dump.c | 4 ++++ common/utils/itti/memory_pools.c | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 572c207b3f..6789dadce6 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -58,6 +58,10 @@ # include "vcd_signal_dumper.h" #endif +#if T_TRACER +#include "T.h" +#endif + /* Includes "intertask_interface_init.h" to check prototype coherence, but * disable threads and messages information generation. */ diff --git a/common/utils/itti/intertask_interface_dump.c b/common/utils/itti/intertask_interface_dump.c index 491bff59b0..30d92e3a29 100644 --- a/common/utils/itti/intertask_interface_dump.c +++ b/common/utils/itti/intertask_interface_dump.c @@ -64,6 +64,10 @@ #include "vcd_signal_dumper.h" #endif +#if T_TRACER +#include "T.h" +#endif + static const int itti_dump_debug = 0; // 0x8 | 0x4 | 0x2; #ifdef RTAI diff --git a/common/utils/itti/memory_pools.c b/common/utils/itti/memory_pools.c index dadc80ca2a..112287ef41 100644 --- a/common/utils/itti/memory_pools.c +++ b/common/utils/itti/memory_pools.c @@ -37,6 +37,11 @@ # include "vcd_signal_dumper.h" #endif +#if T_TRACER +#include +#include "T.h" +#endif + /*------------------------------------------------------------------------------*/ const static int mp_debug = 0; From cc67ce6dcc02bc4bdc873a904145c0680a02e75b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 18:35:43 +0200 Subject: [PATCH 167/217] add RRC messages to T_messages.txt --- common/utils/T/T_messages.txt | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 0271cb82b5..5347f054f7 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -49,14 +49,38 @@ ID = ENB_RRC_SECURITY_MODE_COMMAND DESC = RRC security mode command GROUP = ALL:RRC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_SECURITY_MODE_COMPLETE + DESC = RRC security mode complete + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_SECURITY_MODE_FAILURE + DESC = RRC security mode failure + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti ID = ENB_RRC_UE_CAPABILITY_ENQUIRY DESC = RRC UE capability enquiry GROUP = ALL:RRC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UE_CAPABILITY_INFORMATION + DESC = RRC UE capability information + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_REQUEST + DESC = RRC connection request + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti ID = ENB_RRC_CONNECTION_REJECT DESC = RRC connection reject GROUP = ALL:RRC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST + DESC = RRC connection reestablishment request + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE + DESC = RRC connection reestablishment complete + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti ID = ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT DESC = RRC connection reestablishment reject GROUP = ALL:RRC:ENB @@ -93,6 +117,42 @@ ID = ENB_RRC_UL_DCCH_DATA_IN DESC = RRC uplink DCCH data in GROUP = ALL:RRC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER + DESC = RRC uplink handover preparation transfer + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UL_INFORMATION_TRANSFER + DESC = RRC uplink information transfer + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_COUNTER_CHECK_RESPONSE + DESC = RRC counter check response + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UE_INFORMATION_RESPONSE_R9 + DESC = RRC UE information response r9 + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_PROXIMITY_INDICATION_R9 + DESC = RRC proximity indication r9 + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_RECONFIGURATION_COMPLETE_R10 + DESC = RRC reconfiguration complete r10 + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_MBMS_COUNTING_RESPONSE_R10 + DESC = RRC MBMS counting response r10 + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION + DESC = RRC inter frequency RSTD measurement indication + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_UNKNOW_MESSAGE + DESC = RRC unknown message + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti #legacy logs ID = LEGACY_MAC_INFO From f6bfd8a397b4a16d5851899ba7ec0e72d4b55eeb Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 18:38:25 +0200 Subject: [PATCH 168/217] bugfix: T_ENB_RRC_CONNECTION_RECONFIGURATION was done at the wrong place --- openair2/RRC/LITE/rrc_eNB.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 11c27c1aa2..d857575702 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -1205,9 +1205,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( cba_RNTI->size = 2; cba_RNTI->bits_unused = 0; - T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // associate UEs to the CBa groups as a function of their UE id if (rrc_inst->num_active_cba_groups) { cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; @@ -1224,6 +1221,10 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( } #endif + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + // Configure SRB2 /// SRB2 SRB2_config = CALLOC(1, sizeof(*SRB2_config)); From 2e6c04cd3fe114edfbbd5581d210f6e893bc37a3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 18:38:56 +0200 Subject: [PATCH 169/217] add T traces to rrc_eNB.c --- openair2/RRC/LITE/rrc_eNB.c | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index d857575702..0db8fe9960 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3658,6 +3658,9 @@ rrc_eNB_decode_ccch( break; case UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest: + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC Connection Reestablishement Request\n"); @@ -3700,6 +3703,9 @@ rrc_eNB_decode_ccch( break; case UL_CCCH_MessageType__c1_PR_rrcConnectionRequest: + T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC Connection Request\n"); @@ -4073,6 +4079,9 @@ rrc_eNB_decode_dcch( break; case UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC Connection Reestablishment Complete\n"); @@ -4147,6 +4156,9 @@ rrc_eNB_decode_dcch( break; case UL_DCCH_MessageType__c1_PR_securityModeComplete: + T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC Security Mode Complete\n"); @@ -4189,6 +4201,9 @@ rrc_eNB_decode_dcch( break; case UL_DCCH_MessageType__c1_PR_securityModeFailure: + T(T_ENB_RRC_SECURITY_MODE_FAILURE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC Security Mode Failure\n"); @@ -4226,6 +4241,9 @@ rrc_eNB_decode_dcch( break; case UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC UECapablility Information \n"); @@ -4288,9 +4306,15 @@ rrc_eNB_decode_dcch( break; case UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: + T(T_ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; case UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC UL Information Transfer \n"); @@ -4324,27 +4348,48 @@ rrc_eNB_decode_dcch( break; case UL_DCCH_MessageType__c1_PR_counterCheckResponse: + T(T_ENB_RRC_COUNTER_CHECK_RESPONSE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; #ifdef Rel10 case UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: + T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; case UL_DCCH_MessageType__c1_PR_proximityIndication_r9: + T(T_ENB_RRC_PROXIMITY_INDICATION_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; case UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: + T(T_ENB_RRC_RECONFIGURATION_COMPLETE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; case UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: + T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; case UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: + T(T_ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; #endif default: + T(T_ENB_RRC_UNKNOW_MESSAGE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message %s:%u\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), __FILE__, __LINE__); From d9202e43f7a6c13a4636d210adaf62538fc2bcd7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 18:39:40 +0200 Subject: [PATCH 170/217] add RRC traces to the RRC view in enb.c --- common/utils/T/tracer/enb.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index dd84971e6b..682a49eca3 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -303,6 +303,36 @@ int main(int n, char **v) h, database, is_on); view_add_log(eg.rrcview, "ENB_RRC_UL_DCCH_DATA_IN", h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMPLETE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_FAILURE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UE_CAPABILITY_INFORMATION", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REQUEST", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UL_INFORMATION_TRANSFER", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_COUNTER_CHECK_RESPONSE", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UE_INFORMATION_RESPONSE_R9", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_PROXIMITY_INDICATION_R9", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_RECONFIGURATION_COMPLETE_R10", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_MBMS_COUNTING_RESPONSE_R10", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION", + h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_UNKNOW_MESSAGE", + h, database, is_on); for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); From 655e48c5dc009f16e6ce67ce6650af5f6ff68cbf Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 May 2016 18:40:09 +0200 Subject: [PATCH 171/217] enable legacy RRC info/error/warning by default in enb.c can be deactivated on the command line or in the gui --- common/utils/T/tracer/enb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 682a49eca3..b370962e9d 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -277,6 +277,10 @@ int main(int n, char **v) on_off(database, "ENB_DLSCH_UE_ACK", is_on, 1); on_off(database, "ENB_DLSCH_UE_NACK", is_on, 1); + on_off(database, "LEGACY_RRC_INFO", is_on, 1); + on_off(database, "LEGACY_RRC_ERROR", is_on, 1); + on_off(database, "LEGACY_RRC_WARNING", is_on, 1); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE", h, database, is_on); view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMMAND", From 3a71ecb759576e52dbd35e3221ce74b94810d731 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 15:47:55 +0200 Subject: [PATCH 172/217] remove T_USE_SHARED_MEMORY The T only works when it's TRUE, the version without shared memory is not supported anymore. --- cmake_targets/CMakeLists.txt | 1 - common/utils/T/Makefile | 2 -- common/utils/T/T.c | 43 ---------------------------- common/utils/T/T.h | 32 --------------------- common/utils/T/tracee/Makefile | 2 +- common/utils/T/tracer/Makefile.local | 1 - 6 files changed, 1 insertion(+), 80 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a95994a8b1..2a51f376d8 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1487,7 +1487,6 @@ set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODU #add the T tracer add_boolean_option(T_TRACER True "Activate the T tracer" ) include_directories("${OPENAIR_DIR}/common/utils/T") -add_boolean_option(T_USE_SHARED_MEMORY True "Use shared memory to communicate with the T tracer" ) set(T_SOURCE ${OPENAIR_DIR}/common/utils/T/T.c) set (T_LIB "-lrt") diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 6690e7d38d..73c07c7e82 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -1,8 +1,6 @@ CC=gcc CFLAGS=-Wall -g -pthread -DT_TRACER -#comment those two lines to NOT use shared memory -CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=t diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 1a5ff0a54c..61fd554090 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -62,42 +62,6 @@ printf("got mess %d\n", t); } } -#ifndef T_USE_SHARED_MEMORY - -static void *T_send_thread(void *_) -{ - while (1) { - usleep(5000); - __sync_synchronize(); - while (T_cache[T_busylist_head].busy) { - char *b; - int l; - /* TODO: be sure about those memory barriers - in doubt one is - * put here too - */ - __sync_synchronize(); - b = T_cache[T_busylist_head].buffer; - l = T_cache[T_busylist_head].length; - while (l) { - int done = write(T_socket, b, l); - if (done <= 0) { - printf("%s:%d:%s: error sending to socket\n", - __FILE__, __LINE__, __FUNCTION__); - abort(); - } - b += done; - l -= done; - } - T_cache[T_busylist_head].busy = 0; - T_busylist_head++; - T_busylist_head &= T_CACHE_SIZE - 1; - } - } - return NULL; -} - -#endif /* T_USE_SHARED_MEMORY */ - static void *T_receive_thread(void *_) { while (1) get_message(T_socket); @@ -123,9 +87,7 @@ void T_connect_to_tracer(char *addr, int port) { struct sockaddr_in a; int s; -#ifdef T_USE_SHARED_MEMORY int T_shm_fd; -#endif unsigned char *buf; int len; @@ -156,7 +118,6 @@ again: T_socket = s; -#ifdef T_USE_SHARED_MEMORY /* setup shared memory */ T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666); shm_unlink(T_SHM_FILENAME); @@ -166,11 +127,7 @@ again: if (T_cache == NULL) { perror(T_SHM_FILENAME); abort(); } close(T_shm_fd); -#endif -#ifndef T_USE_SHARED_MEMORY - new_thread(T_send_thread, NULL); -#endif new_thread(T_receive_thread, NULL); /* trace T_message.txt diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 58e0d5a885..13e1cbc3ca 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -127,26 +127,12 @@ extern T_cache_t *T_cache; #define T_ACTIVE(x) T_active[(intptr_t)x] -#ifdef T_USE_SHARED_MEMORY - #define T_SEND() \ T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ __sync_synchronize(); \ T_cache[T_LOCAL_slot].busy = 1; \ T_send(T_LOCAL_buf, T_LOCAL_size) -#else /* T_USE_SHARED_MEMORY */ - -/* when not using shared memory, wait for send to finish */ -#define T_SEND() \ - T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ - __sync_synchronize(); \ - T_cache[T_LOCAL_slot].busy = 1; \ - T_send(T_LOCAL_buf, T_LOCAL_size); \ - while (T_cache[T_LOCAL_slot].busy) usleep(1*1000) - -#endif /* T_USE_SHARED_MEMORY */ - #define T_CHECK_SIZE(len, argnum) \ if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \ printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \ @@ -575,26 +561,8 @@ extern T_cache_t *T_cache; } \ } while (0) -#ifndef T_USE_SHARED_MEMORY - -#include - -static inline void T_send(char *buf, int size) -{ - int i; -return; - printf("sending %d bytes", size); - for (i = 0; i < size; i++) - printf("%s%2.2x", i?" ":"\n", (unsigned char)buf[i]); - printf("\n"); -} - -#else /* T_USE_SHARED_MEMORY */ - #define T_send(...) /**/ -#endif /* T_USE_SHARED_MEMORY */ - extern int *T_active; void T_connect_to_tracer(char *addr, int port); diff --git a/common/utils/T/tracee/Makefile b/common/utils/T/tracee/Makefile index bc7c01d86b..703d49d029 100644 --- a/common/utils/T/tracee/Makefile +++ b/common/utils/T/tracee/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wall -g -pthread -DT_TRACER -DT_USE_SHARED_MEMORY -I. +CFLAGS=-Wall -g -pthread -DT_TRACER -I. PROG=tracee OBJS=tracee.o ../T.o diff --git a/common/utils/T/tracer/Makefile.local b/common/utils/T/tracer/Makefile.local index a34378470b..ae4e248a20 100644 --- a/common/utils/T/tracer/Makefile.local +++ b/common/utils/T/tracer/Makefile.local @@ -3,7 +3,6 @@ CFLAGS=-Wall -g -pthread -DT_TRACER #CFLAGS += -O3 -ffast-math -fomit-frame-pointer -CFLAGS += -DT_USE_SHARED_MEMORY LIBS += -lrt PROG=tracer_local From a5e63b2726812e1c9386bad43b39d45123ff5f19 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 15:56:35 +0200 Subject: [PATCH 173/217] rename T_SEND to T_COMMIT, sounds better get rid of T_send(), no use anymore --- common/utils/T/T.c | 4 ++-- common/utils/T/T.h | 43 ++++++++++++++++------------------- common/utils/T/generate_Txx.c | 2 +- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 61fd554090..818f741a99 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -144,7 +144,7 @@ again: T_LOCAL_DATA T_HEADER(T_ID(-1)); T_PUT_buffer(1, ((T_buffer){addr:(buf), length:(len)})); - T_SEND(); + T_COMMIT(); } while (0); buf += send_size; len -= send_size; @@ -152,6 +152,6 @@ again: do { T_LOCAL_DATA T_HEADER(T_ID(-2)); - T_SEND(); + T_COMMIT(); } while (0); } diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 13e1cbc3ca..7fb6133fcc 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -127,11 +127,10 @@ extern T_cache_t *T_cache; #define T_ACTIVE(x) T_active[(intptr_t)x] -#define T_SEND() \ +#define T_COMMIT() \ T_cache[T_LOCAL_slot].length = T_LOCAL_size; \ __sync_synchronize(); \ T_cache[T_LOCAL_slot].busy = 1; \ - T_send(T_LOCAL_buf, T_LOCAL_size) #define T_CHECK_SIZE(len, argnum) \ if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \ @@ -222,7 +221,7 @@ extern T_cache_t *T_cache; if (T_ACTIVE(t)) { \ T_LOCAL_DATA \ T_HEADER(t); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -232,7 +231,7 @@ extern T_cache_t *T_cache; T_LOCAL_DATA \ T_HEADER(t); \ T_PUT_##t0(2, x0); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -243,7 +242,7 @@ extern T_cache_t *T_cache; T_HEADER(t); \ T_PUT_##t0(2, x0); \ T_PUT_##t1(3, x1); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -255,7 +254,7 @@ extern T_cache_t *T_cache; T_PUT_##t0(2, x0); \ T_PUT_##t1(3, x1); \ T_PUT_##t2(4, x2); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -268,7 +267,7 @@ extern T_cache_t *T_cache; T_PUT_##t1(3, x1); \ T_PUT_##t2(4, x2); \ T_PUT_##t3(5, x3); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -282,7 +281,7 @@ extern T_cache_t *T_cache; T_PUT_##t2(4, x2); \ T_PUT_##t3(5, x3); \ T_PUT_##t4(6, x4); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -297,7 +296,7 @@ extern T_cache_t *T_cache; T_PUT_##t3(5, x3); \ T_PUT_##t4(6, x4); \ T_PUT_##t5(7, x5); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -313,7 +312,7 @@ extern T_cache_t *T_cache; T_PUT_##t4(6, x4); \ T_PUT_##t5(7, x5); \ T_PUT_##t6(8, x6); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -330,7 +329,7 @@ extern T_cache_t *T_cache; T_PUT_##t5(7, x5); \ T_PUT_##t6(8, x6); \ T_PUT_##t7(9, x7); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -348,7 +347,7 @@ extern T_cache_t *T_cache; T_PUT_##t6(8, x6); \ T_PUT_##t7(9, x7); \ T_PUT_##t8(10, x8); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -367,7 +366,7 @@ extern T_cache_t *T_cache; T_PUT_##t7(9, x7); \ T_PUT_##t8(10, x8); \ T_PUT_##t9(11, x9); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -387,7 +386,7 @@ extern T_cache_t *T_cache; T_PUT_##t8(10, x8); \ T_PUT_##t9(11, x9); \ T_PUT_##t10(12, x10); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -408,7 +407,7 @@ extern T_cache_t *T_cache; T_PUT_##t9(11, x9); \ T_PUT_##t10(12, x10); \ T_PUT_##t11(13, x11); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -430,7 +429,7 @@ extern T_cache_t *T_cache; T_PUT_##t10(12, x10); \ T_PUT_##t11(13, x11); \ T_PUT_##t12(14, x12); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -453,7 +452,7 @@ extern T_cache_t *T_cache; T_PUT_##t11(13, x11); \ T_PUT_##t12(14, x12); \ T_PUT_##t13(15, x13); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -477,7 +476,7 @@ extern T_cache_t *T_cache; T_PUT_##t12(14, x12); \ T_PUT_##t13(15, x13); \ T_PUT_##t14(16, x14); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -502,7 +501,7 @@ extern T_cache_t *T_cache; T_PUT_##t13(15, x13); \ T_PUT_##t14(16, x14); \ T_PUT_##t15(17, x15); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -542,7 +541,7 @@ extern T_cache_t *T_cache; T_LOCAL_DATA \ T_HEADER(T_ID((var) + VCD_FIRST_VARIABLE)); \ T_PUT_ulong(1, (val)); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) @@ -557,12 +556,10 @@ extern T_cache_t *T_cache; T_LOCAL_DATA \ T_HEADER(T_ID((fun) + VCD_FIRST_FUNCTION)); \ T_PUT_int(1, (val)); \ - T_SEND(); \ + T_COMMIT(); \ } \ } while (0) -#define T_send(...) /**/ - extern int *T_active; void T_connect_to_tracer(char *addr, int port); diff --git a/common/utils/T/generate_Txx.c b/common/utils/T/generate_Txx.c index da6282adc1..a32b554a71 100644 --- a/common/utils/T/generate_Txx.c +++ b/common/utils/T/generate_Txx.c @@ -11,7 +11,7 @@ void print(int n) printf(" T_LOCAL_DATA \\\n"); printf(" T_HEADER(t); \\\n"); for(i=0; i<(n-1)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i); - printf(" T_SEND(); \\\n"); + printf(" T_COMMIT(); \\\n"); printf(" } \\\n"); printf(" } while (0)\n"); printf("\n"); From 6b9db37802a57c34a31142e3dc0c8213f0aa420c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 17:06:45 +0200 Subject: [PATCH 174/217] start integrating local tracer directly into tracee first step: let the tracee connect before the remote tracer and let's have a "no wait" mode where the local tracer starts the tracee before the remote tracer is connected --- common/utils/T/T.c | 1 + common/utils/T/tracer/local.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 818f741a99..8d9f3d2aa0 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -59,6 +59,7 @@ printf("got mess %d\n", t); l--; } break; + case 2: break; /* do nothing, this message is to wait for local tracer */ } } diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c index 6c1368cc13..8f60eca340 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/tracer/local.c @@ -98,7 +98,9 @@ void usage(void) "tracer - local side\n" "options:\n" " -r forwards packets to remote IP:port\n" -" (default %s:%d)\n", +" (default %s:%d)\n" +" -nowait don't wait for remote tracer,\n" +" start tracee immediately\n", DEFAULT_REMOTE_IP, DEFAULT_REMOTE_PORT ); exit(1); @@ -111,20 +113,27 @@ int main(int n, char **v) char *remote_ip = DEFAULT_REMOTE_IP; int remote_port = DEFAULT_REMOTE_PORT; int port = 2020; + int dont_wait = 0; void *f; for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); if (!strcmp(v[i], "-r")) { if (i > n-3) usage(); remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-nowait")) { dont_wait = 1; continue; } printf("ERROR: unknown option %s\n", v[i]); usage(); } - f = forwarder(remote_ip, remote_port); init_shm(); s = get_connection("127.0.0.1", port); + if (dont_wait) { + char t = 2; + if (write(s, &t, 1) != 1) abort(); + } + + f = forwarder(remote_ip, remote_port); forward_start_client(f, s); /* read messages */ From b6854b15b8faf01a8537c71b7c76ea70afaae2da Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 17:18:30 +0200 Subject: [PATCH 175/217] cleanup --- common/utils/T/tracer/forward.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c index 15a23307b5..840f9fbc35 100644 --- a/common/utils/T/tracer/forward.c +++ b/common/utils/T/tracer/forward.c @@ -95,22 +95,11 @@ static void *forward_s_to_sc(void *_f) return NULL; } -static void *forward_sc_to_s(void *_f) -{ -#if 0 - forward_data *f = _f; - do_forward(f, f->sc, f->s, 1); - printf("INFO: forwarder exits\n"); -#endif - return NULL; -} - void forward_start_client(void *_f, int s) { forward_data *f = _f; f->sc = s; new_thread(forward_s_to_sc, f); - new_thread(forward_sc_to_s, f); } void *forwarder(char *ip, int port) From b3889a44be87c2f860b5de72c15b0f57431f13d9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 18:01:49 +0200 Subject: [PATCH 176/217] integration of local tracer into tracee - step 2 The local tracer now waits for the remote tracer to connect, that's no more the other way around. All the remote tracers (textlog, enb, vcd) have also been converted. --- common/utils/T/tracer/defs.h | 2 +- common/utils/T/tracer/enb.c | 9 +++++++-- common/utils/T/tracer/forward.c | 23 +++++------------------ common/utils/T/tracer/local.c | 24 ++++++++++-------------- common/utils/T/tracer/textlog.c | 9 +++++++-- common/utils/T/tracer/utils.c | 26 ++++++++++++++++++++++++++ common/utils/T/tracer/utils.h | 1 + common/utils/T/tracer/vcd.c | 9 +++++++-- 8 files changed, 64 insertions(+), 39 deletions(-) diff --git a/common/utils/T/tracer/defs.h b/common/utils/T/tracer/defs.h index 7a6f57b312..498f9e5b79 100644 --- a/common/utils/T/tracer/defs.h +++ b/common/utils/T/tracer/defs.h @@ -16,7 +16,7 @@ void iq_plot_set_sized(void *_plot, short *data, int len, int pp); void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp); void iq_plot_add_energy_point_loop(void *_plot, int e, int pp); -void *forwarder(char *ip, int port); +void *forwarder(int port); void forward(void *forwarder, char *buf, int size); void forward_start_client(void *forwarder, int socket); diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index b370962e9d..c80fd9bda3 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -19,6 +19,7 @@ typedef struct { view *legacy; } enb_gui; +#define DEFAULT_REMOTE_IP "127.0.0.1" #define DEFAULT_REMOTE_PORT 2021 void usage(void) @@ -33,8 +34,10 @@ void usage(void) " note: you may pass several -on/-off/-ON/-OFF,\n" " they will be processed in order\n" " by default, all is off\n" -" -p use given port (default %d)\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n" " -debug-gui activate GUI debug logs\n", + DEFAULT_REMOTE_IP, DEFAULT_REMOTE_PORT ); exit(1); @@ -204,6 +207,7 @@ int main(int n, char **v) extern int volatile gui_logd; char *database_filename = NULL; void *database; + char *ip = DEFAULT_REMOTE_IP; int port = DEFAULT_REMOTE_PORT; char **on_off_name; int *on_off_action; @@ -225,6 +229,7 @@ int main(int n, char **v) 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; } if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); @@ -341,7 +346,7 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = get_connection("0.0.0.0", port); + s = connect_to(ip, port); /* send the first message - activate selected traces */ t = 0; diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c index 840f9fbc35..e9eb93e1bb 100644 --- a/common/utils/T/tracer/forward.c +++ b/common/utils/T/tracer/forward.c @@ -102,10 +102,11 @@ void forward_start_client(void *_f, int s) new_thread(forward_s_to_sc, f); } -void *forwarder(char *ip, int port) +int get_connection(char *addr, int port); + +void *forwarder(int port) { forward_data *f; - struct sockaddr_in a; f = malloc(sizeof(*f)); if (f == NULL) abort(); @@ -119,23 +120,9 @@ void *forwarder(char *ip, int port) f->memusage = 0; f->last_warning_memusage = 0; - printf("connecting to remote tracer %s:%d\n", ip, port); + printf("waiting for remote tracer on port %d\n", port); -again: - f->s = socket(AF_INET, SOCK_STREAM, 0); - if (f->s == -1) { perror("socket"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(ip); - - if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) { - perror("connect"); - close(f->s); - printf("trying again in 1s\n"); - sleep(1); - goto again; - } + f->s = get_connection("127.0.0.1", port); printf("connected\n"); diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c index 8f60eca340..1648ae7d60 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/tracer/local.c @@ -9,8 +9,7 @@ #include #include -#define DEFAULT_REMOTE_IP "127.0.0.1" -#define DEFAULT_REMOTE_PORT 2021 +#define DEFAULT_PORT 2021 #include "defs.h" @@ -97,11 +96,9 @@ void usage(void) printf( "tracer - local side\n" "options:\n" -" -r forwards packets to remote IP:port\n" -" (default %s:%d)\n" -" -nowait don't wait for remote tracer,\n" -" start tracee immediately\n", - DEFAULT_REMOTE_IP, DEFAULT_REMOTE_PORT +" -p wait for remote tracer on port (default %d)\n" +" -nowait don't wait for remote tracer, start tracee immediately\n", + DEFAULT_PORT ); exit(1); } @@ -110,30 +107,29 @@ int main(int n, char **v) { int s; int i; - char *remote_ip = DEFAULT_REMOTE_IP; - int remote_port = DEFAULT_REMOTE_PORT; - int port = 2020; + int port = DEFAULT_PORT; + int local_port = 2020; int dont_wait = 0; void *f; for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-r")) { if (i > n-3) usage(); - remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); + port = atoi(v[++i]); continue; } if (!strcmp(v[i], "-nowait")) { dont_wait = 1; continue; } printf("ERROR: unknown option %s\n", v[i]); usage(); } init_shm(); - s = get_connection("127.0.0.1", port); + s = get_connection("127.0.0.1", local_port); if (dont_wait) { char t = 2; if (write(s, &t, 1) != 1) abort(); } - f = forwarder(remote_ip, remote_port); + f = forwarder(port); forward_start_client(f, s); /* read messages */ diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 9b1b486460..6ff36f650c 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -13,6 +13,7 @@ #include "event_selector.h" #include "config.h" +#define DEFAULT_REMOTE_IP "127.0.0.1" #define DEFAULT_REMOTE_PORT 2021 void usage(void) @@ -27,10 +28,12 @@ void usage(void) " note: you may pass several -on/-off/-ON/-OFF,\n" " they will be processed in order\n" " by default, all is off\n" -" -p use given port (default %d)\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n" " -x GUI output\n" " -debug-gui activate GUI debug logs\n" " -no-gui disable GUI entirely\n", + DEFAULT_REMOTE_IP, DEFAULT_REMOTE_PORT ); exit(1); @@ -48,6 +51,7 @@ int main(int n, char **v) extern int volatile gui_logd; char *database_filename = NULL; void *database; + char *ip = DEFAULT_REMOTE_IP; int port = DEFAULT_REMOTE_PORT; char **on_off_name; int *on_off_action; @@ -72,6 +76,7 @@ int main(int n, char **v) 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; } if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); @@ -136,7 +141,7 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = get_connection("0.0.0.0", port); + s = connect_to(ip, port); /* send the first message - activate selected traces */ t = 0; diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index aac80e9fa5..cb2e123fce 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -125,6 +125,32 @@ int fullread(int fd, void *_buf, int count) return ret; } +int connect_to(char *addr, int port) +{ + int s; + struct sockaddr_in a; + + printf("connecting to %s:%d\n", addr, port); + +again: + s = socket(AF_INET, SOCK_STREAM, 0); + if (s == -1) { perror("socket"); exit(1); } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) { + perror("connect"); + close(s); + printf("trying again in 1s\n"); + sleep(1); + goto again; + } + + return s; +} + /****************************************************************************/ /* buffer */ /****************************************************************************/ diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index cdee2e0bc9..00193b9eeb 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -23,6 +23,7 @@ list *list_append(list *l, void *data); void socket_send(int socket, void *buffer, int size); int get_connection(char *addr, int port); int fullread(int fd, void *_buf, int count); +int connect_to(char *addr, int port); /****************************************************************************/ /* buffer */ diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index 4d36db59df..bf66bddd29 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -13,6 +13,7 @@ #include "event_selector.h" #include "config.h" +#define DEFAULT_REMOTE_IP "127.0.0.1" #define DEFAULT_REMOTE_PORT 2021 void usage(void) @@ -27,8 +28,10 @@ void usage(void) " note: you may pass several -on/-off/-ON/-OFF,\n" " they will be processed in order\n" " by default, all is off\n" -" -p use given port (default %d)\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n" " -debug-gui activate GUI debug logs\n", + DEFAULT_REMOTE_IP, DEFAULT_REMOTE_PORT ); exit(1); @@ -88,6 +91,7 @@ int main(int n, char **v) extern int volatile gui_logd; char *database_filename = NULL; void *database; + char *ip = DEFAULT_REMOTE_IP; int port = DEFAULT_REMOTE_PORT; char **on_off_name; int *on_off_action; @@ -108,6 +112,7 @@ int main(int n, char **v) 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; } if (!strcmp(v[i], "-on")) { if (i > n-2) usage(); @@ -147,7 +152,7 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = get_connection("0.0.0.0", port); + s = connect_to(ip, port); /* send the first message - activate selected traces */ t = 0; From 3b226410d2188cbe0a8baa6a3cb368a7777bec59 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 18:09:26 +0200 Subject: [PATCH 177/217] cleanup remove forward stuff from defs.h remove defs.h from local.c and forward.c --- common/utils/T/tracer/defs.h | 4 ---- common/utils/T/tracer/forward.c | 8 +++++--- common/utils/T/tracer/forward.h | 8 ++++++++ common/utils/T/tracer/local.c | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 common/utils/T/tracer/forward.h diff --git a/common/utils/T/tracer/defs.h b/common/utils/T/tracer/defs.h index 498f9e5b79..443fabdde8 100644 --- a/common/utils/T/tracer/defs.h +++ b/common/utils/T/tracer/defs.h @@ -16,10 +16,6 @@ void iq_plot_set_sized(void *_plot, short *data, int len, int pp); void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp); void iq_plot_add_energy_point_loop(void *_plot, int e, int pp); -void *forwarder(int port); -void forward(void *forwarder, char *buf, int size); -void forward_start_client(void *forwarder, int socket); - /* T gui functions */ void t_gui_start(void); void t_gui_set_input_signal(int eNB, int frame, int subframe, int antenna, diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c index e9eb93e1bb..2bddb80330 100644 --- a/common/utils/T/tracer/forward.c +++ b/common/utils/T/tracer/forward.c @@ -1,4 +1,4 @@ -#include "defs.h" +#include "forward.h" #include #include #include @@ -9,6 +9,10 @@ #include #include +/* from local.c */ +int get_connection(char *addr, int port); +void new_thread(void *(*f)(void *), void *data); + typedef struct databuf { char *d; int l; @@ -102,8 +106,6 @@ void forward_start_client(void *_f, int s) new_thread(forward_s_to_sc, f); } -int get_connection(char *addr, int port); - void *forwarder(int port) { forward_data *f; diff --git a/common/utils/T/tracer/forward.h b/common/utils/T/tracer/forward.h new file mode 100644 index 0000000000..80607d74fc --- /dev/null +++ b/common/utils/T/tracer/forward.h @@ -0,0 +1,8 @@ +#ifndef _FORWARD_H_ +#define _FORWARD_H_ + +void *forwarder(int port); +void forward(void *forwarder, char *buf, int size); +void forward_start_client(void *forwarder, int socket); + +#endif /* _FORWARD_H_ */ diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c index 1648ae7d60..fbe4d6d420 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/tracer/local.c @@ -11,7 +11,7 @@ #define DEFAULT_PORT 2021 -#include "defs.h" +#include "forward.h" #include "../T_defs.h" From f5313266ad6174edddb53d27e4297123ece38e6b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 18:30:59 +0200 Subject: [PATCH 178/217] integration of local tracer into tracee - step 3 get rid of forward.c, make everything static inside local.c --- common/utils/T/tracer/Makefile.local | 2 +- common/utils/T/tracer/forward.c | 171 ---------------------- common/utils/T/tracer/forward.h | 8 -- common/utils/T/tracer/local.c | 203 +++++++++++++++++++++++---- 4 files changed, 176 insertions(+), 208 deletions(-) delete mode 100644 common/utils/T/tracer/forward.c delete mode 100644 common/utils/T/tracer/forward.h diff --git a/common/utils/T/tracer/Makefile.local b/common/utils/T/tracer/Makefile.local index ae4e248a20..4e971fc627 100644 --- a/common/utils/T/tracer/Makefile.local +++ b/common/utils/T/tracer/Makefile.local @@ -6,7 +6,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER LIBS += -lrt PROG=tracer_local -OBJS=local.o forward.o +OBJS=local.o $(PROG): $(OBJS) $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) diff --git a/common/utils/T/tracer/forward.c b/common/utils/T/tracer/forward.c deleted file mode 100644 index 2bddb80330..0000000000 --- a/common/utils/T/tracer/forward.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "forward.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* from local.c */ -int get_connection(char *addr, int port); -void new_thread(void *(*f)(void *), void *data); - -typedef struct databuf { - char *d; - int l; - struct databuf *next; -} databuf; - -typedef struct { - int s; - int sc; - pthread_mutex_t lock; - pthread_mutex_t datalock; - pthread_cond_t datacond; - databuf * volatile head, *tail; - uint64_t memusage; - uint64_t last_warning_memusage; -} forward_data; - -static void *data_sender(void *_f) -{ - forward_data *f = _f; - databuf *cur; - char *buf, *b; - int size; - -wait: - if (pthread_mutex_lock(&f->datalock)) abort(); - while (f->head == NULL) - if (pthread_cond_wait(&f->datacond, &f->datalock)) abort(); - cur = f->head; - buf = cur->d; - size = cur->l; - f->head = cur->next; - f->memusage -= size; - if (f->head == NULL) f->tail = NULL; - if (pthread_mutex_unlock(&f->datalock)) abort(); - free(cur); - goto process; - -process: - if (pthread_mutex_lock(&f->lock)) abort(); - - b = buf; - while (size) { - int l = write(f->s, b, size); - if (l <= 0) { printf("forward error\n"); exit(1); } - size -= l; - b += l; - } - - if (pthread_mutex_unlock(&f->lock)) abort(); - - free(buf); - - goto wait; -} - -static void do_forward(forward_data *f, int from, int to, int lock) -{ - int l, len; - char *b; - char buf[1024]; - while (1) { - len = read(from, buf, 1024); - if (len <= 0) break; - b = buf; - - if (lock) if (pthread_mutex_lock(&f->lock)) abort(); - - while (len) { - l = write(to, b, len); - if (l <= 0) break; - len -= l; - b += l; - } - - if (lock) if (pthread_mutex_unlock(&f->lock)) abort(); - } -} - -static void *forward_s_to_sc(void *_f) -{ - forward_data *f = _f; - do_forward(f, f->s, f->sc, 0); - return NULL; -} - -void forward_start_client(void *_f, int s) -{ - forward_data *f = _f; - f->sc = s; - new_thread(forward_s_to_sc, f); -} - -void *forwarder(int port) -{ - forward_data *f; - - f = malloc(sizeof(*f)); if (f == NULL) abort(); - - pthread_mutex_init(&f->lock, NULL); - pthread_mutex_init(&f->datalock, NULL); - pthread_cond_init(&f->datacond, NULL); - - f->sc = -1; - f->head = f->tail = NULL; - - f->memusage = 0; - f->last_warning_memusage = 0; - - printf("waiting for remote tracer on port %d\n", port); - - f->s = get_connection("127.0.0.1", port); - - printf("connected\n"); - - new_thread(data_sender, f); - - return f; -} - -void forward(void *_forwarder, char *buf, int size) -{ - forward_data *f = _forwarder; - int32_t ssize = size; - databuf *new; - - new = malloc(sizeof(*new)); if (new == NULL) abort(); - - if (pthread_mutex_lock(&f->datalock)) abort(); - - new->d = malloc(size + 4); if (new->d == NULL) abort(); - /* put the size of the message at the head */ - memcpy(new->d, &ssize, 4); - memcpy(new->d+4, buf, size); - new->l = size+4; - new->next = NULL; - if (f->head == NULL) f->head = new; - if (f->tail != NULL) f->tail->next = new; - f->tail = new; - - f->memusage += size+4; - /* warn every 100MB */ - if (f->memusage > f->last_warning_memusage && - f->memusage - f->last_warning_memusage > 100000000) { - f->last_warning_memusage += 100000000; - printf("WARNING: memory usage is over %"PRIu64"MB\n", - f->last_warning_memusage / 1000000); - } else - if (f->memusage < f->last_warning_memusage && - f->last_warning_memusage - f->memusage > 100000000) { - f->last_warning_memusage = (f->memusage/100000000) * 100000000; - } - - if (pthread_cond_signal(&f->datacond)) abort(); - if (pthread_mutex_unlock(&f->datalock)) abort(); -} diff --git a/common/utils/T/tracer/forward.h b/common/utils/T/tracer/forward.h deleted file mode 100644 index 80607d74fc..0000000000 --- a/common/utils/T/tracer/forward.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _FORWARD_H_ -#define _FORWARD_H_ - -void *forwarder(int port); -void forward(void *forwarder, char *buf, int size); -void forward_start_client(void *forwarder, int socket); - -#endif /* _FORWARD_H_ */ diff --git a/common/utils/T/tracer/local.c b/common/utils/T/tracer/local.c index fbe4d6d420..2550a02549 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/tracer/local.c @@ -8,18 +8,53 @@ #include #include #include +#include #define DEFAULT_PORT 2021 -#include "forward.h" - #include "../T_defs.h" -T_cache_t *T_cache; -int T_busylist_head; -int T_pos; +static T_cache_t *T_cache; +static int T_busylist_head; -int get_connection(char *addr, int port) +typedef struct databuf { + char *d; + int l; + struct databuf *next; +} databuf; + +typedef struct { + int socket_local; + int socket_remote; + pthread_mutex_t lock; + pthread_cond_t cond; + databuf * volatile head, *tail; + uint64_t memusage; + uint64_t last_warning_memusage; +} forward_data; + +/****************************************************************************/ +/* utility functions */ +/****************************************************************************/ + +static void new_thread(void *(*f)(void *), void *data) +{ + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) + { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) + { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } + if (pthread_attr_setstacksize(&att, 10000000)) + { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } + if (pthread_create(&t, &att, f, data)) + { fprintf(stderr, "pthread_create err\n"); exit(1); } + if (pthread_attr_destroy(&att)) + { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } +} + +static int get_connection(char *addr, int port) { struct sockaddr_in a; socklen_t alen; @@ -49,12 +84,142 @@ int get_connection(char *addr, int port) return t; } -void wait_message(void) +/****************************************************************************/ +/* forward functions */ +/****************************************************************************/ + +static void *data_sender(void *_f) +{ + forward_data *f = _f; + databuf *cur; + char *buf, *b; + int size; + +wait: + if (pthread_mutex_lock(&f->lock)) abort(); + while (f->head == NULL) + if (pthread_cond_wait(&f->cond, &f->lock)) abort(); + cur = f->head; + buf = cur->d; + size = cur->l; + f->head = cur->next; + f->memusage -= size; + if (f->head == NULL) f->tail = NULL; + if (pthread_mutex_unlock(&f->lock)) abort(); + free(cur); + goto process; + +process: + b = buf; + while (size) { + int l = write(f->socket_remote, b, size); + if (l <= 0) { printf("forward error\n"); exit(1); } + size -= l; + b += l; + } + + free(buf); + + goto wait; +} + +static void *forward_remote_messages(void *_f) +{ + forward_data *f = _f; + int from = f->socket_remote; + int to = f->socket_local; + int l, len; + char *b; + char buf[1024]; + while (1) { + len = read(from, buf, 1024); + if (len <= 0) break; + b = buf; + + while (len) { + l = write(to, b, len); + if (l <= 0) break; + len -= l; + b += l; + } + } + return NULL; +} + +static void *forwarder(int port, int s) +{ + forward_data *f; + + f = malloc(sizeof(*f)); if (f == NULL) abort(); + + pthread_mutex_init(&f->lock, NULL); + pthread_cond_init(&f->cond, NULL); + + f->socket_local = s; + f->head = f->tail = NULL; + + f->memusage = 0; + f->last_warning_memusage = 0; + + printf("waiting for remote tracer on port %d\n", port); + + f->socket_remote = get_connection("127.0.0.1", port); + + printf("connected\n"); + + new_thread(data_sender, f); + new_thread(forward_remote_messages, f); + + return f; +} + +static void forward(void *_forwarder, char *buf, int size) +{ + forward_data *f = _forwarder; + int32_t ssize = size; + databuf *new; + + new = malloc(sizeof(*new)); if (new == NULL) abort(); + + if (pthread_mutex_lock(&f->lock)) abort(); + + new->d = malloc(size + 4); if (new->d == NULL) abort(); + /* put the size of the message at the head */ + memcpy(new->d, &ssize, 4); + memcpy(new->d+4, buf, size); + new->l = size+4; + new->next = NULL; + if (f->head == NULL) f->head = new; + if (f->tail != NULL) f->tail->next = new; + f->tail = new; + + f->memusage += size+4; + /* warn every 100MB */ + if (f->memusage > f->last_warning_memusage && + f->memusage - f->last_warning_memusage > 100000000) { + f->last_warning_memusage += 100000000; + printf("WARNING: memory usage is over %"PRIu64"MB\n", + f->last_warning_memusage / 1000000); + } else + if (f->memusage < f->last_warning_memusage && + f->last_warning_memusage - f->memusage > 100000000) { + f->last_warning_memusage = (f->memusage/100000000) * 100000000; + } + + if (pthread_cond_signal(&f->cond)) abort(); + if (pthread_mutex_unlock(&f->lock)) abort(); +} + +/****************************************************************************/ +/* local functions */ +/****************************************************************************/ + +static void wait_message(void) { while (T_cache[T_busylist_head].busy == 0) usleep(1000); } -void init_shm(void) +static void init_shm(void) { int i; int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); @@ -74,24 +239,7 @@ void init_shm(void) for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0; } -void new_thread(void *(*f)(void *), void *data) -{ - pthread_t t; - pthread_attr_t att; - - if (pthread_attr_init(&att)) - { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } - if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) - { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } - if (pthread_attr_setstacksize(&att, 10000000)) - { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } - if (pthread_create(&t, &att, f, data)) - { fprintf(stderr, "pthread_create err\n"); exit(1); } - if (pthread_attr_destroy(&att)) - { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } -} - -void usage(void) +static void usage(void) { printf( "tracer - local side\n" @@ -129,8 +277,7 @@ int main(int n, char **v) if (write(s, &t, 1) != 1) abort(); } - f = forwarder(port); - forward_start_client(f, s); + f = forwarder(port, s); /* read messages */ while (1) { From 05afc953e8dc1ce0d30fe473e445d00cddff72f6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 31 May 2016 18:50:01 +0200 Subject: [PATCH 179/217] cleanup - _T_cache variable had no place here... --- common/utils/T/T.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 8d9f3d2aa0..9a9df9418d 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -24,8 +24,7 @@ static int T_socket; volatile int _T_freelist_head; volatile int *T_freelist_head = &_T_freelist_head; int T_busylist_head; -T_cache_t _T_cache[T_CACHE_SIZE]; -T_cache_t *T_cache = _T_cache; +T_cache_t *T_cache; static void get_message(int s) { From 358a37910ca5df7d952bd3268825ccaa008fe127 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 1 Jun 2016 15:42:29 +0200 Subject: [PATCH 180/217] put local tracer in tracee plus some cleanup here and there --- cmake_targets/CMakeLists.txt | 3 +- common/utils/T/Makefile | 20 +- common/utils/T/T.c | 41 +-- common/utils/T/T.h | 2 +- common/utils/T/database.c | 325 ------------------ common/utils/T/forward.c | 162 --------- .../T/{tracer/local.c => local_tracer.c} | 39 +-- common/utils/T/main.c | 21 -- common/utils/T/tracer/Makefile | 43 ++- common/utils/T/tracer/Makefile.local | 18 - common/utils/T/tracer/Makefile.remote | 38 -- targets/SIMU/USER/oaisim.c | 20 +- targets/SIMU/USER/oaisim_functions.c | 25 ++ 13 files changed, 103 insertions(+), 654 deletions(-) delete mode 100644 common/utils/T/database.c delete mode 100644 common/utils/T/forward.c rename common/utils/T/{tracer/local.c => local_tracer.c} (88%) delete mode 100644 common/utils/T/main.c delete mode 100644 common/utils/T/tracer/Makefile.local delete mode 100644 common/utils/T/tracer/Makefile.remote diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 2a51f376d8..6a053451c5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1488,7 +1488,8 @@ set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODU add_boolean_option(T_TRACER True "Activate the T tracer" ) include_directories("${OPENAIR_DIR}/common/utils/T") set(T_SOURCE - ${OPENAIR_DIR}/common/utils/T/T.c) + ${OPENAIR_DIR}/common/utils/T/T.c + ${OPENAIR_DIR}/common/utils/T/local_tracer.c) set (T_LIB "-lrt") # Hack on a test of asn1c version (already dirty) diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 73c07c7e82..dcb0d12fab 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -1,37 +1,23 @@ CC=gcc -CFLAGS=-Wall -g -pthread -DT_TRACER - -LIBS += -lrt - -PROG=t -OBJS=main.o T.o +CFLAGS=-Wall -g GENIDS=genids GENIDS_OBJS=genids.o -ALL=$(PROG) $(GENIDS) - -all : $(ALL) +all : $(GENIDS) T_messages.txt.h T_IDs.h $(GENIDS): $(GENIDS_OBJS) $(CC) $(CFLAGS) -o $(GENIDS) $(GENIDS_OBJS) -$(PROG): $(OBJS) - $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) - %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -T.o: T_messages.txt.h - T_messages.txt.h: T_messages.txt xxd -i T_messages.txt > T_messages.txt.h T_IDs.h: $(GENIDS) T_messages.txt ./$(GENIDS) T_messages.txt T_IDs.h -main.o: T.h T_IDs.h T_defs.h - clean: - rm -f *.o $(PROG) $(GENIDS) core T_IDs.h T_messages.txt.h + rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h cd tracer && make clean diff --git a/common/utils/T/T.c b/common/utils/T/T.c index 9a9df9418d..c556a9c2a5 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -1,8 +1,6 @@ #include "T.h" #include "T_messages.txt.h" #include -#include -#include #include #include #include @@ -10,6 +8,7 @@ #include #include #include +#include /* array used to activate/disactivate a log */ static int T_IDs[T_NUMBER_OF_IDS]; @@ -23,7 +22,6 @@ static int T_socket; */ volatile int _T_freelist_head; volatile int *T_freelist_head = &_T_freelist_head; -int T_busylist_head; T_cache_t *T_cache; static void get_message(int s) @@ -83,36 +81,31 @@ static void new_thread(void *(*f)(void *), void *data) { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } } -void T_connect_to_tracer(char *addr, int port) +/* defined in local_tracer.c */ +void T_local_tracer_main(int remote_port, int wait_for_tracer, + int local_socket); + +void T_init(int remote_port, int wait_for_tracer) { - struct sockaddr_in a; + int socket_pair[2]; int s; int T_shm_fd; unsigned char *buf; int len; + int f; - if (strcmp(addr, "127.0.0.1") != 0) { - printf("error: local tracer must be on same host\n"); - abort(); - } + if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) + { perror("socketpair"); abort(); } - printf("connecting to local tracer on port %d\n", port); -again: - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr("127.0.0.1"); - - if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) { - perror("connect"); - close(s); - printf("trying again in 1s\n"); - sleep(1); - goto again; + f = fork(); if (f == -1) abort(); + if (f == 0) { + close(socket_pair[1]); + T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]); + exit(0); } + close(socket_pair[0]); + s = socket_pair[1]; /* wait for first message - initial list of active T events */ get_message(s); diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 7fb6133fcc..a5aacb4b4f 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -562,7 +562,7 @@ extern T_cache_t *T_cache; extern int *T_active; -void T_connect_to_tracer(char *addr, int port); +void T_init(int remote_port, int wait_for_tracer); #else /* T_TRACER */ diff --git a/common/utils/T/database.c b/common/utils/T/database.c deleted file mode 100644 index 59d8cbdc85..0000000000 --- a/common/utils/T/database.c +++ /dev/null @@ -1,325 +0,0 @@ -#include "defs.h" -#include -#include -#include -#include - -typedef struct { - char *name; - char *desc; - char **groups; - int size; - int id; -} id; - -typedef struct { - char *name; - char **ids; - int size; -} group; - -typedef struct { - char *name; - id *i; - int isize; - group *g; - int gsize; -} database; - -typedef struct { - char *data; - int size; - int maxsize; -} buffer; - -typedef struct { - buffer name; - buffer value; -} parser; - -void put(buffer *b, int c) -{ - if (b->size == b->maxsize) { - b->maxsize += 256; - b->data = realloc(b->data, b->maxsize); - if (b->data == NULL) { printf("memory allocation error\n"); exit(1); } - } - b->data[b->size] = c; - b->size++; -} - -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(parser *p, FILE *f, char **name, char **value) -{ - int c; - p->name.size = 0; - p->value.size = 0; - *name = NULL; - *value = NULL; - smash_spaces(f); - c = fgetc(f); - while (!(c == '=' || isspace(c) || c == EOF)) - { put(&p->name, c); c = fgetc(f); } - if (c == EOF) return; - put(&p->name, 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)) - { put(&p->value, c); c = fgetc(f); } - put(&p->value, 0); - if (p->name.size <= 1) return; - if (p->value.size <= 1) return; - *name = p->name.data; - *value = p->value.data; -} - -int group_cmp(const void *_p1, const void *_p2) -{ - const group *p1 = _p1; - const group *p2 = _p2; - return strcmp(p1->name, p2->name); -} - -int id_cmp(const void *_p1, const void *_p2) -{ - const id *p1 = _p1; - const id *p2 = _p2; - return strcmp(p1->name, p2->name); -} - -int string_cmp(const void *_p1, const void *_p2) -{ - char * const *p1 = _p1; - char * const *p2 = _p2; - return strcmp(*p1, *p2); -} - -id *add_id(database *r, char *idname, int i) -{ - if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL) - { printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); } - if ((r->isize & 1023) == 0) { - r->i = realloc(r->i, (r->isize + 1024) * sizeof(id)); - if (r->i == NULL) { printf("out of memory\n"); exit(1); } - } - r->i[r->isize].name = strdup(idname); - if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); } - r->i[r->isize].desc = NULL; - r->i[r->isize].groups = NULL; - r->i[r->isize].size = 0; - r->i[r->isize].id = i; - r->isize++; - qsort(r->i, r->isize, sizeof(id), id_cmp); - return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp); -} - -group *get_group(database *r, char *group_name) -{ - group *ret; - - ret = bsearch(&(group){name:group_name}, - r->g, r->gsize, sizeof(group), group_cmp); - if (ret != NULL) return ret; - - if ((r->gsize & 1023) == 0) { - r->g = realloc(r->g, (r->gsize + 1024) * sizeof(group)); - if (r->g == NULL) abort(); - } - r->g[r->gsize].name = strdup(group_name); - if (r->g[r->gsize].name == NULL) abort(); - r->g[r->gsize].ids = NULL; - r->g[r->gsize].size = 0; - r->gsize++; - - qsort(r->g, r->gsize, sizeof(group), group_cmp); - - return bsearch(&(group){name:group_name}, - r->g, r->gsize, sizeof(group), group_cmp); -} - -void group_add_id(group *g, char *id) -{ - if ((g->size & 1023) == 0) { - g->ids = realloc(g->ids, (g->size + 1024) * sizeof(char *)); - if (g->ids == NULL) abort(); - } - g->ids[g->size] = id; - g->size++; -} - -void id_add_group(id *i, char *group) -{ - char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp); - if (g != NULL) return; - - if ((i->size & 1023) == 0) { - i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *)); - if (i->groups == NULL) abort(); - } - i->groups[i->size] = group; - i->size++; - qsort(i->groups, i->size, sizeof(char *), string_cmp); -} - -void add_groups(database *r, id *i, char *groups) -{ - group *g; - if (i == NULL) {printf("ERROR: GROUP line before ID line\n");exit(1);} - while (1) { - char *start = groups; - char *end = start; - while (!isspace(*end) && *end != ':' && *end != 0) end++; - if (end == start) { - printf("bad group line: groups are seperated by ':'\n"); - abort(); - } - if (*end == 0) end = NULL; else *end = 0; - - g = get_group(r, start); - group_add_id(g, i->name); - id_add_group(i, g->name); - - if (end == NULL) break; - end++; - while ((isspace(*end) || *end == ':') && *end != 0) end++; - if (*end == 0) break; - groups = end; - } -} - -void add_desc(id *i, char *desc) -{ - if (i == NULL) {printf("ERROR: DESC line before ID line\n");exit(1);} - i->desc = strdup(desc); if (i->desc == NULL) abort(); -} - -void *parse_database(char *filename) -{ - FILE *in; - parser p; - database *r; - char *name, *value; - id *last_id = NULL; - int i; - - r = calloc(1, sizeof(*r)); if (r == NULL) abort(); - memset(&p, 0, sizeof(p)); - - r->name = strdup(filename); if (r->name == NULL) abort(); - - in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); } - - i = 0; - - while (1) { - get_line(&p, in, &name, &value); - if (name == NULL) break; -//printf("%s %s\n", name, value); - if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; } - if (!strcmp(name, "GROUP")) add_groups(r, last_id, value); - if (!strcmp(name, "DESC")) add_desc(last_id, value); - } - - fclose(in); - free(p.name.data); - free(p.value.data); - - return r; -} - -void dump_database(void *_d) -{ - database *d = _d; - int i; - - printf("database %s: %d IDs, %d GROUPs\n", d->name, d->isize, d->gsize); - for (i = 0; i < d->isize; i++) { - int j; - printf("ID %s [%s] [in %d group%s]\n", - d->i[i].name, d->i[i].desc ? d->i[i].desc : "", - d->i[i].size, d->i[i].size > 1 ? "s" : ""); - for (j = 0; j < d->i[i].size; j++) - printf(" in GROUP: %s\n", d->i[i].groups[j]); - } - for (i = 0; i < d->gsize; i++) { - int j; - printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size); - for (j = 0; j < d->g[i].size; j++) - printf(" contains ID: %s\n", d->g[i].ids[j]); - } -} - -void list_ids(void *_d) -{ - database *d = _d; - int i; - for (i = 0; i < d->isize; i++) printf("%s\n", d->i[i].name); -} - -void list_groups(void *_d) -{ - database *d = _d; - int i; - for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name); -} - -static int onoff_id(database *d, char *name, int *a, int onoff) -{ - id *i; - i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp); - if (i == NULL) return 0; - a[i->id] = onoff; - printf("turning %s %s\n", onoff ? "ON" : "OFF", name); - return 1; -} - -static int onoff_group(database *d, char *name, int *a, int onoff) -{ - group *g; - int i; - g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp); - if (g == NULL) return 0; - for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff); - return 1; -} - -void on_off(void *_d, char *item, int *a, int onoff) -{ - int done; - database *d = _d; - int i; - if (item == NULL) { - for (i = 0; i < d->isize; i++) a[i] = onoff; - printf("turning %s all traces\n", onoff ? "ON" : "OFF"); - return; - } - done = onoff_group(d, item, a, onoff); - done += onoff_id(d, item, a, onoff); - if (done == 0) { - printf("ERROR: ID/group '%s' not found in database\n", item); - exit(1); - } -} diff --git a/common/utils/T/forward.c b/common/utils/T/forward.c deleted file mode 100644 index 3177e22b2c..0000000000 --- a/common/utils/T/forward.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "defs.h" -#include -#include -#include -#include -#include -#include -#include - -typedef struct databuf { - char *d; - int l; - struct databuf *next; -} databuf; - -typedef struct { - int s; - int sc; - pthread_mutex_t lock; - pthread_mutex_t datalock; - pthread_cond_t datacond; - databuf * volatile head, *tail; -} forward_data; - -static void *data_sender(void *_f) -{ - forward_data *f = _f; - databuf *cur; - char *buf, *b; - int size; - -wait: - if (pthread_mutex_lock(&f->datalock)) abort(); - while (f->head == NULL) - if (pthread_cond_wait(&f->datacond, &f->datalock)) abort(); - cur = f->head; - buf = cur->d; - size = cur->l; - f->head = cur->next; - if (f->head == NULL) f->tail = NULL; - if (pthread_mutex_unlock(&f->datalock)) abort(); - free(cur); - goto process; - -process: - if (pthread_mutex_lock(&f->lock)) abort(); - -int *x = (int*)buf; -if (*x < 0 || *x >= 132) printf("bad id %d\n", *x); -printf("DATA_SENDER sends type %d\n", *x); - - b = buf; - while (size) { - int l = write(f->s, b, size); -printf("DATA_SENDER write buffer %p len %d returns %d\n", b, size, l); - if (l <= 0) { printf("forward error\n"); exit(1); } - size -= l; - b += l; - } - - if (pthread_mutex_unlock(&f->lock)) abort(); - - free(buf); - - goto wait; -} - -static void do_forward(forward_data *f, int from, int to, int lock) -{ - int l, len; - char *b; - char buf[1024]; - while (1) { - len = read(from, buf, 1024); - if (len <= 0) break; - b = buf; - - if (lock) if (pthread_mutex_lock(&f->lock)) abort(); - - while (len) { - l = write(to, b, len); -printf("DO_FORWARD write buffer %p len %d returns %d\n", b, len, l); - if (l <= 0) break; - len -= l; - b += l; - } - - if (lock) if (pthread_mutex_unlock(&f->lock)) abort(); - } -} - -static void *forward_s_to_sc(void *_f) -{ - forward_data *f = _f; - do_forward(f, f->s, f->sc, 0); - return NULL; -} - -static void *forward_sc_to_s(void *_f) -{ - forward_data *f = _f; - do_forward(f, f->sc, f->s, 1); - printf("INFO: forwarder exits\n"); - return NULL; -} - -void forward_start_client(void *_f, int s) -{ - forward_data *f = _f; - f->sc = s; - new_thread(forward_s_to_sc, f); - new_thread(forward_sc_to_s, f); -} - -void *forwarder(char *ip, int port) -{ - forward_data *f; - struct sockaddr_in a; - - f = malloc(sizeof(*f)); if (f == NULL) abort(); - - pthread_mutex_init(&f->lock, NULL); - pthread_mutex_init(&f->datalock, NULL); - pthread_cond_init(&f->datacond, NULL); - - f->sc = -1; - f->head = f->tail = NULL; - - f->s = socket(AF_INET, SOCK_STREAM, 0); - if (f->s == -1) { perror("socket"); exit(1); } - - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = inet_addr(ip); - - if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1) - { perror("connect"); exit(1); } - - new_thread(data_sender, f); - - return f; -} - -void forward(void *_forwarder, char *buf, int size) -{ - forward_data *f = _forwarder; - databuf *new; - - new = malloc(sizeof(*new)); if (new == NULL) abort(); - - if (pthread_mutex_lock(&f->datalock)) abort(); - - new->d = malloc(size); if (new->d == NULL) abort(); - memcpy(new->d, buf, size); - new->l = size; - new->next = NULL; - if (f->head == NULL) f->head = new; - f->tail = new; - - if (pthread_cond_signal(&f->datacond)) abort(); - if (pthread_mutex_unlock(&f->datalock)) abort(); -} diff --git a/common/utils/T/tracer/local.c b/common/utils/T/local_tracer.c similarity index 88% rename from common/utils/T/tracer/local.c rename to common/utils/T/local_tracer.c index 2550a02549..f61df5a483 100644 --- a/common/utils/T/tracer/local.c +++ b/common/utils/T/local_tracer.c @@ -10,9 +10,7 @@ #include #include -#define DEFAULT_PORT 2021 - -#include "../T_defs.h" +#include "T_defs.h" static T_cache_t *T_cache; static int T_busylist_head; @@ -165,8 +163,6 @@ static void *forwarder(int port, int s) f->socket_remote = get_connection("127.0.0.1", port); - printf("connected\n"); - new_thread(data_sender, f); new_thread(forward_remote_messages, f); @@ -239,38 +235,16 @@ static void init_shm(void) for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0; } -static void usage(void) -{ - printf( -"tracer - local side\n" -"options:\n" -" -p wait for remote tracer on port (default %d)\n" -" -nowait don't wait for remote tracer, start tracee immediately\n", - DEFAULT_PORT - ); - exit(1); -} - -int main(int n, char **v) +void T_local_tracer_main(int remote_port, int wait_for_tracer, + int local_socket) { int s; - int i; - int port = DEFAULT_PORT; - int local_port = 2020; - int dont_wait = 0; + int port = remote_port; + int dont_wait = wait_for_tracer ? 0 : 1; void *f; - for (i = 1; i < n; i++) { - if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); - port = atoi(v[++i]); continue; } - if (!strcmp(v[i], "-nowait")) { dont_wait = 1; continue; } - printf("ERROR: unknown option %s\n", v[i]); - usage(); - } - init_shm(); - s = get_connection("127.0.0.1", local_port); + s = local_socket; if (dont_wait) { char t = 2; @@ -289,5 +263,4 @@ int main(int n, char **v) T_busylist_head++; T_busylist_head &= T_CACHE_SIZE - 1; } - return 0; } diff --git a/common/utils/T/main.c b/common/utils/T/main.c deleted file mode 100644 index 3552f19df5..0000000000 --- a/common/utils/T/main.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "T.h" -#include -#include -#include -#include -#include - -int main(void) -{ - T_connect_to_tracer("127.0.0.1", 2020); - printf("after connect\n"); - while (1) { - char *buf = "hello world %s!\n"; - //T(T_first, T_PRINTF("hello world %s!\n", "yo")); - T(T_buf_test, T_BUFFER("hello world %s!\n", strlen(buf)+1)); - usleep(1); - } - while (1) pause(); - - return 0; -} diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 5044c2e8b3..e9d9b99da7 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -1,11 +1,40 @@ -all: local remote +CC=gcc +CFLAGS=-Wall -g -pthread -DT_TRACER -I. -local: - make -f Makefile.local +#CFLAGS += -O3 -ffast-math -fomit-frame-pointer -remote: - make -f Makefile.remote textlog enb vcd +LIBS=-lX11 -lm -lpng -lXft + +all: textlog enb vcd + +textlog: utils.o textlog.o database.o event.o handler.o config.o \ + event_selector.o view/view.a gui/gui.a logger/logger.a + $(CC) $(CFLAGS) -o textlog $^ $(LIBS) + +enb: utils.o enb.o database.o event.o handler.o config.o \ + event_selector.o view/view.a gui/gui.a logger/logger.a + $(CC) $(CFLAGS) -o enb $^ $(LIBS) + +vcd: utils.o vcd.o database.o event.o handler.o config.o \ + event_selector.o view/view.a gui/gui.a logger/logger.a + $(CC) $(CFLAGS) -o vcd $^ $(LIBS) + +.PHONY: all gui/gui.a view/view.a logger/logger.a + +gui/gui.a: + cd gui && make + +view/view.a: + cd view && make + +logger/logger.a: + cd logger && make + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< clean: - make -f Makefile.local clean - make -f Makefile.remote clean + rm -f *.o core tracer_remote textlog enb vcd + cd gui && make clean + cd view && make clean + cd logger && make clean diff --git a/common/utils/T/tracer/Makefile.local b/common/utils/T/tracer/Makefile.local deleted file mode 100644 index 4e971fc627..0000000000 --- a/common/utils/T/tracer/Makefile.local +++ /dev/null @@ -1,18 +0,0 @@ -CC=gcc -CFLAGS=-Wall -g -pthread -DT_TRACER - -#CFLAGS += -O3 -ffast-math -fomit-frame-pointer - -LIBS += -lrt - -PROG=tracer_local -OBJS=local.o - -$(PROG): $(OBJS) - $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -clean: - rm -f *.o $(PROG) core diff --git a/common/utils/T/tracer/Makefile.remote b/common/utils/T/tracer/Makefile.remote deleted file mode 100644 index b2663f8651..0000000000 --- a/common/utils/T/tracer/Makefile.remote +++ /dev/null @@ -1,38 +0,0 @@ -CC=gcc -CFLAGS=-Wall -g -pthread -DT_TRACER -I. - -#CFLAGS += -O3 -ffast-math -fomit-frame-pointer - -LIBS=-lX11 -lm -lpng -lXft - -textlog: utils.o textlog.o database.o event.o handler.o config.o \ - event_selector.o view/view.a gui/gui.a logger/logger.a - $(CC) $(CFLAGS) -o textlog $^ $(LIBS) - -enb: utils.o enb.o database.o event.o handler.o config.o \ - event_selector.o view/view.a gui/gui.a logger/logger.a - $(CC) $(CFLAGS) -o enb $^ $(LIBS) - -vcd: utils.o vcd.o database.o event.o handler.o config.o \ - event_selector.o view/view.a gui/gui.a logger/logger.a - $(CC) $(CFLAGS) -o vcd $^ $(LIBS) - -.PHONY: gui/gui.a view/view.a logger/logger.a - -gui/gui.a: - cd gui && make - -view/view.a: - cd view && make - -logger/logger.a: - cd logger && make - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -clean: - rm -f *.o core tracer_remote textlog enb vcd - cd gui && make clean - cd view && make clean - cd logger && make clean diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index c3700c9da9..30b1c20bc8 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -250,6 +250,10 @@ help (void) printf ("-Y Set the global log verbosity (none, low, medium, high, full) \n"); printf ("-z Set the cooperation flag (0 for no cooperation, 1 for delay diversity and 2 for distributed alamouti\n"); printf ("-Z Reserved\n"); +#if T_TRACER + printf ("--T_port [port] use given port\n"); + printf ("--T_nowait don't wait for tracer, start immediately\n"); +#endif } pthread_t log_thread; @@ -1252,6 +1256,11 @@ l2l1_task (void *args_p) return NULL; } +#if T_TRACER +int T_wait = 1; /* by default we wait for the tracer */ +int T_port = 2021; /* default port to listen to to wait for the tracer */ +#endif + /*------------------------------------------------------------------------------*/ int main (int argc, char **argv) @@ -1269,13 +1278,6 @@ main (int argc, char **argv) int port,Process_Flag=0,wgt,Channel_Flag=0,temp; #endif -#if T_TRACER - char *T_ip = "127.0.0.1"; - int T_port = 2020; - printf("connecting to T tracer IP %s port %d\n", T_ip, T_port); - T_connect_to_tracer(T_ip, T_port); -#endif - //default parameters oai_emulation.info.n_frames = 0xffff; //1024; //10; oai_emulation.info.n_frames_flag = 0; //fixme @@ -1292,6 +1294,10 @@ main (int argc, char **argv) // get command-line options get_simulation_options (argc, argv); //Command-line options +#if T_TRACER + T_init(T_port, T_wait); +#endif + // Initialize VCD LOG module VCD_SIGNAL_DUMPER_INIT (oai_emulation.info.vcd_file); diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 014a9e39d0..9927cba293 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -213,6 +213,11 @@ void get_simulation_options(int argc, char *argv[]) LONG_OPTION_PHYTEST, LONG_OPTION_XFORMS, + +#if T_TRACER + LONG_OPTION_T_PORT, + LONG_OPTION_T_NOWAIT, +#endif }; static struct option long_options[] = { @@ -247,6 +252,11 @@ void get_simulation_options(int argc, char *argv[]) {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, {"xforms", no_argument, 0, LONG_OPTION_XFORMS}, +#if T_TRACER + {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, + {"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT}, +#endif + {NULL, 0, NULL, 0} }; @@ -414,6 +424,21 @@ void get_simulation_options(int argc, char *argv[]) xforms=1; break; +#if T_TRACER + case LONG_OPTION_T_PORT: { + extern int T_port; + if (optarg == NULL) abort(); /* should not happen */ + T_port = atoi(optarg); + break; + } + + case LONG_OPTION_T_NOWAIT: { + extern int T_wait; + T_wait = 0; + break; + } +#endif + case 'a': abstraction_flag = 1; break; From 2966fae4a5c010beb6ed391cccc2ea424b9183df Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 1 Jun 2016 16:15:55 +0200 Subject: [PATCH 181/217] update lte-softmodem to deal with the locally integrated tracer --- targets/RT/USER/lte-softmodem.c | 53 ++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 67ee981100..21ebb0f55a 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -490,8 +490,13 @@ void help (void) { printf(" -U Set the lte softmodem as a UE\n"); printf(" -W Enable L2 wireshark messages on localhost \n"); printf(" -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"); - printf(" -x Set the transmission mode, valid options: 1 \n"RESET); - + printf(" -x Set the transmission mode, valid options: 1 \n"); +#if T_TRACER + printf(" --T_port [port] use given port\n"); + printf(" --T_nowait don't wait for tracer, start immediately\n"); +#endif + printf(RESET); + fflush(stdout); } void exit_fun(const char* s) { @@ -2123,7 +2128,12 @@ static void get_options (int argc, char **argv) LONG_OPTION_MAXPOWER, LONG_OPTION_DUMP_FRAME, LONG_OPTION_LOOPMEMORY, - LONG_OPTION_PHYTEST + LONG_OPTION_PHYTEST, + +#if T_TRACER + LONG_OPTION_T_PORT, + LONG_OPTION_T_NOWAIT, +#endif }; static const struct option long_options[] = { @@ -2142,6 +2152,12 @@ static void get_options (int argc, char **argv) {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME}, {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY}, {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, + +#if T_TRACER + {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, + {"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT}, +#endif + {NULL, 0, NULL, 0} }; @@ -2229,6 +2245,21 @@ static void get_options (int argc, char **argv) phy_test = 1; break; +#if T_TRACER + case LONG_OPTION_T_PORT: { + extern int T_port; + if (optarg == NULL) abort(); /* should not happen */ + T_port = atoi(optarg); + break; + } + + case LONG_OPTION_T_NOWAIT: { + extern int T_wait; + T_wait = 0; + break; + } +#endif + case 'A': timing_advance = atoi (optarg); break; @@ -2589,6 +2620,11 @@ static void get_options (int argc, char **argv) } } +#if T_TRACER +int T_wait = 1; /* by default we wait for the tracer */ +int T_port = 2021; /* default port to listen to to wait for the tracer */ +#endif + int main( int argc, char **argv ) { int i,aa,card=0; @@ -2619,13 +2655,6 @@ int main( int argc, char **argv ) PHY_VARS_UE *UE[MAX_NUM_CCs]; -#if T_TRACER - char *T_ip = "127.0.0.1"; - int T_port = 2020; - printf("connecting to T tracer IP %s port %d\n", T_ip, T_port); - T_connect_to_tracer(T_ip, T_port); -#endif - mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); @@ -2665,6 +2694,10 @@ int main( int argc, char **argv ) else openair0_cfg[0].configFilename = rf_config_file; +#if T_TRACER + T_init(T_port, T_wait); +#endif + // initialize the log (see log.h for details) set_glog(glog_level, glog_verbosity); From 2219fe54ef58c9f28428bca2d966fb29c9117f0c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 1 Jun 2016 17:18:57 +0200 Subject: [PATCH 182/217] the tracer can now stop its tracing without disturbing the tracee it's buggy. Next commit to fix it. The problem is if the tracer exits while sending a message. The local tracer will not get it full and will throw garbage to the T in the tracee, leading to some bad things... --- common/utils/T/local_tracer.c | 45 +++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index f61df5a483..fb4cbd9a3e 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -11,6 +11,7 @@ #include #include "T_defs.h" +#include "T_IDs.h" static T_cache_t *T_cache; static int T_busylist_head; @@ -23,7 +24,8 @@ typedef struct databuf { typedef struct { int socket_local; - int socket_remote; + volatile int socket_remote; + int remote_port; pthread_mutex_t lock; pthread_cond_t cond; databuf * volatile head, *tail; @@ -109,9 +111,15 @@ wait: process: b = buf; + if (f->socket_remote != -1) while (size) { int l = write(f->socket_remote, b, size); - if (l <= 0) { printf("forward error\n"); exit(1); } + if (l <= 0) { + printf("forward error\n"); + close(f->socket_remote); + f->socket_remote = -1; + break; + } size -= l; b += l; } @@ -124,23 +132,49 @@ process: static void *forward_remote_messages(void *_f) { forward_data *f = _f; - int from = f->socket_remote; - int to = f->socket_local; + int from; + int to; int l, len; char *b; char buf[1024]; + +again: + + /* Note: if the remote socket dies while a transfer is running + * then the state of the tracer will be totally messed up. + * If that ever happens, things are messed up anyway, so no big + * deal... (TODO: to be refined at some point, maybe) + */ while (1) { + from = f->socket_remote; + to = f->socket_local; len = read(from, buf, 1024); if (len <= 0) break; b = buf; while (len) { l = write(to, b, len); - if (l <= 0) break; + if (l <= 0) abort(); len -= l; b += l; } } + + /* socket died, let's stop all traces and wait for another tracer */ + buf[0] = 1; + if (write(to, buf, 1) != 1) abort(); + len = T_NUMBER_OF_IDS; + if (write(to, &len, sizeof(int)) != sizeof(int)) abort(); + l = 0; + while (len) { + if (write(to, &l, sizeof(int)) != sizeof(int)) abort(); + len--; + }; + + close(f->socket_remote); + f->socket_remote = get_connection("127.0.0.1", f->remote_port); + goto again; + return NULL; } @@ -161,6 +195,7 @@ static void *forwarder(int port, int s) printf("waiting for remote tracer on port %d\n", port); + f->remote_port = port; f->socket_remote = get_connection("127.0.0.1", port); new_thread(data_sender, f); From 2cb4d347d04242be04383433771626bd8ca26129 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 1 Jun 2016 17:44:53 +0200 Subject: [PATCH 183/217] make the local tracer more robust if a read from the remote tracer's socket fails, let's smash the socket and wait for another remote tracer --- common/utils/T/local_tracer.c | 58 +++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index fb4cbd9a3e..c7247e980b 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -131,35 +131,69 @@ process: static void *forward_remote_messages(void *_f) { +#define PUT(x) do { \ + if (bufsize == bufmaxsize) { \ + bufmaxsize += 4096; \ + buf = realloc(buf, bufmaxsize); \ + if (buf == NULL) abort(); \ + } \ + buf[bufsize] = x; \ + bufsize++; \ + } while (0) +#define PUT_BUF(x, l) do { \ + char *zz = (char *)(x); \ + int len = l; \ + while (len) { PUT(*zz); zz++; len--; } \ + } while (0) + forward_data *f = _f; int from; int to; int l, len; char *b; - char buf[1024]; + char *buf = NULL; + int bufsize = 0; + int bufmaxsize = 0; + char t; again: - /* Note: if the remote socket dies while a transfer is running - * then the state of the tracer will be totally messed up. - * If that ever happens, things are messed up anyway, so no big - * deal... (TODO: to be refined at some point, maybe) - */ while (1) { from = f->socket_remote; to = f->socket_local; - len = read(from, buf, 1024); - if (len <= 0) break; - b = buf; - while (len) { - l = write(to, b, len); + bufsize = 0; + + /* let's read and process messages */ + len = read(from, &t, 1); if (len <= 0) goto dead; + PUT(t); + + switch (t) { + case 0: + case 1: + /* message 0 and 1: get a length and then 'length' numbers */ + if (read(from, &len, sizeof(int)) != sizeof(int)) goto dead; + PUT_BUF(&len, 4); + while (len) { + if (read(from, &l, sizeof(int)) != sizeof(int)) goto dead; + PUT_BUF(&l, 4); + len--; + } + break; + + case 2: break; + } + + b = buf; + while (bufsize) { + l = write(to, b, bufsize); if (l <= 0) abort(); - len -= l; + bufsize -= l; b += l; } } +dead: /* socket died, let's stop all traces and wait for another tracer */ buf[0] = 1; if (write(to, buf, 1) != 1) abort(); From fb6746537af9e2e9a9e7941a3d75af0de32aaa43 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 2 Jun 2016 12:38:33 +0200 Subject: [PATCH 184/217] bugfix: include T.h or compilation fails when T unused (the T macro is then undefined) --- openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c | 1 + openair1/PHY/LTE_TRANSPORT/pucch.c | 2 ++ openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c | 2 ++ openair1/SCHED/phy_procedures_lte_eNb.c | 2 ++ openair2/RRC/LITE/rrc_eNB.c | 2 ++ 5 files changed, 9 insertions(+) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index f17c69c5f3..74b6e8cfbb 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -31,6 +31,7 @@ #include "PHY/sse_intrin.h" //#define DEBUG_CH +#include "T.h" // For Channel Estimation in Distributed Alamouti Scheme //static int16_t temp_out_ifft[2048*4] __attribute__((aligned(16))); diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 51b13c82c5..d0d914ef73 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -41,6 +41,8 @@ #include "PHY/extern.h" #include "LAYER2/MAC/extern.h" +#include "T.h" + //uint8_t ncs_cell[20][7]; //#define DEBUG_PUCCH_TX //#define DEBUG_PUCCH_RX diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 5a0115a24b..106181dfc8 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -47,6 +47,8 @@ //#define DEBUG_ULSCH #include "PHY/sse_intrin.h" +#include "T.h" + //extern char* namepointer_chMag ; //eren //extern int **ulchmag_eren; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index e251bddbee..e8c2e87414 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -60,6 +60,8 @@ #include "assertions.h" #include "msc.h" +#include "T.h" + #if defined(ENABLE_ITTI) # include "intertask_interface.h" # if ENABLE_RAL diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 0db8fe9960..87e65987b9 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -63,6 +63,8 @@ #include "platform_types.h" #include "msc.h" +#include "T.h" + //#ifdef Rel10 #include "MeasResults.h" //#endif From 91e57c8a793acbbc7951d5f75648b2c8ba7a05b3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 2 Jun 2016 12:39:56 +0200 Subject: [PATCH 185/217] fully integrate the T into build_oai/CMake The unit simulators may still need some checks. --- cmake_targets/CMakeLists.txt | 67 +++++++++++++++++++++++++++++------- cmake_targets/build_oai | 11 ++++++ 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6a053451c5..faf602caf1 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -212,6 +212,7 @@ add_boolean_option(TEST_OMG False "???") add_boolean_option(DEBUG_OMG False "???") add_boolean_option(XFORMS False "This adds the possibility to see the signal oscilloscope") add_boolean_option(PRINT_STATS False "This adds the possibility to see the status") +add_boolean_option(T_TRACER False "Activate the T tracer, a debugging/monitoring framework" ) add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") @@ -1484,13 +1485,36 @@ endif (${XFORMS}) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") -#add the T tracer -add_boolean_option(T_TRACER True "Activate the T tracer" ) +#include T directory even if the T is off because T macros are in the code +#no matter what include_directories("${OPENAIR_DIR}/common/utils/T") -set(T_SOURCE - ${OPENAIR_DIR}/common/utils/T/T.c - ${OPENAIR_DIR}/common/utils/T/local_tracer.c) -set (T_LIB "-lrt") + +if (${T_TRACER}) + set(T_SOURCE + ${OPENAIR_DIR}/common/utils/T/T.c + ${OPENAIR_DIR}/common/utils/T/local_tracer.c) + set (T_LIB "rt") +endif (${T_TRACER}) + +#Some files in the T directory are generated. +#This rule and the following deal with it. +add_custom_command ( + OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h + COMMAND make + WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T + DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt + ) + +#This rule is specifically needed to generate T files +#before anything else in a project that uses the T. +#See below, there are some 'add_dependencies' showing that. +#Basically we create a custom target and we make other +#targets depend on it. That forces cmake to generate +#T files before anything else. +add_custom_target ( + generate_T + DEPENDS ${OPENAIR_DIR}/common/utils/T/T_IDs.h +) # Hack on a test of asn1c version (already dirty) add_definitions(-DASN1_MINIMUM_VERSION=924) @@ -1536,7 +1560,6 @@ target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} ) target_link_libraries (lte-softmodem ${LIBBOOST_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) - target_link_libraries (lte-softmodem ${T_LIB}) # lte-softmodem-nos1 is both eNB and UE implementation @@ -1573,7 +1596,6 @@ target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} ) target_link_libraries (lte-softmodem-nos1 ${LIBBOOST_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) - target_link_libraries (lte-softmodem ${T_LIB}) # rrh @@ -1587,6 +1609,7 @@ add_executable(rrh_gw ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${HW_SOURCE} ${TRANSPORT_SOURCE} + ${T_SOURCE} ) target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti) target_link_libraries(rrh_gw @@ -1596,6 +1619,7 @@ target_link_libraries(rrh_gw target_link_libraries (rrh_gw rt pthread m ) target_link_libraries (rrh_gw ${option_HW_lib} ${option_TP_lib} ${LIBBOOST_LIBRARIES} ) target_link_libraries (rrh_gw ${LIB_LMS_LIBRARIES}) +target_link_libraries (rrh_gw ${T_LIB}) Message("-- option_HW_lib=${option_HW_lib}") Message("-- HW_SOURCE=${HW_SOURCE}") @@ -1661,6 +1685,7 @@ add_executable(oaisim ${HW_SOURCE} ${TRANSPORT_SOURCE} ${XFORMS_SOURCE} + ${T_SOURCE} ) @@ -1675,6 +1700,7 @@ target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LI ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim forms) +target_link_libraries (oaisim ${T_LIB}) @@ -1713,8 +1739,7 @@ target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYP ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim_nos1 forms) - -target_link_libraries (lte-softmodem ${T_LIB}) +target_link_libraries (oaisim_nos1 ${T_LIB}) # Unitary tests for each piece of L1: example, mbmssim is MBMS L1 simulator ##################################### @@ -1724,10 +1749,11 @@ foreach(myExe dlsim ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syn ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c ${XFORMS_SOURCE} + ${T_SOURCE} ) target_link_libraries (${myExe} -Wl,--start-group SIMU UTIL SCHED_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} + pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} ) endforeach(myExe) @@ -1770,8 +1796,23 @@ endforeach(myExe) #../targets/TEST/PDCP/test_pdcp.c #../targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c - - +#ensure that the T header files are generated before targets depending on them +if (${T_TRACER}) + add_dependencies(lte-softmodem generate_T) + add_dependencies(lte-softmodem-nos1 generate_T) + add_dependencies(rrh_gw generate_T) + add_dependencies(oaisim generate_T) + add_dependencies(oaisim_nos1 generate_T) + add_dependencies(dlsim generate_T) + add_dependencies(ulsim generate_T) + add_dependencies(pbchsim generate_T) + add_dependencies(scansim generate_T) + add_dependencies(mbmssim generate_T) + add_dependencies(pdcchsim generate_T) + add_dependencies(pucchsim generate_T) + add_dependencies(prachsim generate_T) + add_dependencies(syncsim generate_T) +endif (${T_TRACER}) ################################################## # Generated specific cases is not regular code diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 821b3bca27..a198e8cf67 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -57,6 +57,7 @@ CFLAGS_PROCESSOR_USER="" RUN_GROUP=0 TEST_CASE_GROUP="" BUILD_DOXYGEN=0 +T_TRACER="False" trap handle_ctrl_c INT function print_help() { @@ -125,6 +126,8 @@ Options Disables deadline scheduler of Linux kernel (>=3.14.x). --enable-deadline Disables deadline scheduler of Linux kernel (>=3.14.x). +--T-tracer + Enables the T tracer. Usage (first build): oaisim (eNB + UE): ./build_oai -I -g --oaisim -x --install-system-files Eurecom EXMIMO + COTS UE : ./build_oai -I -g --eNB -x --install-system-files @@ -263,6 +266,10 @@ function main() { FORCE_LOWLATENCY_FLAG_USER="True" echo_info "Enabling the usage of deadline scheduler" shift 1;; + --T-tracer) + T_TRACER="True" + echo_info "Enabling the T tracer" + shift 1;; -h | --help) print_help exit 1;; @@ -421,6 +428,7 @@ function main() { echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file echo "set(PACKAGE_NAME \"${lte_exec}\")" >> $cmake_file echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file + echo "set ( T_TRACER $T_TRACER )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$lte_build_dir/build cmake .. @@ -549,6 +557,7 @@ function main() { echo "set ( PRINT_STATS $PRINT_STATS )" >> $cmake_file echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file + echo "set ( T_TRACER $T_TRACER )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file [ "$CLEAN" = "1" ] && rm -rf $DIR/$oaisim_build_dir/build mkdir -p $DIR/$oaisim_build_dir/build @@ -614,6 +623,7 @@ function main() { echo "set(XFORMS $XFORMS )" >> $cmake_file echo "set(RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file + echo "set ( T_TRACER $T_TRACER )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file #[ "$CLEAN" = "1" ] && rm -rf $DIR/oaisim_mme_build_oai/build #mkdir -p $DIR/oaisim_mme_build_oai/build @@ -643,6 +653,7 @@ function main() { echo "set(TRANSP_PRO \"${TP}\")" >> $cmake_file echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file + echo "set ( T_TRACER $T_TRACER )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$rrh_build_dir/build cmake .. From a9d91337c0d95ed454178cc6e6d9831ff60a31a4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 4 Jun 2016 22:41:14 +0200 Subject: [PATCH 186/217] bugfix: local tracer to accept connection from everywhere --- common/utils/T/local_tracer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index c7247e980b..5d46d2d38d 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -206,7 +206,7 @@ dead: }; close(f->socket_remote); - f->socket_remote = get_connection("127.0.0.1", f->remote_port); + f->socket_remote = get_connection("0.0.0.0", f->remote_port); goto again; return NULL; @@ -230,7 +230,7 @@ static void *forwarder(int port, int s) printf("waiting for remote tracer on port %d\n", port); f->remote_port = port; - f->socket_remote = get_connection("127.0.0.1", port); + f->socket_remote = get_connection("0.0.0.0", port); new_thread(data_sender, f); new_thread(forward_remote_messages, f); From daf9f16b9b4c18953ddbcd8f08c31553b631ec43 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 4 Jun 2016 23:23:19 +0200 Subject: [PATCH 187/217] minor: gui/image.c did include string.h --- common/utils/T/tracer/gui/image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/utils/T/tracer/gui/image.c b/common/utils/T/tracer/gui/image.c index 64d305747e..df9a7b8296 100644 --- a/common/utils/T/tracer/gui/image.c +++ b/common/utils/T/tracer/gui/image.c @@ -3,6 +3,7 @@ #include "x.h" #include #include +#include #include static void paint(gui *_gui, widget *_w) From 51292c247228d5ae0c961bd603153ab73495b5d4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 4 Jun 2016 23:48:03 +0200 Subject: [PATCH 188/217] event_selector does not deal with socket anymore It was wrong. Plus it is starting work so as to make enb.c not crashing if the tracee goes away (maybe also textlog and vcd, but those are of less importance). --- common/utils/T/tracer/enb.c | 52 +++++++++++++++++-------- common/utils/T/tracer/event_selector.c | 36 ++++++++--------- common/utils/T/tracer/event_selector.h | 4 +- common/utils/T/tracer/textlog.c | 54 ++++++++++++++++++-------- common/utils/T/tracer/vcd.c | 52 +++++++++++++++++-------- 5 files changed, 128 insertions(+), 70 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index c80fd9bda3..eeaa0ff31f 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "database.h" #include "event.h" #include "handler.h" @@ -19,9 +19,34 @@ typedef struct { view *legacy; } enb_gui; +typedef struct { + int socket; + int *is_on; + int nevents; + pthread_mutex_t lock; +} enb_data; + #define DEFAULT_REMOTE_IP "127.0.0.1" #define DEFAULT_REMOTE_PORT 2021 +void is_on_changed(void *_d) +{ + enb_data *d = _d; + char t; + + if (pthread_mutex_lock(&d->lock)) abort(); + + if (d->socket == -1) goto no_connection; + + t = 1; + socket_send(d->socket, &t, 1); + socket_send(d->socket, &d->nevents, sizeof(int)); + socket_send(d->socket, d->is_on, d->nevents * sizeof(int)); + +no_connection: + if (pthread_mutex_unlock(&d->lock)) abort(); +} + void usage(void) { printf( @@ -214,13 +239,11 @@ int main(int n, char **v) int on_off_n = 0; int *is_on; int number_of_events; - int s; int i; - char t; - int l; event_handler *h; gui *g; enb_gui eg; + enb_data enb_data; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -346,25 +369,22 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = connect_to(ip, port); + enb_data.socket = -1; + enb_data.is_on = is_on; + enb_data.nevents = number_of_events; + if (pthread_mutex_init(&enb_data.lock, NULL)) abort(); + setup_event_selector(g, database, is_on, is_on_changed, &enb_data); + + enb_data.socket = connect_to(ip, port); /* send the first message - activate selected traces */ - t = 0; - if (write(s, &t, 1) != 1) abort(); - l = 0; - for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - for (l = 0; l < number_of_events; l++) - if (is_on[l]) - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - - setup_event_selector(g, database, s, is_on); + is_on_changed(&enb_data); /* read messages */ while (1) { char v[T_BUFFER_MAX]; event e; - e = get_event(s, v, database); + e = get_event(enb_data.socket, v, database); handle_event(h, e); } diff --git a/common/utils/T/tracer/event_selector.c b/common/utils/T/tracer/event_selector.c index bc1f25f4b7..a03846c056 100644 --- a/common/utils/T/tracer/event_selector.c +++ b/common/utils/T/tracer/event_selector.c @@ -7,6 +7,8 @@ struct event_selector { int *is_on; + int *is_on_paused; /* when pausing, is_on is set to all 0, this one + * is used to copy back data when un-pausing */ int red; int green; gui *g; @@ -15,12 +17,13 @@ struct event_selector { void *database; int nevents; int ngroups; - int socket; int paused; /* those three widgets used to pause/unpause reception of events */ widget *parent_widget; widget *normal_widget; widget *pause_widget; + void (*change_callback)(void *change_callback_data); + void *change_callback_data; }; static void scroll(void *private, gui *g, @@ -57,7 +60,6 @@ static void click(void *private, gui *g, char *text; int color; int i; - char t; /* notification_data depends on the kind of widget */ if (w == this->pause_widget) { @@ -76,22 +78,17 @@ static void click(void *private, gui *g, container_set_child_growable(g, this->parent_widget, this->pause_widget, 1); /* pause */ - t = 1; - socket_send(this->socket, &t, 1); - socket_send(this->socket, &this->nevents, sizeof(int)); - set_on = 0; - for (i = 0; i < this->nevents; i++) - socket_send(this->socket, &set_on, sizeof(int)); + memcpy(this->is_on_paused, this->is_on, this->nevents * sizeof(int)); + memset(this->is_on, 0, this->nevents * sizeof(int)); + this->change_callback(this->change_callback_data); } else { widget_del_child(g, this->parent_widget, this->pause_widget); widget_add_child(g, this->parent_widget, this->normal_widget, 0); container_set_child_growable(g, this->parent_widget, this->normal_widget, 1); /* un-pause */ - t = 1; - socket_send(this->socket, &t, 1); - socket_send(this->socket, &this->nevents, sizeof(int)); - socket_send(this->socket, this->is_on, this->nevents * sizeof(int)); + memcpy(this->is_on, this->is_on_paused, this->nevents * sizeof(int)); + this->change_callback(this->change_callback_data); } this->paused = 1 - this->paused; return; @@ -121,14 +118,11 @@ static void click(void *private, gui *g, textlist_set_color(this->g, this->groups, line, set_on ? this->green : this->red); - t = 1; - socket_send(this->socket, &t, 1); - socket_send(this->socket, &this->nevents, sizeof(int)); - socket_send(this->socket, this->is_on, this->nevents * sizeof(int)); + this->change_callback(this->change_callback_data); } -event_selector *setup_event_selector(gui *g, void *database, int socket, - int *is_on) +event_selector *setup_event_selector(gui *g, void *database, int *is_on, + void (*change_callback)(void *), void *change_callback_data) { struct event_selector *ret; widget *win; @@ -198,6 +192,9 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, ret->nevents = n; + ret->is_on_paused = calloc(n, sizeof(int)); + if (ret->is_on_paused == NULL) abort(); + n = database_get_groups(database, &gps); for (i = 0; i < n; i++) { textlist_add(g, groups, gps[i], -1, FOREGROUND_COLOR); @@ -213,7 +210,8 @@ event_selector *setup_event_selector(gui *g, void *database, int socket, ret->events = events; ret->groups = groups; ret->database = database; - ret->socket = socket; + ret->change_callback = change_callback; + ret->change_callback_data = change_callback_data; ret->parent_widget = win_container; ret->normal_widget = main_container; diff --git a/common/utils/T/tracer/event_selector.h b/common/utils/T/tracer/event_selector.h index 60da0a07e5..dedd79965c 100644 --- a/common/utils/T/tracer/event_selector.h +++ b/common/utils/T/tracer/event_selector.h @@ -5,7 +5,7 @@ typedef void event_selector; -event_selector *setup_event_selector(gui *g, void *database, int socket, - int *is_on); +event_selector *setup_event_selector(gui *g, void *database, int *is_on, + void (*change_callback)(void *), void *change_callback_data); #endif /* _EVENT_SELECTOR_H_ */ diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 6ff36f650c..f7bde62a43 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "database.h" #include "event.h" #include "handler.h" @@ -16,6 +16,31 @@ #define DEFAULT_REMOTE_IP "127.0.0.1" #define DEFAULT_REMOTE_PORT 2021 +typedef struct { + int socket; + int *is_on; + int nevents; + pthread_mutex_t lock; +} textlog_data; + +void is_on_changed(void *_d) +{ + textlog_data *d = _d; + char t; + + if (pthread_mutex_lock(&d->lock)) abort(); + + if (d->socket == -1) goto no_connection; + + t = 1; + socket_send(d->socket, &t, 1); + socket_send(d->socket, &d->nevents, sizeof(int)); + socket_send(d->socket, d->is_on, d->nevents * sizeof(int)); + +no_connection: + if (pthread_mutex_unlock(&d->lock)) abort(); +} + void usage(void) { printf( @@ -58,16 +83,14 @@ int main(int n, char **v) int on_off_n = 0; int *is_on; int number_of_events; - int s; int i; - char t; - int l; event_handler *h; logger *textlog; gui *g; int gui_mode = 0; view *out; int gui_active = 1; + textlog_data textlog_data; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -141,26 +164,23 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = connect_to(ip, port); + textlog_data.socket = -1; + textlog_data.is_on = is_on; + textlog_data.nevents = number_of_events; + if (pthread_mutex_init(&textlog_data.lock, NULL)) abort(); + if (gui_active) + setup_event_selector(g, database, is_on, is_on_changed, &textlog_data); + + textlog_data.socket = connect_to(ip, port); /* send the first message - activate selected traces */ - t = 0; - if (write(s, &t, 1) != 1) abort(); - l = 0; - for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - for (l = 0; l < number_of_events; l++) - if (is_on[l]) - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - - if (gui_active) - setup_event_selector(g, database, s, is_on); + is_on_changed(&textlog_data); /* read messages */ while (1) { char v[T_BUFFER_MAX]; event e; - e = get_event(s, v, database); + e = get_event(textlog_data.socket, v, database); handle_event(h, e); } diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index bf66bddd29..46187f751b 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "database.h" #include "event.h" #include "handler.h" @@ -13,6 +13,31 @@ #include "event_selector.h" #include "config.h" +typedef struct { + int socket; + int *is_on; + int nevents; + pthread_mutex_t lock; +} vcd_data; + +void is_on_changed(void *_d) +{ + vcd_data *d = _d; + char t; + + if (pthread_mutex_lock(&d->lock)) abort(); + + if (d->socket == -1) goto no_connection; + + t = 1; + socket_send(d->socket, &t, 1); + socket_send(d->socket, &d->nevents, sizeof(int)); + socket_send(d->socket, d->is_on, d->nevents * sizeof(int)); + +no_connection: + if (pthread_mutex_unlock(&d->lock)) abort(); +} + #define DEFAULT_REMOTE_IP "127.0.0.1" #define DEFAULT_REMOTE_PORT 2021 @@ -98,12 +123,10 @@ int main(int n, char **v) int on_off_n = 0; int *is_on; int number_of_events; - int s; int i; - char t; - int l; event_handler *h; gui *g; + vcd_data vcd_data; on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); @@ -152,25 +175,22 @@ int main(int n, char **v) for (i = 0; i < on_off_n; i++) on_off(database, on_off_name[i], is_on, on_off_action[i]); - s = connect_to(ip, port); + vcd_data.socket = -1; + vcd_data.is_on = is_on; + vcd_data.nevents = number_of_events; + if (pthread_mutex_init(&vcd_data.lock, NULL)) abort(); + setup_event_selector(g, database, is_on, is_on_changed, &vcd_data); + + vcd_data.socket = connect_to(ip, port); /* send the first message - activate selected traces */ - t = 0; - if (write(s, &t, 1) != 1) abort(); - l = 0; - for (i = 0; i < number_of_events; i++) if (is_on[i]) l++; - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - for (l = 0; l < number_of_events; l++) - if (is_on[l]) - if (write(s, &l, sizeof(int)) != sizeof(int)) abort(); - - setup_event_selector(g, database, s, is_on); + is_on_changed(&vcd_data); /* read messages */ while (1) { char v[T_BUFFER_MAX]; event e; - e = get_event(s, v, database); + e = get_event(vcd_data.socket, v, database); handle_event(h, e); } From 9338f06e900a459cbd5f33fe5e45234f5e541bbd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 5 Jun 2016 13:10:52 +0200 Subject: [PATCH 189/217] socket_send does not crash anymore but returns an error The application (enb.c basically) will now monitor the socket and reconnect if it dies. See following commits. --- common/utils/T/tracer/enb.c | 7 ++++--- common/utils/T/tracer/textlog.c | 7 ++++--- common/utils/T/tracer/utils.c | 5 +++-- common/utils/T/tracer/utils.h | 3 ++- common/utils/T/tracer/vcd.c | 7 ++++--- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index eeaa0ff31f..1d97b428d3 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -39,9 +39,10 @@ void is_on_changed(void *_d) if (d->socket == -1) goto no_connection; t = 1; - socket_send(d->socket, &t, 1); - socket_send(d->socket, &d->nevents, sizeof(int)); - socket_send(d->socket, d->is_on, d->nevents * sizeof(int)); + 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) + abort(); no_connection: if (pthread_mutex_unlock(&d->lock)) abort(); diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index f7bde62a43..362ff8103e 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -33,9 +33,10 @@ void is_on_changed(void *_d) if (d->socket == -1) goto no_connection; t = 1; - socket_send(d->socket, &t, 1); - socket_send(d->socket, &d->nevents, sizeof(int)); - socket_send(d->socket, d->is_on, d->nevents * sizeof(int)); + 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) + abort(); no_connection: if (pthread_mutex_unlock(&d->lock)) abort(); diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index cb2e123fce..f285a71fb1 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -68,16 +68,17 @@ list *list_append(list *l, void *data) /* socket */ /****************************************************************************/ -void socket_send(int socket, void *buffer, int size) +int socket_send(int socket, void *buffer, int size) { char *x = buffer; int ret; while (size) { ret = write(socket, x, size); - if (ret <= 0) abort(); + if (ret <= 0) return -1; size -= ret; x += ret; } + return 0; } int get_connection(char *addr, int port) diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index 00193b9eeb..a5b1f1b9f6 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -20,7 +20,8 @@ list *list_append(list *l, void *data); /* socket */ /****************************************************************************/ -void socket_send(int socket, void *buffer, int size); +/* socket_send: return 0 if okay, -1 on error */ +int socket_send(int socket, void *buffer, int size); int get_connection(char *addr, int port); int fullread(int fd, void *_buf, int count); int connect_to(char *addr, int port); diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index 46187f751b..d4972d15fc 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -30,9 +30,10 @@ void is_on_changed(void *_d) if (d->socket == -1) goto no_connection; t = 1; - socket_send(d->socket, &t, 1); - socket_send(d->socket, &d->nevents, sizeof(int)); - socket_send(d->socket, d->is_on, d->nevents * sizeof(int)); + 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) + abort(); no_connection: if (pthread_mutex_unlock(&d->lock)) abort(); From 83350a807f8bb7403664af9a83541c5b215847e3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 5 Jun 2016 17:39:06 +0200 Subject: [PATCH 190/217] reading a socket does not abort anymore fullread has been changed, so get_event too, and the callers also for the moment the callers crash, enb.c will be a bit more clever, the others to see... --- common/utils/T/tracer/enb.c | 1 + common/utils/T/tracer/event.c | 11 +++++++---- common/utils/T/tracer/textlog.c | 1 + common/utils/T/tracer/utils.c | 2 +- common/utils/T/tracer/utils.h | 1 + common/utils/T/tracer/vcd.c | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 1d97b428d3..9cb8d12699 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -386,6 +386,7 @@ int main(int n, char **v) char v[T_BUFFER_MAX]; event e; e = get_event(enb_data.socket, v, database); + if (e.type == -1) abort(); handle_event(h, e); } diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c index e626b4a7d6..0917c010b3 100644 --- a/common/utils/T/tracer/event.c +++ b/common/utils/T/tracer/event.c @@ -22,14 +22,14 @@ event get_event(int socket, char *event_buffer, void *database) */ again: - fullread(socket, &length, 4); + if (fullread(socket, &length, 4) == -1) goto read_error; #ifdef T_SEND_TIME - fullread(socket, &t, sizeof(struct timespec)); + if (fullread(socket, &t, sizeof(struct timespec)) == -1) goto read_error; length -= sizeof(struct timespec); #endif - fullread(socket, &type, sizeof(int)); + if (fullread(socket, &type, sizeof(int)) == -1) goto read_error; length -= sizeof(int); - fullread(socket, event_buffer, length); + if (fullread(socket, event_buffer, length) == -1) goto read_error; if (type == -1) append_received_config_chunk(event_buffer, length); if (type == -2) verify_config(); @@ -41,6 +41,9 @@ again: #else return new_event(type, length, event_buffer, database); #endif + +read_error: + return (event){type: -1}; } #ifdef T_SEND_TIME diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 362ff8103e..2118cc1bf9 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -182,6 +182,7 @@ int main(int n, char **v) char v[T_BUFFER_MAX]; event e; e = get_event(textlog_data.socket, v, database); + if (e.type == -1) abort(); handle_event(h, e); } diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index f285a71fb1..3ebc000c67 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -118,7 +118,7 @@ int fullread(int fd, void *_buf, int count) int l; while (count) { l = read(fd, buf, count); - if (l <= 0) { printf("read socket problem\n"); abort(); } + if (l <= 0) return -1; count -= l; buf += l; ret += l; diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index a5b1f1b9f6..e15a8d2fba 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -23,6 +23,7 @@ list *list_append(list *l, void *data); /* socket_send: return 0 if okay, -1 on error */ int socket_send(int socket, void *buffer, int size); int get_connection(char *addr, int port); +/* fullread: return length read if okay (that is: 'count'), -1 on error */ int fullread(int fd, void *_buf, int count); int connect_to(char *addr, int port); diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index d4972d15fc..2dc34aead9 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -192,6 +192,7 @@ int main(int n, char **v) char v[T_BUFFER_MAX]; event e; e = get_event(vcd_data.socket, v, database); + if (e.type == -1) abort(); handle_event(h, e); } From 1a9d614f0e6e536e2b65e537334148354f14823e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 5 Jun 2016 17:42:44 +0200 Subject: [PATCH 191/217] take care of SIGPIPE received when writing a dead socket write() on a socket with the other end closed throws a SIGPIPE. Let's ignore this signal. write() will return an error anyway... --- common/utils/T/local_tracer.c | 5 +++++ common/utils/T/tracer/enb.c | 4 ++++ common/utils/T/tracer/textlog.c | 4 ++++ common/utils/T/tracer/vcd.c | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index 5d46d2d38d..df6d350a8b 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "T_defs.h" #include "T_IDs.h" @@ -195,6 +196,7 @@ again: dead: /* socket died, let's stop all traces and wait for another tracer */ + /* TODO: be careful with those write, they might write less than wanted */ buf[0] = 1; if (write(to, buf, 1) != 1) abort(); len = T_NUMBER_OF_IDS; @@ -312,6 +314,9 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer, int dont_wait = wait_for_tracer ? 0 : 1; void *f; + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); + init_shm(); s = local_socket; diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 9cb8d12699..d0a2f38104 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "database.h" #include "event.h" #include "handler.h" @@ -246,6 +247,9 @@ int main(int n, char **v) enb_gui eg; enb_data enb_data; + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 2118cc1bf9..4b977a3eaa 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "database.h" #include "event.h" #include "handler.h" @@ -93,6 +94,9 @@ int main(int n, char **v) int gui_active = 1; textlog_data textlog_data; + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index 2dc34aead9..e2460282b0 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "database.h" #include "event.h" #include "handler.h" @@ -129,6 +130,9 @@ int main(int n, char **v) gui *g; vcd_data vcd_data; + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); + on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort(); on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort(); From 18c2bdda98900f0849c4056129813c401a9454cd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 5 Jun 2016 17:47:08 +0200 Subject: [PATCH 192/217] don't abord if read fails in get_message it may legitimately happen when the tracee is ctrl+c'ed. Let's print something though because read may fail for other reasons. Why not? --- common/utils/T/T.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index c556a9c2a5..fca7139991 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -10,6 +10,11 @@ #include #include +#define QUIT(x) do { \ + printf("T tracer: QUIT: %s\n", x); \ + exit(1); \ +} while (0) + /* array used to activate/disactivate a log */ static int T_IDs[T_NUMBER_OF_IDS]; int *T_active = T_IDs; @@ -31,15 +36,15 @@ static void get_message(int s) int id; int is_on; - if (read(s, &t, 1) != 1) abort(); + if (read(s, &t, 1) != 1) QUIT("get_message fails"); printf("got mess %d\n", t); switch (t) { case 0: /* toggle all those IDs */ /* optimze? (too much syscalls) */ - if (read(s, &l, sizeof(int)) != sizeof(int)) abort(); + if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails"); while (l) { - if (read(s, &id, sizeof(int)) != sizeof(int)) abort(); + if (read(s, &id, sizeof(int)) != sizeof(int)) QUIT("get_message fails"); T_IDs[id] = 1 - T_IDs[id]; l--; } @@ -47,10 +52,11 @@ printf("got mess %d\n", t); case 1: /* set IDs as given */ /* optimize? */ - if (read(s, &l, sizeof(int)) != sizeof(int)) abort(); + if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails"); id = 0; while (l) { - if (read(s, &is_on, sizeof(int)) != sizeof(int)) abort(); + if (read(s, &is_on, sizeof(int)) != sizeof(int)) + QUIT("get_message fails"); T_IDs[id] = is_on; id++; l--; From 88c44ef9fef846c176fd737dbae65cc926ad283f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 5 Jun 2016 17:54:38 +0200 Subject: [PATCH 193/217] rename store_config_file load_config_file --- common/utils/T/tracer/config.c | 2 +- common/utils/T/tracer/config.h | 2 +- common/utils/T/tracer/enb.c | 2 +- common/utils/T/tracer/textlog.c | 2 +- common/utils/T/tracer/vcd.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/config.c b/common/utils/T/tracer/config.c index 333c28ce43..98085956a2 100644 --- a/common/utils/T/tracer/config.c +++ b/common/utils/T/tracer/config.c @@ -33,7 +33,7 @@ void append_received_config_chunk(char *buf, int length) } } -void store_config_file(char *filename) +void load_config_file(char *filename) { int c; FILE *f = fopen(filename, "r"); diff --git a/common/utils/T/tracer/config.h b/common/utils/T/tracer/config.h index 88b207e9f6..5234b0f537 100644 --- a/common/utils/T/tracer/config.h +++ b/common/utils/T/tracer/config.h @@ -2,7 +2,7 @@ #define _CONFIG_H_ void append_received_config_chunk(char *buf, int length); -void store_config_file(char *filename); +void load_config_file(char *filename); void verify_config(void); #endif /* _CONFIG_H_ */ diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index d0a2f38104..3f1e864763 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -279,7 +279,7 @@ int main(int n, char **v) database = parse_database(database_filename); - store_config_file(database_filename); + load_config_file(database_filename); number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 4b977a3eaa..f3d0b34831 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -130,7 +130,7 @@ int main(int n, char **v) database = parse_database(database_filename); - store_config_file(database_filename); + load_config_file(database_filename); number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index e2460282b0..45aa4e26e2 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -162,7 +162,7 @@ int main(int n, char **v) database = parse_database(database_filename); - store_config_file(database_filename); + load_config_file(database_filename); number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); From 0b7d24208375cf529f5ab80dab5e6e2762034d79 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 5 Jun 2016 17:57:57 +0200 Subject: [PATCH 194/217] enb.c stays alive if tracee dies enb.c will then try to reconnect. --- common/utils/T/tracer/config.c | 7 +++++++ common/utils/T/tracer/config.h | 1 + common/utils/T/tracer/enb.c | 13 +++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/config.c b/common/utils/T/tracer/config.c index 98085956a2..f88966ed79 100644 --- a/common/utils/T/tracer/config.c +++ b/common/utils/T/tracer/config.c @@ -17,6 +17,13 @@ static char *PUT(char *to, int tosize, char c) return to; } +void clear_remote_config(void) +{ + free(remote); + remote = NULL; + remote_size = 0; +} + void append_received_config_chunk(char *buf, int length) { int buflen = *(int *)buf; diff --git a/common/utils/T/tracer/config.h b/common/utils/T/tracer/config.h index 5234b0f537..f90869eb66 100644 --- a/common/utils/T/tracer/config.h +++ b/common/utils/T/tracer/config.h @@ -1,6 +1,7 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ +void clear_remote_config(void); void append_received_config_chunk(char *buf, int length); void load_config_file(char *filename); void verify_config(void); diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 3f1e864763..a8c4232892 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include "database.h" @@ -43,10 +44,16 @@ void is_on_changed(void *_d) 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) - abort(); + 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) @@ -380,6 +387,8 @@ int main(int n, char **v) if (pthread_mutex_init(&enb_data.lock, NULL)) abort(); setup_event_selector(g, database, is_on, is_on_changed, &enb_data); +restart: + clear_remote_config(); enb_data.socket = connect_to(ip, port); /* send the first message - activate selected traces */ @@ -390,7 +399,7 @@ int main(int n, char **v) char v[T_BUFFER_MAX]; event e; e = get_event(enb_data.socket, v, database); - if (e.type == -1) abort(); + if (e.type == -1) goto restart; handle_event(h, e); } From 127ca5ee8165f925572f43f424ae12780a91e9ef Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 2 Jun 2016 12:50:37 +0200 Subject: [PATCH 195/217] minor improvement always a good idea to crash in unknown situations... --- common/utils/T/local_tracer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index df6d350a8b..93a56a9e3d 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -183,6 +183,10 @@ again: break; case 2: break; + default: + printf("%s:%d:%s: unhandled message type %d\n", + __FILE__, __LINE__, __FUNCTION__, t); + abort(); } b = buf; From b87405ad7cf1eea77dae5a57001026d53d72bac0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jun 2016 11:40:46 +0200 Subject: [PATCH 196/217] add PHY uplink dci/retrans/ack/nack T traces --- common/utils/T/T_messages.txt | 16 ++++++++++++++++ openair1/PHY/LTE_TRANSPORT/phich.c | 2 ++ openair1/SCHED/phy_procedures_lte_eNb.c | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 5347f054f7..e6c83b5105 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -19,6 +19,22 @@ ID = ENB_DLSCH_UE_NACK DESC = eNodeB downlink UE NACK as seen by the PHY layer in process_HARQ_feedback GROUP = ALL:PHY:GRAPHIC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti +ID = ENB_ULSCH_UE_DCI + DESC = eNodeB uplink UE specific DCI as sent by the PHY layer + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti +ID = ENB_ULSCH_UE_NO_DCI_RETRANSMISSION + DESC = eNodeB uplink UE retransmission due to PHICH NACK (see generate_phich_top) + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti +ID = ENB_ULSCH_UE_ACK + DESC = eNodeB uplink UE ACK as seen by the PHY layer + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti +ID = ENB_ULSCH_UE_NACK + DESC = eNodeB uplink UE NACK as seen by the PHY layer + GROUP = ALL:PHY:GRAPHIC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index e08ad239bd..ddf78bdcce 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1506,6 +1506,8 @@ void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB, if ((ulsch_eNB[UE_id]->harq_processes[harq_pid]->dci_alloc == 0) && (ulsch_eNB[UE_id]->harq_processes[harq_pid]->rar_alloc == 0) ) { if (ulsch_eNB[UE_id]->harq_processes[harq_pid]->phich_ACK==0 ) { + T(T_ENB_ULSCH_UE_NO_DCI_RETRANSMISSION, T_INT(phy_vars_eNB->Mod_id), T_INT(phy_vars_eNB->proc[sched_subframe].frame_tx), + T_INT(subframe), T_INT(UE_id), T_INT(ulsch_eNB[UE_id]->rnti)); LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d, subframe %d : PHICH NACK / (no format0 DCI) Setting subframe_scheduling_flag\n", phy_vars_eNB->Mod_id,harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index e8c2e87414..f0d811a3ac 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1250,6 +1250,9 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e else UE_id = i; + T(T_ENB_ULSCH_UE_DCI, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), + T_INT(DCI_pdu->dci_alloc[i].rnti)); + if (UE_id<0) { LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Unknown UE_id for rnti %"PRIx16"\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti); mac_exit_wrapper("Invalid UE id (< 0) detected"); @@ -2795,6 +2798,7 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ } if (ret == (1+MAX_TURBO_ITERATIONS)) { + T(T_ENB_ULSCH_UE_NACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(phy_vars_eNB->ulsch_eNB[i]->rnti)); /* if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round>0) { @@ -2919,6 +2923,8 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ } } // ulsch in error else { + T(T_ENB_ULSCH_UE_ACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(phy_vars_eNB->ulsch_eNB[i]->rnti)); + if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) { LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n", phy_vars_eNB->Mod_id,harq_pid, From c96039108c8be032333052acea08aaec0a7be849 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jun 2016 11:41:39 +0200 Subject: [PATCH 197/217] update enb.c to trace uplink dci/retrans/ack/nack and also start to use the PHY textview --- common/utils/T/tracer/enb.c | 45 +++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index a8c4232892..25dee9c2f0 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -17,6 +17,7 @@ #include "config.h" typedef struct { + view *phyview; view *rrcview; view *legacy; } enb_gui; @@ -122,7 +123,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) g, input_signal_plot, new_color(g, "#0c0c72")); logger_add_view(input_signal_log, input_signal_view); - /* downlink UE DCIs */ + /* downlink/uplink UE DCIs */ widget_add_child(g, top_container, new_label(g,"DL/UL TICK/DCI/ACK/NACK "), -1); line = new_container(g, HORIZONTAL); @@ -134,27 +135,43 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) timeline_set_subline_background_color(g, timeline_plot, i, new_color(g, i==0 || i==4 ? "#aaf" : "#eee")); timeview = new_view_time(3600, 10, g, timeline_plot); - /* tick logging */ + /* DL tick logging */ timelog = new_timelog(h, database, "ENB_DL_TICK"); subview = new_subview_time(timeview, 0, new_color(g, "#77c"), 3600*1000); logger_add_view(timelog, subview); - /* DCI logging */ + /* DL DCI logging */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_DCI"); subview = new_subview_time(timeview, 1, new_color(g, "#228"), 3600*1000); logger_add_view(timelog, subview); - /* ACK */ + /* DL ACK */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_ACK"); subview = new_subview_time(timeview, 2, new_color(g, "#282"), 3600*1000); logger_add_view(timelog, subview); - /* NACK */ + /* DL NACK */ timelog = new_timelog(h, database, "ENB_DLSCH_UE_NACK"); subview = new_subview_time(timeview, 3, new_color(g, "#f22"), 3600*1000); logger_add_view(timelog, subview); - /* uplink UE DCIs */ + /* UL tick logging */ timelog = new_timelog(h, database, "ENB_UL_TICK"); subview = new_subview_time(timeview, 4, new_color(g, "#77c"), 3600*1000); logger_add_view(timelog, subview); + /* UL DCI logging */ + timelog = new_timelog(h, database, "ENB_ULSCH_UE_DCI"); + subview = new_subview_time(timeview, 5, new_color(g, "#228"), 3600*1000); + logger_add_view(timelog, subview); + /* UL retransmission without DCI logging */ + timelog = new_timelog(h, database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION"); + subview = new_subview_time(timeview, 5, new_color(g, "#f22"), 3600*1000); + logger_add_view(timelog, subview); + /* UL ACK */ + timelog = new_timelog(h, database, "ENB_ULSCH_UE_ACK"); + subview = new_subview_time(timeview, 6, new_color(g, "#282"), 3600*1000); + logger_add_view(timelog, subview); + /* UL NACK */ + timelog = new_timelog(h, database, "ENB_ULSCH_UE_NACK"); + subview = new_subview_time(timeview, 7, new_color(g, "#f22"), 3600*1000); + logger_add_view(timelog, subview); /* phy/mac/rlc/pdcp/rrc textlog */ line = new_container(g, HORIZONTAL); @@ -170,6 +187,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) widget_add_child(g, col, text, -1); container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); + e->phyview = textview; /* mac */ col = new_container(g, VERTICAL); @@ -311,16 +329,29 @@ int main(int n, char **v) } on_off(database, "ENB_INPUT_SIGNAL", is_on, 1); - on_off(database, "ENB_UL_TICK", is_on, 1); on_off(database, "ENB_DL_TICK", is_on, 1); on_off(database, "ENB_DLSCH_UE_DCI", is_on, 1); on_off(database, "ENB_DLSCH_UE_ACK", is_on, 1); on_off(database, "ENB_DLSCH_UE_NACK", is_on, 1); + on_off(database, "ENB_UL_TICK", is_on, 1); + on_off(database, "ENB_ULSCH_UE_DCI", is_on, 1); + on_off(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", is_on, 1); + on_off(database, "ENB_ULSCH_UE_ACK", is_on, 1); + on_off(database, "ENB_ULSCH_UE_NACK", is_on, 1); on_off(database, "LEGACY_RRC_INFO", is_on, 1); on_off(database, "LEGACY_RRC_ERROR", is_on, 1); on_off(database, "LEGACY_RRC_WARNING", is_on, 1); + view_add_log(eg.phyview, "ENB_DLSCH_UE_DCI", h, database, is_on); + view_add_log(eg.phyview, "ENB_DLSCH_UE_ACK", h, database, is_on); + view_add_log(eg.phyview, "ENB_DLSCH_UE_NACK", h, database, is_on); + view_add_log(eg.phyview, "ENB_ULSCH_UE_DCI", h, database, is_on); + view_add_log(eg.phyview, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", + h, database, is_on); + view_add_log(eg.phyview, "ENB_ULSCH_UE_ACK", h, database, is_on); + view_add_log(eg.phyview, "ENB_ULSCH_UE_NACK", h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE", h, database, is_on); view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMMAND", From e0966584cf9b291317a89f06df5759306fa2c6c0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jun 2016 12:30:50 +0200 Subject: [PATCH 198/217] monitor tracee and local tracer to avoid "dead" processes this may be removed at some point, it's very brutal. But when you write some code, it may happen (it "may"!!) that *sometimes* the code does not work and crashes. In thoses cases I prefer the local tracer (or the tracee) to go away immediately without even thinking about it maybe still running in the background. In case of monitoring (as opposed to debugging) maybe it's preferable to let the process live its life as it wants. Time will tell. --- common/utils/T/T.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index fca7139991..786b3722ed 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -91,6 +91,23 @@ static void new_thread(void *(*f)(void *), void *data) void T_local_tracer_main(int remote_port, int wait_for_tracer, int local_socket); +/* We monitor the tracee and the local tracer processes. + * When one dies we forcefully kill the other. + */ +#include +#include +static void monitor_and_kill(int child1, int child2) +{ + int child; + int status; + + child = wait(&status); + if (child == -1) perror("wait"); + kill(child1, SIGKILL); + kill(child2, SIGKILL); + exit(0); +} + void T_init(int remote_port, int wait_for_tracer) { int socket_pair[2]; @@ -98,19 +115,27 @@ void T_init(int remote_port, int wait_for_tracer) int T_shm_fd; unsigned char *buf; int len; - int f; + int child1, child2; if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) { perror("socketpair"); abort(); } - f = fork(); if (f == -1) abort(); - if (f == 0) { + /* child1 runs the local tracer and child2 runs the tracee */ + + child1 = fork(); if (child1 == -1) abort(); + if (child1 == 0) { close(socket_pair[1]); T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]); exit(0); } close(socket_pair[0]); + child2 = fork(); if (child2 == -1) abort(); + if (child2 != 0) { + close(socket_pair[1]); + monitor_and_kill(child1, child2); + } + s = socket_pair[1]; /* wait for first message - initial list of active T events */ get_message(s); From 2b1287384a38819385df284f97d253e11da2ddce Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jun 2016 17:52:05 +0200 Subject: [PATCH 199/217] bugfix: include T.h in phich.c --- openair1/PHY/LTE_TRANSPORT/phich.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index ddf78bdcce..6c884129df 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -46,6 +46,8 @@ #include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" #endif +#include "T.h" + //#define DEBUG_PHICH 1 //extern unsigned short pcfich_reg[4]; From 63652f94fa5490d0f95086a58990c87cdba6556e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 8 Jun 2016 12:50:35 +0200 Subject: [PATCH 200/217] tick timeview/log this is like timeview but the plotting is done at frame/subframe resolution of a given reference clock signal, let's say. The realtime information of the events is not used. It's all logical. It will be used to log harq processes for the moment. --- common/utils/T/tracer/logger/Makefile | 2 +- common/utils/T/tracer/logger/logger.h | 2 + common/utils/T/tracer/logger/ticklog.c | 80 +++++ common/utils/T/tracer/view/Makefile | 4 +- common/utils/T/tracer/view/ticktime.c | 410 +++++++++++++++++++++++++ common/utils/T/tracer/view/view.h | 3 + 6 files changed, 498 insertions(+), 3 deletions(-) create mode 100644 common/utils/T/tracer/logger/ticklog.c create mode 100644 common/utils/T/tracer/view/ticktime.c diff --git a/common/utils/T/tracer/logger/Makefile b/common/utils/T/tracer/logger/Makefile index 18f70e0bc5..e539100838 100644 --- a/common/utils/T/tracer/logger/Makefile +++ b/common/utils/T/tracer/logger/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -pthread -I.. -OBJS=logger.o textlog.o framelog.o ttilog.o timelog.o +OBJS=logger.o textlog.o framelog.o ttilog.o timelog.o ticklog.o logger.a: $(OBJS) ar cr logger.a $(OBJS) diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index ec04e60819..2c26f8dcb2 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -11,6 +11,8 @@ logger *new_ttilog(void *event_handler, void *database, char *event_name, char *frame_varname, char *subframe_varname, char *data_varname, int convert_to_dB); 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); void framelog_set_skip(logger *_this, int skip_delay); diff --git a/common/utils/T/tracer/logger/ticklog.c b/common/utils/T/tracer/logger/ticklog.c new file mode 100644 index 0000000000..b2462aabb6 --- /dev/null +++ b/common/utils/T/tracer/logger/ticklog.c @@ -0,0 +1,80 @@ +#include "logger.h" +#include "logger_defs.h" +#include "event.h" +#include "database.h" +#include "handler.h" +#include +#include +#include + +struct ticklog { + struct logger common; + void *database; + int frame_arg; + int subframe_arg; +}; + +static void _event(void *p, event e) +{ + struct ticklog *l = p; + int i; + int frame; + int subframe; + + frame = e.e[l->frame_arg].i; + subframe = e.e[l->subframe_arg].i; + + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], e.sending_time, frame, subframe); +} + +logger *new_ticklog(event_handler *h, void *database, + char *event_name, char *frame_varname, char *subframe_varname) +{ + struct ticklog *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct ticklog)); 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,ret); + + f = get_format(database, event_id); + + /* look for frame and subframe args */ + ret->frame_arg = -1; + ret->subframe_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], frame_varname)) ret->frame_arg = i; + if (!strcmp(f.name[i], subframe_varname)) ret->subframe_arg = i; + } + if (ret->frame_arg == -1) { + printf("%s:%d: frame argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, frame_varname, event_name); + abort(); + } + if (ret->subframe_arg == -1) { + printf("%s:%d: subframe argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, subframe_varname, event_name); + abort(); + } + if (strcmp(f.type[ret->frame_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, frame_varname); + abort(); + } + if (strcmp(f.type[ret->subframe_arg], "int") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", + __FILE__, __LINE__, subframe_varname); + abort(); + } + + return ret; +} diff --git a/common/utils/T/tracer/view/Makefile b/common/utils/T/tracer/view/Makefile index 51b5114a0e..32b267ec24 100644 --- a/common/utils/T/tracer/view/Makefile +++ b/common/utils/T/tracer/view/Makefile @@ -1,7 +1,7 @@ CC=gcc -CFLAGS=-Wall -g -pthread -I.. +CFLAGS=-Wall -g -pthread -I.. -I../logger -OBJS=stdout.o textlist.o xy.o tti.o time.o +OBJS=stdout.o textlist.o xy.o tti.o time.o ticktime.o view.a: $(OBJS) ar cr view.a $(OBJS) diff --git a/common/utils/T/tracer/view/ticktime.c b/common/utils/T/tracer/view/ticktime.c new file mode 100644 index 0000000000..90ded4dd43 --- /dev/null +++ b/common/utils/T/tracer/view/ticktime.c @@ -0,0 +1,410 @@ +#include "view.h" +#include "../utils.h" +#include "logger.h" +#include +#include +#include +#include + +/* TODO: some code is identical/almost identical to time.c, merge/factorize */ + +/****************************************************************************/ +/* tick timeview */ +/****************************************************************************/ + +struct plot { + struct timespec *tick; + int ticksize; + int tickmaxsize; + int tickstart; + int line; + int color; +}; + +struct ticktime { + view common; + gui *g; + widget *w; + float refresh_rate; + pthread_mutex_t lock; + struct plot *p; + int psize; + double pixel_length; /* unit: nanosecond (maximum 1 hour/pixel) */ + struct timespec latest_time; + struct timespec start_time; + int autoscroll; + struct timespec tick_latest_time; + int tick_latest_frame; + int tick_latest_subframe; + void *clock_ticktime; /* data for the clock tick, see below */ +}; + +/* TODO: put that function somewhere else (utils.c) */ +static struct timespec time_add(struct timespec a, struct timespec b) +{ + struct timespec ret; + ret.tv_sec = a.tv_sec + b.tv_sec; + ret.tv_nsec = a.tv_nsec + b.tv_nsec; + if (ret.tv_nsec > 1000000000) { + ret.tv_sec++; + ret.tv_nsec -= 1000000000; + } + return ret; +} + +/* TODO: put that function somewhere else (utils.c) */ +static struct timespec time_sub(struct timespec a, struct timespec b) +{ + struct timespec ret; + if (a.tv_nsec < b.tv_nsec) { + ret.tv_nsec = (int64_t)a.tv_nsec - (int64_t)b.tv_nsec + 1000000000; + ret.tv_sec = a.tv_sec - b.tv_sec - 1; + } else { + ret.tv_nsec = a.tv_nsec - b.tv_nsec; + ret.tv_sec = a.tv_sec - b.tv_sec; + } + return ret; +} + +/* TODO: put that function somewhere else (utils.c) */ +static struct timespec nano_to_time(int64_t n) +{ + struct timespec ret; + ret.tv_sec = n / 1000000000; + ret.tv_nsec = n % 1000000000; + return ret; +} + +/* TODO: put that function somewhere else (utils.c) */ +static int time_cmp(struct timespec a, struct timespec b) +{ + if (a.tv_sec < b.tv_sec) return -1; + if (a.tv_sec > b.tv_sec) return 1; + if (a.tv_nsec < b.tv_nsec) return -1; + if (a.tv_nsec > b.tv_nsec) return 1; + return 0; +} + +static int interval_empty(struct ticktime *this, int sub, + struct timespec start, struct timespec end) +{ + int a, b, mid; + int i; + + if (this->p[sub].ticksize == 0) return 1; + + /* look for a tick larger than start and smaller than end */ + a = 0; + b = this->p[sub].ticksize - 1; + while (b >= a) { + mid = (a+b) / 2; + i = (this->p[sub].tickstart + mid) % this->p[sub].ticksize; + if (time_cmp(this->p[sub].tick[i], start) < 0) a = mid + 1; + else if (time_cmp(this->p[sub].tick[i], end) > 0) b = mid - 1; + else return 0; + } + return 1; +} + +static void *ticktime_thread(void *_this) +{ + struct ticktime *this = _this; + int width; + int l; + int i; + struct timespec tstart; + struct timespec tnext; + struct plot *p; + int64_t pixel_length; + + while (1) { + if (pthread_mutex_lock(&this->lock)) abort(); + + timeline_get_width(this->g, this->w, &width); + timeline_clear_silent(this->g, this->w); + + /* TODO: optimize? */ + + /* use rounded pixel_length */ + pixel_length = this->pixel_length; + + if (this->autoscroll) { + tnext = time_add(this->latest_time, + (struct timespec){tv_sec:0,tv_nsec:1}); + tstart = time_sub(tnext, nano_to_time(pixel_length * width)); + this->start_time = tstart; + } else { + tstart = this->start_time; + tnext = time_add(tstart, nano_to_time(pixel_length * width)); + } + + for (l = 0; l < this->psize; l++) { + for (i = 0; i < width; i++) { + struct timespec tick_start, tick_end; + tick_start = time_add(tstart, nano_to_time(pixel_length * i)); + tick_end = time_add(tick_start, nano_to_time(pixel_length-1)); + if (interval_empty(this, l, tick_start, tick_end)) + continue; + p = &this->p[l]; + /* TODO: only one call */ + timeline_add_points_silent(this->g, this->w, p->line, p->color, &i, 1); + } + } + + widget_dirty(this->g, this->w); + + if (pthread_mutex_unlock(&this->lock)) abort(); + sleepms(1000 / this->refresh_rate); + } + + return 0; +} + +static void scroll(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + struct ticktime *this = private; + int *d = notification_data; + int x = d[0]; + int key_modifiers = d[2]; + double mul = 1.2; + double pixel_length; + int64_t old_px_len_rounded; + struct timespec t; + int scroll_px; + int width; + + if (pthread_mutex_lock(&this->lock)) abort(); + + old_px_len_rounded = this->pixel_length; + + /* scroll if control+wheel, zoom otherwise */ + + if (key_modifiers & KEY_CONTROL) { + timeline_get_width(this->g, this->w, &width); + if (width < 2) width = 2; + scroll_px = 100; + if (scroll_px > width - 1) scroll_px = width - 1; + if (!strcmp(notification, "scrolldown")) + this->start_time = time_add(this->start_time, + nano_to_time(scroll_px * old_px_len_rounded)); + else + this->start_time = time_sub(this->start_time, + nano_to_time(scroll_px * old_px_len_rounded)); + goto end; + } + + if (!strcmp(notification, "scrollup")) mul = 1 / mul; + +again: + pixel_length = this->pixel_length * mul; + if (pixel_length < 1) pixel_length = 1; + if (pixel_length > (double)3600 * 1000000000) + pixel_length = (double)3600 * 1000000000; + + this->pixel_length = pixel_length; + + /* due to rounding, we may need to zoom by more than 1.2 with + * very close lookup, otherwise the user zooming command won't + * be visible (say length is 2.7, zoom in, new length is 2.25, + * and rounding is 2, same value, no change, no feedback to user => bad) + * TODO: make all this cleaner + */ + if (pixel_length != 1 && pixel_length != (double)3600 * 1000000000 && + (int64_t)pixel_length == old_px_len_rounded) + goto again; + + t = time_add(this->start_time, nano_to_time(x * old_px_len_rounded)); + this->start_time = time_sub(t, nano_to_time(x * (int64_t)pixel_length)); + +end: + if (pthread_mutex_unlock(&this->lock)) abort(); +} + +static void click(void *private, gui *g, + char *notification, widget *w, void *notification_data) +{ + struct ticktime *this = private; + int *d = notification_data; + int button = *d; + + if (button == 3) this->autoscroll = 0; + if (button == 1) this->autoscroll = 1; +} + +view *new_view_ticktime(float refresh_rate, gui *g, widget *w) +{ + struct ticktime *ret = calloc(1, sizeof(struct ticktime)); + if (ret == NULL) abort(); + + ret->refresh_rate = refresh_rate; + ret->g = g; + ret->w = w; + + ret->p = NULL; + ret->psize = 0; + + ret->autoscroll = 1; + + ret->tick_latest_time.tv_sec = 1; + + /* default pixel length: 10ms */ + ret->pixel_length = 10 * 1000000; + + register_notifier(g, "scrollup", w, scroll, ret); + register_notifier(g, "scrolldown", w, scroll, ret); + register_notifier(g, "click", w, click, ret); + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + + new_thread(ticktime_thread, ret); + + return (view *)ret; +} + +/****************************************************************************/ +/* subticktimeview */ +/****************************************************************************/ + +struct subticktime { + view common; + struct ticktime *parent; + int line; + int color; + int subview; +}; + +static void append(view *_this, struct timespec t, int frame, int subframe) +{ + struct subticktime *this = (struct subticktime *)_this; + struct ticktime *ticktime = this->parent; + struct plot *p = &ticktime->p[this->subview]; + int i; + struct timespec swap; + int64_t diff; + + if (pthread_mutex_lock(&ticktime->lock)) abort(); + + /* get time with respect to latest known tick time */ + diff = (frame*10 + subframe) - + (ticktime->tick_latest_frame*10 + ticktime->tick_latest_subframe); + if (diff > 1024*10/2) diff -= 1024*10; + else if (diff < -1024*10/2) diff += 1024*10; + if (diff < 0) + t = time_sub(ticktime->tick_latest_time, nano_to_time(-diff * 1000000)); + else + t = time_add(ticktime->tick_latest_time, nano_to_time(diff * 1000000)); + + if (p->ticksize < p->tickmaxsize) { + p->tick[p->ticksize] = t; + p->ticksize++; + } else { + p->tick[p->tickstart] = t; + p->tickstart = (p->tickstart + 1) % p->ticksize; + } + + /* due to adjustment of the time, array may not be ordered anymore */ + for (i = p->ticksize-2; i >= 0; i--) { + int prev = (p->tickstart + i) % p->ticksize; + int cur = (prev + 1) % p->ticksize; + if (time_cmp(p->tick[prev], p->tick[cur]) <= 0) break; + swap = p->tick[prev]; + p->tick[prev] = p->tick[cur]; + p->tick[cur] = swap; + } + + if (time_cmp(ticktime->latest_time, t) < 0) + ticktime->latest_time = t; + + if (pthread_mutex_unlock(&ticktime->lock)) abort(); +} + +view *new_subview_ticktime(view *_time, int line, int color, int size) +{ + struct ticktime *ticktime = (struct ticktime *)_time; + struct subticktime *ret = calloc(1, sizeof(struct subticktime)); + if (ret == NULL) abort(); + + ret->common.append = (void (*)(view *, ...))append; + + if (pthread_mutex_lock(&ticktime->lock)) abort(); + + ret->parent = ticktime; + ret->line = line; + ret->color = color; + ret->subview = ticktime->psize; + + ticktime->p = realloc(ticktime->p, + (ticktime->psize + 1) * sizeof(struct plot)); + if (ticktime->p == NULL) abort(); + ticktime->p[ticktime->psize].tick = calloc(size, sizeof(struct timespec)); + if (ticktime->p[ticktime->psize].tick == NULL) abort(); + ticktime->p[ticktime->psize].ticksize = 0; + ticktime->p[ticktime->psize].tickmaxsize = size; + ticktime->p[ticktime->psize].tickstart = 0; + ticktime->p[ticktime->psize].line = line; + ticktime->p[ticktime->psize].color = color; + + ticktime->psize++; + + if (pthread_mutex_unlock(&ticktime->lock)) abort(); + + return (view *)ret; +} + +/****************************************************************************/ +/* clock tick */ +/****************************************************************************/ + +struct clock_ticktime { + view common; + struct ticktime *parent; +}; + +static void clock_append(view *_this, struct timespec t, + int frame, int subframe) +{ + struct clock_ticktime *this = (struct clock_ticktime *)_this; + struct ticktime *tt = this->parent; + int64_t diff; + + if (subframe == 10) { subframe = 0; frame = (frame + 1) % 1024; } + + if (pthread_mutex_lock(&tt->lock)) abort(); + + /* get time relative to latest known tick time */ + /* In normal conditions diff is 1 but if the user pauses reception of events + * it may be anything. Let's take only positive values. + */ + diff = (frame*10 + subframe) - + (tt->tick_latest_frame*10 + tt->tick_latest_subframe); + if (diff < 0) diff += 1024*10; + tt->tick_latest_time = time_add(tt->tick_latest_time, + nano_to_time(diff * 1000000)); + tt->tick_latest_frame = frame; + tt->tick_latest_subframe = subframe; + + if (time_cmp(tt->latest_time, tt->tick_latest_time) < 0) + tt->latest_time = tt->tick_latest_time; + + if (pthread_mutex_unlock(&tt->lock)) abort(); +} + +void ticktime_set_tick(view *_ticktime, void *logger) +{ + struct ticktime *ticktime = (struct ticktime *)_ticktime; + struct clock_ticktime *n; + + if (pthread_mutex_lock(&ticktime->lock)) abort(); + + free(ticktime->clock_ticktime); + n = ticktime->clock_ticktime = calloc(1, sizeof(struct clock_ticktime)); + if (n == NULL) abort(); + + n->common.append = (void (*)(view *, ...))clock_append; + n->parent = ticktime; + + logger_add_view(logger, (view *)n); + + if (pthread_mutex_unlock(&ticktime->lock)) abort(); +} diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 4b91291b1c..cbc5e21b73 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -20,5 +20,8 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, 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); #endif /* _VIEW_H_ */ From 72f56da6b6fca986a82f4239b003e15d582e4a46 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 8 Jun 2016 16:35:08 +0200 Subject: [PATCH 201/217] add a filter to loggers events are accepted by the logger if the filter accepts them the filter is optional (no filter means to accept all events) --- common/utils/T/tracer/Makefile | 15 ++- common/utils/T/tracer/filter/Makefile | 13 +++ common/utils/T/tracer/filter/filter.c | 109 +++++++++++++++++++++ common/utils/T/tracer/filter/filter.h | 14 +++ common/utils/T/tracer/logger/framelog.c | 4 + common/utils/T/tracer/logger/logger.c | 6 ++ common/utils/T/tracer/logger/logger.h | 1 + common/utils/T/tracer/logger/logger_defs.h | 2 + common/utils/T/tracer/logger/textlog.c | 4 + common/utils/T/tracer/logger/ticklog.c | 4 + common/utils/T/tracer/logger/timelog.c | 4 + common/utils/T/tracer/logger/ttilog.c | 4 + 12 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 common/utils/T/tracer/filter/Makefile create mode 100644 common/utils/T/tracer/filter/filter.c create mode 100644 common/utils/T/tracer/filter/filter.h diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index e9d9b99da7..bf0f72710c 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -8,18 +8,21 @@ LIBS=-lX11 -lm -lpng -lXft all: textlog enb vcd textlog: utils.o textlog.o database.o event.o handler.o config.o \ - event_selector.o view/view.a gui/gui.a logger/logger.a + event_selector.o view/view.a gui/gui.a logger/logger.a \ + filter/filter.a $(CC) $(CFLAGS) -o textlog $^ $(LIBS) enb: utils.o enb.o database.o event.o handler.o config.o \ - event_selector.o view/view.a gui/gui.a logger/logger.a + event_selector.o view/view.a gui/gui.a logger/logger.a \ + filter/filter.a $(CC) $(CFLAGS) -o enb $^ $(LIBS) vcd: utils.o vcd.o database.o event.o handler.o config.o \ - event_selector.o view/view.a gui/gui.a logger/logger.a + event_selector.o view/view.a gui/gui.a logger/logger.a \ + filter/filter.a $(CC) $(CFLAGS) -o vcd $^ $(LIBS) -.PHONY: all gui/gui.a view/view.a logger/logger.a +.PHONY: all gui/gui.a view/view.a logger/logger.a filter/filter.a gui/gui.a: cd gui && make @@ -30,6 +33,9 @@ view/view.a: logger/logger.a: cd logger && make +filter/filter.a: + cd filter && make + %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< @@ -38,3 +44,4 @@ clean: cd gui && make clean cd view && make clean cd logger && make clean + cd filter && make clean diff --git a/common/utils/T/tracer/filter/Makefile b/common/utils/T/tracer/filter/Makefile new file mode 100644 index 0000000000..fb1427ca6a --- /dev/null +++ b/common/utils/T/tracer/filter/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-Wall -g -pthread -I.. + +OBJS=filter.o + +filter.a: $(OBJS) + ar cr filter.a $(OBJS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + rm -f *.a *.o diff --git a/common/utils/T/tracer/filter/filter.c b/common/utils/T/tracer/filter/filter.c new file mode 100644 index 0000000000..9c1e96a611 --- /dev/null +++ b/common/utils/T/tracer/filter/filter.c @@ -0,0 +1,109 @@ +#include "filter.h" +#include "event.h" +#include "database.h" +#include +#include +#include + +struct filter { + union { + struct { struct filter *a, *b; } eq; + int v; + struct { int event_type; int arg_index; } evarg; + } v; + + int (*eval)(struct filter *this, event e); +}; + +/****************************************************************************/ +/* evaluation functions */ +/****************************************************************************/ + +int eval_eq(struct filter *f, event e) +{ + int a = f->v.eq.a->eval(f->v.eq.a, e); + int b = f->v.eq.b->eval(f->v.eq.b, e); + return a == b; +} + +int eval_int(struct filter *f, event e) +{ + return f->v.v; +} + +int eval_evarg(struct filter *f, event e) +{ + if (e.type != f->v.evarg.event_type) { + printf("%s:%d:%s: bad event type\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } + if (e.e[f->v.evarg.arg_index].type != EVENT_INT) { + printf("%s:%d:%s: bad event argtype; has to be 'int'\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } + return e.e[f->v.evarg.arg_index].i; +} + +/****************************************************************************/ +/* filter construction functions */ +/****************************************************************************/ + +filter *filter_eq(filter *a, filter *b) +{ + struct filter *ret = calloc(1, sizeof(struct filter)); + if (ret == NULL) abort(); + ret->eval = eval_eq; + ret->v.eq.a = a; + ret->v.eq.b = b; + return ret; +} + +filter *filter_int(int v) +{ + struct filter *ret = calloc(1, sizeof(struct filter)); + if (ret == NULL) abort(); + ret->eval = eval_int; + ret->v.v = v; + return ret; +} + +filter *filter_evarg(void *database, char *event_name, char *varname) +{ + struct filter *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct filter)); if (ret == NULL) abort(); + + event_id = event_id_from_name(database, event_name); + f = get_format(database, event_id); + + ret->eval = eval_evarg; + ret->v.evarg.event_type = event_id; + ret->v.evarg.arg_index = -1; + + for (i = 0; i < f.count; i++) { + if (strcmp(f.name[i], varname) != 0) continue; + ret->v.evarg.arg_index = i; + break; + } + if (ret->v.evarg.arg_index == -1) { + printf("%s:%d:%s: event '%s' has no argument '%s'\n", + __FILE__, __LINE__, __FUNCTION__, event_name, varname); + abort(); + } + + return ret; +} + +/****************************************************************************/ +/* eval function */ +/****************************************************************************/ + +int filter_eval(filter *_f, event e) +{ + struct filter *f = _f; + return f->eval(f, e); +} diff --git a/common/utils/T/tracer/filter/filter.h b/common/utils/T/tracer/filter/filter.h new file mode 100644 index 0000000000..b47b755dbc --- /dev/null +++ b/common/utils/T/tracer/filter/filter.h @@ -0,0 +1,14 @@ +#ifndef _FILTER_H_ +#define _FILTER_H_ + +#include "event.h" + +typedef void filter; + +filter *filter_eq(filter *a, filter *b); +filter *filter_int(int v); +filter *filter_evarg(void *database, char *event_name, char *varname); + +int filter_eval(filter *f, event e); + +#endif /* _FILTER_H_ */ diff --git a/common/utils/T/tracer/logger/framelog.c b/common/utils/T/tracer/logger/framelog.c index 0889f2b80c..057960c382 100644 --- a/common/utils/T/tracer/logger/framelog.c +++ b/common/utils/T/tracer/logger/framelog.c @@ -2,6 +2,7 @@ #include "logger_defs.h" #include "handler.h" #include "database.h" +#include "filter/filter.h" #include #include #include @@ -31,6 +32,9 @@ static void _event(void *p, event e) int bsize; int nsamples; + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + subframe = e.e[l->subframe_arg].i; buffer = e.e[l->buffer_arg].b; bsize = e.e[l->buffer_arg].bsize; diff --git a/common/utils/T/tracer/logger/logger.c b/common/utils/T/tracer/logger/logger.c index c27c612f82..ab6fb8bc62 100644 --- a/common/utils/T/tracer/logger/logger.c +++ b/common/utils/T/tracer/logger/logger.c @@ -9,3 +9,9 @@ void logger_add_view(logger *_l, view *v) l->v = realloc(l->v, l->vsize * sizeof(view *)); if (l->v == NULL) abort(); l->v[l->vsize-1] = v; } + +void logger_set_filter(logger *_l, void *filter) +{ + struct logger *l = _l; + l->filter = filter; +} diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index 2c26f8dcb2..e3e4b97aa5 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -19,5 +19,6 @@ void framelog_set_skip(logger *_this, int skip_delay); #include "view/view.h" void logger_add_view(logger *l, view *v); +void logger_set_filter(logger *l, void *filter); #endif /* _LOGGER_H_ */ diff --git a/common/utils/T/tracer/logger/logger_defs.h b/common/utils/T/tracer/logger/logger_defs.h index e4279157ec..8e8d6a2d3e 100644 --- a/common/utils/T/tracer/logger/logger_defs.h +++ b/common/utils/T/tracer/logger/logger_defs.h @@ -9,6 +9,8 @@ struct logger { /* list of views */ view **v; int vsize; + /* filter - NULL if no filter set */ + void *filter; }; #endif /* _LOGGER_DEFS_H_ */ diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index a9503b9510..e80af7813e 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -4,6 +4,7 @@ #include "database.h" #include "view/view.h" #include "utils.h" +#include "filter/filter.h" #include #include #include @@ -42,6 +43,9 @@ static void _event(void *p, event e) char tt[64]; #endif + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + l->o.osize = 0; #ifdef T_SEND_TIME diff --git a/common/utils/T/tracer/logger/ticklog.c b/common/utils/T/tracer/logger/ticklog.c index b2462aabb6..7a3bc45338 100644 --- a/common/utils/T/tracer/logger/ticklog.c +++ b/common/utils/T/tracer/logger/ticklog.c @@ -3,6 +3,7 @@ #include "event.h" #include "database.h" #include "handler.h" +#include "filter/filter.h" #include #include #include @@ -21,6 +22,9 @@ static void _event(void *p, event e) int frame; int subframe; + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + frame = e.e[l->frame_arg].i; subframe = e.e[l->subframe_arg].i; diff --git a/common/utils/T/tracer/logger/timelog.c b/common/utils/T/tracer/logger/timelog.c index 5dadad8c27..b474c8200d 100644 --- a/common/utils/T/tracer/logger/timelog.c +++ b/common/utils/T/tracer/logger/timelog.c @@ -3,6 +3,7 @@ #include "event.h" #include "database.h" #include "handler.h" +#include "filter/filter.h" #include #include @@ -15,6 +16,9 @@ static void _event(void *p, event e) struct timelog *l = p; int i; + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + for (i = 0; i < l->common.vsize; i++) l->common.v[i]->append(l->common.v[i], e.sending_time); } diff --git a/common/utils/T/tracer/logger/ttilog.c b/common/utils/T/tracer/logger/ttilog.c index 172d0eeb2d..29e22fbf10 100644 --- a/common/utils/T/tracer/logger/ttilog.c +++ b/common/utils/T/tracer/logger/ttilog.c @@ -3,6 +3,7 @@ #include "event.h" #include "database.h" #include "handler.h" +#include "filter/filter.h" #include #include #include @@ -25,6 +26,9 @@ static void _event(void *p, event e) int subframe; float value; + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + frame = e.e[l->frame_arg].i; subframe = e.e[l->subframe_arg].i; switch (e.e[l->data_arg].type) { From 1dff773eb2466eb2d17b3df6c4c8093788a5aa2f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 8 Jun 2016 16:47:45 +0200 Subject: [PATCH 202/217] add 'and' filter operation --- common/utils/T/tracer/filter/filter.c | 26 +++++++++++++++++++++----- common/utils/T/tracer/filter/filter.h | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/filter/filter.c b/common/utils/T/tracer/filter/filter.c index 9c1e96a611..b09b01259d 100644 --- a/common/utils/T/tracer/filter/filter.c +++ b/common/utils/T/tracer/filter/filter.c @@ -7,7 +7,7 @@ struct filter { union { - struct { struct filter *a, *b; } eq; + struct { struct filter *a, *b; } op2; int v; struct { int event_type; int arg_index; } evarg; } v; @@ -19,10 +19,16 @@ struct filter { /* evaluation functions */ /****************************************************************************/ +int eval_and(struct filter *f, event e) +{ + if (f->v.op2.a->eval(f->v.op2.a, e) == 0) return 0; + return f->v.op2.b->eval(f->v.op2.b, e); +} + int eval_eq(struct filter *f, event e) { - int a = f->v.eq.a->eval(f->v.eq.a, e); - int b = f->v.eq.b->eval(f->v.eq.b, e); + int a = f->v.op2.a->eval(f->v.op2.a, e); + int b = f->v.op2.b->eval(f->v.op2.b, e); return a == b; } @@ -49,13 +55,23 @@ int eval_evarg(struct filter *f, event e) /* filter construction functions */ /****************************************************************************/ +filter *filter_and(filter *a, filter *b) +{ + struct filter *ret = calloc(1, sizeof(struct filter)); + if (ret == NULL) abort(); + ret->eval = eval_and; + ret->v.op2.a = a; + ret->v.op2.b = b; + return ret; +} + filter *filter_eq(filter *a, filter *b) { struct filter *ret = calloc(1, sizeof(struct filter)); if (ret == NULL) abort(); ret->eval = eval_eq; - ret->v.eq.a = a; - ret->v.eq.b = b; + ret->v.op2.a = a; + ret->v.op2.b = b; return ret; } diff --git a/common/utils/T/tracer/filter/filter.h b/common/utils/T/tracer/filter/filter.h index b47b755dbc..eba02d7fb7 100644 --- a/common/utils/T/tracer/filter/filter.h +++ b/common/utils/T/tracer/filter/filter.h @@ -5,6 +5,7 @@ typedef void filter; +filter *filter_and(filter *a, filter *b); filter *filter_eq(filter *a, filter *b); filter *filter_int(int v); filter *filter_evarg(void *database, char *event_name, char *varname); From e2682812333fd406102b9e66e118ff6a5d0b25ec Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 10:40:53 +0200 Subject: [PATCH 203/217] add T log ENB_MASTER_TICK --- common/utils/T/T_messages.txt | 6 ++++++ targets/RT/USER/lte-softmodem.c | 4 ++-- targets/SIMU/USER/oaisim.c | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index e6c83b5105..49a629c670 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,3 +1,9 @@ +#general logs +ID = ENB_MASTER_TICK + DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view + GROUP = ALL:GENERAL:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe + #PHY logs ID = ENB_UL_TICK DESC = eNodeB uplink tick - one tick per ms at start of uplink processing diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 21ebb0f55a..14e793cec5 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -51,9 +51,7 @@ #include #include -#if T_TRACER #include "T.h" -#endif #include "rt_wrapper.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all @@ -1988,6 +1986,8 @@ static void* eNB_thread( void* arg ) #else int sf = hw_subframe; #endif + /* TODO: is it the right place for master tick? */ + T(T_ENB_MASTER_TICK, T_INT(0), T_INT(frame % 1024), T_INT(sf)); if (frame>50) { for (int CC_id=0; CC_idlte_frame_parms.frame_type, PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.tdd_config, PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.Nid_cell); + } #ifdef OPENAIR2 //Application: traffic gen From bdd8ee3eed723b8d39359e0088538325480da2c3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 10:41:38 +0200 Subject: [PATCH 204/217] restructure a bit the views in enb.c more readable, still not satisfying though --- common/utils/T/tracer/enb.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 25dee9c2f0..ee35464ba6 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -199,6 +199,10 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + container_set_child_growable(g, top_container, line, 1); + /* rlc */ col = new_container(g, VERTICAL); widget_add_child(g, line, col, -1); @@ -219,6 +223,10 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + container_set_child_growable(g, top_container, line, 1); + /* rrc */ col = new_container(g, VERTICAL); widget_add_child(g, line, col, -1); From c27e69f633191078490e3ea94d4d602fec1ea07f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 10:44:47 +0200 Subject: [PATCH 205/217] add harq_pid to some T traces - update T_messages.txt - update call sites of the T for thoses traces --- common/utils/T/T_messages.txt | 14 +++++++------- openair1/PHY/LTE_TRANSPORT/phich.c | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 49a629c670..1d76d35a8a 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -16,31 +16,31 @@ ID = ENB_DL_TICK ID = ENB_DLSCH_UE_DCI DESC = eNodeB downlink UE specific DCI as sent by the PHY layer GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format : int,harq_pid ID = ENB_DLSCH_UE_ACK DESC = eNodeB downlink UE ACK as seen by the PHY layer in process_HARQ_feedback GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid ID = ENB_DLSCH_UE_NACK DESC = eNodeB downlink UE NACK as seen by the PHY layer in process_HARQ_feedback GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid ID = ENB_ULSCH_UE_DCI DESC = eNodeB uplink UE specific DCI as sent by the PHY layer GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid ID = ENB_ULSCH_UE_NO_DCI_RETRANSMISSION DESC = eNodeB uplink UE retransmission due to PHICH NACK (see generate_phich_top) GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid ID = ENB_ULSCH_UE_ACK DESC = eNodeB uplink UE ACK as seen by the PHY layer GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid ID = ENB_ULSCH_UE_NACK DESC = eNodeB uplink UE NACK as seen by the PHY layer GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid ID = ENB_INPUT_SIGNAL DESC = eNodeB received signal in the time domain for a duration of 1ms GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index 6c884129df..37b122323e 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1509,7 +1509,7 @@ void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB, (ulsch_eNB[UE_id]->harq_processes[harq_pid]->rar_alloc == 0) ) { if (ulsch_eNB[UE_id]->harq_processes[harq_pid]->phich_ACK==0 ) { T(T_ENB_ULSCH_UE_NO_DCI_RETRANSMISSION, T_INT(phy_vars_eNB->Mod_id), T_INT(phy_vars_eNB->proc[sched_subframe].frame_tx), - T_INT(subframe), T_INT(UE_id), T_INT(ulsch_eNB[UE_id]->rnti)); + T_INT(subframe), T_INT(UE_id), T_INT(ulsch_eNB[UE_id]->rnti), T_INT(harq_pid)); LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d, subframe %d : PHICH NACK / (no format0 DCI) Setting subframe_scheduling_flag\n", phy_vars_eNB->Mod_id,harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index f0d811a3ac..7973d4f75a 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1164,9 +1164,6 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e else UE_id = i; - T(T_ENB_DLSCH_UE_DCI, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), - T_INT(DCI_pdu->dci_alloc[i].rnti), T_INT(DCI_pdu->dci_alloc[i].format)); - if (UE_id>=0) { if ((frame%100)==0) { LOG_D(PHY,"Frame %3d, SF %d \n",frame,subframe); @@ -1198,6 +1195,10 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e phy_vars_eNB->Mod_id,DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); + T(T_ENB_DLSCH_UE_DCI, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), + T_INT(DCI_pdu->dci_alloc[i].rnti), T_INT(DCI_pdu->dci_alloc[i].format), + T_INT(phy_vars_eNB->dlsch_eNB[(int)UE_id][0]->current_harq_pid)); + phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE; LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16") => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, @@ -1251,7 +1252,7 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e UE_id = i; T(T_ENB_ULSCH_UE_DCI, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), - T_INT(DCI_pdu->dci_alloc[i].rnti)); + T_INT(DCI_pdu->dci_alloc[i].rnti), T_INT(harq_pid)); if (UE_id<0) { LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Unknown UE_id for rnti %"PRIx16"\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti); @@ -2056,7 +2057,8 @@ void process_HARQ_feedback(uint8_t UE_id, dlsch->rnti,dl_harq_pid[m],M,m,mp,dlsch_harq_proc->round); #endif - T(T_ENB_DLSCH_UE_NACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), T_INT(dlsch->rnti)); + T(T_ENB_DLSCH_UE_NACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), T_INT(dlsch->rnti), + T_INT(dl_harq_pid[m])); if (dlsch_harq_proc->round == 0) ue_stats->dlsch_NAK_round0++; @@ -2091,7 +2093,8 @@ void process_HARQ_feedback(uint8_t UE_id, dlsch->rnti,dl_harq_pid[m],dlsch_harq_proc->round); #endif - T(T_ENB_DLSCH_UE_ACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), T_INT(dlsch->rnti)); + T(T_ENB_DLSCH_UE_ACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), T_INT(dlsch->rnti), + T_INT(dl_harq_pid[m])); ue_stats->dlsch_ACK[dl_harq_pid[m]][dlsch_harq_proc->round]++; @@ -2798,7 +2801,8 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ } if (ret == (1+MAX_TURBO_ITERATIONS)) { - T(T_ENB_ULSCH_UE_NACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(phy_vars_eNB->ulsch_eNB[i]->rnti)); + T(T_ENB_ULSCH_UE_NACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(phy_vars_eNB->ulsch_eNB[i]->rnti), + T_INT(harq_pid)); /* if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round>0) { @@ -2923,7 +2927,8 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ } } // ulsch in error else { - T(T_ENB_ULSCH_UE_ACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(phy_vars_eNB->ulsch_eNB[i]->rnti)); + T(T_ENB_ULSCH_UE_ACK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(phy_vars_eNB->ulsch_eNB[i]->rnti), + T_INT(harq_pid)); if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) { LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n", From 6f72af21c29396a0d1f0e865cc7d13709da29dc2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 10:46:48 +0200 Subject: [PATCH 206/217] make tick larger in ticktime.c 3 pixels wide look better than 1 --- common/utils/T/tracer/view/ticktime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/view/ticktime.c b/common/utils/T/tracer/view/ticktime.c index 90ded4dd43..1e1c7352a0 100644 --- a/common/utils/T/tracer/view/ticktime.c +++ b/common/utils/T/tracer/view/ticktime.c @@ -147,7 +147,8 @@ static void *ticktime_thread(void *_this) continue; p = &this->p[l]; /* TODO: only one call */ - timeline_add_points_silent(this->g, this->w, p->line, p->color, &i, 1); + int x[3] = {i==0?i:i-1, i, i==width-1?i:i+1}; + timeline_add_points_silent(this->g, this->w, p->line, p->color, x, 3); } } From f9843f46bc7a18357ca58356e4fd4cc27aeb98e0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 10:51:24 +0200 Subject: [PATCH 207/217] add UL/DL harq ticktime view to enb.c --- common/utils/T/tracer/enb.c | 174 ++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index ee35464ba6..08809d60dc 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -10,6 +10,7 @@ #include "logger/logger.h" #include "view/view.h" #include "gui/gui.h" +#include "filter/filter.h" #include "utils.h" #include "../T_defs.h" #include "event_selector.h" @@ -173,6 +174,178 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_time(timeview, 7, new_color(g, "#f22"), 3600*1000); logger_add_view(timelog, subview); + /* harq processes' ticktime view */ + widget_add_child(g, top_container, + new_label(g,"DL/UL HARQ (x8) "), -1); + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + timeline_plot = new_timeline(g, 512, 2*8+2, 3); + widget_add_child(g, line, timeline_plot, -1); + container_set_child_growable(g, line, timeline_plot, 1); + for (i = 0; i < 2*8+2; i++) + timeline_set_subline_background_color(g, timeline_plot, i, + new_color(g, i==0 || i==9 ? "#ddd" : (i%9)&1 ? "#e6e6e6" : "#eee")); + timeview = new_view_ticktime(10, g, timeline_plot); + ticktime_set_tick(timeview, + new_ticklog(h, database, "ENB_MASTER_TICK", "frame", "subframe")); + /* tick */ + timelog = new_ticklog(h, database, "ENB_MASTER_TICK", "frame", "subframe"); + /* tick on DL view */ + subview = new_subview_ticktime(timeview, 0, new_color(g,"#bbb"), 3600*1000); + logger_add_view(timelog, subview); + /* tick on UL view */ + subview = new_subview_ticktime(timeview, 9, new_color(g,"#bbb"), 3600*1000); + logger_add_view(timelog, subview); + /* DL harq pids */ + for (i = 0; i < 8; i++) { + timelog = new_ticklog(h, database, "ENB_DLSCH_UE_DCI", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+1, + new_color(g,"#55f"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_DCI", "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_DCI", "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_DCI", "eNB_ID"), + filter_int(0))))); + } + /* DL ACK */ + for (i = 0; i < 8; i++) { + timelog = new_ticklog(h, database, "ENB_DLSCH_UE_ACK", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+1, + new_color(g,"#282"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_ACK", "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_ACK", "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_ACK", "eNB_ID"), + filter_int(0))))); + } + /* DL NACK */ + for (i = 0; i < 8; i++) { + timelog = new_ticklog(h, database, "ENB_DLSCH_UE_NACK", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+1, + new_color(g,"#f22"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_NACK", "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_NACK", "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_DLSCH_UE_NACK", "eNB_ID"), + filter_int(0))))); + } + /* UL harq pids */ + for (i = 0; i < 8; i++) { + /* first transmission */ + timelog = new_ticklog(h, database, "ENB_ULSCH_UE_DCI", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+9+1, + new_color(g,"#55f"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_DCI", "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_DCI", "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_DCI", "eNB_ID"), + filter_int(0))))); + /* retransmission */ + timelog = new_ticklog(h, database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+9+1, + new_color(g,"#99f"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", + "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", + "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", + "eNB_ID"), + filter_int(0))))); + } + /* UL ACK */ + for (i = 0; i < 8; i++) { + timelog = new_ticklog(h, database, "ENB_ULSCH_UE_ACK", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+9+1, + new_color(g,"#282"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_ACK", "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_ACK", "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_ACK", "eNB_ID"), + filter_int(0))))); + } + /* UL NACK */ + for (i = 0; i < 8; i++) { + timelog = new_ticklog(h, database, "ENB_ULSCH_UE_NACK", + "frame", "subframe"); + subview = new_subview_ticktime(timeview, i+9+1, + new_color(g,"#f22"), 3600*1000); + logger_add_view(timelog, subview); + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + logger_set_filter(timelog, + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_NACK", "harq_pid"), + filter_int(i)), + filter_and( + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_NACK", "UE_id"), + filter_int(0)), + filter_eq( + filter_evarg(database, "ENB_ULSCH_UE_NACK", "eNB_ID"), + filter_int(0))))); + } + /* phy/mac/rlc/pdcp/rrc textlog */ line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); @@ -346,6 +519,7 @@ int main(int n, char **v) on_off(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", is_on, 1); on_off(database, "ENB_ULSCH_UE_ACK", is_on, 1); on_off(database, "ENB_ULSCH_UE_NACK", is_on, 1); + on_off(database, "ENB_MASTER_TICK", is_on, 1); on_off(database, "LEGACY_RRC_INFO", is_on, 1); on_off(database, "LEGACY_RRC_ERROR", is_on, 1); From b0e50688ee6de1dcdb0118b8150f47d88edaa2a1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 16:20:32 +0200 Subject: [PATCH 208/217] cleanup: introduce ticktime_filter() --- common/utils/T/tracer/enb.c | 98 +++++++------------------------------ 1 file changed, 18 insertions(+), 80 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 08809d60dc..d008866f9e 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -86,6 +86,17 @@ static void *gui_thread(void *_g) return NULL; } +static filter *ticktime_filter(void *database, char *event, int i) +{ + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + return + filter_and( + filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)), + filter_and( + filter_eq(filter_evarg(database, event, "UE_id"), filter_int(0)), + filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0)))); +} + static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) { widget *main_window; @@ -205,17 +216,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_DCI", "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_DCI", "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_DCI", "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_DLSCH_UE_DCI", i)); } /* DL ACK */ for (i = 0; i < 8; i++) { @@ -226,17 +227,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_ACK", "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_ACK", "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_ACK", "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_DLSCH_UE_ACK", i)); } /* DL NACK */ for (i = 0; i < 8; i++) { @@ -247,17 +238,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_NACK", "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_NACK", "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_DLSCH_UE_NACK", "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_DLSCH_UE_NACK", i)); } /* UL harq pids */ for (i = 0; i < 8; i++) { @@ -269,17 +250,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_DCI", "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_DCI", "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_DCI", "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_ULSCH_UE_DCI", i)); /* retransmission */ timelog = new_ticklog(h, database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe"); @@ -288,20 +259,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", - "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", - "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", - "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", i)); } /* UL ACK */ for (i = 0; i < 8; i++) { @@ -312,17 +270,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_ACK", "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_ACK", "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_ACK", "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_ULSCH_UE_ACK", i)); } /* UL NACK */ for (i = 0; i < 8; i++) { @@ -333,17 +281,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) logger_add_view(timelog, subview); /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_NACK", "harq_pid"), - filter_int(i)), - filter_and( - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_NACK", "UE_id"), - filter_int(0)), - filter_eq( - filter_evarg(database, "ENB_ULSCH_UE_NACK", "eNB_ID"), - filter_int(0))))); + ticktime_filter(database, "ENB_ULSCH_UE_NACK", i)); } /* phy/mac/rlc/pdcp/rrc textlog */ From 57240cc03b69ed9ac2439b7d53cdf7ba95bb92ff Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 17:33:43 +0200 Subject: [PATCH 209/217] switch to utf-8 --- common/utils/T/tracer/gui/x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 6f87de4420..af3d05cc14 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -331,7 +331,7 @@ void x_text_get_dimensions(x_connection *_c, int font, const char *t, struct x_connection *c = _c; XGlyphInfo ext; - XftTextExtents8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext); + XftTextExtentsUtf8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext); *width = ext.width; *height = c->fonts[font]->height; @@ -372,7 +372,7 @@ void x_draw_string(x_connection *_c, x_window *_w, int font, int color, struct x_connection *c = _c; struct x_window *w = _w; int tlen = strlen(t); - XftDrawString8(w->xft, &c->xft_colors[color], c->fonts[font], + XftDrawStringUtf8(w->xft, &c->xft_colors[color], c->fonts[font], x, y, (const unsigned char *)t, tlen); } From dd55be2c67606c9d7f48dfdfc41dbf139ef41337 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Jun 2016 17:35:41 +0200 Subject: [PATCH 210/217] cleanup --- common/utils/T/tracer/enb.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index d008866f9e..f5e5e2ebb6 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -88,7 +88,7 @@ static void *gui_thread(void *_g) static filter *ticktime_filter(void *database, char *event, int i) { - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ + /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0" */ return filter_and( filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)), @@ -214,7 +214,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+1, new_color(g,"#55f"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_DLSCH_UE_DCI", i)); } @@ -225,7 +224,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+1, new_color(g,"#282"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_DLSCH_UE_ACK", i)); } @@ -236,7 +234,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+1, new_color(g,"#f22"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_DLSCH_UE_NACK", i)); } @@ -248,7 +245,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+9+1, new_color(g,"#55f"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_ULSCH_UE_DCI", i)); /* retransmission */ @@ -257,7 +253,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+9+1, new_color(g,"#99f"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_ULSCH_UE_NO_DCI_RETRANSMISSION", i)); } @@ -268,7 +263,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+9+1, new_color(g,"#282"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_ULSCH_UE_ACK", i)); } @@ -279,7 +273,6 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) subview = new_subview_ticktime(timeview, i+9+1, new_color(g,"#f22"), 3600*1000); logger_add_view(timelog, subview); - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0 */ logger_set_filter(timelog, ticktime_filter(database, "ENB_ULSCH_UE_NACK", i)); } From 416491821dcbbfbab69afc373c4dac266bf42f55 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 10:44:42 +0200 Subject: [PATCH 211/217] add mac/rlc/pdcp messages' definitions to T_messages.txt to be refined, it's rough --- common/utils/T/T_messages.txt | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 1d76d35a8a..ab3928f419 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -62,6 +62,60 @@ ID = PUCCH_1_ENERGY GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold +#MAC logs +ID = ENB_MAC_UE_DL_SDU + DESC = MAC downlink SDU for an UE coming from RLC to MAC + GROUP = ALL:MAC:ENB + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,lcid : int,length +ID = ENB_MAC_UE_UL_SCHEDULE + DESC = MAC uplink UE scheduling decision + GROUP = ALL:MAC:ENB + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,mcs : int,first_rb : int,nb_rb : int,TBS +ID = ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION + DESC = MAC uplink UE scheduling retransmission decision + GROUP = ALL:MAC:ENB + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,mcs : int,first_rb : int,nb_rb : int,round +ID = ENB_MAC_UE_UL_PDU + DESC = MAC uplink UE received PDU + GROUP = ALL:MAC:ENB + 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_SDU + DESC = MAC uplink UE received SDU + GROUP = ALL:MAC:ENB + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,lcid : int,length +ID = ENB_MAC_UE_UL_CE + DESC = MAC uplink UE received control element + GROUP = ALL:MAC:ENB + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,ce + +#RLC logs +ID = ENB_RLC_DL + DESC = RLC downlink data + GROUP = ALL:RLC:ENB + FORMAT = int,eNB_ID : int,rnti : int,rb_id : int,length +ID = ENB_RLC_UL + DESC = RLC uplink data + GROUP = ALL:RLC:ENB + FORMAT = int,eNB_ID : int,rnti : int,rb_id : int,length +ID = ENB_RLC_MAC_DL + DESC = RLC downlink data + GROUP = ALL:RLC:ENB + FORMAT = int,eNB_ID : int,rnti : int,rb_id : int,length +ID = ENB_RLC_MAC_UL + DESC = RLC uplink data + GROUP = ALL:RLC:ENB + FORMAT = int,eNB_ID : int,rnti : int,rb_id : int,length + +#PDCP logs +ID = ENB_PDCP_UL + DESC = PDCP uplink data + GROUP = ALL:PDCP:ENB + FORMAT = int,eNB_ID : int,rnti : int,rb_id : int,length +ID = ENB_PDCP_DL + DESC = PDCP uplink data + GROUP = ALL:PDCP:ENB + FORMAT = int,eNB_ID : int,rnti : int,rb_id : int,length + #RRC logs ID = ENB_RRC_CONNECTION_SETUP_COMPLETE DESC = RRC connection setup complete From d7e072a4138bf4e913d5947da9ad60130620952f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 10:46:45 +0200 Subject: [PATCH 212/217] MAC tracing in the code --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 9 +++++++++ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 2a52d8779a..d9fd72e3f9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -833,6 +833,9 @@ schedule_ue_spec( DCCH, (char *)&dlsch_buffer[sdu_lengths[0]]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); + LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]); sdu_length_total = sdu_lengths[0]; sdu_lcids[0] = DCCH; @@ -880,6 +883,9 @@ schedule_ue_spec( DCCH+1, (char *)&dlsch_buffer[sdu_lengths[0]]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DCCH+1), T_INT(sdu_lengths[num_sdus])); + sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; header_len_dcch += 2; @@ -924,6 +930,9 @@ schedule_ue_spec( DTCH, (char*)&dlsch_buffer[sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DTCH), T_INT(sdu_lengths[num_sdus])); + LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] CC_id %d Got %d bytes for DTCH %d \n", module_idP,CC_id,sdu_lengths[num_sdus],DTCH); sdu_lcids[num_sdus] = DTCH; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 493ff11d33..0afdcb653c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -107,13 +107,19 @@ void rx_sdu( LOG_D(MAC,"[eNB %d] CC_id %d Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,CC_idP,rntiP,UE_id); payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP); - + + T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); + eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP; eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP; eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1; // control element for (i=0; inb_rb_ul[harq_pid] = rb_table[rb_table_index]; + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(TBS)); + LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs, first_rb[CC_id],rb_table[rb_table_index], @@ -866,6 +879,10 @@ void schedule_ulsch_rnti(module_id_t module_idP, } + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(round)); + LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], From 10dbc33e01cab6778c397315b9a3e373b2a38bb0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 10:47:42 +0200 Subject: [PATCH 213/217] add RLC traces to the code --- openair2/LAYER2/RLC/rlc.c | 11 +++++++++++ openair2/LAYER2/RLC/rlc_mac.c | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index e19c6b0b0a..e4c51a61fb 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -359,6 +359,11 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, #endif +#if T_TRACER + if (ctxt_pP->enb_flag) + T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); +#endif + if (MBMS_flagP) { AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX); } else { @@ -571,6 +576,12 @@ void rlc_data_ind ( rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP); #endif +#if T_TRACER + if (ctxt_pP->enb_flag) + T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); +#endif + + pdcp_data_ind ( ctxt_pP, srb_flagP, diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index 73f323f14b..3bde40888f 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -221,6 +221,11 @@ tbs_size_t mac_rlc_data_req( ; } +#if T_TRACER + if (enb_flagP) + T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(rntiP), T_INT(channel_idP), T_INT(ret_tb_size)); +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_OUT); return ret_tb_size; } @@ -276,6 +281,10 @@ void mac_rlc_data_ind ( #endif +#if T_TRACER + if (enb_flagP) + T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(rntiP), T_INT(channel_idP), T_INT(tb_sizeP)); +#endif if (MBMS_flagP) { if (BOOL_NOT(enb_flagP)) { From 262cda6199e7f883b15cd7b4aae9b8ac1e351524 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 10:48:13 +0200 Subject: [PATCH 214/217] add PDCP traces to the code --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index f25e921570..40a1058409 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -111,6 +111,11 @@ boolean_t pdcp_data_req( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN); CHECK_CTXT_ARGS(ctxt_pP); +#if T_TRACER + if (ctxt_pP->enb_flag != ENB_FLAG_NO) + T(T_ENB_PDCP_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); +#endif + if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); } else { @@ -458,6 +463,11 @@ pdcp_data_ind( LOG_F(PDCP,"\n"); #endif +#if T_TRACER + if (ctxt_pP->enb_flag != ENB_FLAG_NO) + T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); +#endif + if (MBMS_flagP) { AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u rnti %x!\n", From 468020879ee7b8015921931d594296660d6b1385 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 10:48:39 +0200 Subject: [PATCH 215/217] enb.c logs MAC/RLC/PDCP very basic, to be refined, find a nice way to display (plot? text?) protocol data movement --- common/utils/T/tracer/enb.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index f5e5e2ebb6..8e8f3d8e72 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -19,6 +19,9 @@ typedef struct { view *phyview; + view *macview; + view *rlcview; + view *pdcpview; view *rrcview; view *legacy; } enb_gui; @@ -302,6 +305,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) widget_add_child(g, col, text, -1); container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); + e->macview = textview; line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); @@ -316,6 +320,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) widget_add_child(g, col, text, -1); container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); + e->rlcview = textview; /* pdcp */ col = new_container(g, VERTICAL); @@ -326,6 +331,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database) widget_add_child(g, col, text, -1); container_set_child_growable(g, col, text, 1); textview = new_view_textlist(10000, 10, g, text); + e->pdcpview = textview; line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); @@ -465,6 +471,22 @@ int main(int n, char **v) view_add_log(eg.phyview, "ENB_ULSCH_UE_ACK", h, database, is_on); view_add_log(eg.phyview, "ENB_ULSCH_UE_NACK", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_DL_SDU", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_SCHEDULE", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION", + h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_PDU", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_SDU", h, database, is_on); + view_add_log(eg.macview, "ENB_MAC_UE_UL_CE", h, database, is_on); + + view_add_log(eg.rlcview, "ENB_RLC_DL", h, database, is_on); + view_add_log(eg.rlcview, "ENB_RLC_UL", h, database, is_on); + view_add_log(eg.rlcview, "ENB_RLC_MAC_DL", h, database, is_on); + view_add_log(eg.rlcview, "ENB_RLC_MAC_UL", h, database, is_on); + + view_add_log(eg.pdcpview, "ENB_PDCP_UL", h, database, is_on); + view_add_log(eg.pdcpview, "ENB_PDCP_DL", h, database, is_on); + view_add_log(eg.rrcview, "ENB_RRC_CONNECTION_SETUP_COMPLETE", h, database, is_on); view_add_log(eg.rrcview, "ENB_RRC_SECURITY_MODE_COMMAND", From e1cc2fe2b81b4569ecc12d59f4123b40b51e2f91 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 12:12:03 +0200 Subject: [PATCH 216/217] cleanup after merge --- cmake_targets/CMakeLists.txt | 2 +- openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c | 2 ++ openair1/PHY/LTE_TRANSPORT/pucch.c | 1 - openair1/PHY/TOOLS/lte_phy_scope.c | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index d702157dba..c23b0d1a91 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -238,7 +238,7 @@ add_boolean_option(TEST_OMG False "???") add_boolean_option(DEBUG_OMG False "???") add_boolean_option(XFORMS False "This adds the possibility to see the signal oscilloscope") add_boolean_option(PRINT_STATS False "This adds the possibility to see the status") -add_boolean_option(T_TRACER False "Activate the T tracer, a debugging/monitoring framework" ) +add_boolean_option(T_TRACER False "Activate the T tracer, a debugging/monitoring framework" ) add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 74b6e8cfbb..2bfa6e3f60 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -332,10 +332,12 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB, break; } +#if T_TRACER if (aa == 0) T(T_ENB_UL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(UE_id), T_INT(phy_vars_eNB->proc[sched_subframe].frame_rx), T_INT(subframe), T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4)); +#endif #ifdef DEBUG_CH diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 67d1a5d95a..9dfc1bb358 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1044,7 +1044,6 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe] = (phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023; /* frame not available here - set to -1 for the moment */ -printf("sending %d %d\n", stat_re, stat_im); T(T_PUCCH_1AB_IQ, T_INT(phy_vars_eNB->Mod_id), T_INT(UE_id), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im)); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index fd7c2e014d..4b623fb9dc 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -352,8 +352,8 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED); - fl_set_xyplot_ybounds(form->pucch_comp,-100,100); - fl_set_xyplot_xbounds(form->pucch_comp,-100,100); + fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000); + fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000); fl_set_xyplot_ybounds(form->pucch_comp1,0,80); } From 26c3a6a039f84881421b3448b53d47d383fae9b3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Jun 2016 12:42:44 +0200 Subject: [PATCH 217/217] forgot to include T.h if you compile *without* T it fails because the T macro is interpreted as a function call --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 ++ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index c4a34b55d2..81e1df4dc5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -65,6 +65,8 @@ # include "intertask_interface.h" #endif +#include "T.h" + #define ENABLE_MAC_PAYLOAD_DEBUG //#define DEBUG_eNB_SCHEDULER 1 diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index a156aedc8b..92327572a6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -63,6 +63,8 @@ # include "intertask_interface.h" #endif +#include "T.h" + #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1