nas_log.c 10.9 KB
Newer Older
gauthier's avatar
GPLv3  
gauthier committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*******************************************************************************
    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.
Cedric Roux's avatar
 
Cedric Roux committed
15

gauthier's avatar
GPLv3  
gauthier committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29
    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 <http://www.gnu.org/licenses/>.

  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.

 *******************************************************************************/
/*****************************************************************************
30
Source    nas_log.c
Cedric Roux's avatar
 
Cedric Roux committed
31

32
Version   0.1
Cedric Roux's avatar
 
Cedric Roux committed
33

34
Date    2012/02/28
Cedric Roux's avatar
 
Cedric Roux committed
35

36
Product   NAS stack
Cedric Roux's avatar
 
Cedric Roux committed
37

38
Subsystem Utilities
Cedric Roux's avatar
 
Cedric Roux committed
39

40
Author    Frederic Maurel
Cedric Roux's avatar
 
Cedric Roux committed
41

42
Description Usefull logging functions
Cedric Roux's avatar
 
Cedric Roux committed
43 44 45 46

*****************************************************************************/

#include "nas_log.h"
47
#if defined(NAS_BUILT_IN_UE) && defined(NAS_UE)
48 49
int nas_log_func_indent;
#else
50 51
#include <stdio.h>  // stderr, sprintf, fprintf, vfprintf
#include <stdarg.h> // va_list, va_start, va_end
Cedric Roux's avatar
 
Cedric Roux committed
52 53 54 55 56 57

/****************************************************************************/
/****************  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 */
58 59 60 61 62 63 64 65 66 67
#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
Cedric Roux's avatar
 
Cedric Roux committed
68 69 70 71 72 73 74 75

/****************************************************************************/
/*******************  L O C A L    D E F I N I T I O N S  *******************/
/****************************************************************************/

/* ------------------------
 * Internal logging context
 * ------------------------
76 77 78 79 80 81 82 83 84 85
 *  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)
Cedric Roux's avatar
 
Cedric Roux committed
86
 */
87
typedef struct {
88
#define LOG_PREFIX_SIZE 118
89 90 91 92 93 94 95 96
  char prefix[LOG_PREFIX_SIZE];
  unsigned char filter;
  int indent;
  const struct {
    char* name;
    unsigned char mask;
    char* color;
  } level[];
Cedric Roux's avatar
 
Cedric Roux committed
97 98 99 100 101 102
} log_context_t;

/*
 * Definition of the logging context
 */
static log_context_t _log_context = {
103 104 105 106 107 108 109 110 111 112 113
  "",   /* 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[]  */
Cedric Roux's avatar
 
Cedric Roux committed
114 115 116
};

/* Maximum number of bytes into a line of dump logging data */
117
#define LOG_DUMP_LINE_SIZE  16
Cedric Roux's avatar
 
Cedric Roux committed
118 119 120 121 122 123 124

/****************************************************************************/
/******************  E X P O R T E D    F U N C T I O N S  ******************/
/****************************************************************************/

/****************************************************************************
 **                                                                        **
125
 ** Name:  log_init()                                                **
Cedric Roux's avatar
 
Cedric Roux committed
126 127 128
 **                                                                        **
 ** Description: Initializes internal logging data                         **
 **                                                                        **
129 130 131 132
 ** Inputs:  filter:  Value of the severity level that will be   **
 **       used as a filter to enable or disable      **
 **       specific logging traces                    **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
133
 **                                                                        **
134 135
 ** Outputs:   Return:  None                                       **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
136 137 138 139
 **                                                                        **
 ***************************************************************************/
void nas_log_init(char filter)
{
140
  _log_context.filter = filter;
Cedric Roux's avatar
 
Cedric Roux committed
141 142 143 144
}

