Files
EggDuino/src/Logging.cpp
André Fiedler 83a55fcc47 Add print log functionality and device name handling
- Introduced functions to capture and manage incoming print logs.
- Added a download link for the incoming print log in the web interface.
- Updated device name prefix for BLE and added device name building logic.
- Enhanced SerialCommand class with line handler support.
- Implemented WiFi reconnect logic and status tracking.
2026-02-28 22:36:12 +01:00

153 lines
3.2 KiB
C++

#include "EggDuino.h"
namespace {
constexpr size_t kLogCapacity = 80;
constexpr size_t kLogLineLength = 160;
constexpr size_t kIncomingLogCapacity = 128;
constexpr size_t kIncomingLogLineLength = SERIALCOMMAND_BUFFER + 24;
char g_logLines[kLogCapacity][kLogLineLength];
uint32_t g_logSeq[kLogCapacity];
size_t g_logWritePos = 0;
uint32_t g_nextLogSeq = 1;
char g_incomingLogLines[kIncomingLogCapacity][kIncomingLogLineLength];
uint32_t g_incomingLogSeq[kIncomingLogCapacity];
size_t g_incomingLogWritePos = 0;
uint32_t g_nextIncomingLogSeq = 1;
void appendJsonEscaped(String &out, const char *text) {
out += "\"";
for (size_t i = 0; text[i] != '\0'; ++i) {
const char c = text[i];
switch (c) {
case '\\':
out += "\\\\";
break;
case '"':
out += "\\\"";
break;
case '\n':
out += "\\n";
break;
case '\r':
out += "\\r";
break;
case '\t':
out += "\\t";
break;
default:
if (static_cast<unsigned char>(c) < 0x20) {
out += '?';
} else {
out += c;
}
break;
}
}
out += "\"";
}
const char *transportLabel(ProtocolTransport transport) {
switch (transport) {
case PROTOCOL_TRANSPORT_BLE:
return "BLE";
case PROTOCOL_TRANSPORT_WIFI:
return "WIFI";
case PROTOCOL_TRANSPORT_SERIAL:
default:
return "SERIAL";
}
}
} // namespace
void Log(const String &message) {
snprintf(
g_logLines[g_logWritePos],
kLogLineLength,
"[%010lu] %s",
static_cast<unsigned long>(millis()),
message.c_str()
);
g_logSeq[g_logWritePos] = g_nextLogSeq++;
g_logWritePos = (g_logWritePos + 1) % kLogCapacity;
}
void Log(const char *message) {
Log(String(message));
}
String buildLogsJson(uint32_t sinceSeq) {
String output;
output.reserve(2048);
output += "{\"logs\":[";
uint32_t lastSeq = sinceSeq;
bool first = true;
for (size_t i = 0; i < kLogCapacity; ++i) {
const size_t idx = (g_logWritePos + i) % kLogCapacity;
const uint32_t seq = g_logSeq[idx];
if (seq == 0 || seq <= sinceSeq) {
continue;
}
if (!first) {
output += ",";
}
first = false;
output += "{\"seq\":";
output += String(seq);
output += ",\"text\":";
appendJsonEscaped(output, g_logLines[idx]);
output += "}";
lastSeq = seq;
}
output += "],\"lastSeq\":";
output += String(lastSeq);
output += "}";
return output;
}
void captureIncomingPrintLine(const char *line, ProtocolTransport transport) {
if ((line == NULL) || (line[0] == '\0')) {
return;
}
snprintf(
g_incomingLogLines[g_incomingLogWritePos],
kIncomingLogLineLength,
"[%010lu] %s %s",
static_cast<unsigned long>(millis()),
transportLabel(transport),
line
);
g_incomingLogSeq[g_incomingLogWritePos] = g_nextIncomingLogSeq++;
g_incomingLogWritePos = (g_incomingLogWritePos + 1) % kIncomingLogCapacity;
}
String buildIncomingPrintLogText() {
String output;
output.reserve(4096);
for (size_t i = 0; i < kIncomingLogCapacity; ++i) {
const size_t idx = (g_incomingLogWritePos + i) % kIncomingLogCapacity;
if (g_incomingLogSeq[idx] == 0) {
continue;
}
output += g_incomingLogLines[idx];
output += "\n";
}
return output;
}
void clearIncomingPrintLog() {
for (size_t i = 0; i < kIncomingLogCapacity; ++i) {
g_incomingLogSeq[i] = 0;
g_incomingLogLines[i][0] = '\0';
}
g_incomingLogWritePos = 0;
g_nextIncomingLogSeq = 1;
}