1/*
2 * coap_debug.h -- debug utilities
3 *
4 * Copyright (C) 2010-2011,2014-2023 Olaf Bergmann <bergmann@tzi.org>
5 *
6 * SPDX-License-Identifier: BSD-2-Clause
7 *
8 * This file is part of the CoAP library libcoap. Please see README for terms
9 * of use.
10 */
11
12/**
13 * @file coap_debug.h
14 * @brief CoAP Logging support
15 */
16
17#ifndef COAP_DEBUG_H_
18#define COAP_DEBUG_H_
19
20/**
21 * @ingroup application_api
22 * @defgroup logging Logging Support
23 * API for logging support
24 * @{
25 */
26
27#ifndef COAP_DEBUG_FD
28/**
29 * Used for output for @c COAP_LOG_OSCORE to @c COAP_LOG_ERR.
30 */
31#define COAP_DEBUG_FD stdout
32#endif
33
34#ifndef COAP_ERR_FD
35/**
36 * Used for output for @c COAP_LOG_CRIT to @c COAP_LOG_EMERG.
37 */
38#define COAP_ERR_FD stderr
39#endif
40
41#ifndef COAP_MAX_LOGGING_LEVEL
42#define COAP_MAX_LOGGING_LEVEL 8
43#endif /* ! COAP_MAX_LOGGING_LEVEL */
44
45/**
46 * Logging type.  These should be used where possible in the code instead
47 * of the syslog definitions, or alternatively use the coap_log_*() functions
48 * to reduce line length.
49 */
50typedef enum {
51  COAP_LOG_EMERG = 0,  /* 0 */
52  COAP_LOG_ALERT,      /* 1 */
53  COAP_LOG_CRIT,       /* 2 */
54  COAP_LOG_ERR,        /* 3 */
55  COAP_LOG_WARN,       /* 4 */
56  COAP_LOG_NOTICE,     /* 5 */
57  COAP_LOG_INFO,       /* 6 */
58  COAP_LOG_DEBUG,      /* 7 */
59  COAP_LOG_OSCORE,     /* 8 */
60  COAP_LOG_DTLS_BASE,
61#define COAP_LOG_CIPHERS COAP_LOG_DTLS_BASE /* For backward compatability */
62} coap_log_t;
63
64/*
65 * These have the same values, but can be used in #if tests for better
66 * readability
67 */
68#define _COAP_LOG_EMERG  0
69#define _COAP_LOG_ALERT  1
70#define _COAP_LOG_CRIT   2
71#define _COAP_LOG_ERR    3
72#define _COAP_LOG_WARN   4
73#define _COAP_LOG_NOTICE 5
74#define _COAP_LOG_INFO   6
75#define _COAP_LOG_DEBUG  7
76#define _COAP_LOG_OSCORE 8
77
78COAP_STATIC_INLINE void
79coap_no_log(void) { }
80
81#define coap_log_emerg(...) coap_log(COAP_LOG_EMERG, __VA_ARGS__)
82
83#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_ALERT)
84#define coap_log_alert(...) coap_log(COAP_LOG_ALERT, __VA_ARGS__)
85#else
86#define coap_log_alert(...) coap_no_log()
87#endif
88
89#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_CRIT)
90#define coap_log_crit(...) coap_log(COAP_LOG_CRIT, __VA_ARGS__)
91#else
92#define coap_log_crit(...) coap_no_log()
93#endif
94
95#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_ERR)
96#define coap_log_err(...) coap_log(COAP_LOG_ERR, __VA_ARGS__)
97#else
98#define coap_log_err(...) coap_no_log()
99#endif
100
101#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_WARN)
102#define coap_log_warn(...) coap_log(COAP_LOG_WARN, __VA_ARGS__)
103#else
104#define coap_log_warn(...) coap_no_log()
105#endif
106
107#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_INFO)
108#define coap_log_info(...) coap_log(COAP_LOG_INFO, __VA_ARGS__)
109#else
110#define coap_log_info(...) coap_no_log()
111#endif
112
113#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_NOTICE)
114#define coap_log_notice(...) coap_log(COAP_LOG_NOTICE, __VA_ARGS__)
115#else
116#define coap_log_notice(...) coap_no_log()
117#endif
118
119#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_DEBUG)
120#define coap_log_debug(...) coap_log(COAP_LOG_DEBUG, __VA_ARGS__)
121#else
122#define coap_log_debug(...) coap_no_log()
123#endif
124
125#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_OSCORE)
126#define coap_log_oscore(...) coap_log(COAP_LOG_OSCORE, __VA_ARGS__)
127#else
128#define coap_log_oscore(...) coap_no_log()
129#endif
130
131/*
132 * These entries are left here for backward compatability in applications
133 * (which should really "#include <syslog.h>").
134 * and MUST NOT be used anywhere within the libcoap code.
135 *
136 * If clashes occur during a particilar OS port, they can be safely deleted.
137 *
138 * In a future update, they will get removed.
139 */
140#if !defined(RIOT_VERSION) && !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
141#ifndef LOG_EMERG
142# define LOG_EMERG  COAP_LOG_EMERG
143#endif
144#ifndef LOG_ALERT
145# define LOG_ALERT  COAP_LOG_ALERT
146#endif
147#ifndef LOG_CRIT
148# define LOG_CRIT   COAP_LOG_CRIT
149#endif
150#ifndef LOG_ERR
151# define LOG_ERR    COAP_LOG_ERR
152#endif
153#ifndef LOG_WARNING
154# define LOG_WARNING COAP_LOG_WARN
155#endif
156#ifndef LOG_NOTICE
157# define LOG_NOTICE COAP_LOG_NOTICE
158#endif
159#ifndef LOG_INFO
160# define LOG_INFO   COAP_LOG_INFO
161#endif
162#ifndef LOG_DEBUG
163# define LOG_DEBUG  COAP_LOG_DEBUG
164#endif
165#endif /* ! RIOT_VERSION && ! WITH_LWIP && ! WITH_CONTIKI */
166
167/**
168 * Get the current logging level.
169 *
170 * @return One of the COAP_LOG_* values.
171 */
172coap_log_t coap_get_log_level(void);
173
174/**
175 * Sets the log level to the specified value.
176 *
177 * @param level One of the COAP_LOG_* values.
178 */
179void coap_set_log_level(coap_log_t level);
180
181/**
182 * Sets the (D)TLS logging level to the specified @p level.
183 *
184 * @param level One of the COAP_LOG_* values.
185 */
186void coap_dtls_set_log_level(coap_log_t level);
187
188/**
189 * Get the current (D)TLS logging.
190 *
191 * @return One of the COAP_LOG_* values.
192 */
193coap_log_t coap_dtls_get_log_level(void);
194
195/**
196 * Logging callback handler definition.
197 *
198 * @param level One of the COAP_LOG_* values, or if used for (D)TLS logging,
199 *              COAP_LOG_DTLS_BASE + one of the COAP_LOG_* values.
200 * @param message Zero-terminated string message to log.
201 */
202typedef void (*coap_log_handler_t)(coap_log_t level, const char *message);
203
204/**
205 * Add a custom log callback handler.
206 *
207 * @param handler The logging handler to use or @p NULL to use default handler.
208 *                 This handler will be used for both CoAP and (D)TLS logging.
209 */
210void coap_set_log_handler(coap_log_handler_t handler);
211
212/**
213 * Get the library package name.
214 *
215 * @return Zero-terminated string with the name of this library.
216 */
217const char *coap_package_name(void);
218
219/**
220 * Get the library package version.
221 *
222 * @return Zero-terminated string with the library version.
223 */
224const char *coap_package_version(void);
225
226/**
227 * Get the library package build.
228 *
229 * @return Zero-terminated string with the library build.
230 */
231const char *coap_package_build(void);
232
233/**
234 * Writes the given text to @c COAP_ERR_FD (for @p level <= @c COAP_LOG_CRIT) or
235 * @c COAP_DEBUG_FD (for @p level >= @c COAP_LOG_ERR). The text is output only
236 * when @p level is below or equal to the log level that set by
237 * coap_set_log_level().
238 *
239 * Internal function.
240 *
241 * @param level One of the COAP_LOG_* values.
242 & @param format The format string to use.
243 */
244#if (defined(__GNUC__))
245void coap_log_impl(coap_log_t level,
246                   const char *format, ...) __attribute__((format(printf, 2, 3)));
247#else
248void coap_log_impl(coap_log_t level, const char *format, ...);
249#endif
250
251#ifndef coap_log
252#ifdef WITH_CONTIKI
253#include <stdio.h>
254
255#ifndef LOG_CONF_LEVEL_COAP
256#define LOG_CONF_LEVEL_COAP 0 /* = LOG_LEVEL_NONE */
257#endif
258
259void coap_print_contiki_prefix(coap_log_t level);
260
261#define coap_log(level, ...) do { \
262    if (LOG_CONF_LEVEL_COAP && \
263        ((int)((level)) <= (int)coap_get_log_level())) { \
264      coap_print_contiki_prefix(level); \
265      printf(__VA_ARGS__); \
266    } \
267  } while(0)
268#else /* !WITH_CONTIKI */
269/**
270 * Logging function.
271 * Writes the given text to @c COAP_ERR_FD (for @p level <= @c COAP_LOG_CRIT) or @c
272 * COAP_DEBUG_FD (for @p level >= @c COAP_LOG_ERR). The text is output only when
273 * @p level is below or equal to the log level that set by coap_set_log_level().
274 *
275 * @param level One of the COAP_LOG_* values.
276 */
277#define coap_log(level, ...) do { \
278    if ((int)((level))<=(int)coap_get_log_level()) \
279      coap_log_impl((level), __VA_ARGS__); \
280  } while(0)
281#endif /* !WITH_CONTIKI */
282#endif
283
284#ifndef coap_dtls_log
285/**
286 * Logging function.
287 * Writes the given text to @c COAP_ERR_FD (for @p level <= @c COAP_LOG_CRIT) or @c
288 * COAP_DEBUG_FD (for @p level >= @c COAP_LOG_ERR). The text is output only when
289 * @p level is below or equal to the log level that set by coap_dtls_set_log_level().
290 *
291 * @param level One of the COAP_LOG_* values.
292 */
293#define coap_dtls_log(level, ...) do { \
294    if ((int)((level))<=(int)coap_dtls_get_log_level()) \
295      coap_log_impl((level)+COAP_LOG_DTLS_BASE, __VA_ARGS__); \
296  } while(0)
297#endif
298
299#include "coap_pdu.h"
300
301/**
302 * Defines the output mode for the coap_show_pdu() function.
303 *
304 * @param use_fprintf @p 1 if the output is to use fprintf() (the default)
305 *                    @p 0 if the output is to use coap_log().
306 */
307void coap_set_show_pdu_output(int use_fprintf);
308
309/**
310 * Display the contents of the specified @p pdu.
311 * Note: The output method of coap_show_pdu() is dependent on the setting of
312 * coap_set_show_pdu_output().
313 *
314 * @param level The required minimum logging level.
315 * @param pdu The PDU to decode.
316 */
317void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu);
318
319/**
320 * Display the current (D)TLS library linked with and built for version.
321 *
322 * @param level The required minimum logging level.
323 */
324void coap_show_tls_version(coap_log_t level);
325
326/**
327 * Build a string containing the current (D)TLS library linked with and
328 * built for version.
329 *
330 * @param buffer The buffer to put the string into.
331 * @param bufsize The size of the buffer to put the string into.
332 *
333 * @return A pointer to the provided buffer.
334 */
335char *coap_string_tls_version(char *buffer, size_t bufsize);
336
337/**
338 * Build a string containing the current (D)TLS library support
339 *
340 * @param buffer The buffer to put the string into.
341 * @param bufsize The size of the buffer to put the string into.
342 *
343 * @return A pointer to the provided buffer.
344 */
345char *coap_string_tls_support(char *buffer, size_t bufsize);
346
347/**
348 * Print the address into the defined buffer.
349 *
350 * @param address The address to print.
351 * @param buffer The buffer to print into.
352 * @param size The size of the buffer to print into.
353 *
354 * @return The amount written into the buffer.
355 */
356size_t coap_print_addr(const coap_address_t *address,
357                       unsigned char *buffer, size_t size);
358
359/**
360 * Print the IP address into the defined buffer.
361 *
362 * @param address The address to print.
363 * @param buffer The buffer to print into.
364 * @param size The size of the buffer to print into.
365 *
366 * @return The pointer to provided buffer with as much of the IP address added
367 *         as possible.
368 */
369const char *coap_print_ip_addr(const coap_address_t *address,
370                               char *buffer, size_t size);
371
372/** @} */
373
374/**
375 * Set the packet loss level for testing.  This can be in one of two forms.
376 *
377 * Percentage : 0% to 100%.  Use the specified probability.
378 * 0% is send all packets, 100% is drop all packets.
379 *
380 * List: A comma separated list of numbers or number ranges that are the
381 * packets to drop.
382 *
383 * @param loss_level The defined loss level (percentage or list).
384 *
385 * @return @c 1 If loss level set, @c 0 if there is an error.
386 */
387int coap_debug_set_packet_loss(const char *loss_level);
388
389#endif /* COAP_DEBUG_H_ */
390