#include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LOGGER_OUTPUT_BY_INTERRUPT #include #endif //LOGGER_OUTPUT_BY_INTERRUPT #ifndef LOGGER_OUTPUT_BY_INTERRUPT #include #endif //LOGGER_OUTPUT_BY_INTERRUPT #define LOGBUFFER_SIZE 2048 #define MSGBUFFER_SIZE 256 extern const uint8_t SYSLOG_SOCK; const uint8_t syslogAddr[] = { 172, 16, 11, 15 }; uint8_t singleOctetTXBuffer; static ringbuffer_t logBuffer; void logInit() { ringbufferInit(&logBuffer, LOGBUFFER_SIZE); } void logFree() { ringbufferFree(&logBuffer); } #ifdef LOGGER_OUTPUT_BY_INTERRUPT void debugTxCpltCallback(UART_HandleTypeDef *huart) { int c = ringbufferGetOne(&logBuffer); if (c > 0) { singleOctetTXBuffer = (uint8_t) c; HAL_UART_Transmit_IT(&debugUart, &singleOctetTXBuffer, 1); } } #endif //LOGGER_OUTPUT_BY_INTERRUPT #ifndef LOGGER_OUTPUT_BY_INTERRUPT int logExec() { int c = -1; if (__HAL_UART_GET_FLAG(&debugUart, UART_FLAG_TXE)) { // is the TX channel free c = ringbufferGetOne(&logBuffer); if (c > 0) { // transfer to TX channel uint8_t cc = (uint8_t) c; HAL_UART_Transmit(&debugUart, &cc, 1, HAL_MAX_DELAY); } } return c; } #endif //LOGGER_OUTPUT_BY_INTERRUPT void syslog(char *msg) { static uint8_t state = 0; int8_t res8 = 0; if (isNetworkAvailable()) { switch (state) { case 0: res8 = socket(SYSLOG_SOCK, Sn_MR_UDP, 514, SF_IO_NONBLOCK); if (res8 == SYSLOG_SOCK) { state = 1; } break; case 1: sendto(SYSLOG_SOCK, (uint8_t*)msg, strlen(msg), syslogAddr, 514); break; } } } static int innerLogMsg(const char *pre, const char *post, bool syslogToo, const char *format, va_list vl) { const static char SYSLOG_HEADER[] = "<133>1 "; #define MAX_PREFIX_SIZE 20 int res = -1; int offset = 0; char msgBuffer[MSGBUFFER_SIZE+MAX_PREFIX_SIZE]; char *bufferStart; memset(msgBuffer, 0, MSGBUFFER_SIZE+MAX_PREFIX_SIZE); uint16_t syslogHeaderSize = strlen(SYSLOG_HEADER); uint16_t preSize = (pre) ? strlen(pre) : 0; uint16_t prefixSize = (syslogHeaderSize > preSize) ? syslogHeaderSize : preSize; if (prefixSize > MAX_PREFIX_SIZE) { return -1; } bufferStart = msgBuffer + prefixSize; int vcnt = vsnprintf(bufferStart, MSGBUFFER_SIZE, format, vl); if (vcnt < MSGBUFFER_SIZE) { if (syslogToo) { memcpy(bufferStart - syslogHeaderSize, SYSLOG_HEADER, syslogHeaderSize); syslog(bufferStart - syslogHeaderSize); } if (pre) { memcpy(bufferStart - preSize, pre, preSize); } if (post) { strcat(bufferStart - preSize, post); } #ifdef LOGGER_OUTPUT_BY_INTERRUPT HAL_NVIC_DisableIRQ(UART4_IRQn); #endif //LOGGER_OUTPUT_BY_INTERRUPT res = ringbufferPut(&logBuffer, (uint8_t*) (bufferStart - preSize), strlen(bufferStart - preSize)); #ifdef LOGGER_OUTPUT_BY_INTERRUPT HAL_NVIC_EnableIRQ(UART4_IRQn); #endif //LOGGER_OUTPUT_BY_INTERRUPT #ifdef LOGGER_OUTPUT_BY_INTERRUPT debugTxCpltCallback(NULL); #endif LOGGER_OUTPUT_BY_INTERRUPT } return res; } int logMsg(const char *format, ...) { va_list vl; va_start(vl, format); int res = innerLogMsg(NULL, "\r\n", false, format, vl); va_end(vl); return res; } int coloredMsg(const t_logColor color, bool syslogToo, const char *format, ...) { const static char POST[] = "\x1b[0m\r\n"; const static char HIGH[] = "\x1b[1m"; const static char RED[] = "\x1b[31;1m"; const static char GREEN[] = "\x1b[32;1m"; const static char BLUE[] = "\x1b[34;1m"; const static char YELLOW[] = "\x1b[33;1m"; const char *pre = NULL; switch (color) { case LOG_HIGH: pre = HIGH; break; case LOG_RED: pre = RED; break; case LOG_BLUE: pre = BLUE; break; case LOG_GREEN: pre = GREEN; break; case LOG_YELLOW: pre = YELLOW; break; } va_list vl; va_start(vl, format); int res = innerLogMsg(pre, POST, syslogToo, format, vl); va_end(vl); return res; }