Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
alex037yang
OpenXG-RAN
Commits
e15a8094
Commit
e15a8094
authored
Apr 27, 2016
by
Cedric Roux
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first version of a textlog remote logger
parent
dca2143b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
556 additions
and
1 deletion
+556
-1
common/utils/T/tracer/Makefile.remote
common/utils/T/tracer/Makefile.remote
+4
-1
common/utils/T/tracer/event.c
common/utils/T/tracer/event.c
+52
-0
common/utils/T/tracer/event.h
common/utils/T/tracer/event.h
+34
-0
common/utils/T/tracer/handler.c
common/utils/T/tracer/handler.c
+104
-0
common/utils/T/tracer/handler.h
common/utils/T/tracer/handler.h
+16
-0
common/utils/T/tracer/remote.c
common/utils/T/tracer/remote.c
+169
-0
common/utils/T/tracer/textlog.c
common/utils/T/tracer/textlog.c
+168
-0
common/utils/T/tracer/textlog.h
common/utils/T/tracer/textlog.h
+9
-0
No files found.
common/utils/T/tracer/Makefile.remote
View file @
e15a8094
...
...
@@ -11,6 +11,9 @@ OBJS=remote_old.o plot.o database.o gui.o
$(PROG)
:
gui/gui.a $(OBJS)
$(CC)
$(CFLAGS)
-o
$(PROG)
$(OBJS)
gui/gui.a
$(LIBS)
textlog
:
remote.o database.o event.o handler.o textlog.o
$(CC)
$(CFLAGS)
-o
textlog
$^
.PHONY
:
gui/gui.a
gui/gui.a
:
...
...
@@ -22,5 +25,5 @@ gui/gui.a:
main.o
:
../T_IDs.h ../T_defs.h
clean
:
rm
-f
*
.o
$(PROG)
core
rm
-f
*
.o
$(PROG)
core
textlog
cd
gui
&&
make clean
common/utils/T/tracer/event.c
0 → 100644
View file @
e15a8094
#include "event.h"
#include "database.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
event
new_event
(
int
type
,
int
length
,
char
*
buffer
,
void
*
database
)
{
database_event_format
f
;
event
e
;
int
i
;
int
offset
;
e
.
type
=
type
;
e
.
buffer
=
buffer
;
f
=
get_format
(
database
,
type
);
e
.
ecount
=
f
.
count
;
offset
=
0
;
/* setup offsets */
/* TODO: speedup (no strcmp, string event to include length at head) */
for
(
i
=
0
;
i
<
f
.
count
;
i
++
)
{
//e.e[i].offset = offset;
if
(
!
strcmp
(
f
.
type
[
i
],
"int"
))
{
e
.
e
[
i
].
type
=
EVENT_INT
;
e
.
e
[
i
].
i
=
*
(
int
*
)(
&
buffer
[
offset
]);
offset
+=
4
;
}
else
if
(
!
strcmp
(
f
.
type
[
i
],
"string"
))
{
e
.
e
[
i
].
type
=
EVENT_STRING
;
e
.
e
[
i
].
s
=
&
buffer
[
offset
];
while
(
buffer
[
offset
])
offset
++
;
offset
++
;
}
else
if
(
!
strcmp
(
f
.
type
[
i
],
"buffer"
))
{
int
len
;
e
.
e
[
i
].
type
=
EVENT_BUFFER
;
len
=
*
(
int
*
)(
&
buffer
[
offset
]);
e
.
e
[
i
].
bsize
=
len
;
e
.
e
[
i
].
b
=
&
buffer
[
offset
+
sizeof
(
int
)];
offset
+=
len
+
sizeof
(
int
);
}
else
{
printf
(
"unhandled type '%s'
\n
"
,
f
.
type
[
i
]);
abort
();
}
}
if
(
e
.
ecount
==
0
)
{
printf
(
"FORMAT not set in event %d
\n
"
,
type
);
abort
();
}
return
e
;
}
common/utils/T/tracer/event.h
0 → 100644
View file @
e15a8094
#ifndef _EVENT_H_
#define _EVENT_H_
#include "../T_defs.h"
enum
event_arg_type
{
EVENT_INT
,
EVENT_STRING
,
EVENT_BUFFER
};
typedef
struct
{
enum
event_arg_type
type
;
//int offset;
union
{
int
i
;
char
*
s
;
struct
{
int
bsize
;
void
*
b
;
};
};
}
event_arg
;
typedef
struct
{
int
type
;
char
*
buffer
;
event_arg
e
[
T_MAX_ARGS
];
int
ecount
;
}
event
;
event
new_event
(
int
type
,
int
length
,
char
*
buffer
,
void
*
database
);
#endif
/* _EVENT_H_ */
common/utils/T/tracer/handler.c
0 → 100644
View file @
e15a8094
#include "handler.h"
#include "event.h"
#include "database.h"
#include <stdlib.h>
#include <stdio.h>
typedef
void
(
*
handler_function
)(
void
*
p
,
event
e
);
struct
handler_data
{
handler_function
f
;
void
*
p
;
unsigned
long
id
;
};
struct
handler_list
{
struct
handler_data
*
f
;
int
size
;
int
maxsize
;
};
/* internal definition of an event handler */
struct
_event_handler
{
void
*
database
;
struct
handler_list
*
events
;
unsigned
long
next_id
;
};
#if 0
#include <stdio.h>
void handle_event(event_handler *h, event e)
{
int i;
printf("event %s (%d)\n", event_name_from_id(h->database, e.type), e.type);
for (i = 0; i < e.ecount; i++) {
switch (e.e[i].type) {
case EVENT_INT:
printf(" %d: INT %d\n", i, *(int *)&e.buffer[e.e[i].offset]);
break;
case EVENT_STRING:
printf(" %d: STRING '%s'\n", i, &e.buffer[e.e[i].offset]);
break;
case EVENT_BUFFER:
printf(" %d: BUFFER size %d\n", i, *(int *)&e.buffer[e.e[i].offset]);
break;
}
}
}
#endif
void
handle_event
(
event_handler
*
_h
,
event
e
)
{
struct
_event_handler
*
h
=
_h
;
int
i
;
for
(
i
=
0
;
i
<
h
->
events
[
e
.
type
].
size
;
i
++
)
h
->
events
[
e
.
type
].
f
[
i
].
f
(
h
->
events
[
e
.
type
].
f
[
i
].
p
,
e
);
}
event_handler
*
new_handler
(
void
*
database
)
{
struct
_event_handler
*
ret
=
calloc
(
1
,
sizeof
(
struct
_event_handler
));
if
(
ret
==
NULL
)
abort
();
ret
->
database
=
database
;
ret
->
events
=
calloc
(
number_of_ids
(
database
),
sizeof
(
struct
handler_list
));
if
(
ret
->
events
==
NULL
)
abort
();
ret
->
next_id
=
1
;
return
ret
;
}
unsigned
long
register_handler_function
(
event_handler
*
_h
,
int
event_id
,
void
(
*
f
)(
void
*
,
event
),
void
*
p
)
{
struct
_event_handler
*
h
=
_h
;
unsigned
long
ret
=
h
->
next_id
;
struct
handler_list
*
l
;
h
->
next_id
++
;
if
(
h
->
next_id
==
2UL
*
1024
*
1024
*
1024
)
{
printf
(
"%s:%d: this is bad...
\n
"
,
__FILE__
,
__LINE__
);
abort
();
}
l
=
&
h
->
events
[
event_id
];
if
(
l
->
size
==
l
->
maxsize
)
{
l
->
maxsize
+=
16
;
l
->
f
=
realloc
(
l
->
f
,
l
->
maxsize
*
sizeof
(
struct
handler_data
));
if
(
l
->
f
==
NULL
)
abort
();
}
l
->
f
[
l
->
size
].
f
=
f
;
l
->
f
[
l
->
size
].
p
=
p
;
l
->
f
[
l
->
size
].
id
=
ret
;
l
->
size
++
;
return
ret
;
}
void
remove_handler_function
(
event_handler
*
h
,
int
event_id
,
unsigned
long
handler_id
)
{
printf
(
"%s:%d: TODO
\n
"
,
__FILE__
,
__LINE__
);
abort
();
}
common/utils/T/tracer/handler.h
0 → 100644
View file @
e15a8094
#ifndef _HANDLER_H_
#define _HANDLER_H_
typedef
void
event_handler
;
#include "event.h"
event_handler
*
new_handler
(
void
*
database
);
void
handle_event
(
event_handler
*
h
,
event
e
);
unsigned
long
register_handler_function
(
event_handler
*
_h
,
int
event_id
,
void
(
*
f
)(
void
*
,
event
),
void
*
p
);
void
remove_handler_function
(
event_handler
*
h
,
int
event_id
,
unsigned
long
handler_id
);
#endif
/* _HANDLER_H_ */
common/utils/T/tracer/remote.c
0 → 100644
View file @
e15a8094
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "database.h"
#include "event.h"
#include "handler.h"
#include "textlog.h"
#include "../T_defs.h"
#define DEFAULT_REMOTE_PORT 2020
int
get_connection
(
char
*
addr
,
int
port
)
{
struct
sockaddr_in
a
;
socklen_t
alen
;
int
s
,
t
;
printf
(
"waiting for connection on %s:%d
\n
"
,
addr
,
port
);
s
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
s
==
-
1
)
{
perror
(
"socket"
);
exit
(
1
);
}
t
=
1
;
if
(
setsockopt
(
s
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
t
,
sizeof
(
int
)))
{
perror
(
"setsockopt"
);
exit
(
1
);
}
a
.
sin_family
=
AF_INET
;
a
.
sin_port
=
htons
(
port
);
a
.
sin_addr
.
s_addr
=
inet_addr
(
addr
);
if
(
bind
(
s
,
(
struct
sockaddr
*
)
&
a
,
sizeof
(
a
)))
{
perror
(
"bind"
);
exit
(
1
);
}
if
(
listen
(
s
,
5
))
{
perror
(
"bind"
);
exit
(
1
);
}
alen
=
sizeof
(
a
);
t
=
accept
(
s
,
(
struct
sockaddr
*
)
&
a
,
&
alen
);
if
(
t
==
-
1
)
{
perror
(
"accept"
);
exit
(
1
);
}
close
(
s
);
printf
(
"connected
\n
"
);
return
t
;
}
void
usage
(
void
)
{
printf
(
"options:
\n
"
" -d <database file> this option is mandatory
\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,
\n
"
" they will be processed in order
\n
"
" by default, all is off
\n
"
" -r <port> remote side: use given port (default %d)
\n
"
,
DEFAULT_REMOTE_PORT
);
exit
(
1
);
}
int
fullread
(
int
fd
,
void
*
_buf
,
int
count
)
{
char
*
buf
=
_buf
;
int
ret
=
0
;
int
l
;
while
(
count
)
{
l
=
read
(
fd
,
buf
,
count
);
if
(
l
<=
0
)
{
printf
(
"read socket problem
\n
"
);
abort
();
}
count
-=
l
;
buf
+=
l
;
ret
+=
l
;
}
return
ret
;
}
event
get_event
(
int
s
,
char
*
v
,
void
*
d
)
{
int
type
;
int32_t
length
;
fullread
(
s
,
&
length
,
4
);
fullread
(
s
,
&
type
,
sizeof
(
int
));
length
-=
sizeof
(
int
);
fullread
(
s
,
v
,
length
);
return
new_event
(
type
,
length
,
v
,
d
);
}
int
main
(
int
n
,
char
**
v
)
{
char
*
database_filename
=
NULL
;
void
*
database
;
int
port
=
DEFAULT_REMOTE_PORT
;
char
**
on_off_name
;
int
*
on_off_action
;
int
on_off_n
=
0
;
int
*
is_on
;
int
number_of_events
;
int
s
;
int
i
;
char
t
;
int
l
;
event_handler
*
h
;
textlog
*
textlog
;
on_off_name
=
malloc
(
n
*
sizeof
(
char
*
));
if
(
on_off_name
==
NULL
)
abort
();
on_off_action
=
malloc
(
n
*
sizeof
(
int
));
if
(
on_off_action
==
NULL
)
abort
();
for
(
i
=
1
;
i
<
n
;
i
++
)
{
if
(
!
strcmp
(
v
[
i
],
"-h"
)
||
!
strcmp
(
v
[
i
],
"--help"
))
usage
();
if
(
!
strcmp
(
v
[
i
],
"-d"
))
{
if
(
i
>
n
-
2
)
usage
();
database_filename
=
v
[
++
i
];
continue
;
}
if
(
!
strcmp
(
v
[
i
],
"-r"
))
{
if
(
i
>
n
-
2
)
usage
();
port
=
atoi
(
v
[
++
i
]);
continue
;
}
if
(
!
strcmp
(
v
[
i
],
"-on"
))
{
if
(
i
>
n
-
2
)
usage
();
on_off_name
[
on_off_n
]
=
v
[
++
i
];
on_off_action
[
on_off_n
++
]
=
1
;
continue
;
}
if
(
!
strcmp
(
v
[
i
],
"-off"
))
{
if
(
i
>
n
-
2
)
usage
();
on_off_name
[
on_off_n
]
=
v
[
++
i
];
on_off_action
[
on_off_n
++
]
=
0
;
continue
;
}
if
(
!
strcmp
(
v
[
i
],
"-ON"
))
{
on_off_name
[
on_off_n
]
=
NULL
;
on_off_action
[
on_off_n
++
]
=
1
;
continue
;
}
if
(
!
strcmp
(
v
[
i
],
"-OFF"
))
{
on_off_name
[
on_off_n
]
=
NULL
;
on_off_action
[
on_off_n
++
]
=
0
;
continue
;
}
usage
();
}
if
(
database_filename
==
NULL
)
{
printf
(
"ERROR: provide a database file (-d)
\n
"
);
exit
(
1
);
}
database
=
parse_database
(
database_filename
);
number_of_events
=
number_of_ids
(
database
);
is_on
=
calloc
(
number_of_events
,
sizeof
(
int
));
if
(
is_on
==
NULL
)
abort
();
h
=
new_handler
(
database
);
textlog
=
new_textlog
(
h
,
database
,
"ENB_UL_CHANNEL_ESTIMATE"
,
"ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"
);
for
(
i
=
0
;
i
<
on_off_n
;
i
++
)
on_off
(
database
,
on_off_name
[
i
],
is_on
,
on_off_action
[
i
]);
s
=
get_connection
(
"127.0.0.1"
,
port
);
/* send the first message - activate selected traces */
t
=
0
;
if
(
write
(
s
,
&
t
,
1
)
!=
1
)
abort
();
l
=
0
;
for
(
i
=
0
;
i
<
number_of_events
;
i
++
)
if
(
is_on
[
i
])
l
++
;
if
(
write
(
s
,
&
l
,
sizeof
(
int
))
!=
sizeof
(
int
))
abort
();
for
(
l
=
0
;
l
<
number_of_events
;
l
++
)
if
(
is_on
[
l
])
if
(
write
(
s
,
&
l
,
sizeof
(
int
))
!=
sizeof
(
int
))
abort
();
/* read messages */
while
(
1
)
{
char
v
[
T_BUFFER_MAX
];
event
e
;
e
=
get_event
(
s
,
v
,
database
);
handle_event
(
h
,
e
);
}
return
0
;
}
common/utils/T/tracer/textlog.c
0 → 100644
View file @
e15a8094
#include "textlog.h"
#include "handler.h"
#include "database.h"
#include <stdlib.h>
#include <string.h>
enum
format_item_type
{
INSTRING
,
INT
,
STRING
,
BUFFER
};
struct
format_item
{
enum
format_item_type
type
;
union
{
/* INSTRING */
char
*
s
;
/* others */
int
event_arg
;
};
};
struct
textlog
{
char
*
event_name
;
char
*
format
;
void
*
database
;
unsigned
long
handler_id
;
struct
format_item
*
f
;
int
fsize
;
};
#include <stdio.h>
static
void
_event
(
void
*
p
,
event
e
)
{
struct
textlog
*
l
=
p
;
int
i
;
//printf("%s %s\n", l->event_name, l->format);
for
(
i
=
0
;
i
<
l
->
fsize
;
i
++
)
switch
(
l
->
f
[
i
].
type
)
{
case
INSTRING
:
printf
(
"%s"
,
l
->
f
[
i
].
s
);
break
;
case
INT
:
printf
(
"%d"
,
e
.
e
[
l
->
f
[
i
].
event_arg
].
i
);
break
;
case
STRING
:
printf
(
"%s"
,
e
.
e
[
l
->
f
[
i
].
event_arg
].
s
);
break
;
case
BUFFER
:
printf
(
"{buffer size:%d}"
,
e
.
e
[
l
->
f
[
i
].
event_arg
].
bsize
);
break
;
}
printf
(
"
\n
"
);
}
enum
chunk_type
{
C_ERROR
,
C_STRING
,
C_ARG_NAME
,
C_EVENT_NAME
};
struct
chunk
{
enum
chunk_type
type
;
char
*
s
;
enum
format_item_type
it
;
int
event_arg
;
};
/* TODO: speed it up? */
static
int
find_argument
(
char
*
name
,
database_event_format
f
,
enum
format_item_type
*
it
,
int
*
event_arg
)
{
int
i
;
for
(
i
=
0
;
i
<
f
.
count
;
i
++
)
if
(
!
strcmp
(
name
,
f
.
name
[
i
]))
break
;
if
(
i
==
f
.
count
)
return
0
;
*
event_arg
=
i
;
if
(
!
strcmp
(
f
.
type
[
i
],
"int"
))
*
it
=
INT
;
else
if
(
!
strcmp
(
f
.
type
[
i
],
"string"
))
*
it
=
STRING
;
else
if
(
!
strcmp
(
f
.
type
[
i
],
"buffer"
))
*
it
=
BUFFER
;
else
return
0
;
return
1
;
}
static
struct
chunk
next_chunk
(
char
**
s
,
database_event_format
f
)
{
char
*
cur
=
*
s
;
char
*
name
;
enum
format_item_type
it
;
int
event_arg
;
/* argument in [ ] */
if
(
*
cur
==
'['
)
{
*
cur
=
0
;
cur
++
;
name
=
cur
;
/* no \ allowed there */
while
(
*
cur
&&
*
cur
!=
']'
&&
*
cur
!=
'\\'
)
cur
++
;
if
(
*
cur
!=
']'
)
goto
error
;
*
cur
=
0
;
cur
++
;
*
s
=
cur
;
if
(
find_argument
(
name
,
f
,
&
it
,
&
event_arg
)
==
0
)
goto
error
;
return
(
struct
chunk
){
type
:
C_ARG_NAME
,
s
:
name
,
it
:
it
,
event_arg
:
event_arg
};
}
/* { } is name of event (anything in between is smashed) */
if
(
*
cur
==
'{'
)
{
*
cur
=
0
;
cur
++
;
while
(
*
cur
&&
*
cur
!=
'}'
)
cur
++
;
if
(
*
cur
!=
'}'
)
goto
error
;
*
cur
=
0
;
cur
++
;
*
s
=
cur
;
return
(
struct
chunk
){
type
:
C_EVENT_NAME
};
}
/* anything but [ and { is raw string */
/* TODO: deal with \ */
name
=
cur
;
while
(
*
cur
&&
*
cur
!=
'['
&&
*
cur
!=
'{'
)
cur
++
;
*
s
=
cur
;
return
(
struct
chunk
){
type
:
C_STRING
,
s
:
name
};
error:
return
(
struct
chunk
){
type
:
C_ERROR
};
}
textlog
*
new_textlog
(
event_handler
*
h
,
void
*
database
,
char
*
event_name
,
char
*
format
)
{
struct
textlog
*
ret
;
int
event_id
;
database_event_format
f
;
char
*
cur
;
ret
=
calloc
(
1
,
sizeof
(
struct
textlog
));
if
(
ret
==
NULL
)
abort
();
ret
->
event_name
=
strdup
(
event_name
);
if
(
ret
->
event_name
==
NULL
)
abort
();
ret
->
format
=
strdup
(
format
);
if
(
ret
->
format
==
NULL
)
abort
();
ret
->
database
=
database
;
event_id
=
event_id_from_name
(
database
,
event_name
);
ret
->
handler_id
=
register_handler_function
(
h
,
event_id
,
_event
,
ret
);
f
=
get_format
(
database
,
event_id
);
/* we won't get more than strlen(format) "chunks" */
ret
->
f
=
malloc
(
sizeof
(
struct
format_item
)
*
strlen
(
format
));
if
(
ret
->
f
==
NULL
)
abort
();
cur
=
ret
->
format
;
while
(
*
cur
)
{
printf
(
"before chunk cur '%s'
\n
"
,
cur
);
struct
chunk
c
=
next_chunk
(
&
cur
,
f
);
printf
(
"after chunk, cur is '%s' (%d) (type %d)
\n
"
,
cur
,
*
cur
,
c
.
type
);
switch
(
c
.
type
)
{
case
C_ERROR
:
goto
error
;
case
C_STRING
:
ret
->
f
[
ret
->
fsize
].
type
=
INSTRING
;
ret
->
f
[
ret
->
fsize
].
s
=
c
.
s
;
break
;
case
C_ARG_NAME
:
ret
->
f
[
ret
->
fsize
].
type
=
c
.
it
;
ret
->
f
[
ret
->
fsize
].
event_arg
=
c
.
event_arg
;
break
;
case
C_EVENT_NAME
:
ret
->
f
[
ret
->
fsize
].
type
=
INSTRING
;
ret
->
f
[
ret
->
fsize
].
s
=
ret
->
event_name
;
break
;
}
ret
->
fsize
++
;
}
return
ret
;
error:
printf
(
"%s:%d: bad format '%s'
\n
"
,
__FILE__
,
__LINE__
,
format
);
abort
();
}
common/utils/T/tracer/textlog.h
0 → 100644
View file @
e15a8094
#ifndef _TEXTLOG_H_
#define _TEXTLOG_H_
typedef
void
textlog
;
textlog
*
new_textlog
(
void
*
event_handler
,
void
*
database
,
char
*
event_name
,
char
*
format
);
#endif
/* _TEXTLOG_H_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment