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"
26 static oic_log_ctx_t *logCtx = 0;
28 static oic_log_level LEVEL_XTABLE[] =
29 { OIC_LOG_DEBUG, OIC_LOG_INFO, OIC_LOG_WARNING, OIC_LOG_ERROR, OIC_LOG_FATAL };
31 static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
33 // Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino
35 static android_LogPriority LEVEL[] =
36 { ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL};
37 #elif defined __linux__
38 static const char * LEVEL[] __attribute__ ((unused)) =
39 { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
43 PROGMEM const char level0[] = "DEBUG";
44 PROGMEM const char level1[] = "INFO";
45 PROGMEM const char level2[] = "WARNING";
46 PROGMEM const char level3[] = "ERROR";
47 PROGMEM const char level4[] = "FATAL";
49 PROGMEM const char * const LEVEL[] =
50 { level0, level1, level2, level3, level4};
52 static void OICLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr);
53 #ifdef ARDUINO_ARCH_AVR
54 //Mega2560 and other 8-bit AVR microcontrollers
55 #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));}
56 #elif defined ARDUINO_ARCH_SAM
57 //Arduino Due and other 32-bit ARM micro-controllers
58 #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_dword(addr));}
60 #define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';}
65 void OICLogConfig(oic_log_ctx_t *ctx)
78 if (logCtx && logCtx->destroy)
80 logCtx->destroy(logCtx);
86 * Output a log string with the specified priority level.
87 * Only defined for Linux and Android
89 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
90 * @param tag - Module name
91 * @param logStr - log string
93 void OICLog(LogLevel level, const char * tag, const char * logStr)
101 __android_log_write(LEVEL[level], tag, logStr);
102 #elif defined __linux__
103 if (logCtx && logCtx->write_level)
105 logCtx->write_level(logCtx, LEVEL_XTABLE[level], logStr);
110 printf("%s: %s: %s\n", LEVEL[level], tag, logStr);
116 * Output a variable argument list log string with the specified priority level.
117 * Only defined for Linux and Android
119 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
120 * @param tag - Module name
121 * @param format - variadic log string
123 void OICLogv(LogLevel level, const char * tag, const char * format, ...)
129 char buffer[MAX_LOG_V_BUFFER_SIZE];
130 memset(buffer, 0, sizeof buffer);
132 va_start(args, format);
133 vsnprintf(buffer, sizeof buffer - 1, format, args);
135 OICLog(level, tag, buffer);
139 * Output the contents of the specified buffer (in hex) with the specified priority level.
141 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
142 * @param tag - Module name
143 * @param buffer - pointer to buffer of bytes
144 * @param bufferSize - max number of byte in buffer
146 void OICLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize)
148 if (!buffer || !tag || (bufferSize == 0))
153 char lineBuffer[LINE_BUFFER_SIZE];
154 memset(lineBuffer, 0, sizeof lineBuffer);
157 for (i = 0; i < bufferSize; i++)
159 // Format the buffer data into a line
160 snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
162 // Output 16 values per line
163 if (((i + 1) % 16) == 0)
165 OICLog(level, tag, lineBuffer);
166 memset(lineBuffer, 0, sizeof lineBuffer);
170 // Output last values in the line, if any
173 OICLog(level, tag, lineBuffer);
179 * Initialize the serial logger for Arduino
180 * Only defined for Arduino
184 Serial.begin(115200);
188 * Output a log string with the specified priority level.
189 * Only defined for Arduino. Only uses PROGMEM strings
190 * for the tag parameter
192 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
193 * @param tag - Module name
194 * @param logStr - log string
196 void OICLogString(LogLevel level, PROGMEM const char * tag, const char * logStr)
203 char buffer[LINE_BUFFER_SIZE];
205 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
206 Serial.print(buffer);
209 Serial.print(F(": "));
210 while ((c = pgm_read_byte(tag)))
215 Serial.print(F(": "));
217 Serial.println(logStr);
221 * Output the contents of the specified buffer (in hex) with the specified priority level.
223 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
224 * @param tag - Module name
225 * @param buffer - pointer to buffer of bytes
226 * @param bufferSize - max number of byte in buffer
228 void OICLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buffer, uint16_t bufferSize)
230 if (!buffer || !tag || (bufferSize == 0))
235 char lineBuffer[LINE_BUFFER_SIZE] =
237 uint8_t lineIndex = 0;
238 for (uint8_t i = 0; i < bufferSize; i++)
240 // Format the buffer data into a line
241 snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
243 // Output 16 values per line
246 OICLogString(level, tag, lineBuffer);
247 memset(lineBuffer, 0, sizeof lineBuffer);
251 // Output last values in the line, if any
254 OICLogString(level, tag, lineBuffer);
259 * Output a log string with the specified priority level.
260 * Only defined for Arduino. Uses PROGMEM strings
262 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
263 * @param tag - Module name
264 * @param logStr - log string
266 void OICLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr)
273 char buffer[LINE_BUFFER_SIZE];
275 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
276 Serial.print(buffer);
279 Serial.print(F(": "));
280 while ((c = pgm_read_byte(tag)))
285 Serial.print(F(": "));
287 while ((c = pgm_read_byte(logStr)))
296 * Output a variable argument list log string with the specified priority level.
297 * Only defined for Arduino as depicted below.
299 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
300 * @param tag - Module name
301 * @param format - variadic log string
303 void OICLogv(LogLevel level, PROGMEM const char * tag, const char * format, ...)
305 char buffer[LINE_BUFFER_SIZE];
307 va_start(ap, format);
309 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
310 Serial.print(buffer);
313 Serial.print(F(": "));
315 while ((c = pgm_read_byte(tag)))
320 Serial.print(F(": "));
322 vsnprintf(buffer, sizeof(buffer), format, ap);
323 for(char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines
335 * Output a variable argument list log string with the specified priority level.
336 * Only defined for Arduino as depicted below.
338 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
339 * @param tag - Module name
340 * @param format - variadic log string
342 void OICLogv(LogLevel level, PROGMEM const char * tag, const __FlashStringHelper *format, ...)
344 char buffer[LINE_BUFFER_SIZE];
346 va_start(ap, format);
348 GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
349 Serial.print(buffer);
352 Serial.print(F(": "));
354 while ((c = pgm_read_byte(tag)))
359 Serial.print(F(": "));
362 vsnprintf_P(buffer, sizeof(buffer), (const char *)format, ap); // progmem for AVR
364 vsnprintf(buffer, sizeof(buffer), (const char *)format, ap); // for the rest of the world
366 for(char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines