put code in the right place for integration into openair
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
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
|
||||
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 T_defs.h
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROG) $(GENIDS) core T_IDs.h
|
||||
@@ -0,0 +1,147 @@
|
||||
#include "T.h"
|
||||
#include <string.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
#ifndef _T_T_T_
|
||||
#define _T_T_T_
|
||||
|
||||
#if T_TRACER
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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 <stdio.h>
|
||||
|
||||
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_ */
|
||||
@@ -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_ */
|
||||
@@ -0,0 +1,430 @@
|
||||
#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
|
||||
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
|
||||
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
|
||||
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
|
||||
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_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
|
||||
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_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
|
||||
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
|
||||
ID = buf_test
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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 <source> <dest>\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;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "T.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -g -pthread -DT_TRACER
|
||||
|
||||
#CFLAGS += -O3 -ffast-math -fomit-frame-pointer
|
||||
|
||||
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
|
||||
|
||||
$(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
|
||||
@@ -0,0 +1,325 @@
|
||||
#include "defs.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -0,0 +1,159 @@
|
||||
#include "defs.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
if (f->tail != NULL) f->tail->next = new;
|
||||
f->tail = new;
|
||||
|
||||
if (pthread_cond_signal(&f->datacond)) abort();
|
||||
if (pthread_mutex_unlock(&f->datalock)) abort();
|
||||
}
|
||||
@@ -0,0 +1,582 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#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;
|
||||
|
||||
#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)
|
||||
{
|
||||
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 */
|
||||
|
||||
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[T_BUFFER_MAX]; \
|
||||
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[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);
|
||||
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();
|
||||
}
|
||||
|
||||
#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;
|
||||
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(
|
||||
"common options:\n"
|
||||
" -d <database file> 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"
|
||||
" -on <GROUP or ID> turn log ON for given GROUP or ID\n"
|
||||
" -off <GROUP or ID> 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 <port> remote side (use given port)\n"
|
||||
" -l <IP address> <port> local side (forwards packets to remote IP:port)\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;
|
||||
int do_xforms = 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
|
||||
|
||||
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], "-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(); 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]);
|
||||
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;
|
||||
|
||||
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]);
|
||||
|
||||
no_database:
|
||||
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);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
/* send the first message - activate all 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();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
#include "defs.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user