#include "infra_config.h" extern void **LITE_get_mem_mutex(void); extern void *HAL_MutexCreate(void); extern void HAL_MutexDestroy(void *); #include #include #include "infra_compat.h" #include "infra_log.h" #if defined(INFRA_CJSON) #include "infra_cjson.h" #endif #if defined(INFRA_LOG) && !defined(INFRA_LOG_ALL_MUTED) static log_client logcb = { .name = "linkkit", .priority = LOG_DEBUG_LEVEL, .text_buf = {0} }; static char *lvl_names[] = { "non", "crt", "err", "wrn", "inf", "dbg", "flw" }; /* 31, red. 32, green. 33, yellow. 34, blue. 35, magenta. 36, cyan. 37, white. */ char *lvl_color[] = { "[0m", "[1;31m", "[1;31m", "[1;35m", "[1;33m", "[1;36m", "[1;37m" }; void LITE_syslog_routine(char *m, const char *f, const int l, const int level, const char *fmt, va_list *params) { char *tmpbuf = logcb.text_buf; char *o = tmpbuf; int truncated = 0; if (LITE_get_loglevel() < level || level < LOG_NONE_LEVEL) { return; } #if !defined(_WIN32) LITE_printf("%s%s", "\033", lvl_color[level]); LITE_printf(LOG_PREFIX_FMT, lvl_names[level], f, l); #endif /* #if !defined(_WIN32) */ memset(tmpbuf, 0, sizeof(logcb.text_buf)); o = tmpbuf; o += LITE_vsnprintf(o, LOG_MSG_MAXLEN + 1, fmt, *params); if (o - tmpbuf > LOG_MSG_MAXLEN) { o = tmpbuf + strlen(tmpbuf); truncated = 1; } if (strlen(tmpbuf) == LOG_MSG_MAXLEN) { truncated = 1; } LITE_printf("%s", tmpbuf); if (truncated) { LITE_printf(" ..."); } if (tmpbuf[strlen(tmpbuf) - 1] != '\n') { LITE_printf("\r\n"); } #if !defined(_WIN32) LITE_printf("%s", "\033[0m"); #endif /* #if !defined(_WIN32) */ return; } void LITE_syslog(char *m, const char *f, const int l, const int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); LITE_syslog_routine(m, f, l, level, fmt, &ap); va_end(ap); } int LITE_get_loglevel(void) { return logcb.priority; } void LITE_set_loglevel(int pri) { void **mutex = NULL; logcb.priority = pri; #if WITH_MEM_STATS mutex = LITE_get_mem_mutex(); if (pri != LOG_NONE_LEVEL) { if (*mutex == NULL) { *mutex = HAL_MutexCreate(); if (*mutex == NULL) { LITE_printf("\nCreate memStats mutex error\n"); } } } else if (*mutex != NULL) { HAL_MutexDestroy(*mutex); *mutex = NULL; } #endif } void LITE_rich_hexdump(const char *f, const int l, const int level, const char *buf_str, const void *buf_ptr, const int buf_len) { if (LITE_get_loglevel() < level) { return; } LITE_printf("%s%s", "\033", lvl_color[level]); LITE_printf(LOG_PREFIX_FMT, lvl_names[level], f, l); LITE_printf("HEXDUMP %s @ %p[%d]\r\n", buf_str, buf_ptr, buf_len); LITE_hexdump(buf_str, buf_ptr, buf_len); LITE_printf("%s", "\033[0m"); return; } int log_multi_line_internal(const char *f, const int l, const char *title, int level, char *payload, const char *mark) { const char *pos; const char *endl; int i; if (LITE_get_loglevel() < level) { return 1; } LITE_printf("[%s] %s(%d): %s (Length: %d Bytes)\r\n", lvl_names[LITE_get_loglevel()], f, l, title, (int)strlen(payload)); pos = payload; while (pos && *pos) { LITE_printf("%s ", mark); if (*pos == '\r') { LITE_printf("\r\n"); pos += 2; continue; } endl = strchr(pos + 1, '\r'); if (endl == NULL) { endl = pos; do { ++endl; } while (*endl); } for (i = 0; i < endl - pos; ++i) { LITE_printf("%c", pos[i]); } LITE_printf("\r\n"); pos = *endl ? endl + 2 : 0; } return 0; } #define LITE_HEXDUMP_DRAWLINE(start_mark, len, end_mark) \ do { \ int i; \ \ LITE_printf("%s", start_mark); \ for(i = 0; i < len; ++i) { LITE_printf("-"); } \ LITE_printf("%s", end_mark); \ LITE_printf("\r\n"); \ \ } while(0) int LITE_hexdump(const char *title, const void *buff, const int len) { int i, j, written; unsigned char ascii[20] = {0}; char header[64] = {0}; unsigned char *buf = (unsigned char *)buff; LITE_snprintf(header, sizeof(header), "| %s: (len=%d) |\r\n", title, (int)len); LITE_HEXDUMP_DRAWLINE("+", strlen(header) - 4, "+"); LITE_printf("%s", header); LITE_printf("%s\r\n", HEXDUMP_SEP_LINE); written = 0; for (i = 0; i < len; ++ i) { if (i % 16 == 0) { LITE_printf("| %08X: ", (unsigned int)(i + (long)buff)); written += 8; } LITE_printf("%02X", buf[i]); written += 2; if (i % 2 == 1) { LITE_printf(" "); written += 1; } LITE_snprintf((char *)ascii + i % 16, (1 + 1), "%c", ((buf[i] >= ' ' && buf[i] <= '~') ? buf[i] : '.')); if (((i + 1) % 16 == 0) || (i == len - 1)) { for (j = 0; j < 48 - written; ++j) { LITE_printf(" "); } LITE_printf(" %s", ascii); LITE_printf("\r\n"); written = 0; memset(ascii, 0, sizeof(ascii)); } } LITE_printf("%s\r\n", HEXDUMP_SEP_LINE); return 0; } void IOT_SetLogLevel(IOT_LogLevel level) { int lvl = (int)level; if (lvl > LOG_DEBUG_LEVEL) { HAL_Printf("Invalid input level: %d out of [%d, %d]", level, LOG_NONE_LEVEL, LOG_DEBUG_LEVEL); return; } LITE_set_loglevel(lvl); HAL_Printf("[prt] log level set as: [ %d ]\r\n", lvl); } #else void IOT_SetLogLevel(IOT_LogLevel level) { return; } int log_multi_line_internal(const char *f, const int l, const char *title, int level, char *payload, const char *mark) { return 0; } void LITE_rich_hexdump(const char *f, const int l, const int level, const char *buf_str, const void *buf_ptr, const int buf_len) { return; } #endif /* #if defined(INFRA_LOG) && !defined(INFRA_LOG_ALL_MUTED) */