blob: 8efa4539fdaa84239717a0611a5df0377a00070d [file] [log] [blame]
/* See Project CHIP LICENSE file for licensing information. */
#include <platform/logging/LogV.h>
#include <inttypes.h>
#include <lib/core/CHIPConfig.h>
#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <platform/CHIPDeviceConfig.h>
#include <src/lib/support/CodeUtils.h>
#include "fsl_debug_console.h"
#include <cstring>
#ifdef CONFIG_ENABLE_PW_RPC
#include <examples/platform/nxp/PigweedLogger.h>
#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 <openthread/platform/logging.h>
#include <utils/uart.h>
#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