move log/debug codebase to libosmocore
The logging/debugging code is generic enough to move it into libosmocore while keeping OpenBSC specific definitions in openbsc itself. This commit uses the logging support present in libosmocore-0.1.2, you will have to update your library to this version.
This commit is contained in:
parent
b464fb4a89
commit
dc5062b185
|
@ -18,7 +18,7 @@ dnl checks for libraries
|
|||
AC_SEARCH_LIBS(crypt, crypt,
|
||||
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.1)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.2)
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define DEBUG
|
||||
#include <osmocore/logging.h>
|
||||
|
||||
/* Debug Areas of the code */
|
||||
enum {
|
||||
|
@ -31,31 +32,6 @@ enum {
|
|||
Debug_LastEntry,
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args)
|
||||
#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args)
|
||||
#else
|
||||
#define DEBUGP(xss, fmt, args...)
|
||||
#define DEBUGPC(ss, fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
|
||||
|
||||
char *hexdump(const unsigned char *buf, int len);
|
||||
void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
|
||||
|
||||
/* new logging interface */
|
||||
#define LOGP(ss, level, fmt, args...) debugp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
|
||||
#define LOGPC(ss, level, fmt, args...) debugp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
|
||||
|
||||
/* different levels */
|
||||
#define LOGL_DEBUG 1 /* debugging information */
|
||||
#define LOGL_INFO 3
|
||||
#define LOGL_NOTICE 5 /* abnormal/unexpected condition */
|
||||
#define LOGL_ERROR 7 /* error condition, requires user action */
|
||||
#define LOGL_FATAL 8 /* fatal, program aborted */
|
||||
|
||||
/* context */
|
||||
#define BSC_CTX_LCHAN 0
|
||||
#define BSC_CTX_SUBSCR 1
|
||||
|
@ -65,67 +41,12 @@ void debugp(unsigned int subsys, char *file, int line, int cont, const char *for
|
|||
/* target */
|
||||
|
||||
enum {
|
||||
DEBUG_FILTER_IMSI = 1 << 0,
|
||||
DEBUG_FILTER_ALL = 1 << 1,
|
||||
//DEBUG_FILTER_ALL = 1 << 0,
|
||||
LOG_FILTER_IMSI = 1 << 1,
|
||||
};
|
||||
|
||||
struct debug_category {
|
||||
int enabled;
|
||||
int loglevel;
|
||||
};
|
||||
void log_set_imsi_filter(struct log_target *target, const char *imsi);
|
||||
|
||||
struct debug_target {
|
||||
int filter_map;
|
||||
char *imsi_filter;
|
||||
extern const struct log_info log_info;
|
||||
|
||||
|
||||
struct debug_category categories[Debug_LastEntry];
|
||||
int use_color;
|
||||
int print_timestamp;
|
||||
int loglevel;
|
||||
|
||||
union {
|
||||
struct {
|
||||
FILE *out;
|
||||
} tgt_stdout;
|
||||
|
||||
struct {
|
||||
int priority;
|
||||
} tgt_syslog;
|
||||
|
||||
struct {
|
||||
void *vty;
|
||||
} tgt_vty;
|
||||
};
|
||||
|
||||
void (*output) (struct debug_target *target, const char *string);
|
||||
|
||||
struct llist_head entry;
|
||||
};
|
||||
|
||||
/* use the above macros */
|
||||
void debugp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
||||
void debug_init(void);
|
||||
|
||||
/* context management */
|
||||
void debug_reset_context(void);
|
||||
void debug_set_context(int ctx, void *value);
|
||||
|
||||
/* filter on the targets */
|
||||
void debug_set_imsi_filter(struct debug_target *target, const char *imsi);
|
||||
void debug_set_all_filter(struct debug_target *target, int);
|
||||
void debug_set_use_color(struct debug_target *target, int);
|
||||
void debug_set_print_timestamp(struct debug_target *target, int);
|
||||
void debug_set_log_level(struct debug_target *target, int log_level);
|
||||
void debug_parse_category_mask(struct debug_target *target, const char* mask);
|
||||
int debug_parse_level(const char *lvl);
|
||||
int debug_parse_category(const char *category);
|
||||
void debug_set_category_filter(struct debug_target *target, int category, int enable, int level);
|
||||
|
||||
|
||||
/* management of the targets */
|
||||
struct debug_target *debug_target_create(void);
|
||||
struct debug_target *debug_target_create_stderr(void);
|
||||
void debug_add_target(struct debug_target *target);
|
||||
void debug_del_target(struct debug_target *target);
|
||||
#endif /* _DEBUG_H */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define TELNET_INTERFACE_H
|
||||
|
||||
#include "gsm_data.h"
|
||||
#include "debug.h"
|
||||
#include <openbsc/debug.h>
|
||||
#include <osmocore/select.h>
|
||||
|
||||
#include <vty/vty.h>
|
||||
|
@ -32,7 +32,7 @@ struct telnet_connection {
|
|||
struct gsm_network *network;
|
||||
struct bsc_fd fd;
|
||||
struct vty *vty;
|
||||
struct debug_target *dbg;
|
||||
struct log_target *dbg;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -118,8 +118,8 @@ struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
|
|||
}
|
||||
|
||||
lchan = &ts->lchan[lch_idx];
|
||||
debug_set_context(BSC_CTX_LCHAN, lchan);
|
||||
debug_set_context(BSC_CTX_SUBSCR, lchan->conn.subscr);
|
||||
log_set_context(BSC_CTX_LCHAN, lchan);
|
||||
log_set_context(BSC_CTX_SUBSCR, lchan->conn.subscr);
|
||||
|
||||
return lchan;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ static const char *trx1_password = "1111111111";
|
|||
|
||||
static const u_int8_t too_fast[] = { 0x12, 0x80, 0x00, 0x00, 0x02, 0x02 };
|
||||
|
||||
static struct debug_target *stderr_target;
|
||||
static struct log_target *stderr_target;
|
||||
|
||||
/* dummy function to keep gsm_data.c happy */
|
||||
struct counter *counter_alloc(const char *name)
|
||||
|
@ -778,7 +778,7 @@ static void handle_options(int argc, char **argv)
|
|||
serial_port = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
debug_parse_category_mask(stderr_target, optarg);
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
break;
|
||||
case 's':
|
||||
fname_software = optarg;
|
||||
|
@ -834,10 +834,10 @@ int main(int argc, char **argv)
|
|||
struct gsm_network *gsmnet;
|
||||
int rc;
|
||||
|
||||
debug_init();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
handle_options(argc, argv);
|
||||
bts_model_bs11_init();
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <openbsc/signal.h>
|
||||
|
||||
/* MCC and MNC for the Location Area Identifier */
|
||||
static struct debug_target *stderr_target;
|
||||
static struct log_target *stderr_target;
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *database_name = "hlr.sqlite3";
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
|
@ -127,10 +127,10 @@ static void handle_options(int argc, char** argv)
|
|||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
debug_set_use_color(stderr_target, 0);
|
||||
log_set_use_color(stderr_target, 0);
|
||||
break;
|
||||
case 'd':
|
||||
debug_parse_category_mask(stderr_target, optarg);
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
break;
|
||||
case 'l':
|
||||
database_name = strdup(optarg);
|
||||
|
@ -142,13 +142,13 @@ static void handle_options(int argc, char** argv)
|
|||
create_pcap_file(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
debug_set_print_timestamp(stderr_target, 1);
|
||||
log_set_print_timestamp(stderr_target, 1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case 'e':
|
||||
debug_set_log_level(stderr_target, atoi(optarg));
|
||||
log_set_log_level(stderr_target, atoi(optarg));
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
|
@ -211,21 +211,21 @@ int main(int argc, char **argv)
|
|||
{
|
||||
int rc;
|
||||
|
||||
debug_init();
|
||||
log_init(&log_info);
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
talloc_ctx_init();
|
||||
on_dso_load_token();
|
||||
on_dso_load_rrlp();
|
||||
on_dso_load_ho_dec();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
|
||||
bts_model_unknown_init();
|
||||
bts_model_bs11_init();
|
||||
bts_model_nanobts_init();
|
||||
|
||||
/* enable filters */
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
@ -262,7 +262,7 @@ int main(int argc, char **argv)
|
|||
|
||||
while (1) {
|
||||
bsc_upqueue(bsc_gsmnet);
|
||||
debug_reset_context();
|
||||
log_reset_context();
|
||||
bsc_select_main(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Debugging/Logging support code */
|
||||
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
|
||||
/* OpenBSC Debugging/Logging support code */
|
||||
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
|
@ -27,401 +28,160 @@
|
|||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/logging.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
/* default categories */
|
||||
static struct debug_category default_categories[Debug_LastEntry] = {
|
||||
[DRLL] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DCC] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DNM] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DRR] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DRSL] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DMM] = { .enabled = 1, .loglevel = LOGL_INFO },
|
||||
[DMNCC] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DSMS] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DPAG] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DMEAS] = { .enabled = 0, .loglevel = LOGL_NOTICE },
|
||||
[DMI] = { .enabled = 0, .loglevel = LOGL_NOTICE },
|
||||
[DMIB] = { .enabled = 0, .loglevel = LOGL_NOTICE },
|
||||
[DMUX] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DINP] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DSCCP] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DMSC] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DMGCP] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DHO] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DDB] = { .enabled = 1, .loglevel = LOGL_NOTICE },
|
||||
[DREF] = { .enabled = 0, .loglevel = LOGL_NOTICE },
|
||||
static const struct log_info_cat default_categories[] = {
|
||||
[DRLL] = {
|
||||
.name = "DRLL",
|
||||
.description = "Radio Link Layer",
|
||||
.color = "\033[1;31m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DCC] = {
|
||||
.name = "DCC",
|
||||
.description = "Call Control",
|
||||
.color = "\033[1;32m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMM] = {
|
||||
.name = "DMM",
|
||||
.description = "Mobility Management",
|
||||
.color = "\033[1;33m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DRR] = {
|
||||
.name = "DRR",
|
||||
.description = "Radio Resource",
|
||||
.color = "\033[1;34m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DRSL] = {
|
||||
.name = "DRSL",
|
||||
.description = "Radio Siganlling Link",
|
||||
.color = "\033[1;35m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DNM] = {
|
||||
.name = "DNM",
|
||||
.description = "Network Management (OML)",
|
||||
.color = "\033[1;36m",
|
||||
.enabled = 1, .loglevel = LOGL_INFO,
|
||||
},
|
||||
[DMNCC] = {
|
||||
.name = "DMNCC",
|
||||
.description = "BSC<->MSC interface",
|
||||
.color = "\033[1;39m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DSMS] = {
|
||||
.name = "DSMS",
|
||||
.description = "Short Message Service",
|
||||
.color = "\033[1;37m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DPAG] = {
|
||||
.name = "DPAG",
|
||||
.description = "Paging",
|
||||
.color = "\033[1;38m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMEAS] = {
|
||||
.name = "DMEAS",
|
||||
.description = "Measurement Processing",
|
||||
.enabled = 0, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMI] = {
|
||||
.name = "DMI",
|
||||
.description = "mISDN Input Driver",
|
||||
.enabled = 0, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMIB] = {
|
||||
.name = "DMIB",
|
||||
.description = "mISDN B-Channels",
|
||||
.enabled = 0, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMUX] = {
|
||||
.name = "DMUX",
|
||||
.description = "TRAU Frame Multiplex",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DINP] = {
|
||||
.name = "DINP",
|
||||
.description = "Input Driver",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DSCCP] = {
|
||||
.name = "DSCCP",
|
||||
.description = "SCCP Protocol",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMSC] = {
|
||||
.name = "DMSC",
|
||||
.description = "Mobile Switching Center",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMGCP] = {
|
||||
.name = "DMGCP",
|
||||
.description = "Media Gateway Control Protocol",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DHO] = {
|
||||
.name = "DHO",
|
||||
.description = "Hand-Over",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DDB] = {
|
||||
.name = "DDB",
|
||||
.description = "Database",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DREF] = {
|
||||
.name = "DREF",
|
||||
.description = "Reference Counting",
|
||||
.enabled = 0, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
};
|
||||
|
||||
struct debug_info {
|
||||
const char *name;
|
||||
const char *color;
|
||||
const char *description;
|
||||
int number;
|
||||
int position;
|
||||
enum log_ctxt {
|
||||
CTX_SUBSCRIBER,
|
||||
};
|
||||
|
||||
struct debug_context {
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_bts *bts;
|
||||
enum log_filter {
|
||||
FLT_IMSI,
|
||||
};
|
||||
|
||||
static struct debug_context debug_context;
|
||||
static void *tall_dbg_ctx = NULL;
|
||||
static LLIST_HEAD(target_list);
|
||||
static int filter_fn(const struct log_context *ctx,
|
||||
struct log_target *tar)
|
||||
{
|
||||
struct gsm_subscriber *subscr = ctx->ctx[CTX_SUBSCRIBER];
|
||||
|
||||
#define DEBUG_CATEGORY(NUMBER, NAME, COLOR, DESCRIPTION) \
|
||||
{ .name = NAME, .color = COLOR, .description = DESCRIPTION, .number = NUMBER },
|
||||
if ((tar->filter_map & (1 << FLT_IMSI)) != 0
|
||||
&& subscr && strcmp(subscr->imsi, tar->filter_data[FLT_IMSI]) == 0)
|
||||
return 1;
|
||||
|
||||
static const struct debug_info debug_info[] = {
|
||||
DEBUG_CATEGORY(DRLL, "DRLL", "\033[1;31m", "")
|
||||
DEBUG_CATEGORY(DCC, "DCC", "\033[1;32m", "")
|
||||
DEBUG_CATEGORY(DMM, "DMM", "\033[1;33m", "")
|
||||
DEBUG_CATEGORY(DRR, "DRR", "\033[1;34m", "")
|
||||
DEBUG_CATEGORY(DRSL, "DRSL", "\033[1;35m", "")
|
||||
DEBUG_CATEGORY(DNM, "DNM", "\033[1;36m", "")
|
||||
DEBUG_CATEGORY(DSMS, "DSMS", "\033[1;37m", "")
|
||||
DEBUG_CATEGORY(DPAG, "DPAG", "\033[1;38m", "")
|
||||
DEBUG_CATEGORY(DMNCC, "DMNCC","\033[1;39m", "")
|
||||
DEBUG_CATEGORY(DINP, "DINP", "", "")
|
||||
DEBUG_CATEGORY(DMI, "DMI", "", "")
|
||||
DEBUG_CATEGORY(DMIB, "DMIB", "", "")
|
||||
DEBUG_CATEGORY(DMUX, "DMUX", "", "")
|
||||
DEBUG_CATEGORY(DMEAS, "DMEAS", "", "")
|
||||
DEBUG_CATEGORY(DSCCP, "DSCCP", "", "")
|
||||
DEBUG_CATEGORY(DMSC, "DMSC", "", "")
|
||||
DEBUG_CATEGORY(DMGCP, "DMGCP", "", "")
|
||||
DEBUG_CATEGORY(DHO, "DHO", "", "")
|
||||
DEBUG_CATEGORY(DDB, "DDB", "", "")
|
||||
DEBUG_CATEGORY(DREF, "DREF", "", "")
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct log_info log_info = {
|
||||
.filter_fn = filter_fn,
|
||||
.cat = default_categories,
|
||||
.num_cat = ARRAY_SIZE(default_categories),
|
||||
};
|
||||
|
||||
static const struct value_string loglevel_strs[] = {
|
||||
{ 0, "EVERYTHING" },
|
||||
{ 1, "DEBUG" },
|
||||
{ 3, "INFO" },
|
||||
{ 5, "NOTICE" },
|
||||
{ 7, "ERROR" },
|
||||
{ 8, "FATAL" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
int debug_parse_level(const char *lvl)
|
||||
{
|
||||
return get_string_value(loglevel_strs, lvl);
|
||||
}
|
||||
|
||||
int debug_parse_category(const char *category)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(debug_info); ++i) {
|
||||
if (!strcasecmp(debug_info[i].name+1, category))
|
||||
return debug_info[i].number;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the category mask.
|
||||
* The format can be this: category1:category2:category3
|
||||
* or category1,2:category2,3:...
|
||||
*/
|
||||
void debug_parse_category_mask(struct debug_target* target, const char *_mask)
|
||||
{
|
||||
int i = 0;
|
||||
char *mask = strdup(_mask);
|
||||
char *category_token = NULL;
|
||||
|
||||
/* Disable everything to enable it afterwards */
|
||||
for (i = 0; i < ARRAY_SIZE(target->categories); ++i)
|
||||
target->categories[i].enabled = 0;
|
||||
|
||||
category_token = strtok(mask, ":");
|
||||
do {
|
||||
for (i = 0; i < ARRAY_SIZE(debug_info); ++i) {
|
||||
char* colon = strstr(category_token, ",");
|
||||
int length = strlen(category_token);
|
||||
|
||||
if (colon)
|
||||
length = colon - category_token;
|
||||
|
||||
if (strncasecmp(debug_info[i].name, category_token, length) == 0) {
|
||||
int number = debug_info[i].number;
|
||||
int level = 0;
|
||||
|
||||
if (colon)
|
||||
level = atoi(colon+1);
|
||||
|
||||
target->categories[number].enabled = 1;
|
||||
target->categories[number].loglevel = level;
|
||||
}
|
||||
}
|
||||
} while ((category_token = strtok(NULL, ":")));
|
||||
|
||||
free(mask);
|
||||
}
|
||||
|
||||
static const char* color(int subsys)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(debug_info); ++i) {
|
||||
if (debug_info[i].number == subsys)
|
||||
return debug_info[i].color;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static void _output(struct debug_target *target, unsigned int subsys, char *file, int line,
|
||||
int cont, const char *format, va_list ap)
|
||||
{
|
||||
char col[30];
|
||||
char sub[30];
|
||||
char tim[30];
|
||||
char buf[4096];
|
||||
char final[4096];
|
||||
|
||||
/* prepare the data */
|
||||
col[0] = '\0';
|
||||
sub[0] = '\0';
|
||||
tim[0] = '\0';
|
||||
buf[0] = '\0';
|
||||
|
||||
/* are we using color */
|
||||
if (target->use_color) {
|
||||
snprintf(col, sizeof(col), "%s", color(subsys));
|
||||
col[sizeof(col)-1] = '\0';
|
||||
}
|
||||
vsnprintf(buf, sizeof(buf), format, ap);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
|
||||
if (!cont) {
|
||||
if (target->print_timestamp) {
|
||||
char *timestr;
|
||||
time_t tm;
|
||||
tm = time(NULL);
|
||||
timestr = ctime(&tm);
|
||||
timestr[strlen(timestr)-1] = '\0';
|
||||
snprintf(tim, sizeof(tim), "%s ", timestr);
|
||||
tim[sizeof(tim)-1] = '\0';
|
||||
}
|
||||
snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line);
|
||||
sub[sizeof(sub)-1] = '\0';
|
||||
}
|
||||
|
||||
snprintf(final, sizeof(final), "%s%s%s%s\033[0;m", col, tim, sub, buf);
|
||||
final[sizeof(final)-1] = '\0';
|
||||
target->output(target, final);
|
||||
}
|
||||
|
||||
|
||||
static void _debugp(unsigned int subsys, int level, char *file, int line,
|
||||
int cont, const char *format, va_list ap)
|
||||
{
|
||||
struct debug_target *tar;
|
||||
|
||||
llist_for_each_entry(tar, &target_list, entry) {
|
||||
struct debug_category *category;
|
||||
int output = 0;
|
||||
|
||||
category = &tar->categories[subsys];
|
||||
/* subsystem is not supposed to be debugged */
|
||||
if (!category->enabled)
|
||||
continue;
|
||||
|
||||
/* Check the global log level */
|
||||
if (tar->loglevel != 0 && level < tar->loglevel)
|
||||
continue;
|
||||
|
||||
/* Check the category log level */
|
||||
if (tar->loglevel == 0 && category->loglevel != 0 && level < category->loglevel)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Apply filters here... if that becomes messy we will need to put
|
||||
* filters in a list and each filter will say stop, continue, output
|
||||
*/
|
||||
if ((tar->filter_map & DEBUG_FILTER_ALL) != 0) {
|
||||
output = 1;
|
||||
} else if ((tar->filter_map & DEBUG_FILTER_IMSI) != 0
|
||||
&& debug_context.subscr && strcmp(debug_context.subscr->imsi, tar->imsi_filter) == 0) {
|
||||
output = 1;
|
||||
}
|
||||
|
||||
if (output) {
|
||||
/* FIXME: copying the va_list is an ugly workaround against a bug
|
||||
* hidden somewhere in _output. If we do not copy here, the first
|
||||
* call to _output() will corrupt the va_list contents, and any
|
||||
* further _output() calls with the same va_list will segfault */
|
||||
va_list bp;
|
||||
va_copy(bp, ap);
|
||||
_output(tar, subsys, file, line, cont, format, bp);
|
||||
va_end(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
_debugp(subsys, LOGL_DEBUG, file, line, cont, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void debugp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
_debugp(subsys, level, file, line, cont, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static char hexd_buff[4096];
|
||||
|
||||
char *hexdump(const unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
char *cur = hexd_buff;
|
||||
|
||||
hexd_buff[0] = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
int len_remain = sizeof(hexd_buff) - (cur - hexd_buff);
|
||||
int rc = snprintf(cur, len_remain, "%02x ", buf[i]);
|
||||
if (rc <= 0)
|
||||
break;
|
||||
cur += rc;
|
||||
}
|
||||
hexd_buff[sizeof(hexd_buff)-1] = 0;
|
||||
return hexd_buff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void debug_add_target(struct debug_target *target)
|
||||
{
|
||||
llist_add_tail(&target->entry, &target_list);
|
||||
}
|
||||
|
||||
void debug_del_target(struct debug_target *target)
|
||||
{
|
||||
llist_del(&target->entry);
|
||||
}
|
||||
|
||||
void debug_reset_context(void)
|
||||
{
|
||||
memset(&debug_context, 0, sizeof(debug_context));
|
||||
}
|
||||
|
||||
/* currently we are not reffing these */
|
||||
void debug_set_context(int ctx, void *value)
|
||||
{
|
||||
switch (ctx) {
|
||||
case BSC_CTX_LCHAN:
|
||||
debug_context.lchan = (struct gsm_lchan *) value;
|
||||
break;
|
||||
case BSC_CTX_SUBSCR:
|
||||
debug_context.subscr = (struct gsm_subscriber *) value;
|
||||
break;
|
||||
case BSC_CTX_BTS:
|
||||
debug_context.bts = (struct gsm_bts *) value;
|
||||
break;
|
||||
case BSC_CTX_SCCP:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void debug_set_imsi_filter(struct debug_target *target, const char *imsi)
|
||||
void log_set_imsi_filter(struct log_target *target, const char *imsi)
|
||||
{
|
||||
if (imsi) {
|
||||
target->filter_map |= DEBUG_FILTER_IMSI;
|
||||
target->imsi_filter = talloc_strdup(target, imsi);
|
||||
} else if (target->imsi_filter) {
|
||||
target->filter_map &= ~DEBUG_FILTER_IMSI;
|
||||
talloc_free(target->imsi_filter);
|
||||
target->imsi_filter = NULL;
|
||||
target->filter_map |= (1 << FLT_IMSI);
|
||||
target->filter_data[FLT_IMSI] = talloc_strdup(target, imsi);
|
||||
} else if (target->filter_data[FLT_IMSI]) {
|
||||
target->filter_map &= ~(1 << FLT_IMSI);
|
||||
talloc_free(target->filter_data[FLT_IMSI]);
|
||||
target->filter_data[FLT_IMSI] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void debug_set_all_filter(struct debug_target *target, int all)
|
||||
{
|
||||
if (all)
|
||||
target->filter_map |= DEBUG_FILTER_ALL;
|
||||
else
|
||||
target->filter_map &= ~DEBUG_FILTER_ALL;
|
||||
}
|
||||
|
||||
void debug_set_use_color(struct debug_target *target, int use_color)
|
||||
{
|
||||
target->use_color = use_color;
|
||||
}
|
||||
|
||||
void debug_set_print_timestamp(struct debug_target *target, int print_timestamp)
|
||||
{
|
||||
target->print_timestamp = print_timestamp;
|
||||
}
|
||||
|
||||
void debug_set_log_level(struct debug_target *target, int log_level)
|
||||
{
|
||||
target->loglevel = log_level;
|
||||
}
|
||||
|
||||
void debug_set_category_filter(struct debug_target *target, int category, int enable, int level)
|
||||
{
|
||||
if (category >= Debug_LastEntry)
|
||||
return;
|
||||
target->categories[category].enabled = !!enable;
|
||||
target->categories[category].loglevel = level;
|
||||
}
|
||||
|
||||
static void _stderr_output(struct debug_target *target, const char *log)
|
||||
{
|
||||
fprintf(target->tgt_stdout.out, "%s", log);
|
||||
fflush(target->tgt_stdout.out);
|
||||
}
|
||||
|
||||
struct debug_target *debug_target_create(void)
|
||||
{
|
||||
struct debug_target *target;
|
||||
|
||||
target = talloc_zero(tall_dbg_ctx, struct debug_target);
|
||||
if (!target)
|
||||
return NULL;
|
||||
|
||||
INIT_LLIST_HEAD(&target->entry);
|
||||
memcpy(target->categories, default_categories, sizeof(default_categories));
|
||||
target->use_color = 1;
|
||||
target->print_timestamp = 0;
|
||||
target->loglevel = 0;
|
||||
return target;
|
||||
}
|
||||
|
||||
struct debug_target *debug_target_create_stderr(void)
|
||||
{
|
||||
struct debug_target *target;
|
||||
|
||||
target = debug_target_create();
|
||||
if (!target)
|
||||
return NULL;
|
||||
|
||||
target->tgt_stdout.out = stderr;
|
||||
target->output = _stderr_output;
|
||||
return target;
|
||||
}
|
||||
|
||||
void debug_init(void)
|
||||
{
|
||||
tall_dbg_ctx = talloc_named_const(NULL, 1, "debug");
|
||||
}
|
||||
|
|
|
@ -442,7 +442,7 @@ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
debug_set_context(BSC_CTX_BTS, link->trx->bts);
|
||||
log_set_context(BSC_CTX_BTS, link->trx->bts);
|
||||
switch (link->type) {
|
||||
case E1INP_SIGN_OML:
|
||||
msg->trx = link->trx;
|
||||
|
|
|
@ -612,14 +612,14 @@ int main(int argc, char **argv)
|
|||
struct gsm_bts *bts;
|
||||
struct sockaddr_in sin;
|
||||
int rc, option_index = 0, stream_id = 0xff;
|
||||
struct debug_target *stderr_target;
|
||||
struct log_target *stderr_target;
|
||||
|
||||
debug_init();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
debug_set_log_level(stderr_target, 0);
|
||||
debug_parse_category_mask(stderr_target, "DNM,0");
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
log_set_log_level(stderr_target, 0);
|
||||
log_parse_category_mask(stderr_target, "DNM,0");
|
||||
bts_model_nanobts_init();
|
||||
|
||||
printf("ipaccess-config (C) 2009 by Harald Welte\n");
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include <openbsc/ipaccess.h>
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
static struct debug_target *stderr_target;
|
||||
static struct log_target *stderr_target;
|
||||
|
||||
/* one instance of an ip.access protocol proxy */
|
||||
struct ipa_proxy {
|
||||
|
@ -265,10 +265,10 @@ static void _logp_ipbc_uid(unsigned int ss, unsigned int lvl, char *file, int li
|
|||
struct ipa_bts_conn *ipbc, u_int8_t trx_id)
|
||||
{
|
||||
if (ipbc)
|
||||
debugp2(ss, lvl, file, line, 0, "(%u/%u/%u) ", ipbc->unit_id.site_id,
|
||||
logp2(ss, lvl, file, line, 0, "(%u/%u/%u) ", ipbc->unit_id.site_id,
|
||||
ipbc->unit_id.bts_id, trx_id);
|
||||
else
|
||||
debugp2(ss, lvl, file, line, 0, "unknown ");
|
||||
logp2(ss, lvl, file, line, 0, "unknown ");
|
||||
}
|
||||
|
||||
/* UDP socket handling */
|
||||
|
@ -1108,11 +1108,11 @@ int main(int argc, char **argv)
|
|||
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "ipaccess-proxy");
|
||||
|
||||
debug_init();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
debug_parse_category_mask(stderr_target, "DINP:DMI");
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
log_parse_category_mask(stderr_target, "DINP:DMI");
|
||||
|
||||
rc = ipaccess_proxy_setup();
|
||||
if (rc < 0)
|
||||
|
|
|
@ -166,14 +166,14 @@ int main(int argc, char** argv)
|
|||
struct gsm_network dummy_network;
|
||||
struct sockaddr_in addr;
|
||||
int on = 1, rc;
|
||||
struct debug_target *stderr_target;
|
||||
struct log_target *stderr_target;
|
||||
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "mgcp-callagent");
|
||||
|
||||
debug_init();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
|
||||
cfg = mgcp_config_alloc();
|
||||
if (!cfg)
|
||||
|
|
|
@ -117,7 +117,7 @@ int telnet_close_client(struct bsc_fd *fd) {
|
|||
bsc_unregister_fd(fd);
|
||||
|
||||
if (conn->dbg) {
|
||||
debug_del_target(conn->dbg);
|
||||
log_del_target(conn->dbg);
|
||||
talloc_free(conn->dbg);
|
||||
}
|
||||
|
||||
|
|
|
@ -878,7 +878,7 @@ DEFUN(show_paging,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void _vty_output(struct debug_target *tgt, const char *line)
|
||||
static void _vty_output(struct log_target *tgt, const char *line)
|
||||
{
|
||||
struct vty *vty = tgt->tgt_vty.vty;
|
||||
vty_out(vty, "%s", line);
|
||||
|
@ -887,11 +887,11 @@ static void _vty_output(struct debug_target *tgt, const char *line)
|
|||
vty_out(vty, "\r");
|
||||
}
|
||||
|
||||
struct debug_target *debug_target_create_vty(struct vty *vty)
|
||||
struct log_target *log_target_create_vty(struct vty *vty)
|
||||
{
|
||||
struct debug_target *target;
|
||||
struct log_target *target;
|
||||
|
||||
target = debug_target_create();
|
||||
target = log_target_create();
|
||||
if (!target)
|
||||
return NULL;
|
||||
|
||||
|
@ -913,11 +913,11 @@ DEFUN(enable_logging,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
conn->dbg = debug_target_create_vty(vty);
|
||||
conn->dbg = log_target_create_vty(vty);
|
||||
if (!conn->dbg)
|
||||
return CMD_WARNING;
|
||||
|
||||
debug_add_target(conn->dbg);
|
||||
log_add_target(conn->dbg);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -934,7 +934,7 @@ DEFUN(logging_fltr_imsi,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_set_imsi_filter(conn->dbg, argv[0]);
|
||||
log_set_imsi_filter(conn->dbg, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -951,7 +951,7 @@ DEFUN(logging_fltr_all,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_set_all_filter(conn->dbg, atoi(argv[0]));
|
||||
log_set_all_filter(conn->dbg, atoi(argv[0]));
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -968,7 +968,7 @@ DEFUN(logging_use_clr,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_set_use_color(conn->dbg, atoi(argv[0]));
|
||||
log_set_use_color(conn->dbg, atoi(argv[0]));
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -985,7 +985,7 @@ DEFUN(logging_prnt_timestamp,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_set_print_timestamp(conn->dbg, atoi(argv[0]));
|
||||
log_set_print_timestamp(conn->dbg, atoi(argv[0]));
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -998,8 +998,8 @@ DEFUN(logging_level,
|
|||
"Set the log level for a specified category\n")
|
||||
{
|
||||
struct telnet_connection *conn;
|
||||
int category = debug_parse_category(argv[0]);
|
||||
int level = debug_parse_level(argv[1]);
|
||||
int category = log_parse_category(argv[0]);
|
||||
int level = log_parse_level(argv[1]);
|
||||
|
||||
conn = (struct telnet_connection *) vty->priv;
|
||||
if (!conn->dbg) {
|
||||
|
@ -1025,7 +1025,7 @@ DEFUN(logging_level,
|
|||
|
||||
DEFUN(logging_set_category_mask,
|
||||
logging_set_category_mask_cmd,
|
||||
"logging set debug mask MASK",
|
||||
"logging set log mask MASK",
|
||||
"Decide which categories to output.\n")
|
||||
{
|
||||
struct telnet_connection *conn;
|
||||
|
@ -1036,7 +1036,7 @@ DEFUN(logging_set_category_mask,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_parse_category_mask(conn->dbg, argv[0]);
|
||||
log_parse_category_mask(conn->dbg, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1053,7 @@ DEFUN(logging_set_log_level,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_set_log_level(conn->dbg, atoi(argv[0]));
|
||||
log_set_log_level(conn->dbg, atoi(argv[0]));
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1070,7 +1070,7 @@ DEFUN(diable_logging,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
debug_del_target(conn->dbg);
|
||||
log_del_target(conn->dbg);
|
||||
talloc_free(conn->dbg);
|
||||
conn->dbg = NULL;
|
||||
return CMD_SUCCESS;
|
||||
|
|
|
@ -24,17 +24,17 @@
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct debug_target *stderr_target;
|
||||
struct log_target *stderr_target;
|
||||
|
||||
debug_init();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
|
||||
debug_parse_category_mask(stderr_target, "DRLL");
|
||||
log_parse_category_mask(stderr_target, "DRLL");
|
||||
DEBUGP(DCC, "You should not see this\n");
|
||||
|
||||
debug_parse_category_mask(stderr_target, "DRLL:DCC");
|
||||
log_parse_category_mask(stderr_target, "DRLL:DCC");
|
||||
DEBUGP(DRLL, "You should see this\n");
|
||||
DEBUGP(DCC, "You should see this\n");
|
||||
DEBUGP(DMM, "You should not see this\n");
|
||||
|
|
Loading…
Reference in New Issue