/* See Project CHIP LICENSE file for licensing information. */ #include #include #include #include #include #include #include #include "fsl_debug_console.h" #include #ifdef CONFIG_ENABLE_PW_RPC #include #endif #define K32W_LOG_MODULE_NAME chip #define EOL_CHARS "\r\n" /* End of Line Characters */ #define EOL_CHARS_LEN 2 /* Length of EOL */ /* maximum value for uint32_t is 4294967295 - 10 bytes + 2 bytes for the brackets */ static constexpr uint8_t timestamp_max_len_bytes = 12; /* one byte for the category + 2 bytes for the brackets */ static constexpr uint8_t category_max_len_bytes = 3; #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include #include #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD static bool isLogInitialized; extern "C" uint32_t otPlatAlarmMilliGetNow(void); extern "C" void otPlatUartSendBlocking(const uint8_t * aBuf, uint32_t len); namespace chip { namespace Logging { namespace Platform { void GetMessageString(char * buf, uint8_t bufLen, const char * module, uint8_t category) { int writtenLen = 0; const char * categoryString; /* bufLen must accommodate the length of the timestamp + length of the category + * length of the module + 2 bytes for the module's brackets + * 1 byte for the terminating character. */ assert(bufLen >= (timestamp_max_len_bytes + category_max_len_bytes + (strlen(module) + 2) + 1)); writtenLen = snprintf(buf, bufLen, "[%ld]", otPlatAlarmMilliGetNow()); bufLen -= writtenLen; buf += writtenLen; if (category != kLogCategory_None) { switch (category) { case kLogCategory_Error: categoryString = "E"; break; case kLogCategory_Progress: categoryString = "P"; break; case kLogCategory_Detail: categoryString = "D"; break; default: categoryString = "U"; } writtenLen = snprintf(buf, bufLen, "[%s]", categoryString); bufLen -= writtenLen; buf += writtenLen; } writtenLen = snprintf(buf, bufLen, "[%s]", module); } } // namespace Platform } // namespace Logging } // namespace chip void FillPrefix(char * buf, uint8_t bufLen, const char * module, uint8_t category) { chip::Logging::Platform::GetMessageString(buf, bufLen, module, category); } namespace chip { namespace DeviceLayer { /** * Called whenever a log message is emitted by CHIP or LwIP. * * This function is intended be overridden by the application to, e.g., * schedule output of queued log entries. */ void __attribute__((weak)) OnLogOutput(void) {} } // namespace DeviceLayer } // namespace chip void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const char * module, uint8_t category) { #if K32W_LOG_ENABLED char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE - 1] = { 0 }; size_t prefixLen, writtenLen; if (!isLogInitialized) { isLogInitialized = true; #ifndef CONFIG_ENABLE_PW_RPC otPlatUartEnable(); #endif } /* Prefix is composed of [Time Reference][Debug String][Module Name String] */ FillPrefix(formattedMsg, CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE - 1, module, category); prefixLen = strlen(formattedMsg); // Append the log message. writtenLen = vsnprintf(formattedMsg + prefixLen, CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE - prefixLen - EOL_CHARS_LEN, format, arg); VerifyOrDie(writtenLen > 0); memcpy(formattedMsg + prefixLen + writtenLen, EOL_CHARS, EOL_CHARS_LEN); #ifndef CONFIG_ENABLE_PW_RPC otPlatUartSendBlocking((const uint8_t *) formattedMsg, strlen(formattedMsg)); #else PigweedLogger::PutString((const char *) formattedMsg, strlen(formattedMsg)); #endif // Let the application know that a log message has been emitted. chip::DeviceLayer::OnLogOutput(); #endif // K32W_LOG_ENABLED } namespace chip { namespace Logging { namespace Platform { /** * CHIP log output function. */ void LogV(const char * module, uint8_t category, const char * msg, va_list v) { (void) module; (void) category; #if K32W_LOG_ENABLED GenericLog(msg, v, module, category); // Let the application know that a log message has been emitted. DeviceLayer::OnLogOutput(); #endif // K32W_LOG_ENABLED } } // namespace Platform } // namespace Logging } // namespace chip #undef K32W_LOG_MODULE_NAME #define K32W_LOG_MODULE_NAME lwip #if CHIP_SYSTEM_CONFIG_USE_LWIP /** * LwIP log output function. */ extern "C" void ENFORCE_FORMAT(1, 2) LwIPLog(const char * msg, ...) { #if K32W_LOG_ENABLED va_list v; const char * module = "LWIP"; va_start(v, msg); GenericLog(msg, v, module, chip::Logging::kLogCategory_None); va_end(v); #endif } #endif // CHIP_SYSTEM_CONFIG_USE_LWIP #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #undef K32W_LOG_MODULE_NAME #define K32W_LOG_MODULE_NAME thread extern "C" void ENFORCE_FORMAT(3, 4) otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char * aFormat, ...) { #if K32W_LOG_ENABLED va_list v; const char * module = "OT"; (void) aLogLevel; (void) aLogRegion; va_start(v, aFormat); GenericLog(aFormat, v, module, chip::Logging::kLogCategory_None); va_end(v); #endif } #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD