Morse Micro IoT SDK  2.10.4
mmlog.h
1/*
2 * Morse logging API
3 *
4 * Copyright 2025 Morse Micro
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
16#pragma once
17
18#ifdef __cplusplus
19extern "C"
20{
21#endif
22
23#include <stddef.h>
24#include <stdint.h>
25
26#include "mmosal.h"
27
32#define MM_X64_VAL(value) ((uint32_t)(value >> 32)), ((uint32_t)value)
33
35#define MM_X64_FMT "%08lx%08lx"
36
47#define MM_MAC_ADDR_VAL(value) \
48 ((value)[0]), ((value)[1]), ((value)[2]), ((value)[3]), ((value)[4]), ((value)[5])
49
51#define MM_MAC_ADDR_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
52
59void mm_logging_init(void);
60
71void mm_hexdump(char level,
72 const char *function,
73 unsigned line_number,
74 const char *title,
75 const uint8_t *buf,
76 size_t len);
77
78/*
79 * The log level is selected as follows, in decending priority order:
80 *
81 * 1. The value of MMLOG_LEVEL_OVRD (if defined)
82 * 2. The value of MMLOG_LEVEL_DEFAULT (if defined)
83 * 3. MMLOG_LEVEL_WRN
84 */
85#if defined(MMLOG_LEVEL_OVRD)
86#define MMLOG_LEVEL MMLOG_LEVEL_OVRD
87#elif defined(MMLOG_LEVEL_DEFAULT)
88#define MMLOG_LEVEL MMLOG_LEVEL_DEFAULT
89#else
91#define MMLOG_LEVEL MMLOG_LEVEL_ERR
92#endif
93
95#define MMLOG_LEVEL_INVALID (0)
97#define MMLOG_LEVEL_OFF (1)
99#define MMLOG_LEVEL_APP (2)
101#define MMLOG_LEVEL_ERR (3)
103#define MMLOG_LEVEL_WRN (4)
105#define MMLOG_LEVEL_INF (5)
107#define MMLOG_LEVEL_DBG (6)
109#define MMLOG_LEVEL_VRB (7)
110
111/* ANSI Escape Codes for Colours (0;xx) */
113#define MMLOG_COLOR_RED (31)
115#define MMLOG_COLOR_GREEN (32)
117#define MMLOG_COLOR_ORANGE (33)
119#define MMLOG_COLOR_BLUE (34)
121#define MMLOG_COLOR_PURPLE (35)
123#define MMLOG_COLOR_CYAN (36)
125#define MMLOG_COLOR_LIGHT_GRAY (37)
126
127#if defined(MMLOG_COLOR_ENABLED) && MMLOG_COLOR_ENABLED
128
129/*
130 * Prefix/Suffix with Colour Enabled (all log levels excluding APP)
131 */
132#ifndef MMLOG_PREFIX_FMT
133#define MMLOG_PREFIX_FMT "\x1b[0;%um%c %8lu %s %s[%d] "
134#endif
135
136#ifndef MMLOG_PREFIX_ARGS
137#define MMLOG_PREFIX_ARGS col, lvl, mmosal_get_time_ms(), short_task_name, __func__, __LINE__
138#endif
139
140#ifndef MMLOG_SUFFIX_FMT
141#define MMLOG_SUFFIX_FMT "\x1b[0m"
142#endif
143
144/*
145 * Prefix/Suffix with Colour Enabled (APP log level)
146 */
147#ifndef MMLOG_APP_PREFIX_FMT
148#define MMLOG_APP_PREFIX_FMT "\x1b[1;37m %8lu "
149#endif
150
151#ifndef MMLOG_APP_PREFIX_ARGS
152#define MMLOG_APP_PREFIX_ARGS mmosal_get_time_ms()
153#endif
154
155#ifndef MMLOG_APP_SUFFIX_FMT
156#define MMLOG_APP_SUFFIX_FMT "\x1b[0m"
157#endif
158
159#else
160
161/*
162 * Prefix/Suffix with Colour Disabled (all log levels excluding APP)
163 */
164#ifndef MMLOG_PREFIX_FMT
166#define MMLOG_PREFIX_FMT "%c %8lu %s %s[%d] "
167#endif
168
169#ifndef MMLOG_PREFIX_ARGS
171#define MMLOG_PREFIX_ARGS lvl, mmosal_get_time_ms(), short_task_name, __func__, __LINE__
172#endif
173
174#ifndef MMLOG_SUFFIX_FMT
176#define MMLOG_SUFFIX_FMT
177#endif
178
179/*
180 * Prefix/Suffix with Colour Enabled (APP messages)
181 */
182#ifndef MMLOG_APP_PREFIX_FMT
184#define MMLOG_APP_PREFIX_FMT " %8lu "
185#endif
186
187#ifndef MMLOG_APP_PREFIX_ARGS
189#define MMLOG_APP_PREFIX_ARGS mmosal_get_time_ms()
190#endif
191
192#ifndef MMLOG_APP_SUFFIX_FMT
194#define MMLOG_APP_SUFFIX_FMT
195#endif
196
197#endif
198
206static inline int printf_blackhole(const char *fmt, ...)
207{
208 (void)(fmt);
209 return 0;
210}
211
220static inline void mm_hexdump_blackhole(const char *title, const uint8_t *buf, size_t len)
221{
222 (void)(title);
223 (void)(buf);
224 (void)(len);
225}
226
227#if MMLOG_LEVEL == MMLOG_LEVEL_INVALID
228#error Invalid value of MMLOG_LEVEL
229#endif
230
231#ifndef MMLOG_PRINTF
233#define MMLOG_PRINTF(...) mmosal_printf(__VA_ARGS__)
234#endif
235
236#if MMLOG_LEVEL >= MMLOG_LEVEL_APP
238#define MMLOG_APP(fmt, ...) \
239 MMLOG_PRINTF(MMLOG_APP_PREFIX_FMT fmt MMLOG_APP_SUFFIX_FMT, \
240 MMLOG_APP_PREFIX_ARGS, \
241 ##__VA_ARGS__)
242#else
243#define MMLOG_APP(fmt, ...) printf_blackhole(fmt, ##__VA_ARGS__)
244#endif
245
246#if MMLOG_LEVEL >= MMLOG_LEVEL_ERR
248#define MMLOG(fmt, _col, _lvl, ...) \
249 do { \
250 char lvl = (_lvl); \
251 char col = (_col); \
252 char short_task_name[3] = { '?', '?', '\0' }; \
253 const char *task_name = mmosal_task_name(); \
254 if (task_name != NULL) \
255 { \
256 short_task_name[0] = task_name[0]; \
257 short_task_name[1] = task_name[1]; \
258 } \
259 (void)(lvl); \
260 (void)(col); \
261 (void)(short_task_name); \
262 MMLOG_PRINTF(MMLOG_PREFIX_FMT fmt MMLOG_SUFFIX_FMT, MMLOG_PREFIX_ARGS, ##__VA_ARGS__); \
263 } while (0)
264
266#define MMLOG_ERR(fmt, ...) MMLOG(fmt, MMLOG_COLOR_RED, 'E', ##__VA_ARGS__)
268#define MMLOG_DUMP_ERR(title, buf, len) mm_hexdump('E', __func__, __LINE__, (title), (buf), (len))
269#else
271#define MMLOG_ERR(fmt, ...) printf_blackhole(fmt, ##__VA_ARGS__)
273#define MMLOG_DUMP_ERR(title, buf, len) mm_hexdump_blackhole(title, buf, len)
274#endif
275
276#if MMLOG_LEVEL >= MMLOG_LEVEL_WRN
278#define MMLOG_WRN(fmt, ...) MMLOG(fmt, MMLOG_COLOR_ORANGE, 'W', ##__VA_ARGS__)
280#define MMLOG_DUMP_WRN(title, buf, len) mm_hexdump('W', __func__, __LINE__, (title), (buf), (len))
281#else
283#define MMLOG_WRN(fmt, ...) printf_blackhole(fmt, ##__VA_ARGS__)
285#define MMLOG_DUMP_WRN(title, buf, len) mm_hexdump_blackhole(title, buf, len)
286#endif
287
288#if MMLOG_LEVEL >= MMLOG_LEVEL_INF
290#define MMLOG_INF(fmt, ...) MMLOG(fmt, MMLOG_COLOR_LIGHT_GRAY, 'I', ##__VA_ARGS__)
292#define MMLOG_DUMP_INF(title, buf, len) mm_hexdump('I', __func__, __LINE__, (title), (buf), (len))
293#else
295#define MMLOG_INF(fmt, ...) printf_blackhole(fmt, ##__VA_ARGS__)
297#define MMLOG_DUMP_INF(title, buf, len) mm_hexdump_blackhole(title, buf, len)
298#endif
299
300#if MMLOG_LEVEL >= MMLOG_LEVEL_DBG
302#define MMLOG_DBG(fmt, ...) MMLOG(fmt, MMLOG_COLOR_GREEN, 'D', ##__VA_ARGS__)
304#define MMLOG_DUMP_DBG(title, buf, len) mm_hexdump('D', __func__, __LINE__, (title), (buf), (len))
305#else
307#define MMLOG_DBG(fmt, ...) printf_blackhole(fmt, ##__VA_ARGS__)
309#define MMLOG_DUMP_DBG(title, buf, len) mm_hexdump_blackhole(title, buf, len)
310#endif
311
312#if MMLOG_LEVEL >= MMLOG_LEVEL_VRB
314#define MMLOG_VRB(fmt, ...) MMLOG(fmt, MMLOG_COLOR_PURPLE, 'V', ##__VA_ARGS__)
316#define MMLOG_DUMP_VRB(title, buf, len) mm_hexdump('V', __func__, __LINE__, (title), (buf), (len))
317#else
319#define MMLOG_VRB(fmt, ...) printf_blackhole(fmt, ##__VA_ARGS__)
321#define MMLOG_DUMP_VRB(title, buf, len) mm_hexdump_blackhole(title, buf, len)
322#endif
323
324#ifdef __cplusplus
325}
326#endif
327
static void mm_hexdump_blackhole(const char *title, const uint8_t *buf, size_t len)
Black hole version of mm_hexdump() to ensure arguments are referenced when a given log level is disab...
Definition: mmlog.h:220
void mm_logging_init(void)
Initialize Morse logging API.
void mm_hexdump(char level, const char *function, unsigned line_number, const char *title, const uint8_t *buf, size_t len)
Dumps a binary buffer in hex.
static int printf_blackhole(const char *fmt,...)
Black hole printf to ensure arguments are referenced when a given log level is disabled.
Definition: mmlog.h:206
char buf[1408]
Statically allocated buffer for HTTP GET request, just under 1 packet size.
Definition: sslclient.c:176