Contiki 2.5
logging.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Daniel Willmann
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * @(#)$Id:$
32  */
33 
34 /**
35  * \addtogroup logging
36  * @{
37  */
38 
39 /**
40  * \file
41  * Implementation of the logging subsystem
42  * \author
43  * Daniel Willmann <daniel@totalueberwachung.de>
44  *
45  */
46 
47 
48 #include "logging.h"
49 #include "list.h"
50 #include "contiki-conf.h"
51 #include <string.h>
52 
53 #define SUBDOMS 5
54 #ifndef LOGL_DEFAULT
55 #define LOGL_DEFAULT LOGL_WRN
56 #endif
57 
58 struct log_cfg {
59  uint8_t subl[SUBDOMS];
60  uint8_t subdom_next;
61 };
62 
63 static char *logdomains[LOGD_NUM] = {
64  [LOGD_CORE] = "COR", /* Contiki core */
65  [LOGD_CPU] = "CPU", /* CPU */
66  [LOGD_INGA] = "PLA", /* Platform */
67  [LOGD_DTN] = "DTN", /* uDTN */
68  [LOGD_APP] = "APP", /* Application */
69 };
70 
71 static char *loglevels[LOGL_NUM] = {
72  [LOGL_DBG] = "DBG",
73  [LOGL_INF] = "INF",
74  [LOGL_WRN] = "WRN",
75  [LOGL_ERR] = "ERR",
76  [LOGL_CRI] = "CRI",
77 };
78 
79 static struct log_cfg log_d[LOGD_NUM];
80 static uint8_t inited = 0;
81 
82 /*---------------------------------------------------------------------------*/
83 /**
84  * \brief Convert the log domain symbol to a string
85  * \param logdom the log domain
86  * \return String of the log domain
87  * \author Daniel Willmann
88  *
89  * The function returns a three letter acronym
90  * used in the log messages to identify the
91  * different log domains.
92  *
93  */
94 const char *logging_dom2str(uint8_t logdom)
95 {
96  if (logdom >= LOGD_NUM)
97  return "UNK";
98  return logdomains[logdom];
99 }
100 
101 /*---------------------------------------------------------------------------*/
102 /**
103  * \brief Convert the log level symbol to a string
104  * \param logl the log level
105  * \return String of the log level
106  * \author Daniel Willmann
107  *
108  * The function returns a three letter acronym
109  * used in the log messages to identify the
110  * different log levels.
111  *
112  */
113 const char *logging_level2str(uint8_t logl)
114 {
115  if (logl >= LOGL_NUM)
116  return "UNK";
117  return loglevels[logl];
118 }
119 
120 /*---------------------------------------------------------------------------*/
121 /**
122  * \brief Initialize the logging subsystem
123  * \author Daniel Willmann
124  *
125  * This function initializes the logging subsystem and
126  * should be called before any other function from the
127  * module.
128  *
129  */
130 void logging_init(void)
131 {
132  int i, j;
133  if (inited)
134  return;
135 
136  for(i=0; i<LOGD_NUM; i++) {
137  for(j=0;j<SUBDOMS;j++) {
138  log_d[i].subl[j] = LOGL_DEFAULT;
139  }
140  log_d[i].subdom_next = 1;
141  }
142  inited = 1;
143 }
144 
145 /*---------------------------------------------------------------------------*/
146 /**
147  * \brief Set the verbosity of the logging domain
148  * \param logdom the domain for which to set the verbosity
149  * \param sdom the subdomain
150  * \param logl the minimal severity of the mesages that are
151  * logged
152  * \author Daniel Willmann
153  *
154  * This function sets the loglevel above which messages
155  * are logged (printed). Possible values are in order:
156  * * LOGL_DBG - Debug messages. Very verbose output
157  * * LOGL_INF - Informational messages. General information
158  * that might be useful
159  * * LOGL_WRN - Warnings. Abnormal program conditions that
160  * do not impair normal operation of the program
161  * * LOGL_ERR - Errors. The program can recover from these,
162  * but some functionality is impaired
163  * * LOGL_CRI - Critical errors. The program usually cannot
164  * recover from these
165  *
166  */
167 void logging_domain_level_set(uint8_t logdom, uint8_t sdom, uint8_t logl)
168 {
169  if ((logdom >= LOGD_NUM)||(logl >= LOGL_NUM)||(sdom >= SUBDOMS))
170  return;
171 
172  log_d[logdom].subl[sdom] = logl;
173 }
174 
175 /*---------------------------------------------------------------------------*/
176 /**
177  * \brief Log a message
178  * \param logdom the logdomain of the message
179  * \param sdom the subdomain
180  * \param logl the loglevel of the mesage
181  * \param fmt the format string of the message
182  * \param ... any parameters that are needed for the format string
183  * \author Daniel Willmann
184  *
185  * This is the actual logging function that decides whether
186  * the message should be printed or not. Do not use this
187  * function, instead use the LOGGING_LOG macro as this
188  * includes source file and line number inside the message.
189  *
190  */
191 void logging_logfn(uint8_t logdom, uint8_t sdom, uint8_t logl, const char *fmt, ...)
192 {
193  va_list ap;
194 
195  va_start(ap, fmt);
196 
197  if (logdom >= LOGD_NUM) {
198  printf("Unknown log domain %d (", logdom);
199  vprintf(fmt, ap);
200  printf(")\r\n");
201  va_end(ap);
202  return;
203  }
204 
205  if (logl >= LOGL_NUM)
206  logl = LOGL_ERR;
207  if (sdom >= SUBDOMS)
208  sdom = 0;
209  if (logl >= log_d[logdom].subl[sdom]) {
210  vprintf(fmt, ap);
211  printf("\r\n");
212  }
213 
214  va_end(ap);
215 }
216 
217 /*---------------------------------------------------------------------------*/
218 
219 void logging_hexdump(uint8_t *data, unsigned int len)
220 {
221  unsigned int i;
222 
223  for (i=0; i < len; i++) {
224  if (i % 16 == 0)
225  printf("\n%02X: ", i);
226 
227  printf(" %02X", data[i]);
228  }
229  printf("\n");
230 }
231 
232 /** @} */