1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #include "oic_logger.h"
24 #include "oic_console_logger.h"
27 #include <avr/pgmspace.h>
31 static oic_log_ctx_t *logCtx = 0;
33 static oic_log_level LEVEL_XTABLE[] =
34 { OIC_LOG_DEBUG, OIC_LOG_INFO, OIC_LOG_WARNING, OIC_LOG_ERROR, OIC_LOG_FATAL };
38 static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 +
39 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
41 // Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino
44 static const char *LEVEL[] =
45 { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
48 static android_LogPriority LEVEL[] =
49 { ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL};
51 #elif defined __linux__
52 static const char *LEVEL[] __attribute__ ((unused)) =
53 { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
57 PROGMEM const char level0[] = "DEBUG";
58 PROGMEM const char level1[] = "INFO";
59 PROGMEM const char level2[] = "WARNING";
60 PROGMEM const char level3[] = "ERROR";
61 PROGMEM const char level4[] = "FATAL";
63 PROGMEM const char *const LEVEL[] =
64 { level0, level1, level2, level3, level4};
66 static void OICLogString(LogLevel level, PROGMEM const char *tag, PROGMEM const char *logStr);
67 #ifdef ARDUINO_ARCH_AVR
68 //Mega2560 and other 8-bit AVR microcontrollers
69 #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));}
70 #elif defined ARDUINO_ARCH_SAM
71 //Arduino Due and other 32-bit ARM micro-controllers
72 #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_dword(addr));}
74 #define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';}
80 void OICLogConfig(oic_log_ctx_t *ctx)
93 if (logCtx && logCtx->destroy)
95 logCtx->destroy(logCtx);
101 * Output a log string with the specified priority level.
102 * Only defined for Linux and Android
104 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
105 * @param tag - Module name
106 * @param logStr - log string
108 void OICLog(LogLevel level, const char *tag, const char *logStr)
118 printf("%s: %s: %s\n", LEVEL[level], tag, logStr);
120 __android_log_write(LEVEL[level], tag, logStr);
123 #elif defined __linux__
124 if (logCtx && logCtx->write_level)
126 logCtx->write_level(logCtx, LEVEL_XTABLE[level], logStr);
131 printf("%s: %s: %s\n", LEVEL[level], tag, logStr);
137 * Output a variable argument list log string with the specified priority level.
138 * Only defined for Linux and Android
140 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
141 * @param tag - Module name
142 * @param format - variadic log string
144 void OICLogv(LogLevel level, const char *tag, const char *format, ...)
150 char buffer[MAX_LOG_V_BUFFER_SIZE];
151 memset(buffer, 0, sizeof buffer);
153 va_start(args, format);
154 vsnprintf(buffer, sizeof buffer - 1, format, args);
156 OICLog(level, tag, buffer);
160 * Output the contents of the specified buffer (in hex) with the specified priority level.
162 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
163 * @param tag - Module name
164 * @param buffer - pointer to buffer of bytes
165 * @param bufferSize - max number of byte in buffer
167 void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16_t bufferSize)
169 if (!buffer || !tag || (bufferSize == 0))
174 char lineBuffer[LINE_BUFFER_SIZE];
175 memset(lineBuffer, 0, sizeof lineBuffer);
178 for (i = 0; i < bufferSize; i++)
180 // Format the buffer data into a line
181 snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
183 // Output 16 values per line
184 if (((i + 1) % 16) == 0)
186 OICLog(level, tag, lineBuffer);
187 memset(lineBuffer, 0, sizeof lineBuffer);
191 // Output last values in the line, if any
194 OICLog(level, tag, lineBuffer);
200 * Initialize the serial logger for Arduino
201 * Only defined for Arduino
205 Serial.begin(115200);
209 * Output a log string with the specified priority level.
210 * Only defined for Arduino. Only uses PROGMEM strings
211 * for the tag parameter
213 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
214 * @param tag - Module name
215 * @param logStr - log string
217 void OICLogString(LogLevel level, PROGMEM const char *tag, const char *logStr)
224 char buffer[LINE_BUFFER_SIZE];
226 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
227 Serial.print(buffer);
230 Serial.print(F(": "));
231 while ((c = pgm_read_byte(tag)))
236 Serial.print(F(": "));
238 Serial.println(logStr);
242 * Output the contents of the specified buffer (in hex) with the specified priority level.
244 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
245 * @param tag - Module name
246 * @param buffer - pointer to buffer of bytes
247 * @param bufferSize - max number of byte in buffer
249 void OICLogBuffer(LogLevel level, PROGMEM const char *tag, const uint8_t *buffer,
252 if (!buffer || !tag || (bufferSize == 0))
257 char lineBuffer[LINE_BUFFER_SIZE] =
259 uint8_t lineIndex = 0;
260 for (uint8_t i = 0; i < bufferSize; i++)
262 // Format the buffer data into a line
263 snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
265 // Output 16 values per line
266 if (((i + 1) % 16) == 0)
268 OICLogString(level, tag, lineBuffer);
269 memset(lineBuffer, 0, sizeof lineBuffer);
273 // Output last values in the line, if any
276 OICLogString(level, tag, lineBuffer);
281 * Output a log string with the specified priority level.
282 * Only defined for Arduino. Uses PROGMEM strings
284 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
285 * @param tag - Module name
286 * @param logStr - log string
288 void OICLog(LogLevel level, PROGMEM const char *tag, PROGMEM const char *logStr)
295 char buffer[LINE_BUFFER_SIZE];
297 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
298 Serial.print(buffer);
301 Serial.print(F(": "));
302 while ((c = pgm_read_byte(tag)))
307 Serial.print(F(": "));
309 while ((c = pgm_read_byte(logStr)))
318 * Output a variable argument list log string with the specified priority level.
319 * Only defined for Arduino as depicted below.
321 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
322 * @param tag - Module name
323 * @param format - variadic log string
325 void OICLogv(LogLevel level, PROGMEM const char *tag, const char *format, ...)
327 char buffer[LINE_BUFFER_SIZE];
329 va_start(ap, format);
331 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
332 Serial.print(buffer);
335 Serial.print(F(": "));
337 while ((c = pgm_read_byte(tag)))
342 Serial.print(F(": "));
344 vsnprintf(buffer, sizeof(buffer), format, ap);
345 for (char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines
357 * Output a variable argument list log string with the specified priority level.
358 * Only defined for Arduino as depicted below.
360 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
361 * @param tag - Module name
362 * @param format - variadic log string
364 void OICLogv(LogLevel level, PROGMEM const char *tag, const __FlashStringHelper *format, ...)
366 char buffer[LINE_BUFFER_SIZE];
368 va_start(ap, format);
370 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
371 Serial.print(buffer);
374 Serial.print(F(": "));
376 while ((c = pgm_read_byte(tag)))
381 Serial.print(F(": "));
384 vsnprintf_P(buffer, sizeof(buffer), (const char *)format, ap); // progmem for AVR
386 vsnprintf(buffer, sizeof(buffer), (const char *)format, ap); // for the rest of the world
388 for (char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines