/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see .
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
/*****************************************************************************
Source nas_log.c
Version 0.1
Date 2012/02/28
Product NAS stack
Subsystem Utilities
Author Frederic Maurel
Description Usefull logging functions
*****************************************************************************/
#include "nas_log.h"
#if defined(NAS_BUILT_IN_UE) && defined(NAS_UE)
int nas_log_func_indent;
#else
#include // stderr, sprintf, fprintf, vfprintf
#include // va_list, va_start, va_end
/****************************************************************************/
/**************** E X T E R N A L D E F I N I T I O N S ****************/
/****************************************************************************/
/* ANSI escape codes for colored display */
#define LOG_BLACK "\033[30m"
#define LOG_RED "\033[31m"
#define LOG_GREEN "\033[32m"
#define LOG_YELLOW "\033[33m"
#define LOG_BLUE "\033[34m"
#define LOG_MAGENTA "\033[35m"
#define LOG_CYAN "\033[36m"
#define LOG_WHITE "\033[37m"
#define LOG_END "\033[0m"
#define LOG_AUTO LOG_END
/****************************************************************************/
/******************* L O C A L D E F I N I T I O N S *******************/
/****************************************************************************/
/* ------------------------
* Internal logging context
* ------------------------
* Internal logging context consists on:
* - The file name and the line number from where the data have been
* logged. These information are gathered into a string that will
* be displayed as a prefix of the logging trace with the format
* filename[line]
* - The severity level filter
* - The indentation level to convey FUNC logging traces
* - The data definition of each logging trace level: name and mask
* (the mask is used against the severity level filter to enable
* or disable specific logging traces)
*/
typedef struct {
#define LOG_PREFIX_SIZE 118
char prefix[LOG_PREFIX_SIZE];
unsigned char filter;
int indent;
const struct {
char* name;
unsigned char mask;
char* color;
} level[];
} log_context_t;
/*
* Definition of the logging context
*/
static log_context_t _log_context = {
"", /* prefix */
0x00, /* filter */
0, /* indent */
{
{ "DEBUG", NAS_LOG_DEBUG, LOG_GREEN }, /* DEBUG */
{ "INFO", NAS_LOG_INFO, LOG_AUTO }, /* INFO */
{ "WARNING", NAS_LOG_WARNING, LOG_BLUE }, /* WARNING */
{ "ERROR", NAS_LOG_ERROR, LOG_RED }, /* ERROR */
{ "", NAS_LOG_FUNC, LOG_AUTO }, /* FUNC_IN */
{ "", NAS_LOG_FUNC, LOG_AUTO }, /* FUNC_OUT */
} /* level[] */
};
/* Maximum number of bytes into a line of dump logging data */
#define LOG_DUMP_LINE_SIZE 16
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
/****************************************************************************
** **
** Name: log_init() **
** **
** Description: Initializes internal logging data **
** **
** Inputs: filter: Value of the severity level that will be **
** used as a filter to enable or disable **
** specific logging traces **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
void nas_log_init(char filter)
{
_log_context.filter = filter;
}
/****************************************************************************
** **
** Name: log_data() **
** **
** Description: Defines internal logging data **
** **
** Inputs: filename: Name of the file from where the data have **
** been logged **
** line: Number of the line in the file **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
void log_data(const char* filename, int line)
{
int len = strlen(filename) + 2 + 1; //2:[], 1:/0
if (line > 9999) len+=5;
else if (line > 999) len+=4;
else if (line > 99) len+=3;
else if (line > 9) len+=2;
else len+=1;
if (len > LOG_PREFIX_SIZE) {
snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s:%d", &filename[len - LOG_PREFIX_SIZE], line);
} else {
snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s:%d", filename, line);
}
}
/****************************************************************************
** **
** Name: log_trace() **
** **
** Description: Displays logging data **
** **
** Inputs: severity: Severity level of the logging data **
** data: Formated logging data to display **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
void log_trace(log_severity_t severity, const char* data, ...)
{
int i;
/* Sanity check */
if (severity > LOG_SEVERITY_MAX) return;
/* Display only authorized logging traces */
if (_log_context.level[severity].mask & _log_context.filter) {
va_list argp;
/*
* First, display internal logging data (logging trace prefix: file
* name and line number from where the data have been logged) and
* the severity level.
*/
fprintf(stderr, "%s%-120.118s%-10s", _log_context.level[severity].color,
_log_context.prefix, _log_context.level[severity].name);
{
/* Next, perform indentation for FUNC logging trace */
if (severity == FUNC_OUT) {
_log_context.indent--;
}
for (i=0; i<_log_context.indent; i++) {
fprintf(stderr, " ");
}
if (severity == FUNC_IN) {
_log_context.indent++;
}
}
/* Finally, display logging data */
va_start(argp, data);
vfprintf(stderr, data, argp);
/* Terminate with line feed character */
fprintf(stderr, "%s\n", LOG_END);
va_end(argp);
}
}
/****************************************************************************
** **
** Name: log_dump() **
** **
** Description: Dump logging data **
** **
** Inputs: data: Logging data to dump **
** len: Number of bytes to be dumped **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
void log_dump(const char* data, int len)
{
int i;
/* Display only authorized logging traces */
if ( (len > 0) && (NAS_LOG_HEX & _log_context.filter) ) {
int bytes = 0;
fprintf(stderr, "\n\t");
for (i=0; i < len; i++) {
fprintf(stderr, "%.2hx ", (const unsigned char) data[i]);
/* Add new line when the number of displayed bytes exceeds
* the line's size */
if ( ++bytes > (LOG_DUMP_LINE_SIZE - 1) ) {
bytes = 0;
fprintf(stderr, "\n\t");
}
}
if (bytes % LOG_DUMP_LINE_SIZE) {
fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
fflush(stderr);
}
}
/****************************************************************************/
/********************* L O C A L F U N C T I O N S *********************/
/****************************************************************************/
#endif