#define _POSIX_C_SOURCE 200809L
#endif
-// Platform check can be extended to check and/or define more, or could be
-// moved into a config.h
-#if !defined(__ARDUINO__) && !defined(ARDUINO)
-#define HAVE_UNISTD_H 1
-#endif
+#include "iotivity_config.h"
// Pull in _POSIX_TIMERS feature test macro to check for
// clock_gettime() support.
#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
-// if we have unistd.h, we're a Unix system
+#ifdef HAVE_ARDUINO_TIME_H
+#include <Time.h>
+#else
#include <time.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
#include "logger.h"
#include "string.h"
-#include "oc_logger.h"
-#include "oc_console_logger.h"
+#include "logger_types.h"
+
+// log level
+LogLevel g_level = DEBUG;
+// privacy log
+bool g_hidePrivateLogEntries = false;
#ifndef __TIZEN__
static oc_log_ctx_t *logCtx = 0;
+#endif
-static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO, OC_LOG_WARNING, OC_LOG_ERROR, OC_LOG_FATAL};
+#if defined(_MSC_VER)
+#define LINE_BUFFER_SIZE (16 * 2) + 16 + 1 // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
+#define S_LINE_BUFFER_SIZE (50 * 2) + 50 + 1 // Show 50 bytes, 2 chars/byte, spaces between bytes, null termination
+#else
+static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
+static const uint16_t S_LINE_BUFFER_SIZE = (50 * 2) + 50 + 1; // Show 50 bytes, 2 chars/byte, spaces between bytes, null termination
+#endif //defined(_MSC_VER)
+#ifdef __ANDROID__
+#elif defined __linux__ || defined __APPLE__ || defined _WIN32 || defined(__TIZENRT__)
+static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO,
+ OC_LOG_WARNING, OC_LOG_ERROR, OC_LOG_FATAL};
#endif
-static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
// Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino
#ifdef __ANDROID__
- static android_LogPriority LEVEL[] = {ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL};
-#elif defined(__linux__) || defined(__APPLE__)
+#ifdef ADB_SHELL
+ static const char *LEVEL[] =
+ {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
+
+#else
+ static android_LogPriority LEVEL[] =
+ {ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL};
+#endif
+#elif defined(__linux__) || defined(__APPLE__) || defined(__msys_nt__)|| defined(__TIZENRT__)
static const char * LEVEL[] __attribute__ ((unused)) = {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
+#elif defined(_MSC_VER)
+ static const char * LEVEL[] = {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
#elif defined ARDUINO
- #include <stdarg.h>
+#include <stdarg.h>
+#include "Arduino.h"
+#include "oic_string.h"
PROGMEM const char level0[] = "DEBUG";
PROGMEM const char level1[] = "INFO";
static void OCLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr);
#ifdef ARDUINO_ARCH_AVR
//Mega2560 and other 8-bit AVR microcontrollers
- #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));}
+ #define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_word(addr));}
#elif defined ARDUINO_ARCH_SAM
//Arduino Due and other 32-bit ARM micro-controllers
- #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_dword(addr));}
+ #define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_dword(addr));}
#else
#define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';}
#endif
-#endif // __ANDROID__
-
+#else // !defined(__ANDROID__) && !defined(ARDUINO)
+ static const char *LEVEL[] __attribute__ ((unused)) =
+ {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
+#endif
#ifndef ARDUINO
-#ifdef __TIZEN__
-int OCGetTizenLogLevel(LogLevel level)
+/**
+ * Output the contents of the specified buffer (in hex) with the specified priority level.
+ *
+ * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag - Module name
+ * @param buffer - pointer to buffer of bytes
+ * @param bufferSize - max number of byte in buffer
+ */
+void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize)
{
- switch(level)
+ if (!buffer || !tag || (bufferSize == 0))
{
- case DEBUG:
- return DLOG_DEBUG;
- case INFO:
- return DLOG_INFO;
- case WARNING:
- return DLOG_WARN;
- case ERROR:
- return DLOG_ERROR;
- case FATAL:
- /*
- * Temp fix to resolve DLOG_FATAL runtime crash in tizen binary.
- * TODO: Revert back to DLOG_FATAL once logging issue is fixed in
- * Tizen binary.
- */
- return DLOG_ERROR;
+ return;
+ }
+
+ // No idea why the static initialization won't work here, it seems the compiler is convinced
+ // that this is a variable-sized object.
+ char lineBuffer[LINE_BUFFER_SIZE];
+ memset(lineBuffer, 0, sizeof lineBuffer);
+ int lineIndex = 0;
+ int i;
+ for (i = 0; i < bufferSize; i++)
+ {
+ // Format the buffer data into a line
+ snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
+ lineIndex++;
+ // Output 16 values per line
+ if (((i+1)%16) == 0)
+ {
+ OCLogv(level, tag, "%s", lineBuffer);
+ memset(lineBuffer, 0, sizeof lineBuffer);
+ lineIndex = 0;
+ }
+ }
+ // Output last values in the line, if any
+ if (bufferSize % 16)
+ {
+ OCLogv(level, tag, "%s", lineBuffer);
}
- return DLOG_DEBUG;
}
-#else
-void OCLogConfig(oc_log_ctx_t *ctx) {
+void OCPrintCALogBuffer(LogLevel level, const char *tag, const uint8_t *buffer,
+ uint16_t bufferSize, uint8_t isHeader)
+{
+ if (!buffer || !tag || (bufferSize == 0))
+ {
+ return;
+ }
+
+ // No idea why the static initialization won't work here, it seems the compiler is convinced
+ // that this is a variable-sized object.
+ char lineBuffer[S_LINE_BUFFER_SIZE];
+ int lineIndex = 0;
+ int i;
+ for (i = 0; i < bufferSize; i++)
+ {
+ // Format the buffer data into a line
+ snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
+ lineIndex++;
+ // Output 50 values per line
+ if (((i+1)%50) == 0)
+ {
+ if (1 == isHeader)
+ {
+ OCLogv(level, tag, "| Analyzer(Header) | %s", lineBuffer);
+ }
+ else
+ {
+ OCLogv(level, tag, "| Analyzer(Body) | %s", lineBuffer);
+ }
+ memset(lineBuffer, 0, sizeof lineBuffer);
+ lineIndex = 0;
+ }
+ }
+
+ if (bufferSize % 50)
+ {
+ if (1 == isHeader)
+ {
+ OCLogv(level, tag, "| Analyzer(Header) | %s", lineBuffer);
+ }
+ else
+ {
+ OCLogv(level, tag, "| Analyzer(Body) | %s", lineBuffer);
+ }
+ }
+}
+
+void OCSetLogLevel(LogLevel level, bool hidePrivateLogEntries)
+{
+ g_level = level;
+ g_hidePrivateLogEntries = hidePrivateLogEntries;
+}
+
+bool OCGetPrivateLogLevel()
+{
+ return g_hidePrivateLogEntries;
+}
+
+#ifndef __TIZEN__
+void OCLogConfig(oc_log_ctx_t *ctx)
+{
logCtx = ctx;
}
-void OCLogInit() {
+void OCLogInit()
+{
}
-void OCLogShutdown() {
-#if defined(__linux__) || defined(__APPLE__)
+void OCLogShutdown()
+{
+#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)|| defined(__TIZENRT__)
if (logCtx && logCtx->destroy)
{
logCtx->destroy(logCtx);
* @param tag - Module name
* @param format - variadic log string
*/
-void OCLogv(LogLevel level, const char * tag, const char * format, ...) {
+void OCLogv(LogLevel level, const char * tag, const char * format, ...)
+{
if (!format || !tag) {
return;
}
- char buffer[MAX_LOG_V_BUFFER_SIZE] = {};
+
+ if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
+ {
+ return;
+ }
+
+ if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
+ {
+ return;
+ }
+
+ char buffer[MAX_LOG_V_BUFFER_SIZE] = {0};
va_list args;
va_start(args, format);
vsnprintf(buffer, sizeof buffer - 1, format, args);
OCLog(level, tag, buffer);
}
-static void osalGetTime(int *min,int *sec, int *ms)
-{
- if (min && sec && ms)
- {
-#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
- struct timespec when = {0};
- clockid_t clk = CLOCK_REALTIME;
-#ifdef CLOCK_REALTIME_COARSE
- clk = CLOCK_REALTIME_COARSE;
-#endif
- if (!clock_gettime(clk, &when))
- {
- *min = (when.tv_sec / 60) % 60;
- *sec = when.tv_sec % 60;
- *ms = when.tv_nsec / 1000000;
- }
-#else
- struct timeval now;
- if (!gettimeofday(&now, NULL))
- {
- *min = (now.tv_sec / 60) % 60;
- *sec = now.tv_sec % 60;
- *ms = now.tv_usec * 1000;
- }
-#endif
- }
-}
-
/**
* Output a log string with the specified priority level.
* Only defined for Linux and Android
* @param tag - Module name
* @param logStr - log string
*/
-void OCLog(LogLevel level, const char * tag, const char * logStr) {
- if (!logStr || !tag) {
+void OCLog(LogLevel level, const char * tag, const char * logStr)
+{
+ if (!logStr || !tag)
+ {
+ return;
+ }
+
+ if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
+ {
return;
}
-#ifdef __ANDROID__
- __android_log_write(LEVEL[level], tag, logStr);
-#elif defined(__linux__) || defined(__APPLE__)
- if (logCtx && logCtx->write_level)
+ if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
{
- logCtx->write_level(logCtx, LEVEL_XTABLE[level], logStr);
+ return;
}
- else
+
+ switch(level)
{
+ case DEBUG_LITE:
+ level = DEBUG;
+ break;
+ case INFO_LITE:
+ level = INFO;
+ break;
+ case INFO_PRIVATE:
+ level = INFO;
+ break;
+ default:
+ break;
+ }
- int min = 0;
- int sec = 0;
- int ms = 0;
- osalGetTime(&min,&sec,&ms);
+ #ifdef __ANDROID__
+
+ #ifdef ADB_SHELL
+ printf("%s: %s: %s\n", LEVEL[level], tag, logStr);
+ #else
+ __android_log_write(LEVEL[level], tag, logStr);
+ #endif
+
+ #else
+ if (logCtx && logCtx->write_level)
+ {
+ logCtx->write_level(logCtx, LEVEL_XTABLE[level], logStr);
+
+ }
+ else
+ {
+ int min = 0;
+ int sec = 0;
+ int ms = 0;
+ #if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
+ struct timespec when = { .tv_sec = 0, .tv_nsec = 0 };
+ clockid_t clk = CLOCK_REALTIME;
+ #ifdef CLOCK_REALTIME_COARSE
+ clk = CLOCK_REALTIME_COARSE;
+ #endif
+ if (!clock_gettime(clk, &when))
+ {
+ min = (when.tv_sec / 60) % 60;
+ sec = when.tv_sec % 60;
+ ms = when.tv_nsec / 1000000;
+ }
+ #elif defined(_WIN32)
+ SYSTEMTIME systemTime = {0};
+ GetLocalTime(&systemTime);
+ min = (int)systemTime.wMinute;
+ sec = (int)systemTime.wSecond;
+ ms = (int)systemTime.wMilliseconds;
+ #else
+ struct timeval now;
+ if (!gettimeofday(&now, NULL))
+ {
+ min = (now.tv_sec / 60) % 60;
+ sec = now.tv_sec % 60;
+ ms = now.tv_usec * 1000;
+ }
+ #endif
+ printf("%02d:%02d.%03d %s: %s: %s\n", min, sec, ms, LEVEL[level], tag, logStr);
+ }
+ #endif
+ }
+#endif //__TIZEN__
+#endif //ARDUINO
+#ifdef ARDUINO
+/**
+ * Initialize the serial logger for Arduino
+ * Only defined for Arduino
+ */
+void OCLogInit()
+{
+ Serial.begin(115200);
+}
- printf("%02d:%02d.%03d %s: %s: %s\n", min, sec, ms, LEVEL[level], tag, logStr);
+/**
+ * Output a log string with the specified priority level.
+ * Only defined for Arduino. Only uses PROGMEM strings
+ * for the tag parameter
+ *
+ * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag - Module name
+ * @param logStr - log string
+ */
+void OCLogString(LogLevel level, PROGMEM const char * tag, const char * logStr)
+{
+ if (!logStr || !tag)
+ {
+ return;
}
-#endif
+
+ char buffer[LINE_BUFFER_SIZE];
+
+ GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
+ Serial.print(buffer);
+
+ char c;
+ Serial.print(F(": "));
+ while ((c = pgm_read_byte(tag)))
+ {
+ Serial.write(c);
+ tag++;
+ }
+ Serial.print(F(": "));
+
+ Serial.println(logStr);
}
/**
- * Output the contents of the specified buffer (in hex) with the specified priority level.
+ * Output the contents of the specified buffer (in hex) with the specified
+ * priority level.
*
* @param level - DEBUG, INFO, WARNING, ERROR, FATAL
* @param tag - Module name
* @param buffer - pointer to buffer of bytes
* @param bufferSize - max number of byte in buffer
*/
-void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize) {
- if (!buffer || !tag || (bufferSize == 0)) {
- return;
- }
-
- // No idea why the static initialization won't work here, it seems the compiler is convinced
- // that this is a variable-sized object.
- char lineBuffer[LINE_BUFFER_SIZE];
- memset(lineBuffer, 0, sizeof lineBuffer);
- int lineIndex = 0;
- int i;
- for (i = 0; i < bufferSize; i++) {
+ void OCLogBuffer(LogLevel level, PROGMEM const char * tag,
+ const uint8_t * buffer, size_t bufferSize)
+ {
+ if (!buffer || !tag || (bufferSize == 0))
+ {
+ return;
+ }
+
+ char lineBuffer[LINE_BUFFER_SIZE] = {0};
+ uint8_t lineIndex = 0;
+ for (uint8_t i = 0; i < bufferSize; i++)
+ {
// Format the buffer data into a line
snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
lineIndex++;
- // Output 16 values per line
- if (((i+1)%16) == 0) {
- OCLog(level, tag, lineBuffer);
- memset(lineBuffer, 0, sizeof lineBuffer);
- lineIndex = 0;
- }
- }
- // Output last values in the line, if any
- if (bufferSize % 16) {
- OCLog(level, tag, lineBuffer);
- }
-}
-#endif //__TIZEN__
-#else
- /**
- * Initialize the serial logger for Arduino
- * Only defined for Arduino
- */
- void OCLogInit() {
- Serial.begin(115200);
- }
+ // Output 16 values per line
+ if (((i+1)%16) == 0)
+ {
+ OCLogString(level, tag, lineBuffer);
+ memset(lineBuffer, 0, sizeof lineBuffer);
+ lineIndex = 0;
+ }
+ }
+ // Output last values in the line, if any
+ if (bufferSize % 16)
+ {
+ OCLogString(level, tag, lineBuffer);
+ }
+ }
- /**
- * Output a log string with the specified priority level.
- * Only defined for Arduino. Only uses PROGMEM strings
- * for the tag parameter
- *
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
- * @param tag - Module name
- * @param logStr - log string
- */
- void OCLogString(LogLevel level, PROGMEM const char * tag, const char * logStr) {
- if (!logStr || !tag) {
- return;
- }
-
- char buffer[LINE_BUFFER_SIZE];
-
- GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
- Serial.print(buffer);
-
- char c;
- Serial.print(F(": "));
- while ((c = pgm_read_byte(tag))) {
- Serial.write(c);
- tag++;
- }
- Serial.print(F(": "));
-
- Serial.println(logStr);
+/**
+ * Output a log string with the specified priority level.
+ * Only defined for Arduino. Uses PROGMEM strings
+ *
+ * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag - Module name
+ * @param logStr - log string
+ */
+void OCLog(LogLevel level, PROGMEM const char *tag, const int lineNum,
+ PROGMEM const char *logStr)
+{
+ if (!logStr || !tag)
+ {
+ return;
}
-
- /**
- * Output the contents of the specified buffer (in hex) with the specified priority level.
- *
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
- * @param tag - Module name
- * @param buffer - pointer to buffer of bytes
- * @param bufferSize - max number of byte in buffer
- */
- void OCLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buffer, uint16_t bufferSize) {
- if (!buffer || !tag || (bufferSize == 0)) {
- return;
- }
-
- char lineBuffer[LINE_BUFFER_SIZE] = {0};
- uint8_t lineIndex = 0;
- for (uint8_t i = 0; i < bufferSize; i++) {
- // Format the buffer data into a line
- snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
- lineIndex++;
- // Output 16 values per line
- if (((i+1)%16) == 0) {
- OCLogString(level, tag, lineBuffer);
- memset(lineBuffer, 0, sizeof lineBuffer);
- lineIndex = 0;
- }
- }
- // Output last values in the line, if any
- if (bufferSize % 16) {
- OCLogString(level, tag, lineBuffer);
- }
+ char buffer[LINE_BUFFER_SIZE] = {0};
+ GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
+ Serial.print(buffer);
+ char c;
+ Serial.print(F(": "));
+ while ((c = pgm_read_byte(tag)))
+ {
+ Serial.write(c);
+ tag++;
}
-
- /**
- * Output a log string with the specified priority level.
- * Only defined for Arduino. Uses PROGMEM strings
- *
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
- * @param tag - Module name
- * @param logStr - log string
- */
- void OCLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr) {
- if (!logStr || !tag) {
- return;
- }
-
- char buffer[LINE_BUFFER_SIZE];
-
- GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
- Serial.print(buffer);
-
- char c;
- Serial.print(F(": "));
- while ((c = pgm_read_byte(tag))) {
- Serial.write(c);
- tag++;
- }
- Serial.print(F(": "));
-
- while ((c = pgm_read_byte(logStr))) {
- Serial.write(c);
- logStr++;
- }
- Serial.println();
+ Serial.print(F(": "));
+ Serial.print(lineNum);
+ Serial.print(F(": "));
+ while ((c = pgm_read_byte(logStr)))
+ {
+ Serial.write(c);
+ logStr++;
}
+ Serial.println();
+}
- /**
- * Output a variable argument list log string with the specified priority level.
- * Only defined for Arduino as depicted below.
- *
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
- * @param tag - Module name
- * @param format - variadic log string
- */
- void OCLogv(LogLevel level, PROGMEM const char * tag, PROGMEM const char * format, ...)
+/**
+ * Output a variable argument list log string with the specified priority level.
+ * Only defined for Arduino as depicted below.
+ *
+ * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag - Module name
+ * @param format - variadic log string
+ */
+void OCLogv(LogLevel level, PROGMEM const char *tag, const int lineNum,
+ PROGMEM const char *format, ...)
+{
+ char buffer[LINE_BUFFER_SIZE];
+ va_list ap;
+ va_start(ap, format);
+ GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
+ Serial.print(buffer);
+
+ char c;
+ Serial.print(F(": "));
+ while ((c = pgm_read_byte(tag)))
{
- char buffer[LINE_BUFFER_SIZE];
- va_list ap;
- va_start(ap, format);
-
- GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
- Serial.print(buffer);
+ Serial.write(c);
+ tag++;
+ }
+ Serial.print(F(": "));
+ Serial.print(lineNum);
+ Serial.print(F(": "));
- char c;
- Serial.print(F(": "));
-
- while ((c = pgm_read_byte(tag))) {
- Serial.write(c);
- tag++;
+#ifdef __AVR__
+ vsnprintf_P(buffer, sizeof(buffer), format, ap);
+#else
+ vsnprintf(buffer, sizeof(buffer), format, ap);
+#endif
+ for (char *p = &buffer[0]; *p; p++)
+ {
+ // emulate cooked mode for newlines
+ if (*p == '\n')
+ {
+ Serial.write('\r');
}
- Serial.print(F(": "));
+ Serial.write(*p);
+ }
+ Serial.println();
+ va_end(ap);
+}
+/**
+ * Output a variable argument list log string with the specified priority level.
+ * Only defined for Arduino as depicted below.
+ *
+ * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param tag - Module name
+ * @param format - variadic log string
+ */
+void OCLogv(LogLevel level, const char *tag, const __FlashStringHelper *format, ...)
+{
+ char buffer[LINE_BUFFER_SIZE];
+ va_list ap;
+ va_start(ap, format);
+ // strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
+ // Serial.print(buffer);
+
+ Serial.print(LEVEL[level]);
+ // char c;
+ Serial.print(F(": "));
+
+ /*while ((c = pgm_read_byte(tag))) {
+ Serial.write(c);
+ tag++;
+ }*/
+ Serial.print(tag);
+ Serial.print(F(": "));
#ifdef __AVR__
- vsnprintf_P(buffer, sizeof(buffer), format, ap);
+ vsnprintf_P(buffer, sizeof(buffer), (const char *)format, ap); // progmem for AVR
#else
- vsnprintf(buffer, sizeof(buffer), format, ap);
+ vsnprintf(buffer, sizeof(buffer), (const char *)format, ap); // for the rest of the world
#endif
- for(char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines
+ for (char *p = &buffer[0]; *p; p++)
+ {
+ // emulate cooked mode for newlines
+ if (*p == '\n')
{
- if(*p == '\n')
- {
- Serial.write('\r');
- }
- Serial.write(*p);
+ // Serial.write('\r');
+ Serial.print('\r');
}
- Serial.println();
- va_end(ap);
+ //Serial.write(*p);
+ Serial.print(p);
}
+ Serial.println();
+ va_end(ap);
+}
-#endif
+#endif //ARDUINO