Update snapshot(2017-12-14)
[platform/upstream/iotivity.git] / resource / csdk / logger / src / logger.c
index a92afd4..155b2b6 100644 (file)
 #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 "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)
 
+#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
-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__
@@ -68,12 +88,14 @@ static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1;  // Show 16 bytes, 2
     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__)
-    static const char *LEVEL[] __attribute__ ((unused)) =
-    {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
+#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 "Arduino.h"
+#include "oic_string.h"
 
     PROGMEM const char level0[] = "DEBUG";
     PROGMEM const char level1[] = "INFO";
@@ -86,17 +108,119 @@ 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
+
+/**
+ * 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)
 {
@@ -110,7 +234,7 @@ void OCLogInit()
 
 void OCLogShutdown()
 {
-#if defined(__linux__) || defined(__APPLE__)
+#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)|| defined(__TIZENRT__)
     if (logCtx && logCtx->destroy)
     {
         logCtx->destroy(logCtx);
@@ -131,7 +255,18 @@ 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);
@@ -154,6 +289,31 @@ void OCLog(LogLevel level, const char * tag, const char * logStr)
        return;
     }
 
+    if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
+    {
+        return;
+    }
+
+    if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
+    {
+        return;
+    }
+
+    switch(level)
+    {
+        case DEBUG_LITE:
+            level = DEBUG;
+            break;
+        case INFO_LITE:
+            level = INFO;
+            break;
+        case INFO_PRIVATE:
+            level = INFO;
+            break;
+        default:
+            break;
+    }
+
    #ifdef __ANDROID__
 
    #ifdef ADB_SHELL
@@ -162,7 +322,7 @@ void OCLog(LogLevel level, const char * tag, const char * logStr)
        __android_log_write(LEVEL[level], tag, logStr);
    #endif
 
-   #elif defined __linux__ || defined __APPLE__
+   #else
        if (logCtx && logCtx->write_level)
        {
            logCtx->write_level(logCtx, LEVEL_XTABLE[level], logStr);
@@ -185,6 +345,12 @@ void OCLog(LogLevel level, const char * tag, const char * logStr)
                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))
@@ -198,47 +364,6 @@ void OCLog(LogLevel level, const char * tag, const char * logStr)
        }
    #endif
    }
-
-/**
- * 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)
-        {
-            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__
 #endif //ARDUINO
 #ifdef ARDUINO