X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Flogger%2Fsrc%2Flogger.c;h=155b2b651f864c69aa5bb4909465967563f2558d;hb=bdec944c51c8e0063b6ee0890170e828ac8f2b96;hp=4b090a593685bdaaa0ca79e7c99244e035990ac2;hpb=15e34b0beec1996d5956275d2dc7c55d60cf78cd;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/logger/src/logger.c b/resource/csdk/logger/src/logger.c index 4b090a5..155b2b6 100644 --- a/resource/csdk/logger/src/logger.c +++ b/resource/csdk/logger/src/logger.c @@ -30,40 +30,72 @@ #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 +#endif -// if we have unistd.h, we're a Unix system +#ifdef HAVE_ARDUINO_TIME_H +#include +#else #include +#endif + +#ifdef HAVE_SYS_TIME_H #include #endif +#ifdef HAVE_WINDOWS_H +#include +#endif #include "logger.h" #include "string.h" -#include "oc_logger.h" -#include "oc_console_logger.h" +#include "logger_types.h" -static oc_log_ctx_t *logCtx = 0; +// log level +LogLevel g_level = DEBUG; +// privacy log +bool g_hidePrivateLogEntries = false; -static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO, OC_LOG_WARNING, OC_LOG_ERROR, OC_LOG_FATAL}; +#ifndef __TIZEN__ +static oc_log_ctx_t *logCtx = 0; +#endif +#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) + +#if defined(__ANDROID__) || defined(__TIZEN__) +#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 // 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 +#include +#include "Arduino.h" +#include "oic_string.h" PROGMEM const char level0[] = "DEBUG"; PROGMEM const char level1[] = "INFO"; @@ -76,28 +108,133 @@ static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 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 -void OCLogConfig(oc_log_ctx_t *ctx) { +/** + * 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++) + { + // 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); + } +} + +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); @@ -113,11 +250,23 @@ void OCLogShutdown() { * @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); @@ -125,34 +274,6 @@ void OCLogv(LogLevel level, const char * tag, const char * format, ...) { 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 = {}; - 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 @@ -161,254 +282,298 @@ static void osalGetTime(int *min,int *sec, int *ms) * @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; + } + + switch(level) + { + case DEBUG_LITE: + level = DEBUG; + break; + case INFO_LITE: + level = INFO; + break; + case INFO_PRIVATE: + level = INFO; + break; + default: + break; } - else + + #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); +} + +/** + * 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; + } - int min = 0; - int sec = 0; - int ms = 0; - osalGetTime(&min,&sec,&ms); + char buffer[LINE_BUFFER_SIZE]; - printf("%02d:%02d.%03d %s: %s: %s\n", min, sec, ms, LEVEL[level], tag, logStr); + GET_PROGMEM_BUFFER(buffer, &(LEVEL[level])); + Serial.print(buffer); + + char c; + Serial.print(F(": ")); + while ((c = pgm_read_byte(tag))) + { + Serial.write(c); + tag++; } -#endif + 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); - } -} + // 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); + } + } -#else - /** - * Initialize the serial logger for Arduino - * Only defined for Arduino - */ - void OCLogInit() { - Serial.begin(115200); - } - - /** - * 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, 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); - - char c; - Serial.print(F(": ")); - - while ((c = pgm_read_byte(tag))) { - Serial.write(c); - tag++; - } - Serial.print(F(": ")); - - vsnprintf(buffer, sizeof(buffer), format, ap); - for(char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines + Serial.write(c); + tag++; + } + Serial.print(F(": ")); + Serial.print(lineNum); + Serial.print(F(": ")); + +#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') { - if(*p == '\n') - { - Serial.write('\r'); - } - Serial.write(*p); + Serial.write('\r'); } - Serial.println(); - va_end(ap); + Serial.write(*p); } - /** - * 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 __FlashStringHelper *format, ...) + 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), (const char *)format, ap); // progmem for AVR +#else + vsnprintf(buffer, sizeof(buffer), (const char *)format, ap); // for the rest of the world +#endif + for (char *p = &buffer[0]; *p; p++) { - 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))) { - Serial.write(c); - tag++; - } - Serial.print(F(": ")); - - #ifdef __AVR__ - vsnprintf_P(buffer, sizeof(buffer), (const char *)format, ap); // progmem for AVR - #else - 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 + // 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