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 static oic_log_ctx_t *logCtx = 0;
29 static oic_log_level LEVEL_XTABLE[] =
30 { OIC_LOG_DEBUG, OIC_LOG_INFO, OIC_LOG_WARNING, OIC_LOG_ERROR, OIC_LOG_FATAL };
34 static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 +
35 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
37 // Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino
40 static const char *LEVEL[] =
41 { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
44 static android_LogPriority LEVEL[] =
45 { ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL};
47 #elif defined __linux__
48 static const char *LEVEL[] __attribute__ ((unused)) =
49 { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
54 PROGMEM const char level0[] = "DEBUG";
55 PROGMEM const char level1[] = "INFO";
56 PROGMEM const char level2[] = "WARNING";
57 PROGMEM const char level3[] = "ERROR";
58 PROGMEM const char level4[] = "FATAL";
60 PROGMEM const char *const LEVEL[] =
61 { level0, level1, level2, level3, level4};
63 static void OICLogString(LogLevel level, PROGMEM const char *tag, PROGMEM const char *logStr);
64 #ifdef ARDUINO_ARCH_AVR
65 //Mega2560 and other 8-bit AVR microcontrollers
66 #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));}
67 #elif defined ARDUINO_ARCH_SAM
68 //Arduino Due and other 32-bit ARM micro-controllers
69 #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_dword(addr));}
71 #define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';}
77 void OICLogConfig(oic_log_ctx_t *ctx)
90 if (logCtx && logCtx->destroy)
92 logCtx->destroy(logCtx);
98 * Output a log string with the specified priority level.
99 * Only defined for Linux and Android
101 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
102 * @param tag - Module name
103 * @param logStr - log string
105 void OICLog(LogLevel level, const char *tag, const char *logStr)
115 printf("%s: %s: %s\n", LEVEL[level], tag, logStr);
117 __android_log_write(LEVEL[level], tag, logStr);
120 #elif defined __linux__
121 if (logCtx && logCtx->write_level)
123 logCtx->write_level(logCtx, LEVEL_XTABLE[level], logStr);
128 printf("%s: %s: %s\n", LEVEL[level], tag, logStr);
134 * Output a variable argument list log string with the specified priority level.
135 * Only defined for Linux and Android
137 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
138 * @param tag - Module name
139 * @param format - variadic log string
141 void OICLogv(LogLevel level, const char *tag, const char *format, ...)
147 char buffer[MAX_LOG_V_BUFFER_SIZE];
148 memset(buffer, 0, sizeof buffer);
150 va_start(args, format);
151 vsnprintf(buffer, sizeof buffer - 1, format, args);
153 OICLog(level, tag, buffer);
157 * Output the contents of the specified buffer (in hex) with the specified priority level.
159 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
160 * @param tag - Module name
161 * @param buffer - pointer to buffer of bytes
162 * @param bufferSize - max number of byte in buffer
164 void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16_t bufferSize)
166 if (!buffer || !tag || (bufferSize == 0))
171 char lineBuffer[LINE_BUFFER_SIZE];
172 memset(lineBuffer, 0, sizeof lineBuffer);
175 for (i = 0; i < bufferSize; i++)
177 // Format the buffer data into a line
178 sprintf(&lineBuffer[lineIndex++ * 3], "%02X ", buffer[i]);
179 // Output 16 values per line
180 if (((i + 1) % 16) == 0)
182 OICLog(level, tag, lineBuffer);
183 memset(lineBuffer, 0, sizeof lineBuffer);
187 // Output last values in the line, if any
190 OICLog(level, tag, lineBuffer);
197 * Initialize the serial logger for Arduino
198 * Only defined for Arduino
202 Serial.begin(115200);
206 * Output a log string with the specified priority level.
207 * Only defined for Arduino. Only uses PROGMEM strings
208 * for the tag parameter
210 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
211 * @param tag - Module name
212 * @param logStr - log string
215 void OCLogString(LogLevel level, PROGMEM const char * tag, const char * logStr) {
216 if (!logStr || !tag) {
220 char buffer[LINE_BUFFER_SIZE] = {0};
221 strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
222 Serial.print(buffer);
225 Serial.print(F(": "));
226 while ((c = pgm_read_byte(tag))) {
230 Serial.print(F(": "));
232 Serial.println(logStr);
236 * Output the contents of the specified buffer (in hex) with the specified priority level.
238 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
239 * @param tag - Module name
240 * @param buffer - pointer to buffer of bytes
241 * @param bufferSize - max number of byte in buffer
245 void OCLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buffer, uint16_t bufferSize) {
246 if (!buffer || !tag || (bufferSize == 0)) {
250 char lineBuffer[LINE_BUFFER_SIZE] = {0};
251 uint8_t lineIndex = 0;
252 for (uint8_t i = 0; i < bufferSize; i++) {
253 // Format the buffer data into a line
254 sprintf(&lineBuffer[lineIndex++ * 3], "%02X ", buffer[i]);
255 // Output 16 values per line
256 if (((i+1)%16) == 0) {
257 OCLogString(level, tag, lineBuffer);
258 memset(lineBuffer, 0, sizeof lineBuffer);
262 // Output last values in the line, if any
263 if (bufferSize % 16) {
264 OCLogString(level, tag, lineBuffer);
269 * Output a log string with the specified priority level.
270 * Only defined for Arduino. Uses PROGMEM strings
272 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
273 * @param tag - Module name
274 * @param logStr - log string
276 void OICLog(LogLevel level, PROGMEM const char *tag, const int16_t lineNum, PROGMEM const char *logStr)
282 char buffer[LINE_BUFFER_SIZE] = {0};
283 strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
284 Serial.print(buffer);
286 Serial.print(F(": "));
287 while ((c = pgm_read_byte(tag)))
292 Serial.print(F(": "));
293 Serial.print(lineNum);
294 Serial.print(F(": "));
295 while ((c = pgm_read_byte(logStr)))
304 * Output a variable argument list log string with the specified priority level.
305 * Only defined for Arduino as depicted below.
307 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
308 * @param tag - Module name
309 * @param format - variadic log string
311 void OICLogv(LogLevel level, PROGMEM const char *tag, const int16_t lineNum, PROGMEM const char *format, ...)
313 char buffer[LINE_BUFFER_SIZE];
315 va_start(ap, format);
316 strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
317 Serial.print(buffer);
320 Serial.print(F(": "));
321 while ((c = pgm_read_byte(tag))) {
325 Serial.print(F(": "));
326 Serial.print(lineNum);
327 Serial.print(F(": "));
329 vsnprintf_P(buffer, sizeof(buffer), format, ap);
330 for (char *p = &buffer[0]; *p; p++)
332 // emulate cooked mode for newlines
343 * Output a variable argument list log string with the specified priority level.
344 * Only defined for Arduino as depicted below.
346 * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
347 * @param tag - Module name
348 * @param format - variadic log string
350 void OICLogv(LogLevel level, const char *tag, const __FlashStringHelper *format, ...)
352 char buffer[LINE_BUFFER_SIZE];
354 va_start(ap, format);
355 // strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
356 // Serial.print(buffer);
358 Serial.print(LEVEL[level]);
360 Serial.print(F(": "));
362 /*while ((c = pgm_read_byte(tag))) {
367 Serial.print(F(": "));
370 vsnprintf_P(buffer, sizeof(buffer), (const char *)format, ap); // progmem for AVR
372 vsnprintf(buffer, sizeof(buffer), (const char *)format, ap); // for the rest of the world
374 for (char *p = &buffer[0]; *p; p++)
376 // emulate cooked mode for newlines
379 // Serial.write('\r');