AlteriomPainlessMesh v2.1.1
Easy ESP32/ESP8266 mesh networking with Alteriom IoT extensions
Loading...
Searching...
No Matches
logger.hpp
Go to the documentation of this file.
1#ifndef _PAINLESS_MESH_LOGGER_HPP_
2#define _PAINLESS_MESH_LOGGER_HPP_
3
4#include <list>
5
6namespace painlessmesh {
7namespace logger {
8#include <stdarg.h>
9#include "Arduino.h"
10
11#define REMOTE_QUEUE_SIZE 10
12
13// Windows defines ERROR as a macro, undefine it to avoid conflicts
14#ifdef ERROR
15#undef ERROR
16#endif
17
18typedef enum {
19 ERROR = 1 << 0,
20 STARTUP = 1 << 1,
21 MESH_STATUS = 1 << 2,
22 CONNECTION = 1 << 3,
23 SYNC = 1 << 4,
24 S_TIME = 1 << 5,
25 COMMUNICATION = 1 << 6,
26 GENERAL = 1 << 7,
27 MSG_TYPES = 1 << 8,
28 REMOTE = 1 << 9, // not yet implemented
29 APPLICATION = 1 << 10,
30 DEBUG = 1 << 11
32
33// Log() is printf-like. In the desktop test build the compiler is told so,
34// and -Wall -Werror in CI then rejects any argument that does not match its
35// specifier. That class of bug reached main twice in routePackage(): size_t
36// through %d/%u, and a DeserializationError object through %u (CodeQL
37// cpp/wrong-type-format-argument). The check is kept to the desktop build on
38// purpose: ESP-IDF 5 makes uint32_t `unsigned long`, so on ESP32 every %u of
39// a node id would warn, harmlessly, in every user's build.
40#if defined(PAINLESSMESH_BOOST) && defined(__GNUC__)
41#define PAINLESSMESH_LOG_FORMAT __attribute__((format(printf, 3, 4)))
42#else
43#define PAINLESSMESH_LOG_FORMAT
44#endif
45
46class LogClass {
47 public:
48 // Where messages go instead of Serial. The sketch owns framing: on a board
49 // whose serial port carries a line protocol, mesh logs written straight to
50 // Serial from a Wi-Fi event task splice into the sketch's own frames, so
51 // the sketch queues them here and writes them between its frames. Called
52 // from whichever task logged, so keep it short and re-entrant.
53 typedef void (*Sink)(LogLevel type, const char *message);
54 void setSink(Sink newSink) { sink = newSink; }
55
56 void setLogLevel(uint16_t newTypes) {
57 // set the different kinds of debug messages you want to generate.
58 types = newTypes;
59 Serial.print(F("\nsetLogLevel:"));
60 if (types & ERROR) {
61 Serial.print(F(" ERROR |"));
62 }
63 if (types & STARTUP) {
64 Serial.print(F(" STARTUP |"));
65 }
66 if (types & MESH_STATUS) {
67 Serial.print(F(" MESH_STATUS |"));
68 }
69 if (types & CONNECTION) {
70 Serial.print(F(" CONNECTION |"));
71 }
72 if (types & SYNC) {
73 Serial.print(F(" SYNC |"));
74 }
75 if (types & S_TIME) {
76 Serial.print(F(" S_TIME |"));
77 }
78 if (types & COMMUNICATION) {
79 Serial.print(F(" COMMUNICATION |"));
80 }
81 if (types & GENERAL) {
82 Serial.print(F(" GENERAL |"));
83 }
84 if (types & MSG_TYPES) {
85 Serial.print(F(" MSG_TYPES |"));
86 }
87 if (types & REMOTE) {
88 Serial.print(F(" REMOTE |"));
89 }
90 if (types & APPLICATION) {
91 Serial.print(F(" APPLICATION |"));
92 }
93 if (types & DEBUG) {
94 Serial.print(F(" DEBUG |"));
95 }
96 Serial.println();
97 return;
98 }
99 void operator()(LogLevel type, const char *format...) PAINLESSMESH_LOG_FORMAT {
100 if (type & types) { // Print only the message types set for output
101 va_list args;
102 va_start(args, format);
103
104 vsnprintf(str, 200, format, args);
105
106 if (sink) {
107 sink(type, str);
108 va_end(args);
109 return;
110 }
111
112 if (types) {
113 switch (type) {
114 case ERROR:
115 Serial.print(F("ERROR: "));
116 break;
117 case STARTUP:
118 Serial.print(F("STARTUP: "));
119 break;
120 case MESH_STATUS:
121 Serial.print(F("MESH_STATUS: "));
122 break;
123 case CONNECTION:
124 Serial.print(F("CONNECTION: "));
125 break;
126 case SYNC:
127 Serial.print(F("SYNC: "));
128 break;
129 case S_TIME:
130 Serial.print(F("S_TIME: "));
131 break;
132 case COMMUNICATION:
133 Serial.print(F("COMMUNICATION: "));
134 break;
135 case GENERAL:
136 Serial.print(F("GENERAL: "));
137 break;
138 case MSG_TYPES:
139 Serial.print(F("MSG_TYPES: "));
140 break;
141 case REMOTE:
142 this->remote(format);
143 Serial.print(F("REMOTE: "));
144 break;
145 case APPLICATION:
146 Serial.print(F("APPLICATION: "));
147 break;
148 case DEBUG:
149 Serial.print(F("DEBUG: "));
150 break;
151 }
152 }
153
154 Serial.print(str);
155
156 va_end(args);
157 }
158 }
159
160 void remote(const char *format...) {
161 if (REMOTE & types) { // Store only the message if REMOTE set
162 va_list args;
163 va_start(args, format);
164
165 vsnprintf(str, 200, format, args);
166
167 remote_queue.push_back(std::pair<uint32_t, TSTRING>(remote_uuid, str));
168 ++remote_uuid;
169 if (remote_queue.size() > REMOTE_QUEUE_SIZE) {
170 // No place to store the reason, but do signify the queue is full,
171 // discard any follow up
172 remote_queue.pop_front();
173 }
174 }
175 }
176
177 std::list<std::pair<uint32_t, TSTRING>> &get_remote_queue() {
178 return remote_queue;
179 }
180
181 private:
182 uint16_t types = 0;
183 Sink sink = nullptr;
184 char str[200];
185 std::list<std::pair<uint32_t, TSTRING>> remote_queue;
186 uint32_t remote_uuid = 0;
187};
188
189} // namespace logger
190} // namespace painlessmesh
191#endif
Definition logger.hpp:46
void setSink(Sink newSink)
Definition logger.hpp:54
void remote(const char *format...)
Definition logger.hpp:160
std::list< std::pair< uint32_t, TSTRING > > & get_remote_queue()
Definition logger.hpp:177
void(* Sink)(LogLevel type, const char *message)
Definition logger.hpp:53
void setLogLevel(uint16_t newTypes)
Definition logger.hpp:56
void operator()(LogLevel type, const char *format...) PAINLESSMESH_LOG_FORMAT
Definition logger.hpp:99
#define REMOTE_QUEUE_SIZE
Definition logger.hpp:11
#define PAINLESSMESH_LOG_FORMAT
Definition logger.hpp:43
LogLevel
Definition logger.hpp:18
@ S_TIME
Definition logger.hpp:24
@ GENERAL
Definition logger.hpp:26
@ ERROR
Definition logger.hpp:19
@ MESH_STATUS
Definition logger.hpp:21
@ MSG_TYPES
Definition logger.hpp:27
@ COMMUNICATION
Definition logger.hpp:25
@ APPLICATION
Definition logger.hpp:29
@ SYNC
Definition logger.hpp:23
@ REMOTE
Definition logger.hpp:28
@ DEBUG
Definition logger.hpp:30
@ CONNECTION
Definition logger.hpp:22
@ STARTUP
Definition logger.hpp:20
Definition wifi.hpp:34