/****************************************************************************
 **                                                                        **
145
 ** Name:  log_data()                                                **
Cedric Roux's avatar
 
Cedric Roux committed
146 147 148
 **                                                                        **
 ** Description: Defines internal logging data                             **
 **                                                                        **
149 150 151 152
 ** Inputs:  filename:  Name of the file from where the data have  **
 **         been logged                                **
 **      line:    Number of the line in the file             **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
153
 **                                                                        **
154 155
 ** Outputs:   Return:  None                                       **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
156 157 158 159
 **                                                                        **
 ***************************************************************************/
void log_data(const char* filename, int line)
{
160 161 162 163 164 165 166 167 168 169 170
  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);
  }
Cedric Roux's avatar
 
Cedric Roux committed
171 172 173 174
}

/****************************************************************************
 **                                                                        **
175
 ** Name:  log_trace()                                               **
Cedric Roux's avatar
 
Cedric Roux committed
176 177 178
 **                                                                        **
 ** Description: Displays logging data                                     **
 **                                                                        **
179 180 181
 ** Inputs:  severity:  Severity level of the logging data         **
 **      data:    Formated logging data to display           **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
182
 **                                                                        **
183 184
 ** Outputs:   Return:  None                                       **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
185 186 187 188
 **                                                                        **
 ***************************************************************************/
void log_trace(log_severity_t severity, const char* data, ...)
{
189 190 191 192 193 194 195 196 197 198 199 200 201 202
  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.
     */
203
    fprintf(stderr, "%s%-120.118s%-10s", _log_context.level[severity].color,
204
            _log_context.prefix, _log_context.level[severity].name);
Cedric Roux's avatar
 
Cedric Roux committed
205
    {
206 207 208 209 210 211
      /* Next, perform indentation for FUNC logging trace */
      if (severity == FUNC_OUT) {
        _log_context.indent--;
      }

      for (i=0; i<_log_context.indent; i++) {
212
        fprintf(stderr, "  ");
213 214 215 216 217
      }

      if (severity == FUNC_IN) {
        _log_context.indent++;
      }
Cedric Roux's avatar
 
Cedric Roux committed
218
    }
219 220 221 222 223 224 225 226 227 228

    /* 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);
  }
Cedric Roux's avatar
 
Cedric Roux committed
229 230 231 232
}

/****************************************************************************
 **                                                                        **
233
 ** Name:  log_dump()                                                **
Cedric Roux's avatar
 
Cedric Roux committed
234 235 236
 **                                                                        **
 ** Description: Dump logging data                                         **
 **                                                                        **
237 238 239
 ** Inputs:  data:    Logging data to dump                       **
 **      len:   Number of bytes to be dumped               **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
240
 **                                                                        **
241 242
 ** Outputs:   Return:  None                                       **
 **      Others:  None                                       **
Cedric Roux's avatar
 
Cedric Roux committed
243 244 245 246
 **                                                                        **
 ***************************************************************************/
void log_dump(const char* data, int len)
{
247
  int i;
Cedric Roux's avatar
 
Cedric Roux committed
248

249 250 251
  /* Display only authorized logging traces */
  if ( (len > 0) && (NAS_LOG_HEX & _log_context.filter) ) {
    int bytes = 0;
Cedric Roux's avatar
 
Cedric Roux committed
252

253
    fprintf(stderr, "\n\t");
Cedric Roux's avatar
 
Cedric Roux committed
254

255 256
    for (i=0; i < len; i++) {
      fprintf(stderr, "%.2hx ", (const unsigned char) data[i]);
Cedric Roux's avatar
 
Cedric Roux committed
257

258 259 260 261 262 263 264
      /* 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");
      }
    }
Cedric Roux's avatar
 
Cedric Roux committed
265

266 267
    if (bytes % LOG_DUMP_LINE_SIZE) {
      fprintf(stderr, "\n");
Cedric Roux's avatar
 
Cedric Roux committed
268
    }
269 270 271 272

    fprintf(stderr, "\n");
    fflush(stderr);
  }
Cedric Roux's avatar
 
Cedric Roux committed
273 274 275 276 277
}

/****************************************************************************/
/*********************  L O C A L    F U N C T I O N S  *********************/
/****************************************************************************/
278
#endif
Cedric Roux's avatar
 
Cedric Roux committed
279