merge with latest develop

This commit is contained in:
laurent
2018-09-06 09:43:26 +02:00
204 changed files with 10695 additions and 14709 deletions
+3 -3
View File
@@ -39,7 +39,7 @@
#include "config_userapi.h"
void parse_stringlist(paramdef_t *cfgoptions, char *val)
int parse_stringlist(paramdef_t *cfgoptions, char *val)
{
char *atoken;
char *tokctx;
@@ -64,7 +64,7 @@ int numelt=0;
printf_params("[LIBCONFIG] %s[%i]: %s\n", cfgoptions->optname,i,cfgoptions->strlistptr[i]);
atoken=strtok_r(NULL, ",",&tokctx);
}
cfgoptions->numelt=numelt;
return (cfgoptions->numelt > 0);
}
int processoption(paramdef_t *cfgoptions, char *value)
@@ -96,7 +96,7 @@ char defbool[2]="1";
break;
case TYPE_STRINGLIST:
parse_stringlist(cfgoptions,tmpval);
optisset=parse_stringlist(cfgoptions,tmpval);
break;
case TYPE_UINT32:
case TYPE_INT32:
+138 -101
View File
@@ -54,7 +54,6 @@
mapping log_level_names[] = {
{"error", OAILOG_ERR},
{"file", OAILOG_FILE},
{"warn", OAILOG_WARNING},
{"info", OAILOG_INFO},
{"debug", OAILOG_DEBUG},
@@ -70,18 +69,10 @@ mapping log_options[] = {
};
mapping log_maskmap[] = {
{"prach", DEBUG_PRACH},
{"RU", DEBUG_RU},
{"LTEESTIM", DEBUG_LTEESTIM},
{"ctrlsocket", DEBUG_CTRLSOCKET},
{"UE_PHYPROC", DEBUG_UE_PHYPROC},
{"UE_TIMING", UE_TIMING},
{NULL,-1}
};
mapping log_maskmap[] = LOG_MASKMAP_INIT;
char *log_level_highlight_start[] = {LOG_RED, LOG_GREEN, LOG_ORANGE, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */
char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
char *log_level_highlight_start[] = {LOG_RED, LOG_ORANGE, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */
char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
int write_file_matlab(const char *fname,const char *vname,void *data,int length,int dec,char format)
@@ -243,14 +234,14 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length,
/* get log parameters from configuration file */
void log_getconfig(log_t *g_log) {
char *gloglevel = NULL;
int level;
int consolelog ;
paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC;
paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS];
paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS];
paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)];
paramdef_t logparams_matlab[sizeof(log_maskmap)/sizeof(mapping)];
paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)];
int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
if (ret <0) {
@@ -258,6 +249,7 @@ void log_getconfig(log_t *g_log) {
return;
}
/* set LOG display options (enable/disable color, thread name, level ) */
for(int i=0; i<logparams_defaults[LOG_OPTIONS_IDX].numelt ; i++) {
for(int j=0; log_options[j].name != NULL ; j++) {
if (strcmp(logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i],log_options[j].name) == 0) {
@@ -303,38 +295,40 @@ void log_getconfig(log_t *g_log) {
config_get( logparams_logfile, MAX_LOG_PREDEF_COMPONENTS,CONFIG_STRING_LOG_PREFIX);
/* now set the log levels and infile option, according to what we read */
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
level = map_str_to_int(log_level_names, *(logparams_level[i].strptr));
set_log(i, level,1);
g_log->log_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr));
set_log(i, g_log->log_component[i].level);
if (*(logparams_logfile[i].uptr) == 1)
set_component_filelog(i);
}
/* build then read the debug and matlab parameter array */
/* build then read the debug and dump parameter array */
for (int i=0;log_maskmap[i].name != NULL ; i++) {
sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name);
sprintf(logparams_matlab[i].optname, LOG_CONFIG_MATLAB_FORMAT, log_maskmap[i].name);
sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name);
sprintf(logparams_dump[i].optname, LOG_CONFIG_DUMP_FORMAT, log_maskmap[i].name);
logparams_debug[i].defuintval = 0;
logparams_debug[i].type = TYPE_UINT;
logparams_debug[i].paramflags = PARAMFLAG_BOOL;
logparams_debug[i].uptr = NULL;
logparams_debug[i].chkPptr = NULL;
logparams_debug[i].numelt = 0;
logparams_matlab[i].defuintval = 0;
logparams_matlab[i].type = TYPE_UINT;
logparams_matlab[i].paramflags = PARAMFLAG_BOOL;
logparams_matlab[i].uptr = NULL;
logparams_matlab[i].chkPptr = NULL;
logparams_matlab[i].numelt = 0;
logparams_dump[i].defuintval = 0;
logparams_dump[i].type = TYPE_UINT;
logparams_dump[i].paramflags = PARAMFLAG_BOOL;
logparams_dump[i].uptr = NULL;
logparams_dump[i].chkPptr = NULL;
logparams_dump[i].numelt = 0;
}
config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
config_get( logparams_matlab,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
/* set the debug mask according to the debug parameters values */
for (int i=0; log_maskmap[i].name != NULL ; i++) {
if (*(logparams_debug[i].uptr) )
g_log->debug_mask = g_log->debug_mask | log_maskmap[i].value;
if (*(logparams_matlab[i].uptr) )
g_log->matlab_mask = g_log->matlab_mask | log_maskmap[i].value;
if (*(logparams_dump[i].uptr) )
g_log->dump_mask = g_log->dump_mask | log_maskmap[i].value;
}
/* log globally enabled/disabled */
set_glog_onlinelog(consolelog);
}
int register_log_component(char *name, char *fext, int compidx)
@@ -354,11 +348,9 @@ int computed_compidx=compidx;
}
if (computed_compidx >= 0 && computed_compidx <MAX_LOG_COMPONENTS) {
g_log->log_component[computed_compidx].name = strdup(name);
g_log->log_component[computed_compidx].level = LOG_ERR;
g_log->log_component[computed_compidx].interval = 1;
g_log->log_component[computed_compidx].stream = NULL;
g_log->log_component[computed_compidx].stream = stdout;
g_log->log_component[computed_compidx].filelog = 0;
g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s rounded to ^2 */
g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s */
sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext);
} else {
fprintf(stderr,"{LOG} %s %d Couldn't register componemt %s\n",__FILE__,__LINE__,name);
@@ -421,23 +413,16 @@ int logInit (void)
register_log_component("SCTP","",SCTP);
register_log_component("RRH","",RRH);
register_log_component("X2AP","",X2AP);
register_log_component("LOADER","log",LOADER);
register_log_component("ASN","log",ASN);
for (int i=0 ; log_level_names[i].name != NULL ; i++)
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
g_log->level2string[OAILOG_ERR] = "E"; // ERROR
g_log->level2string[OAILOG_WARNING] = "W"; // WARNING
g_log->level2string[OAILOG_INFO] = "I"; //INFO
g_log->level2string[OAILOG_DEBUG] = "D"; // DEBUG
g_log->level2string[OAILOG_FILE] = "F"; // file
g_log->level2string[OAILOG_TRACE] = "T"; // TRACE
g_log->onlinelog = 1; //online log file
g_log->filelog = 0;
@@ -446,19 +431,6 @@ int logInit (void)
log_getconfig(g_log);
// could put a loop here to check for all comps
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
if (g_log->log_component[i].filelog == 1 ) {
g_log->log_component[i].stream = fopen(g_log->log_component[i].filelog_name,"w");
g_log->log_component[i].fwrite = vfprintf;
} else if (g_log->log_component[i].filelog == 1 ) {
g_log->log_component[i].stream = fopen(g_log->filelog_name,"w");
g_log->log_component[i].fwrite = vfprintf;
} else if (g_log->onlinelog == 1 ) {
g_log->log_component[i].stream = stdout;
g_log->log_component[i].fwrite = vfprintf;
}
}
// set all unused component items to 0, they are for non predefined components
for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
@@ -470,8 +442,6 @@ int logInit (void)
}
char *log_getthreadname(char *threadname, int bufsize) {
int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ;
@@ -483,11 +453,20 @@ int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ;
}
}
int inline log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) {
char threadname[PR_SET_NAME];
return snprintf(log_buffer, buffsize , "%s%s[%s]%c %s %s%s",
log_level_highlight_end[level],
( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]),
g_log->log_component[comp].name,
( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:' '),
( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""),
format,
log_level_highlight_end[level]);
}
void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char* format, ... )
{
char threadname[PR_SET_NAME];
char log_buffer[MAX_LOG_TOTAL];
va_list args;
@@ -496,38 +475,63 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, int le
snprintf(log_buffer, MAX_LOG_TOTAL , "%s%s[%s]%s %s %s",
log_level_highlight_end[level],
( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]),
g_log->log_component[comp].name,
( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:""),
( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""),
format);
g_log->log_component[comp].fwrite(g_log->log_component[comp].stream,log_buffer, args);
log_header(log_buffer,MAX_LOG_TOTAL ,comp, level,format);
g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args);
va_end(args);
}
void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ) {
va_list args;
char *wbuf;
int set_log(int component, int level, int interval)
switch(datatype) {
case LOG_DUMP_DOUBLE:
wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL);
break;
case LOG_DUMP_CHAR:
default:
wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL);
break;
}
if (wbuf != NULL) {
va_start(args, format);
int pos=log_header(wbuf,MAX_LOG_TOTAL ,component, OAILOG_INFO,"");
int pos2=vsprintf(wbuf+pos,format, args);
pos=pos+pos2;
va_end(args);
for (int i=0; i<buffsize; i++) {
switch(datatype) {
case LOG_DUMP_DOUBLE:
pos = pos + sprintf(wbuf+pos,"%04.4lf ", (double)((double *)buffer)[i]);
break;
case LOG_DUMP_CHAR:
default:
pos = pos + sprintf(wbuf+pos,"%02x ", (unsigned char)((unsigned char *)buffer)[i]);
break;
}
}
sprintf(wbuf+pos,"\n");
g_log->log_component[component].print(g_log->log_component[component].stream,wbuf);
free(wbuf);
}
}
int set_log(int component, int level)
{
/* Checking parameters */
DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS),
component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS);
DevCheck((level < NUM_LOG_LEVEL) && (level >= OAILOG_ERR), level, NUM_LOG_LEVEL,
DevCheck((level < NUM_LOG_LEVEL) && (level >= OAILOG_DISABLE), level, NUM_LOG_LEVEL,
OAILOG_ERR);
DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF);
if ( g_log->log_component[component].level != OAILOG_DISABLE )
g_log->log_component[component].savedlevel = g_log->log_component[component].level;
g_log->log_component[component].level = level;
g_log->log_component[component].interval = interval;
return 0;
}
@@ -536,32 +540,67 @@ int set_log(int component, int level, int interval)
void set_glog(int level)
{
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
g_log->log_component[c].level = level;
set_log(c, level);
}
}
void set_glog_onlinelog(int enable)
{
g_log->onlinelog = enable;
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
if ( enable ) {
g_log->log_component[c].level = g_log->log_component[c].savedlevel;
g_log->log_component[c].vprint = vfprintf;
g_log->log_component[c].print = fprintf;
g_log->log_component[c].stream = stdout;
} else {
g_log->log_component[c].level = OAILOG_DISABLE;
}
}
}
void set_glog_filelog(int enable)
{
g_log->filelog = enable;
static FILE *fptr;
if ( enable ) {
fptr = fopen(g_log->filelog_name,"w");
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
close_component_filelog(c);
g_log->log_component[c].stream = fptr;
g_log->log_component[c].filelog = 1;
}
} else {
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
g_log->log_component[c].filelog = 0;
if (fptr != NULL) {
fclose(fptr);
}
g_log->log_component[c].stream = stdout;
}
}
}
void set_component_filelog(int comp)
{
if (g_log->log_component[comp].filelog == 0) {
g_log->log_component[comp].filelog = 1;
if (g_log->log_component[comp].stream == NULL) {
if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) {
g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w");
}
}
g_log->log_component[comp].vprint = vfprintf;
g_log->log_component[comp].print = fprintf;
g_log->log_component[comp].filelog = 1;
}
void close_component_filelog(int comp)
{
g_log->log_component[comp].filelog = 0;
if (g_log->log_component[comp].stream != NULL && g_log->log_component[comp].stream != stdout ) {
fclose(g_log->log_component[comp].stream);
g_log->log_component[comp].stream = stdout;
}
g_log->log_component[comp].vprint = vfprintf;
g_log->log_component[comp].print = fprintf;
}
/*
* for the two functions below, the passed array must have a final entry
@@ -616,15 +655,13 @@ int is_newline( char *str, int size)
void logClean (void)
{
int i;
LOG_I(PHY,"\n");
LOG_UI(PHY,"\n");
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
if (g_log->log_component[i].stream != NULL) {
fclose(g_log->log_component[i].stream);
}
close_component_filelog(i);
}
}
@@ -650,8 +687,8 @@ int test_log(void)
LOG_D(MAC, "1 debug MAC \n");
LOG_W(MAC, "1 warning MAC \n");
set_log(EMU, OAILOG_INFO, FLAG_ONLINE);
set_log(MAC, OAILOG_WARNING, 0);
set_log(EMU, OAILOG_INFO);
set_log(MAC, OAILOG_WARNING);
LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n",
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
@@ -661,7 +698,7 @@ int test_log(void)
LOG_I(MAC, "2 info MAC \n");
set_log(MAC, OAILOG_NOTICE, 1);
set_log(MAC, OAILOG_NOTICE);
LOG_ENTER(MAC);
LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n",
@@ -670,8 +707,8 @@ int test_log(void)
LOG_W(MAC, "3 warning MAC \n");
LOG_I(MAC, "3 info MAC \n");
set_log(MAC, LOG_DEBUG,1);
set_log(EMU, LOG_DEBUG,1);
set_log(MAC, LOG_DEBUG);
set_log(EMU, LOG_DEBUG);
LOG_ENTER(MAC);
LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n",
@@ -681,8 +718,8 @@ int test_log(void)
LOG_I(MAC, "4 info MAC \n");
set_log(MAC, LOG_DEBUG,0);
set_log(EMU, LOG_DEBUG,0);
set_log(MAC, LOG_DEBUG);
set_log(EMU, LOG_DEBUG);
LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n",
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
@@ -691,8 +728,8 @@ int test_log(void)
LOG_I(MAC, "5 info MAC \n");
set_log(MAC, LOG_TRACE,0X07F);
set_log(EMU, LOG_TRACE,0X07F);
set_log(MAC, LOG_TRACE);
set_log(EMU, LOG_TRACE);
LOG_ENTER(MAC);
LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n",
+89 -53
View File
@@ -81,15 +81,14 @@ extern "C" {
* @ingroup _macro
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
* @{*/
# define OAILOG_DISABLE -1 /*!< \brief disable all LOG messages, cannot be used in LOG macros, use only in LOG module */
# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" fuctinalities */
# define OAILOG_WARNING 1 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */
# define OAILOG_INFO 2 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */
# define OAILOG_DEBUG 3 /*!< \brief first level debug-level messages, for developers , may impact real-time behavior */
# define OAILOG_TRACE 4 /*!< \brief second level debug-level messages, for developers ,likely impact real-time behavior*/
# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" fuctinalities */
# define OAILOG_FILE 1 /*!< \brief important informational messages, but everything OK */
# define OAILOG_WARNING 2 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */
# define OAILOG_INFO 3 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */
# define OAILOG_DEBUG 4 /*!< \brief first level debug-level messages, for developers , may impact real-time behavior */
# define OAILOG_TRACE 5 /*!< \brief second level debug-level messages, for developers ,likely impact real-time behavior*/
#define NUM_LOG_LEVEL 6 /*!< \brief the number of message levels users have with LOG */
#define NUM_LOG_LEVEL 5 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/
/* @}*/
@@ -128,21 +127,53 @@ extern "C" {
/** @defgroup macros to identify a debug entity
* @ingroup each macro is a bit mask where the unique bit set identifies an entity to be debugged
* it allows to dynamically activate or not blocks of code
* it allows to dynamically activate or not blocks of code. The LOG_MASKMAP_INIT macro
* is used to map a character string name to each debug bit, it allows to set or clear
* the corresponding bit via the defined name, from the configuration or from the telnet
* server.
* @brief
* @{*/
#define DEBUG_PRACH (1<<0)
#define DEBUG_RU (1<<1)
#define DEBUG_UE_PHYPROC (1<<2)
#define DEBUG_LTEESTIM (1<<3)
#define DEBUG_DLCELLSPEC (1<<4)
#define DEBUG_ULSCH (1<<5)
#define DEBUG_RRC (1<<6)
#define DEBUG_PDCP (1<<7)
#define DEBUG_DFT (1<<8)
#define DEBUG_ASN1 (1<<9)
#define DEBUG_CTRLSOCKET (1<<10)
#define DEBUG_SECURITY (1<<11)
#define DEBUG_NAS (1<<12)
#define UE_TIMING (1<<20)
#define SET_LOG_DEBUG(O) g_log->debug_mask = (g_log->debug_mask | O)
#define CLEAR_LOG_DEBUG(O) g_log->debug_mask = (g_log->debug_mask & (~O))
#define SET_LOG_MATLAB(O) g_log->matlab_mask = (g_log->matlab_mask | O)
#define CLEAR_LOG_MATLAB(O) g_log->matlab_mask = (g_log->matlab_mask & (~O))
#define LOG_MASKMAP_INIT {\
{"PRACH", DEBUG_PRACH},\
{"RU", DEBUG_RU},\
{"UE_PHYPROC", DEBUG_UE_PHYPROC},\
{"LTEESTIM", DEBUG_LTEESTIM},\
{"DLCELLSPEC", DEBUG_DLCELLSPEC},\
{"ULSCH", DEBUG_ULSCH},\
{"RRC", DEBUG_RRC},\
{"PDCP", DEBUG_PDCP},\
{"DFT", DEBUG_DFT},\
{"ASN1", DEBUG_ASN1},\
{"CTRLSOCKET", DEBUG_CTRLSOCKET},\
{"SECURITY", DEBUG_SECURITY},\
{"NAS", DEBUG_NAS},\
{"UE_TIMING", UE_TIMING},\
{NULL,-1}\
}
#define SET_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask | B)
#define CLEAR_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask & (~B))
#define SET_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask | B)
#define CLEAR_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask & (~B))
@@ -183,9 +214,9 @@ typedef enum {
TMR,
USIM,
LOCALIZE,
RRH,
X2AP,
LOADER,
ASN,
MAX_LOG_PREDEF_COMPONENTS,
}
comp_name_t;
@@ -199,17 +230,18 @@ typedef struct {
int value; /*!< \brief integer value of mapping */
} mapping;
typedef int(*log_write_func_t)(FILE *stream, const char *format, va_list ap );
typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap );
typedef int(*log_print_func_t)(FILE *stream, const char *format, ... );
typedef struct {
const char *name;
int level;
int flag;
int interval;
int filelog;
char *filelog_name;
FILE *stream;
log_write_func_t fwrite;
const char *name;
int level;
int savedlevel;
int flag;
int filelog;
char *filelog_name;
FILE *stream;
log_vprint_func_t vprint;
log_print_func_t print;
/* SR: make the log buffer component relative */
char log_buffer[MAX_LOG_TOTAL];
} log_component_t;
@@ -217,13 +249,11 @@ typedef struct {
typedef struct {
log_component_t log_component[MAX_LOG_COMPONENTS];
char* level2string[NUM_LOG_LEVEL];
int onlinelog;
char level2string[NUM_LOG_LEVEL];
int flag;
int filelog;
char* filelog_name;
uint64_t debug_mask;
uint64_t matlab_mask;
uint64_t dump_mask;
} log_t;
@@ -254,14 +284,15 @@ extern log_t *g_log;
/*----------------------------------------------------------------------------*/
int logInit (void);
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
int set_log(int component, int level, int interval);
void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... );
int set_log(int component, int level);
void set_glog(int level);
void set_glog_onlinelog(int enable);
void set_glog_filelog(int enable);
void set_component_filelog(int comp);
void close_component_filelog(int comp);
void set_component_consolelog(int comp);
int map_str_to_int(mapping *map, const char *str);
char *map_int_to_str(mapping *map, int val);
void logClean (void);
@@ -293,7 +324,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
#define LOG_CONFIG_LEVEL_FORMAT "%s_log_level"
#define LOG_CONFIG_LOGFILE_FORMAT "%s_log_infile"
#define LOG_CONFIG_DEBUG_FORMAT "%s_debug"
#define LOG_CONFIG_MATLAB_FORMAT "%s_matlab"
#define LOG_CONFIG_DUMP_FORMAT "%s_dump"
#define LOG_CONFIG_HELP_OPTIONS " list of comma separated options to enable log module behavior. Available options: \n"\
" nocolor: disable color usage in log messages\n"\
@@ -309,7 +340,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define LOG_GLOBALPARAMS_DESC { \
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(g_log->onlinelog), defintval:1, TYPE_INT, 0}, \
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \
}
@@ -319,23 +350,25 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
* @ingroup _macro
* @brief Macro used to call logIt function with different message levels
* @{*/
// debugging macros(g_log->log_component[component].interval?logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0)
#define LOG_DUMP_CHAR 0
#define LOG_DUMP_DOUBLE 1
// debugging macros
#define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */
# if T_TRACER
/* per component, level dependant macros */
# define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0)
# define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0)
# define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0)
# define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0)
# define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0)
# define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0)
# define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0)
# define LOG_F(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_FILE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_FILE, x) ;}} while (0) /* */
/* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */
# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */
# define nfapi_log(FILE, FNC, LN, COMP, LVL, F...) do { if (T_stdout) { logRecord_mt(__FILE__, __FUNCTION__, __LINE__,COMP, LVL, F) ;}} while (0) /* */
/* bitmask dependant macros, to isolate debugging code */
# define LOG_DEBUG_BEGIN(D) if (g_log->debug_mask & D) {
# define LOG_DEBUG_END }
/* bitmask dependant macros, to generate matlab files */
# define LOG_M_BEGIN(D) if (g_log->matlab_mask & D) {
# define LOG_M_END }
# define LOG_DEBUGFLAG(D) (g_log->debug_mask & D)
/* bitmask dependant macros, to generate debug file such as matlab file or message dump */
# define LOG_DUMPFLAG(D) (g_log->dump_mask & D)
# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */
/* define variable only used in LOG macro's */
# define LOG_VAR(A,B) A B
@@ -345,22 +378,22 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
# define LOG_E(c, x...) /* */
# define LOG_D(c, x...) /* */
# define LOG_T(c, x...) /* */
# define LOG_F(c, x...) /* */
# define LOG_DUMPMSG(c, b, s, x...) /* */
# define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...)
# define LOG_DEBUG_BEGIN(D) if (0) {
# define LOG_DEBUG_END }
# define LOG_M_BEGIN(D) if (0) {
# define LOG_M_END }
# define LOG_DEBUGFLAG(D) ( 0 )
# define LOG_DUMPFLAG(D) ( 0 )
# define LOG_M(file, vector, data, len, dec, format)
# define LOG_VAR(A,B)
# endif /* T_TRACER */
/* avoid warnings for variables only used in LOG macro's but set outside debug section */
#define LOG_USEDINLOG_VAR(A,B) __attribute__((unused)) A B
#define GCC_NOTUSED __attribute__((unused))
#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B
/* unfiltered macros, usefull for simulators or messages at init time, before log is configured */
#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)
#define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)
#define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x) ;} while (0) /* */
/* @}*/
@@ -368,9 +401,12 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
* @ingroup _macro
* @brief Macro of some useful functions defined by LOG
* @{*/
#define LOG_ENTER(c) do {LOG_T(c, "Entering\n");}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
#define LOG_EXIT(c) do {LOG_T(c,"Exiting\n"); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */
#define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
#define LOG_ENTER(c) do {LOG_T(c, "Entering %s\n",__FUNCTION__);}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
#define LOG_END(c) do {LOG_T(c, "End of %s\n",__FUNCTION__);}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
#define LOG_EXIT(c) do { LOG_END(c); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */
#define LOG_RETURN(c,r) do {LOG_T(c,"Leaving %s (rc = %08lx)\n", __FUNCTION__ , (unsigned long)(r) );return(r);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
/* @}*/
static __inline__ uint64_t rdtsc(void) {
+7 -7
View File
@@ -39,7 +39,7 @@
/* WARNING: if you edit the enums below, update also string definitions in vcd_signal_dumper.c */
typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB = 0,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB=0,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,
@@ -91,12 +91,12 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM,
VCD_SIGNAL_DUMPER_VARIABLES_CNT,
VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_ALLOC_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
VCD_SIGNAL_DUMPER_VARIABLES_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLES_ITTI_POLL_MSG,
VCD_SIGNAL_DUMPER_VARIABLES_ITTI_RECV_MSG,
VCD_SIGNAL_DUMPER_VARIABLES_ITTI_ALLOC_MSG,
VCD_SIGNAL_DUMPER_VARIABLES_MP_ALLOC,
VCD_SIGNAL_DUMPER_VARIABLES_MP_FREE,
VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX,
VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX,
VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,
+1
View File
@@ -15,4 +15,5 @@ tracer/to_vcd
tracer/extract_input_subframe
tracer/extract_output_subframe
tracer/extract
tracer/multi
tracee/tracee
+12 -3
View File
@@ -13,11 +13,20 @@ $(GENIDS): $(GENIDS_OBJS)
$(CC) $(CFLAGS) -c -o $@ $<
T_messages.txt.h: T_messages.txt
xxd -i T_messages.txt > T_messages.txt.h
xxd -i T_messages.txt T_messages.txt.h
T_IDs.h: $(GENIDS) T_messages.txt
./$(GENIDS) T_messages.txt T_IDs.h
check_vcd:
gcc -Wall -I. -I.. -I../itti -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false)
rm -f ./_check_vcd
.PHONY: check_vcd
clean:
rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h
cd tracer && make clean
rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h _check_vcd
cleanall: clean
cd tracer && $(MAKE) clean
+37 -26
View File
@@ -31,6 +31,12 @@ volatile int _T_freelist_head;
volatile int *T_freelist_head = &_T_freelist_head;
T_cache_t *T_cache;
#if BASIC_SIMULATOR
/* global variables used by T_GET_SLOT, see in T.h */
volatile uint64_t T_next_id;
volatile uint64_t T_active_id;
#endif
static void get_message(int s)
{
char t;
@@ -91,7 +97,7 @@ static void new_thread(void *(*f)(void *), void *data)
/* defined in local_tracer.c */
void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket, char *shm_file);
int local_socket, void *shm_array);
/* We monitor the tracee and the local tracer processes.
* When one dies we forcefully kill the other.
@@ -114,22 +120,31 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
{
int socket_pair[2];
int s;
int T_shm_fd;
int child1, child2;
char shm_file[128];
sprintf(shm_file, "/%s%d", T_SHM_FILENAME, getpid());
int i;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
{ perror("socketpair"); abort(); }
/* setup shared memory */
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (T_cache == MAP_FAILED)
{ perror("mmap"); abort(); }
/* 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;
/* child1 runs the local tracer and child2 (or main) runs the tracee */
child1 = fork(); if (child1 == -1) abort();
if (child1 == 0) {
close(socket_pair[1]);
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0],
shm_file);
T_cache);
exit(0);
}
close(socket_pair[0]);
@@ -138,6 +153,7 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
child2 = fork(); if (child2 == -1) abort();
if (child2 != 0) {
close(socket_pair[1]);
munmap(T_cache, T_CACHE_SIZE * sizeof(T_cache_t));
monitor_and_kill(child1, child2);
}
}
@@ -148,34 +164,29 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
T_socket = s;
/* setup shared memory */
T_shm_fd = shm_open(shm_file, O_RDWR /*| O_SYNC*/, 0666);
shm_unlink(shm_file);
if (T_shm_fd == -1) { perror(shm_file); 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 == MAP_FAILED)
{ perror(shm_file); abort(); }
close(T_shm_fd);
new_thread(T_receive_thread, NULL);
}
void T_Config_Init(void)
{
int T_port; /* by default we wait for the tracer */
int T_nowait; /* default port to listen to to wait for the tracer */
int T_dont_fork; /* default is to fork, see 'T_init' to understand */
int T_port; /* by default we wait for the tracer */
int T_nowait; /* default port to listen to to wait for the tracer */
int T_dont_fork; /* default is to fork, see 'T_init' to understand */
paramdef_t ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC ;
paramdef_t ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC;
/* for a cleaner config file, TTracer params should be defined in a specific section... */
config_get( ttraceparams,sizeof(ttraceparams)/sizeof(paramdef_t),TTRACER_CONFIG_PREFIX);
/* for a cleaner config file, TTracer params should be defined in a
* specific section...
*/
config_get(ttraceparams,
sizeof(ttraceparams) / sizeof(paramdef_t),
TTRACER_CONFIG_PREFIX);
/* compatibility: look for TTracer command line options in root section */
config_process_cmdline( ttraceparams,sizeof(ttraceparams)/sizeof(paramdef_t),NULL);
/* compatibility: look for TTracer command line options in root section */
config_process_cmdline(ttraceparams,
sizeof(ttraceparams) / sizeof(paramdef_t),
NULL);
if (T_stdout == 0) {
if (T_stdout == 0)
T_init(T_port, 1-T_nowait, T_dont_fork);
}
}
+36 -11
View File
@@ -112,13 +112,37 @@ extern volatile int *T_freelist_head;
extern T_cache_t *T_cache;
extern int *T_active;
/* When running the basic simulator, we may fill the T cache too fast.
* Let's not crash if it's full, just wait.
* Let's serialize write accesses to the T cache. For that, we use a
* 'ticket' mechanism. To acquire a T slot the caller needs to own the
* current active ticket. We also wait for the slot to be free if
* it is already in use.
*/
#if BASIC_SIMULATOR
# define T_BASIC_SIMULATOR_WAIT \
while (T_cache[T_LOCAL_slot].busy) usleep(100)
# define T_GET_SLOT \
do { \
extern volatile uint64_t T_next_id; \
extern volatile uint64_t T_active_id; \
uint64_t id; \
/* get a ticket */ \
id = __sync_fetch_and_add(&T_next_id, 1); \
/* wait for our turn */ \
while (id != __sync_fetch_and_add(&T_active_id, 0)) /* busy wait */; \
/* this is our turn, try to acquire the slot until it's free */ \
do { \
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01); \
if (T_LOCAL_busy & 0x01) usleep(100); \
} while (T_LOCAL_busy & 0x01); \
/* check that there are still some tickets */ \
if (__sync_fetch_and_add(&T_active_id, 0) == 0xffffffffffffffff) { \
printf("T: reached the end of times, bye...\n"); \
abort(); \
} \
/* free our ticket, which signals the next waiter that it's its turn */ \
(void)__sync_fetch_and_add(&T_active_id, 1); \
} while (0)
#else
# define T_BASIC_SIMULATOR_WAIT /* */
# define T_GET_SLOT \
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01);
#endif
/* used at header of Tn, allocates buffer */
@@ -126,11 +150,12 @@ extern int *T_active;
char *T_LOCAL_buf; \
int T_LOCAL_size = 0; \
int T_LOCAL_slot; \
int T_LOCAL_busy; \
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); \
T_BASIC_SIMULATOR_WAIT; \
if (T_cache[T_LOCAL_slot].busy) { \
T_GET_SLOT; \
if (T_LOCAL_busy & 0x01) { \
printf("%s:%d:%s: T cache is full - consider increasing its size\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
@@ -142,7 +167,7 @@ extern int *T_active;
#define T_COMMIT() \
T_cache[T_LOCAL_slot].length = T_LOCAL_size; \
__sync_synchronize(); \
T_cache[T_LOCAL_slot].busy = 1; \
(void)__sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x02);
#define T_CHECK_SIZE(len, argnum) \
if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \
@@ -578,10 +603,10 @@ extern int *T_active;
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_TTRACEPARAMS_DESC { \
{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:2021, TYPE_INT, 0}, \
{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0}, \
{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0}, \
{"T_stdout", CONFIG_HLP_STDOUT, PARAMFLAG_BOOL, iptr:&T_stdout, defintval:1, TYPE_INT, 0}, \
{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:2021, TYPE_INT, 0}, \
{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0}, \
{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0}, \
{"T_stdout", CONFIG_HLP_STDOUT, PARAMFLAG_BOOL, iptr:&T_stdout, defintval:1, TYPE_INT, 0}, \
}
+4 -2
View File
@@ -31,13 +31,15 @@
#endif
typedef struct {
/* 'busy' is a bit field
* bit 0: 1 means that slot is acquired by writer
* bit 1: 1 means that slot is ready for consumption
*/
volatile int busy;
char buffer[T_BUFFER_MAX];
int length;
} T_cache_t;
#define T_SHM_FILENAME "/T_shm_segment"
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_FUNCTIONS 190
File diff suppressed because it is too large Load Diff
+249
View File
@@ -0,0 +1,249 @@
/*
* To disable the checks done by this program, see below at the beginning
* of the function 'main'.
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "database.h"
#define T_TRACER 1
#include "T.h"
/* VCD specific defines and includes
* If the codebase changes, it may need to be updated
*/
#define ENB_MODE
#define ENABLE_USE_CPU_EXECUTION_TIME
#include "../LOG/vcd_signal_dumper.c"
void err(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
void err(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
printf("\x1b[31m");
printf("error: ");
vprintf(fmt, ap);
printf("\n"
"\x1b[33m\n"
"You probably added a VCD trace (variable or function) but you did not\n"
"update T_messages.txt and/or T_defs.h in common/utils/T/\n"
"\n"
"Be sure to add the new trace to T_messages.txt, at the right place in the\n"
"file. Do not forget to define VCD_NAME with an identical value as found\n"
"in the array eurecomVariablesNames or eurecomFunctionsNames.\n"
"\n"
"Be sure to update VCD_NUM_FUNCTIONS, VCD_NUM_VARIABLES, VCD_FIRST_FUNCTION\n"
"and VCD_FIRST_VARIABLE in T_defs.h\n"
"\n"
"The same procedure has to be followed when you delete a VCD trace.\n"
"Delete it in T_messages.txt as well and update T_defs.h\n"
"\n"
"You can disable those VCD checks at development time.\n"
"To disable the VCD checks see the file common/utils/T/check_vcd.c\n"
"Do not push any modification that disables the VCD checks to the\n"
"main repository.\n");
printf("\x1b[m\n");
va_end(ap);
exit(1);
}
int main(void)
{
/* to disable the checks done by this program, uncomment the following
* line, ie. remove the leading '//'
*/
//return 0;
void *database = parse_database("T_messages.txt");
int number_of_events;
int first_var = -1;
int last_var;
int first_fun = -1;
int last_fun;
char *prefix;
int prefix_len;
char *name;
char *vcd_name;
int i;
FILE *in;
char *l = NULL;
size_t lsize;
if (database == NULL) err("something wrong with T_messages.txt");
/* check the value of VCD_NUM_FUNCTIONS */
if (VCD_NUM_FUNCTIONS != sizeof(eurecomFunctionsNames) / sizeof(char *))
err("VCD_NUM_FUNCTIONS (%d) must be equal to %zd",
VCD_NUM_FUNCTIONS,
sizeof(eurecomFunctionsNames) / sizeof(char *));
/* check the value of VCD_NUM_VARIABLES */
if (VCD_NUM_VARIABLES != sizeof(eurecomVariablesNames) / sizeof(char *))
err("VCD_NUM_VARIABLES (%d) must be equal to %zd",
VCD_NUM_VARIABLES,
sizeof(eurecomVariablesNames) / sizeof(char *));
number_of_events = number_of_ids(database);
if (number_of_events == 0) err("no event defined in T_messages.txt");
/* T_messages.txt ends with VCD VARIABLES followed by VCD FUNCTIONS
* followed by nothing.
* Let's check.
*/
/* check VCD VARIABLES traces in T_messages.txt */
prefix = "VCD_VARIABLE_";
prefix_len = strlen(prefix);
for (i = 0; i < number_of_events; i++) {
name = event_name_from_id(database, i);
if (strncmp(name, prefix, prefix_len)) continue;
first_var = i;
break;
}
if (first_var == -1)
err("no VCD_VARIABLE_ found in T_messages.txt");
for (; i < number_of_events; i++) {
name = event_name_from_id(database, i);
if (strncmp(name, prefix, prefix_len)) break;
}
last_var = i-1;
/* check VCD FUNCTIONS traces in T_messages.txt */
if (i == number_of_events)
err("no VCD_FUNCTION_ found in T_messages.txt");
prefix = "VCD_FUNCTION_";
prefix_len = strlen(prefix);
first_fun = i;
name = event_name_from_id(database, i);
if (strncmp(name, prefix, prefix_len))
err("last VCD_VARIABLE_ not followed by a VCD_FUNCTION_ in T_messages.txt");
for (; i < number_of_events; i++) {
name = event_name_from_id(database, i);
if (strncmp(name, prefix, prefix_len)) break;
}
if (i != number_of_events)
err("T_messages.txt does not end with a VCD_FUNCTION_ trace");
last_fun = i-1;
if (first_var != (unsigned)VCD_FIRST_VARIABLE)
err("VCD_FIRST_VARIABLE is not correct in T_defs.h");
if (first_fun != (unsigned)VCD_FIRST_FUNCTION)
err("VCD_FIRST_FUNCTION is not correct in T_defs.h");
if (last_var-first_var+1 != VCD_NUM_VARIABLES)
err("VCD_NUM_VARIABLES is not correct in T_defs.h");
if (last_fun-first_fun+1 != VCD_NUM_FUNCTIONS)
err("VCD_NUM_FUNCTIONS is not correct in T_defs.h");
/* check that VCD_NAME is identical to
* eurecomVariablesNames[x]/eurecomFunctionsNames[x]
*/
prefix = "VCD_VARIABLE_";
prefix_len = strlen(prefix);
for (i = 0; i < number_of_events; i++) {
name = event_name_from_id(database, i);
if (strncmp(name, prefix, prefix_len)) continue;
vcd_name = event_vcd_name_from_id(database, i);
if (vcd_name == NULL)
err("%s has no VCD_NAME in T_messages.txt", name);
if (strcmp(vcd_name, eurecomVariablesNames[i - first_var]))
err("%s has a wrong VCD_NAME in T_messages.txt", name);
}
prefix = "VCD_FUNCTION_";
prefix_len = strlen(prefix);
for (i = 0; i < number_of_events; i++) {
name = event_name_from_id(database, i);
if (strncmp(name, prefix, prefix_len)) continue;
vcd_name = event_vcd_name_from_id(database, i);
if (vcd_name == NULL)
err("%s has no VCD_NAME in T_messages.txt", name);
if (strcmp(vcd_name, eurecomFunctionsNames[i - first_fun]))
err("%s has a wrong VCD_NAME in T_messages.txt", name);
}
/* check IDs - these checks are difficult because we parse
* common/utils/LOG/vcd_signal_dumper.h which is expected to
* be formatted as is:
* - define vcd_signal_dump_variables then vcd_signal_dump_functions
* - one VCD_XXXX per line starting with two spaces
* followed by ',' or '=' with no space in between
* - no #ifdef / #if is taken into account
* - we require VCD_SIGNAL_DUMPER_VARIABLES_END and
* VCD_SIGNAL_DUMPER_FUNCTIONS_END at the end of each array,
* each on a line of its own with two spaces before and nothing after.
*
* If these checks fail, consider formatting
* common/utils/LOG/vcd_signal_dumper.h as expected here, if
* it makes sense of course. Otherwise, change the code below.
*
* In common/utils/LOG/vcd_signal_dumper.h a valid name is
* either VCD_SIGNAL_DUMPER_VARIABLES_ABC or
* VCD_SIGNAL_DUMPER_FUNCTIONS_XYZ
* and in T_messages.txt the corresponding name has to be
* VCD_VARIABLE_ABC or VCD_FUNCTION_XYZ
*/
i = first_var;
in = fopen("../LOG/vcd_signal_dumper.h", "r");
if (in == NULL) err("could not open ../LOG/vcd_signal_dumper.h");
while (1) {
char *x = " VCD_SIGNAL_DUMPER_VARIABLES_";
ssize_t r;
free(l);
l = NULL;
lsize = 0;
r = getline(&l, &lsize, in);
if (r == -1) break;
if (!strcmp(l, " VCD_SIGNAL_DUMPER_VARIABLES_END\n")) break;
/* remove ',' or '=' if found */
{ char *s=l; while (*s) { if (*s==','||*s=='=') { *s=0; break; } s++; } }
if (strncmp(l, x, strlen(x))) continue;
if (!(i >= first_var && i <= last_var))
err("T_messages.txt is not correct with respect to VCD VARIABLES");
name = event_name_from_id(database, i);
if (strcmp(l+strlen(x), name+strlen("VCD_VARIABLE_")))
err("%s is not correct in T_messages.txt", name);
i++;
}
if (i != last_var + 1) err("VCD VARIABLES wrong in T_messages.txt");
while (1) {
char *x = " VCD_SIGNAL_DUMPER_FUNCTIONS_";
ssize_t r;
free(l);
l = NULL;
lsize = 0;
r = getline(&l, &lsize, in);
if (r == -1) break;
if (!strcmp(l, " VCD_SIGNAL_DUMPER_FUNCTIONS_END\n")) break;
/* remove ',' or '=' if found */
{ char *s=l; while (*s) { if (*s==','||*s=='=') { *s=0; break; } s++; } }
if (strncmp(l, x, strlen(x))) continue;
if (!(i >= first_fun && i <= last_fun))
err("T_messages.txt is not correct with respect to VCD FUNCTIONS");
name = event_name_from_id(database, i);
if (strcmp(l+strlen(x), name+strlen("VCD_FUNCTION_")))
err("%s is not correct in T_messages.txt", name);
i++;
}
fclose(in);
if (i != last_fun + 1) err("VCD FUNCTIONS wrong in T_messages.txt");
return 0;
}
+11 -10
View File
@@ -14,21 +14,21 @@ int cmp(const void *p1, const void *p2)
}
/* return 1 if s was not already known, 0 if it was */
int new_unique_id(char *s)
int new_unique_id(char *s, char *input_file)
{
if (unique_ids_size)
if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) {
printf("FATAL: ID %s is not unique\n", s);
printf("error: ID %s is not unique in %s\n", s, input_file);
return 0;
}
if (unique_ids_size == unique_ids_maxsize) {
unique_ids_maxsize += 256;
unique_ids = realloc(unique_ids, unique_ids_maxsize * sizeof(char *));
if (unique_ids == NULL) { printf("out of memory\n"); abort(); }
if (unique_ids == NULL) { printf("erorr: 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(); }
{ printf("erorr: out of memory\n"); abort(); }
unique_ids_size++;
qsort(unique_ids, unique_ids_size, sizeof(char *), cmp);
return 1;
@@ -43,7 +43,8 @@ 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); }
if (bufname == NULL)
{ printf("erorr: memory allocation error\n"); exit(1); }
}
bufname[bufname_size] = c;
bufname_size++;
@@ -58,7 +59,8 @@ 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); }
if (bufvalue == NULL)
{ printf("error: memory allocation error\n"); exit(1); }
}
bufvalue[bufvalue_size] = c;
bufvalue_size++;
@@ -119,7 +121,7 @@ int main(int n, char **v)
char *in_name;
char *out_name;
if (n != 3) { printf("gimme <source> <dest>\n"); exit(1); }
if (n != 3) { printf("error: gimme <source> <dest>\n"); exit(1); }
n = 0;
@@ -134,14 +136,13 @@ int main(int n, char **v)
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);
printf("error: bad value '%s' (no space at the end please!)\n", value);
unlink(out_name);
exit(1);
}
if (!strcmp(name, "ID")) {
if (!new_unique_id(value)) { unlink(out_name); exit(1); }
if (!new_unique_id(value, in_name)) { unlink(out_name); exit(1); }
fprintf(out, "#define T_%s T_ID(%d)\n", value, n);
n++;
}
+10 -30
View File
@@ -337,54 +337,34 @@ static void forward(void *_forwarder, char *buf, int size)
static void wait_message(void)
{
while (T_local_cache[T_busylist_head].busy == 0) usleep(1000);
}
static void init_shm(char *shm_file)
{
int i;
int s = shm_open(shm_file, O_RDWR | O_CREAT /*| O_SYNC*/, 0666);
if (s == -1) { perror(shm_file); abort(); }
if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t)))
{ perror(shm_file); abort(); }
T_local_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED, s, 0);
if (T_local_cache == MAP_FAILED)
{ perror(shm_file); abort(); }
close(s);
/* let's garbage the memory to catch some potential problems
* (think multiprocessor sync issues, barriers, etc.)
*/
memset(T_local_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t));
for (i = 0; i < T_CACHE_SIZE; i++) T_local_cache[i].busy = 0;
while ((T_local_cache[T_busylist_head].busy & 0x02) == 0) usleep(1000);
}
void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket, char *shm_file)
int local_socket, void *shm_array)
{
int s;
int port = remote_port;
int dont_wait = wait_for_tracer ? 0 : 1;
void *f;
printf("local tracer starting\n");
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR){
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
printf("local tracer received SIGPIPE\n");
abort();
}
}
T_local_cache = shm_array;
init_shm(shm_file);
s = local_socket;
printf("local tracer starting step 2\n");
if (dont_wait) {
char t = 2;
printf("local tracer in no wait mode \n");
if (write(s, &t, 1) != 1) abort();
}
printf("local tracer starting step 3\n");
f = forwarder(port, s);
printf("local tracer main loop.... \n");
/* read messages */
while (1) {
wait_message();
+14 -11
View File
@@ -7,7 +7,7 @@ LIBS=-lm
XLIBS=-lX11 -lpng -lXft
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
extract_input_subframe extract_output_subframe to_vcd extract
extract_input_subframe extract_output_subframe to_vcd extract multi
record: utils.o record.o database.o config.o
$(CC) $(CFLAGS) -o record $^ $(LIBS)
@@ -57,19 +57,22 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \
config.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
multi: multi.o utils.o database.o config.o
$(CC) $(CFLAGS) -o multi $^ $(LIBS)
.PHONY: all gui/gui.a view/view.a logger/logger.a filter/filter.a
gui/gui.a:
cd gui && make
cd gui && $(MAKE)
view/view.a:
cd view && make
cd view && $(MAKE)
logger/logger.a:
cd logger && make
cd logger && $(MAKE)
filter/filter.a:
cd filter && make
cd filter && $(MAKE)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
@@ -77,9 +80,9 @@ filter/filter.a:
clean:
rm -f *.o core tracer_remote textlog enb ue vcd record replay
rm -f extract_config macpdu2wireshark extract_input_subframe
rm -f extract_output_subframe to_vcd extract
cd gui && make clean
cd view && make clean
cd logger && make clean
cd filter && make clean
cd hacks && make clean
rm -f extract_output_subframe to_vcd extract multi
cd gui && $(MAKE) clean
cd view && $(MAKE) clean
cd logger && $(MAKE) clean
cd filter && $(MAKE) clean
cd hacks && $(MAKE) clean
+6
View File
@@ -60,3 +60,9 @@ void verify_config(void)
abort();
}
}
void get_local_config(char **txt, int *len)
{
*txt = local;
*len = local_size;
}
+1
View File
@@ -5,5 +5,6 @@ void clear_remote_config(void);
void append_received_config_chunk(char *buf, int length);
void load_config_file(char *filename);
void verify_config(void);
void get_local_config(char **txt, int *len);
#endif /* _CONFIG_H_ */
+15
View File
@@ -13,6 +13,7 @@ typedef struct {
char **arg_type;
char **arg_name;
int asize;
char *vcd_name;
int id;
} id;
@@ -138,6 +139,7 @@ id *add_id(database *r, char *idname, int i)
r->i[r->isize].arg_type = NULL;
r->i[r->isize].arg_name = NULL;
r->i[r->isize].asize = 0;
r->i[r->isize].vcd_name = NULL;
r->i[r->isize].id = i;
r->isize++;
qsort(r->i, r->isize, sizeof(id), id_cmp);
@@ -224,6 +226,12 @@ void add_desc(id *i, char *desc)
i->desc = strdup(desc); if (i->desc == NULL) abort();
}
void add_vcd_name(id *i, char *vcd_name)
{
if (i == NULL) {printf("ERROR: VCD_NAME line before ID line\n");exit(1);}
i->vcd_name = strdup(vcd_name); if (i->vcd_name == NULL) abort();
}
char *format_get_next_token(char **cur)
{
char *start;
@@ -320,6 +328,7 @@ void *parse_database(char *filename)
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
if (!strcmp(name, "DESC")) add_desc(last_id, value);
if (!strcmp(name, "FORMAT")) add_format(last_id, value);
if (!strcmp(name, "VCD_NAME")) add_vcd_name(last_id, value);
}
fclose(in);
@@ -424,6 +433,12 @@ char *event_name_from_id(void *_database, int id)
return d->i[d->id_to_pos[id]].name;
}
char *event_vcd_name_from_id(void *_database, int id)
{
database *d = _database;
return d->i[d->id_to_pos[id]].vcd_name;
}
int event_id_from_name(void *_database, char *name)
{
database *d = _database;
+1
View File
@@ -8,6 +8,7 @@ void list_ids(void *database);
void list_groups(void *database);
void on_off(void *d, char *item, int *a, int onoff);
char *event_name_from_id(void *database, int id);
char *event_vcd_name_from_id(void *_database, int id);
int event_id_from_name(void *database, char *name);
int number_of_ids(void *database);
int database_get_ids(void *database, char ***ids);
+1
View File
@@ -878,6 +878,7 @@ int main(int n, char **v)
restart:
clear_remote_config();
if (enb_data.socket != -1) close(enb_data.socket);
enb_data.socket = connect_to(ip, port);
/* send the first message - activate selected traces */
+11 -1
View File
@@ -150,7 +150,17 @@ x_image *x_create_image(x_connection *_x, unsigned char *data,
vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask |
VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
VisualBitsPerRGBMask, &template, &nvs);
if (vs == NULL || nvs == 0) ERR("no good visual found\n");
if (vs == NULL) {
/* try again with 32 bpp */
template.depth = 32;
vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask |
VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
VisualBitsPerRGBMask, &template, &nvs);
}
if (vs == NULL) ERR("no good visual found\n");
v = vs[0].visual;
XFree(vs);
+385
View File
@@ -0,0 +1,385 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include "database.h"
#include "utils.h"
#include "../T.h"
#include "config.h"
#define DEFAULT_LOCAL_PORT 2022
typedef struct {
int id; /* increases at each new tracer's connection */
int s; /* socket */
int *is_on; /* local vision of is_on for this tracer */
int poll_id; /* -1: invalid, otherwise index in fds array */
} ti_t;
typedef struct {
ti_t *ti; /* data for tracers */
int ti_size;
int ti_maxsize;
} multi_t;
void set_is_on(int *is_on, int pos, int val)
{
if (val) is_on[pos]++; else is_on[pos]--;
/* TODO: remove check? */
if (is_on[pos] < 0) { printf("%s:%d:nonono\n",__FILE__,__LINE__); abort(); }
}
int send_messages_txt(int s, char *T_messages_txt, int T_messages_txt_len)
{
char buf[T_BUFFER_MAX];
char *T_LOCAL_buf = buf;
int32_t T_LOCAL_size;
unsigned char *src;
int src_len;
/* trace T_message.txt
* Send several messages -1 with content followed by message -2.
*/
src = (unsigned char *)T_messages_txt;
src_len = T_messages_txt_len;
while (src_len) {
int send_size = src_len;
if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int))
send_size = T_PAYLOAD_MAXSIZE - sizeof(int);
/* TODO: be careful, we use internal T stuff, to rewrite? */
T_LOCAL_size = 0;
T_HEADER(T_ID(-1));
T_PUT_buffer(1, ((T_buffer){addr:(src), length:(send_size)}));
if (socket_send(s, &T_LOCAL_size, 4) == -1) return -1;
if (socket_send(s, buf, T_LOCAL_size) == -1) return -1;
src += send_size;
src_len -= send_size;
}
T_LOCAL_size = 0;
T_HEADER(T_ID(-2));
if (socket_send(s, &T_LOCAL_size, 4) == -1) return -1;
return socket_send(s, buf, T_LOCAL_size);
}
void new_tracer(multi_t *m, int s, int is_on_size, char *t, int t_size, int id)
{
if (send_messages_txt(s, t, t_size) == -1) {
printf("error sending T_messages.txt to new tracer %d => remove tracer\n",
id);
return;
}
if (m->ti_size == m->ti_maxsize) {
m->ti_maxsize += 64;
m->ti = realloc(m->ti, m->ti_maxsize * sizeof(ti_t));
if (m->ti == NULL) abort();
}
m->ti[m->ti_size].id = id;
m->ti[m->ti_size].s = s;
m->ti[m->ti_size].is_on = calloc(is_on_size, sizeof(int));
if (m->ti[m->ti_size].is_on == NULL) abort();
m->ti[m->ti_size].poll_id = -1;
m->ti_size++;
}
void remove_tracer(multi_t *m, int t)
{
free(m->ti[t].is_on);
shutdown(m->ti[t].s, SHUT_RDWR);
close(m->ti[t].s);
m->ti_size--;
memmove(&m->ti[t], &m->ti[t+1], (m->ti_size - t) * sizeof(ti_t));
}
int send_is_on(int socket, int number_of_events, int *is_on)
{
int i;
char mt = 1;
if (socket_send(socket, &mt, 1) == -1 ||
socket_send(socket, &number_of_events, sizeof(int)) == -1) return -1;
for (i = 0; i < number_of_events; i++) {
int v = is_on[i] ? 1 : 0;
if (socket_send(socket, &v, sizeof(int)) == -1) return -1;
}
return 0;
}
int read_tracee(int s, OBUF *ebuf, int *_type, int32_t *_length)
{
int type;
int32_t length;
char *v;
int vpos = 0;
if (fullread(s, &length, 4) == -1) return -1;
if (ebuf->omaxsize < length) {
ebuf->omaxsize = (length + 65535) & ~65535;
ebuf->obuf = realloc(ebuf->obuf, ebuf->omaxsize);
if (ebuf->obuf == NULL) { printf("out of memory\n"); exit(1); }
}
v = ebuf->obuf;
memcpy(v+vpos, &length, 4);
vpos += 4;
#ifdef T_SEND_TIME
if (fullread(s,v+vpos,sizeof(struct timespec))==-1) return -1;
vpos += sizeof(struct timespec);
length -= sizeof(struct timespec);
#endif
if (fullread(s, &type, sizeof(int)) == -1) return -1;
memcpy(v+vpos, &type, sizeof(int));
vpos += sizeof(int);
length -= sizeof(int);
if (fullread(s, v+vpos, length) == -1) return -1;
vpos += length;
ebuf->osize = vpos;
*_type = type;
*_length = length;
return 0;
}
void forward_event(multi_t *m, int number_of_events, OBUF *ebuf, int type)
{
int i;
if (type < 0 || type >= number_of_events)
{ printf("error: bad type of event to forward %d\n", type); abort(); }
for (i = 0; i < m->ti_size; i++) {
if (!m->ti[i].is_on[type]) continue;
if (socket_send(m->ti[i].s, ebuf->obuf, ebuf->osize) == -1)
printf("warning: error forwarding event to tracer %d\n", m->ti[i].id);
}
}
int connect_to_tracee(char *ip, int port, int number_of_events, int *is_on)
{
int s;
printf("connecting to %s:%d\n", ip, port);
s = try_connect_to(ip, port);
if (s == -1) return -1;
if (send_is_on(s, number_of_events, is_on) == -1) {
shutdown(s, SHUT_RDWR);
close(s);
return -1;
}
return s;
}
void usage(void)
{
printf(
"options:\n"
" -d <database file> this option is mandatory\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n"
" -lp <port> listen on local port (default %d)\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT,
DEFAULT_LOCAL_PORT
);
exit(1);
}
int main(int n, char **v)
{
char *database_filename = NULL;
void *database;
char *ip = DEFAULT_REMOTE_IP;
int port = DEFAULT_REMOTE_PORT;
int local_port = DEFAULT_LOCAL_PORT;
int *is_on;
int number_of_events;
int i, j;
char *T_messages_txt;
int T_messages_txt_len;
int l; /* listen socket for tracers' connections */
int s = -1; /* socket connected to tracee. -1 if not connected */
multi_t m;
int is_on_changed;
int current_nfd;
struct pollfd *fds = NULL;
int next_id = 0;
memset(&m, 0, sizeof(m));
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) 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], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
if (!strcmp(v[i], "-p"))
{ if (i > n-2) usage(); port = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-lp"))
{ if (i > n-2) usage(); local_port = atoi(v[++i]); continue; }
usage();
}
if (database_filename == NULL) {
printf("ERROR: provide a database file (-d)\n");
exit(1);
}
database = parse_database(database_filename);
load_config_file(database_filename);
get_local_config(&T_messages_txt, &T_messages_txt_len);
number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL) abort();
/* create listener socket */
l = create_listen_socket("0.0.0.0", local_port);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
current_nfd = 0;
while (1) {
int nfd;
int timeout;
if (s == -1) s = connect_to_tracee(ip, port, number_of_events, is_on);
/* poll on s (if there), l, and all tracers' sockets */
nfd = 1 + (s != -1) + m.ti_size;
if (nfd != current_nfd) {
current_nfd = nfd;
free(fds);
fds = calloc(nfd, sizeof(struct pollfd));
if (fds == NULL) { perror("calloc"); exit(1); }
}
i = 0;
fds[i].fd = l;
fds[i].events = POLLIN;
i++;
if (s != -1) {
fds[i].fd = s;
fds[i].events = POLLIN;
i++;
}
for (j = 0; j < m.ti_size; j++) {
m.ti[j].poll_id = i;
fds[i].fd = m.ti[j].s;
fds[i].events = POLLIN;
i++;
}
if (s == -1) timeout = 1000; else timeout = -1;
if (poll(fds, nfd, timeout) == -1) { perror("poll"); exit(1); }
if (fds[0].revents & ~POLLIN) {
printf("TODO: error on listen socket?\n");
exit(1);
}
/* new tracer connecting? */
if (fds[0].revents & POLLIN) {
int t;
printf("tracer %d connecting\n", next_id);
t = socket_accept(l);
if (t == -1) perror("accept");
else new_tracer(&m, t, number_of_events,
T_messages_txt, T_messages_txt_len, next_id);
next_id++;
}
if (s != -1 && fds[1].revents & ~POLLIN) {
printf("TODO: error on tracee socket?\n");
exit(1);
}
/* data from tracee */
if (s != -1 && fds[1].revents & POLLIN) {
int type;
int32_t length;
if (read_tracee(s, &ebuf, &type, &length) == -1) {
clear_remote_config();
shutdown(s, SHUT_RDWR);
close(s);
s = -1;
} else {
if (type == -1)
append_received_config_chunk(ebuf.obuf+ebuf.osize-length, length);
else if (type == -2) verify_config();
else forward_event(&m, number_of_events, &ebuf, type);
}
}
/* status of each tracer */
is_on_changed = 0;
for (j = 0; j < m.ti_size; j++) {
int l;
int s;
int *t_is_on;
if (m.ti[j].poll_id == -1) continue;
i = m.ti[j].poll_id;
s = m.ti[j].s;
t_is_on = m.ti[j].is_on;
if (fds[i].revents & (POLLHUP | POLLERR)) goto tracer_error;
/* error? */
if (fds[i].revents & ~POLLIN) {
printf("TODO: error with tracer?\n");
exit(1);
}
/* data in */
if (fds[i].revents & POLLIN) {
char t;
int len;
int v;
if (fullread(s, &t, 1) != 1) goto tracer_error;
switch (t) {
case 0:
is_on_changed = 1;
if (fullread(s, &len, sizeof(int)) == -1) goto tracer_error;
for (l = 0; l < len; l++) {
if (fullread(s, &v, sizeof(int)) == -1) goto tracer_error;
if (v < 0 || v >= number_of_events) goto tracer_error;
t_is_on[v] = 1 - t_is_on[v];
set_is_on(is_on, v, t_is_on[v]);
}
break;
case 1:
is_on_changed = 1;
if (fullread(s, &len, sizeof(int)) == -1) goto tracer_error;
if (len < 0 || len > number_of_events) goto tracer_error;
for (l = 0; l < len; l++) {
if (fullread(s, &v, sizeof(int)) == -1) goto tracer_error;
if (v < 0 || v > 1) goto tracer_error;
if (t_is_on[l] != v) set_is_on(is_on, l, v);
t_is_on[l] = v;
}
break;
case 2: break;
default: printf("error: unhandled message type %d\n", t); //abort();
}
}
continue;
tracer_error:
printf("remove tracer %d\n", m.ti[j].id);
for (l = 0; l < number_of_events; l++)
if (m.ti[j].is_on[l]) { is_on_changed = 1; set_is_on(is_on, l, 0); }
remove_tracer(&m, j);
j--;
}
if (is_on_changed && s != -1)
if (send_is_on(s, number_of_events, is_on) == -1) {
clear_remote_config();
shutdown(s, SHUT_RDWR);
close(s);
s = -1;
}
}
return 0;
}
+98 -17
View File
@@ -12,7 +12,14 @@
#include "logger/logger.h"
#include "view/view.h"
enum var_type {
DEFAULT,
VCD_FUNCTION,
VCD_VARIABLE
};
typedef struct {
enum var_type type;
char *event;
char *arg;
char *vcd_name;
@@ -44,16 +51,39 @@ void vcd_write_header(vcd_vars *v, int n)
"$version\n"
" to_vcd\n"
"$end\n"
"$timescale 1ns $end\n"
"$timescale 1ns $end\n") <= 0) abort();
if (fprintf(out,
"$scope module logic $end\n") <= 0) abort();
for (i = 0; i < n; i++)
if (v[i].type == DEFAULT)
if (fprintf(out, "$var wire %d %s %s $end\n",
v[i].boolean ? 1 : 64,
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
if (fprintf(out,
"$upscope $end\n") <= 0) abort();
if (fprintf(out,
"$scope module functions $end\n") <= 0) abort();
for (i = 0; i < n; i++)
if (v[i].type == VCD_FUNCTION)
if (fprintf(out, "$var wire %d %s %s $end\n",
v[i].boolean ? 1 : 64,
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
if (fprintf(out,
"$upscope $end\n") <= 0) abort();
if (fprintf(out,
"$scope module variables $end\n") <= 0) abort();
for (i = 0; i < n; i++)
if (fprintf(out, "$var wire %d %s %s $end\n",
v[i].boolean ? 1 : 64,
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
if (v[i].type == VCD_VARIABLE)
if (fprintf(out, "$var wire %d %s %s $end\n",
v[i].boolean ? 1 : 64,
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
if (fprintf(out,
"$upscope $end\n") <= 0) abort();
if (fprintf(out,
"$upscope $end\n"
"$enddefinitions $end\n"
"$dumpvars\n") <= 0) abort();
@@ -174,7 +204,8 @@ void usage(void)
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n"
" -b <event> <arg> <vcd name> trace as binary (0 off, anything else on)\n"
" -l <event> <arg> <vcd name> trace as uint64_t\n",
" -l <event> <arg> <vcd name> trace as uint64_t\n"
" -vcd trace all VCD variables and functions\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT
);
@@ -192,6 +223,21 @@ void force_stop(int x)
run = 0;
}
vcd_vars *add_var(vcd_vars *vars, int nvars,
char *event, char *arg, char *vcd_name, int is_boolean, enum var_type t)
{
if (nvars % 64 == 0) {
vars = realloc(vars, (nvars+64) * sizeof(vcd_vars));
if (vars == NULL) abort();
}
vars[nvars].type = t;
vars[nvars].event = event;
vars[nvars].arg = arg;
vars[nvars].vcd_name = vcd_name;
vars[nvars].boolean = is_boolean;
return vars;
}
int main(int n, char **v)
{
char *output_filename = NULL;
@@ -202,11 +248,12 @@ int main(int n, char **v)
int *is_on;
int number_of_events;
int i;
vcd_vars vars[n];
vcd_vars *vars = NULL;
int nvars = 0;
view *vcd_view;
event_handler *h;
logger *textlog;
int all_vcd = 0;
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
@@ -221,19 +268,22 @@ int main(int n, char **v)
if (!strcmp(v[i], "-p"))
{ if (i > n-2) usage(); port = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-b")) { if(i>n-4)usage();
vars[nvars].event = v[++i];
vars[nvars].arg = v[++i];
vars[nvars].vcd_name = v[++i];
vars[nvars++].boolean = 1;
char *event = v[++i];
char *arg = v[++i];
char *vcd_name = v[++i];
vars = add_var(vars, nvars, event, arg, vcd_name, 1, DEFAULT);
nvars++;
continue;
}
if (!strcmp(v[i], "-l")) { if(i>n-4)usage();
vars[nvars].event = v[++i];
vars[nvars].arg = v[++i];
vars[nvars].vcd_name = v[++i];
vars[nvars++].boolean = 0;
char *event = v[++i];
char *arg = v[++i];
char *vcd_name = v[++i];
vars = add_var(vars, nvars, event, arg, vcd_name, 0, DEFAULT);
nvars++;
continue;
}
if (!strcmp(v[i], "-vcd")) { all_vcd = 1; continue; }
usage();
}
@@ -260,11 +310,42 @@ int main(int n, char **v)
/* create the view */
vcd_view = new_view_vcd();
if (all_vcd) {
/* activate all VCD traces */
for (i = 0; i < number_of_events; i++) {
int is_boolean;
enum var_type type;
int prefix_length;
char *name = event_name_from_id(database, i);
char *vcd_name;
char *var_prefix = "VCD_VARIABLE_";
char *fun_prefix = "VCD_FUNCTION_";
if (!strncmp(name, var_prefix, strlen(var_prefix))) {
prefix_length = strlen(var_prefix);
is_boolean = 0;
type = VCD_VARIABLE;
} else if (!strncmp(name, fun_prefix, strlen(fun_prefix))) {
prefix_length = strlen(fun_prefix);
is_boolean = 1;
type = VCD_FUNCTION;
} else
continue;
vcd_name = event_vcd_name_from_id(database, i);
if (vcd_name == NULL) {
vcd_name = name+prefix_length;
printf("WARNING: ID %s does not define VCD_NAME in the file %s, using %s\n",
name, database_filename, vcd_name);
}
vars = add_var(vars, nvars,
name, "value", vcd_name, is_boolean, type);
nvars++;
}
}
/* setup traces */
for (i = 0; i < nvars; i++) {
char format[256];
if (strlen(vars[i].arg) > 256-3) abort();
if (strlen(vars[i].vcd_name) > 256-1) abort();
if (strlen(vars[i].arg) + strlen(vars[i].vcd_name) > 256-16) abort();
sprintf(format, "%c [%s] %s",
vars[i].boolean ? 'b' : 'l',
vars[i].arg,
+1
View File
@@ -857,6 +857,7 @@ int main(int n, char **v)
restart:
clear_remote_config();
if (ue_data.socket != -1) close(ue_data.socket);
ue_data.socket = connect_to(ip, port);
/* send the first message - activate selected traces */
+48 -19
View File
@@ -79,6 +79,36 @@ list *list_append(list *l, void *data)
/* socket */
/****************************************************************************/
int create_listen_socket(char *addr, int port)
{
struct sockaddr_in a;
int s;
int v;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
v = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, 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("listen"); exit(1); }
return s;
}
int socket_accept(int s)
{
struct sockaddr_in a;
socklen_t alen;
alen = sizeof(a);
return accept(s, (struct sockaddr *)&a, &alen);
}
int socket_send(int socket, void *buffer, int size)
{
char *x = buffer;
@@ -94,26 +124,13 @@ int 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); }
s = create_listen_socket(addr, port);
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);
t = socket_accept(s);
if (t == -1) { perror("accept"); exit(1); }
close(s);
@@ -137,14 +154,11 @@ int fullread(int fd, void *_buf, int count)
return ret;
}
int connect_to(char *addr, int port)
int try_connect_to(char *addr, int port)
{
int s;
struct sockaddr_in a;
printf("connecting to %s:%d\n", addr, port);
again:
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
@@ -155,6 +169,21 @@ again:
if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) {
perror("connect");
close(s);
return -1;
}
return s;
}
int connect_to(char *addr, int port)
{
int s;
printf("connecting to %s:%d\n", addr, port);
again:
s = try_connect_to(addr, port);
if (s == -1) {
printf("trying again in 1s\n");
sleep(1);
goto again;
+3
View File
@@ -24,11 +24,14 @@ list *list_append(list *l, void *data);
#define DEFAULT_REMOTE_IP "127.0.0.1"
#define DEFAULT_REMOTE_PORT 2021
int create_listen_socket(char *addr, int port);
int socket_accept(int s);
/* socket_send: return 0 if okay, -1 on error */
int socket_send(int socket, void *buffer, int size);
int get_connection(char *addr, int port);
/* fullread: return length read if okay (that is: 'count'), -1 on error */
int fullread(int fd, void *_buf, int count);
int try_connect_to(char *addr, int port);
int connect_to(char *addr, int port);
/****************************************************************************/
+4 -4
View File
@@ -70,8 +70,8 @@ char *tmpstr;
char *shlibpath =NULL;
char *shlibversion=NULL;
char *cfgprefix;
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0},
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}};
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0, NULL},
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0, NULL}};
int ret;
@@ -118,7 +118,7 @@ int ret;
return tmpstr;
}
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
{
void *lib_handle;
initfunc_t fpi;
@@ -155,7 +155,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
fpi = dlsym(lib_handle,afname);
if (fpi != NULL ) {
fpi();
fpi(autoinit_arg);
}
if (farray != NULL) {
+9 -8
View File
@@ -59,7 +59,8 @@ typedef struct {
/* function type of functions which may be implemented by a module */
/* 1: init function, called when loading, if found in the shared lib */
typedef int(*initfunc_t)(void);
typedef int(*initfunc_t)(void *);
/* 2: version checking function, called when loading, if it returns -1, trigger main exec abort */
typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version);
/* 3: get function array function, called when loading when a module doesn't provide */
@@ -72,18 +73,18 @@ typedef int(*getfarrayfunc_t)(loader_shlibfunc_t **funcarray);
#define DEFAULT_MAXSHLIBS 10
loader_data_t loader_data;
/*------------------------------------------------------------------------------------------------------------------------------------------------*/
/* LOADER parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* LOADER parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt check func*/
/*----------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define LOADER_PARAMS_DESC { \
{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0}, \
{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0}, \
{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0, NULL},\
{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0, NULL}\
}
/*-------------------------------------------------------------------------------------------------------------*/
#else /* LOAD_MODULE_SHLIB_MAIN */
extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf);
extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf, void *initfunc_arg);
extern void * get_shlibmodule_fptr(char *modname, char *fname);
extern loader_data_t loader_data;
#endif /* LOAD_MODULE_SHLIB_MAIN */
+23 -6
View File
@@ -32,10 +32,14 @@
#include <stdint.h>
#include <inttypes.h>
#define MSC_LIBRARY
#include "msc.h"
#include "liblfds611.h"
#include "intertask_interface.h"
#include "msc.h"
#include "assertions.h"
//-------------------------------
@@ -66,8 +70,8 @@ void *msc_task(void *args_p)
//------------------------------------------------------------------------------
{
MessageDef *received_message_p = NULL;
const char *msg_name = NULL;
instance_t instance = 0;
// const char *msg_name = NULL;
// instance_t instance = 0;
long timer_id;
itti_mark_task_ready(TASK_MSC);
@@ -87,9 +91,9 @@ void *msc_task(void *args_p)
itti_receive_msg(TASK_MSC, &received_message_p);
if (received_message_p != NULL) {
msg_name = ITTI_MSG_NAME (received_message_p);
instance = ITTI_MSG_INSTANCE (received_message_p);
// msg_name = ITTI_MSG_NAME (received_message_p);
// instance = ITTI_MSG_INSTANCE (received_message_p);
switch (ITTI_MSG_ID(received_message_p)) {
case TIMER_HAS_EXPIRED: {
@@ -570,4 +574,17 @@ error_event:
free(new_item_p);
}
//------------------------------------------------------------------------------
// function called when oai loader loads the msc shared lib
int msc_autoinit(msc_interface_t *msc_interface)
//------------------------------------------------------------------------------
{
msc_interface->msc_init = msc_init;
msc_interface->msc_start_use = msc_start_use;
msc_interface->msc_end = msc_end;
msc_interface->msc_log_event = msc_log_event;
msc_interface->msc_log_message = msc_log_message;
msc_interface->msc_loaded = 1;
return 0;
}
+29 -18
View File
@@ -73,7 +73,23 @@ typedef enum {
#define MSC_AS_TIME_ARGS(CTXT_Pp) \
(CTXT_Pp)->frame, \
(CTXT_Pp)->subframe
#if defined(MESSAGE_CHART_GENERATOR)
typedef int(*msc_init_t)(const msc_env_t, const int );
typedef void(*msc_start_use_t)(void );
typedef void(*msc_end_t)(void);
typedef void(*msc_log_event_t)(const msc_proto_t,char *, ...);
typedef void(*msc_log_message_t)(const char * const, const msc_proto_t, const msc_proto_t,
const uint8_t* const, const unsigned int, char * , ...);
typedef struct msc_interface {
int msc_loaded;
msc_init_t msc_init;
msc_start_use_t msc_start_use;
msc_end_t msc_end;
msc_log_event_t msc_log_event;
msc_log_message_t msc_log_message;
} msc_interface_t;
#ifdef MSC_LIBRARY
int msc_init(const msc_env_t envP, const int max_threadsP);
void msc_start_use(void);
void msc_flush_messages(void);
@@ -88,22 +104,17 @@ void msc_log_message(
const unsigned int num_bytes,
char *format, ...);
#define MSC_INIT(arg1,arg2) msc_init(arg1,arg2)
#define MSC_START_USE msc_start_use
#define MSC_END msc_end
#define MSC_LOG_EVENT(mScPaRaMs, fORMAT, aRGS...) msc_log_event(mScPaRaMs, fORMAT, ##aRGS)
#define MSC_LOG_RX_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("<-",rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, ##aRGS)
#define MSC_LOG_RX_DISCARDED_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("x-",rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, ##aRGS)
#define MSC_LOG_TX_MESSAGE(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("->",sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, ##aRGS)
#define MSC_LOG_TX_MESSAGE_FAILED(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("-x",sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, ##aRGS)
#else
#define MSC_INIT(arg1,arg2)
#define MSC_START_USE(mScPaRaMs)
#define MSC_END(mScPaRaMs)
#define MSC_LOG_EVENT(mScPaRaMs, fORMAT, aRGS...)
#define MSC_LOG_RX_MESSAGE(mScPaRaMs, fORMAT, aRGS...)
#define MSC_LOG_RX_DISCARDED_MESSAGE(mScPaRaMs, fORMAT, aRGS...)
#define MSC_LOG_TX_MESSAGE(mScPaRaMs, fORMAT, aRGS...)
#define MSC_LOG_TX_MESSAGE_FAILED(mScPaRaMs, fORMAT, aRGS...)
#endif
msc_interface_t msc_interface;
#define MSC_INIT(arg1,arg2) if(msc_interface.msc_loaded) msc_interface.msc_init(arg1,arg2)
#define MSC_START_USE if(msc_interface.msc_loaded) msc_interface.msc_start_use
#define MSC_END if(msc_interface.msc_loaded) msc_interface.msc_end
#define MSC_LOG_EVENT(mScPaRaMs, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_event(mScPaRaMs, fORMAT, ##aRGS)
#define MSC_LOG_RX_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("<-",rECEIVER, sENDER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS)
#define MSC_LOG_RX_DISCARDED_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("x-",rECEIVER, sENDER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS)
#define MSC_LOG_TX_MESSAGE(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("->",sENDER, rECEIVER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS)
#define MSC_LOG_TX_MESSAGE_FAILED(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("-x",sENDER, rECEIVER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS)
#endif
#endif
@@ -1,6 +1,6 @@
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#include <vector>
#include <map>
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Author: Laurent THOMAS, Open Cells
Copyleft: OpenAirInterface software alliance
Copyleft: OpenAirInterface software alliance and it's licence
*/
#ifndef INTERTASK_INTERFACE_H_
#define INTERTASK_INTERFACE_H_
+44 -36
View File
@@ -199,28 +199,29 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
print_threads(buf,debug,prnt);
}
if (strcasestr(buf,"loglvl") != NULL) {
prnt(" component level enabled\n");
prnt("\n component level enabled output\n");
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
if (g_log->log_component[i].name != NULL) {
prnt("%02i %17.17s:%10.10s %s\n",i ,g_log->log_component[i].name,
map_int_to_str(log_level_names,g_log->log_component[i].level),
((g_log->log_component[i].interval>0)?"Y":"N") );
prnt("%02i %17.17s:%10.10s %s %s\n",i ,g_log->log_component[i].name,
map_int_to_str(log_level_names,(g_log->log_component[i].level>=0)?g_log->log_component[i].level:g_log->log_component[i].savedlevel),
((g_log->log_component[i].level>=0)?"Y":"N"),
((g_log->log_component[i].filelog>0)?g_log->log_component[i].filelog_name:"stdout"));
}
}
}
if (strcasestr(buf,"logopt") != NULL) {
prnt(" option enabled\n");
prnt("\n option enabled\n");
for (int i=0; log_options[i].name != NULL; i++) {
prnt("%02i %17.17s %10.10s \n",i ,log_options[i].name,
((g_log->flag & log_options[i].value)?"Y":"N") );
}
}
if (strcasestr(buf,"dbgopt") != NULL) {
prnt(" option debug matlab\n");
prnt("\n module debug dumpfile\n");
for (int i=0; log_maskmap[i].name != NULL ; i++) {
prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name,
prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name,
((g_log->debug_mask & log_maskmap[i].value)?"Y":"N"),
((g_log->matlab_mask & log_maskmap[i].value)?"Y":"N") );
((g_log->dump_mask & log_maskmap[i].value)?"Y":"N") );
}
}
if (strcasestr(buf,"config") != NULL) {
@@ -335,15 +336,15 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
prnt("Available log levels: \n ");
for (int i=0; log_level_names[i].name != NULL; i++)
prnt("%s ",log_level_names[i].name);
prnt("\n");
prnt("\n\n");
prnt("Available display options: \n ");
for (int i=0; log_options[i].name != NULL; i++)
prnt("%s ",log_options[i].name);
prnt("\n");
prnt("Available debug or matlab options: \n ");
prnt("\n\n");
prnt("Available debug and dump options: \n ");
for (int i=0; log_maskmap[i].name != NULL; i++)
prnt("%s ",log_maskmap[i].name);
prnt("\n");
prnt("\n\n");
proccmd_show("loglvl",debug,prnt);
proccmd_show("logopt",debug,prnt);
proccmd_show("dbgopt",debug,prnt);
@@ -375,7 +376,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
else if (l == 2 && strcmp(logparam,"debug") == 0){
optbit=map_str_to_int(log_maskmap,opt);
if (optbit < 0) {
prnt("debug flag %s unknown\n",opt);
prnt("module %s unknown\n",opt);
} else {
if (idx1 > 0)
SET_LOG_DEBUG(optbit);
@@ -384,42 +385,51 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
proccmd_show("dbgopt",debug,prnt);
}
}
else if (l == 2 && strcmp(logparam,"matlab") == 0){
else if (l == 2 && strcmp(logparam,"dump") == 0){
optbit=map_str_to_int(log_maskmap,opt);
if (optbit < 0) {
prnt("matlab flag %s unknown\n",opt);
prnt("module %s unknown\n",opt);
} else {
if (idx1 > 0)
SET_LOG_MATLAB(optbit);
SET_LOG_DUMP(optbit);
else
CLEAR_LOG_MATLAB(optbit);
CLEAR_LOG_DUMP(optbit);
proccmd_show("dbgopt",debug,prnt);
}
}
if (logparam != NULL) free(logparam);
if (opt != NULL) free(opt);
} else if ( s == 3 && logsubcmd != NULL) {
int level, interval;
int level, enable,filelog;
char *tmpstr=NULL;
char *logparam=NULL;
int l;
level = interval = -1;
level = OAILOG_DISABLE - 1;
filelog = -1;
enable=-1;
l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr);
if (debug > 0)
prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr));
if (l ==2 ) {
if (strcmp(logparam,"level") == 0) {
level=map_str_to_int(log_level_names,tmpstr);
if (level < 0) prnt("level %s unknown\n",tmpstr);
if (level < 0) {
prnt("level %s unknown\n",tmpstr);
level=OAILOG_DISABLE - 1;
}
} else {
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
}
} else if (l ==1 ) {
if (strcmp(logparam,"enable") == 0) {
interval = 1;
enable=1;
} else if (strcmp(logparam,"disable") == 0) {
interval = 0;
level=OAILOG_DISABLE;
} else if (strcmp(logparam,"file") == 0) {
filelog = 1 ;
} else if (strcmp(logparam,"nofile") == 0) {
filelog = 0 ;
} else {
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
}
@@ -429,20 +439,18 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
if (logparam != NULL) free(logparam);
if (tmpstr != NULL) free(tmpstr);
for (int i=idx1; i<=idx2 ; i++) {
if (level < 0) {
level=g_log->log_component[i].level;
}
if (interval < 0) {
interval=g_log->log_component[i].interval;
}
set_log(i, level, interval);
prnt("log level comp %i %s set to %s (%s)\n",
i,((g_log->log_component[i].name==NULL)?"":g_log->log_component[i].name),
map_int_to_str(log_level_names,g_log->log_component[i].level),
((g_log->log_component[i].interval>0)?"enabled":"disabled"));
}
if (level >= OAILOG_DISABLE)
set_log(i, level);
else if ( enable == 1)
set_log(i,g_log->log_component[i].savedlevel);
else if ( filelog == 1 ) {
set_component_filelog(i);
} else if ( filelog == 0 ) {
close_component_filelog(i);
}
}
proccmd_show("loglvl",debug,prnt);
} else {
prnt("%s: wrong log command...\n",buf);
}
+7 -5
View File
@@ -48,13 +48,15 @@ telnetshell_vardef_t proc_vardef[] = {
show: display current log configuration \n\
online, noonline: enable or disable console logs \n\
enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\
file, nofile id1-id2: enable or disable redirecting logs to file for components index id1 to id2 \n\
logfile name depends on component name and is printed in the show command \n\
level_<level> id1-id2: set log level to <level> for components index id1 to id2 \n\
use the show command to get the authorized values for <level> and the list of component \
indexes that can be used for id1 and id2 \n\
use the show command to get the authorized values for \n\
<level> and the list of component indexes that can be used for id1 and id2 \n\
print_<opt> <0|1> disable or enable the \"opt\" log option, use the show command to get \
the available options\n\
matlab_<opt> debug_<func> disable or enable the debug code or matlab file generation \
for \"func\" function. use the show command to get the available options\n"
the available options\n\
dump_<mod> debug_<mod > disable or enable the debug file generation or debug code\
for \"mod\" module. use the show command to get the available modules\n"
#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\
<thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\