Commit 2e64d54e authored by Cedric Roux's avatar Cedric Roux

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...)
parent 806b6a95
...@@ -24,11 +24,16 @@ $(PROG): $(OBJS) ...@@ -24,11 +24,16 @@ $(PROG): $(OBJS)
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) -c -o $@ $< $(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 T_IDs.h: $(GENIDS) T_messages.txt
./$(GENIDS) T_messages.txt T_IDs.h ./$(GENIDS) T_messages.txt T_IDs.h
main.o: T.h T_IDs.h T_defs.h main.o: T.h T_IDs.h T_defs.h
clean: 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 cd tracer && make clean
#include "T.h" #include "T.h"
#include "T_messages.txt.h"
#include <string.h> #include <string.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <arpa/inet.h> #include <arpa/inet.h>
...@@ -125,6 +126,8 @@ void T_connect_to_tracer(char *addr, int port) ...@@ -125,6 +126,8 @@ void T_connect_to_tracer(char *addr, int port)
#ifdef T_USE_SHARED_MEMORY #ifdef T_USE_SHARED_MEMORY
int T_shm_fd; int T_shm_fd;
#endif #endif
unsigned char *buf;
int len;
if (strcmp(addr, "127.0.0.1") != 0) { if (strcmp(addr, "127.0.0.1") != 0) {
printf("error: local tracer must be on same host\n"); printf("error: local tracer must be on same host\n");
...@@ -169,4 +172,29 @@ again: ...@@ -169,4 +172,29 @@ again:
new_thread(T_send_thread, NULL); new_thread(T_send_thread, NULL);
#endif #endif
new_thread(T_receive_thread, NULL); 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);
} }
...@@ -13,6 +13,13 @@ ...@@ -13,6 +13,13 @@
/* size of the local cache for messages (must be pow(2,something)) */ /* size of the local cache for messages (must be pow(2,something)) */
#define T_CACHE_SIZE (8192 * 2) #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 { typedef struct {
volatile int busy; volatile int busy;
char buffer[T_BUFFER_MAX]; char buffer[T_BUFFER_MAX];
......
...@@ -4,7 +4,7 @@ local: ...@@ -4,7 +4,7 @@ local:
make -f Makefile.local make -f Makefile.local
remote: remote:
make -f Makefile.remote tracer_remote textlog enb vcd make -f Makefile.remote textlog enb vcd
clean: clean:
make -f Makefile.local clean make -f Makefile.local clean
......
...@@ -5,15 +5,15 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. ...@@ -5,15 +5,15 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I.
LIBS=-lX11 -lm -lpng -lXft 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 event_selector.o view/view.a gui/gui.a logger/logger.a
$(CC) $(CFLAGS) -o textlog $^ $(LIBS) $(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 event_selector.o view/view.a gui/gui.a logger/logger.a
$(CC) $(CFLAGS) -o enb $^ $(LIBS) $(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 event_selector.o view/view.a gui/gui.a logger/logger.a
$(CC) $(CFLAGS) -o vcd $^ $(LIBS) $(CC) $(CFLAGS) -o vcd $^ $(LIBS)
......
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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();
}
}
#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_ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include "database.h" #include "database.h"
#include "event.h" #include "event.h"
...@@ -14,39 +12,10 @@ ...@@ -14,39 +12,10 @@
#include "../T_defs.h" #include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "openair_logo.h" #include "openair_logo.h"
#include "config.h"
#define DEFAULT_REMOTE_PORT 2021 #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) void usage(void)
{ {
printf( printf(
...@@ -66,45 +35,6 @@ void usage(void) ...@@ -66,45 +35,6 @@ void usage(void)
exit(1); 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) static void *gui_thread(void *_g)
{ {
gui *g = _g; gui *g = _g;
...@@ -228,6 +158,8 @@ int main(int n, char **v) ...@@ -228,6 +158,8 @@ int main(int n, char **v)
database = parse_database(database_filename); database = parse_database(database_filename);
store_config_file(database_filename);
number_of_events = number_of_ids(database); number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int)); is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL) abort(); if (is_on == NULL) abort();
......
#include "event.h" #include "event.h"
#include "database.h" #include "database.h"
#include "utils.h"
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
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 #ifdef T_SEND_TIME
event new_event(struct timespec sending_time, int type, event new_event(struct timespec sending_time, int type,
int length, char *buffer, void *database) int length, char *buffer, void *database)
......
...@@ -37,6 +37,8 @@ typedef struct { ...@@ -37,6 +37,8 @@ typedef struct {
int ecount; int ecount;
} event; } event;
event get_event(int s, char *v, void *d);
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
event new_event(struct timespec sending_time, int type, event new_event(struct timespec sending_time, int type,
int length, char *buffer, void *database); int length, char *buffer, void *database);
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include "database.h" #include "database.h"
#include "event.h" #include "event.h"
...@@ -13,39 +11,10 @@ ...@@ -13,39 +11,10 @@
#include "utils.h" #include "utils.h"
#include "../T_defs.h" #include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "config.h"
#define DEFAULT_REMOTE_PORT 2021 #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) void usage(void)
{ {
printf( printf(
...@@ -67,45 +36,6 @@ void usage(void) ...@@ -67,45 +36,6 @@ void usage(void)
exit(1); 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) static void *gui_thread(void *_g)
{ {
gui *g = _g; gui *g = _g;
...@@ -167,6 +97,8 @@ int main(int n, char **v) ...@@ -167,6 +97,8 @@ int main(int n, char **v)
database = parse_database(database_filename); database = parse_database(database_filename);
store_config_file(database_filename);
number_of_events = number_of_ids(database); number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int)); is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL) abort(); if (is_on == NULL) abort();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void new_thread(void *(*f)(void *), void *data) void new_thread(void *(*f)(void *), void *data)
{ {
...@@ -78,6 +80,51 @@ void socket_send(int socket, void *buffer, int size) ...@@ -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 */ /* buffer */
/****************************************************************************/ /****************************************************************************/
......
...@@ -21,6 +21,8 @@ list *list_append(list *l, void *data); ...@@ -21,6 +21,8 @@ list *list_append(list *l, void *data);
/****************************************************************************/ /****************************************************************************/
void socket_send(int socket, void *buffer, int size); 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 */ /* buffer */
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include "database.h" #include "database.h"
#include "event.h" #include "event.h"
...@@ -13,39 +11,10 @@ ...@@ -13,39 +11,10 @@
#include "utils.h" #include "utils.h"
#include "../T_defs.h" #include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "config.h"
#define DEFAULT_REMOTE_PORT 2021 #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) void usage(void)
{ {
printf( printf(
...@@ -65,45 +34,6 @@ void usage(void) ...@@ -65,45 +34,6 @@ void usage(void)
exit(1); 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) static void *gui_thread(void *_g)
{ {
gui *g = _g; gui *g = _g;
...@@ -199,6 +129,8 @@ int main(int n, char **v) ...@@ -199,6 +129,8 @@ int main(int n, char **v)
database = parse_database(database_filename); database = parse_database(database_filename);
store_config_file(database_filename);
number_of_events = number_of_ids(database); number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int)); is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL) abort(); if (is_on == NULL) abort();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment