Skip to content

Refactor: Replace RemoteDebug with custom Logger and Telnet server#824

Open
robertlipe wants to merge 4 commits intoPlummersSoftwareLLC:mainfrom
robertlipe:feature/replace-remotedebug
Open

Refactor: Replace RemoteDebug with custom Logger and Telnet server#824
robertlipe wants to merge 4 commits intoPlummersSoftwareLLC:mainfrom
robertlipe:feature/replace-remotedebug

Conversation

@robertlipe
Copy link
Collaborator

Description

This PR replaces the RemoteDebug library with a custom-built, lightweight logging and console management system. While RemoteDebug served us well, it brought along unnecessary complexity and dependencies that didn't perfectly align with the project's long-term architectural goals.

Key Improvements

  1. Lightweight Infrastructure: Replaced a heavy third-party library with a tailored implementation (ConsoleManager, ConsoleSession, Logger) that fits the project's specific needs.
  2. Global Logging: The new Logger hooks directly into the ESP-IDF esp_log system. This means that logs from the system, third-party libraries, and our own debugX macros are all consistently captured and broadcast.
  3. RFC 854 Telnet Server: Implemented a solid, BSD-socket based Telnet server. It properly handles Telnet negotiation (WILL ECHO for server-side echo, WILL SGA for character-at-a-time mode) and RFC 854 line ending conventions.
  4. Enhanced Debug CLI: The CLI has been rewritten to be more memory-efficient. The new tokenizer uses std::string_view for zero-allocation parsing, and tab completion has been improved for both commands and effect names.
  5. Clean Multiplexing: Output is now intelligently routed. Commands executed over Telnet stay on Telnet, while global broadcasts (like system logs) reach all active sessions.

Technical Details

  • Memory Efficiency: The new system avoids unnecessary string copies and large stack buffers. The vprintf hook uses a two-pass approach to measure and then allocate exactly the required heap memory for log lines.
  • Concurrency: Uses std::recursive_mutex in ConsoleManager to ensure thread-safe access to sinks during broadcasts and session management.
  • Standard Compliance: The Telnet server includes a state machine to handle IAC sequences and RFC 854 \r\0 / \r\n sequences correctly, even when split across packet boundaries.

Validation

Verified on hardware:

  • Serial console remains fully functional with Improv support.
  • Telnet server accepts connections, handles multiple commands, and supports tab completion.
  • System logs are correctly interleaved with CLI output.
  • ANSI color coding works correctly in modern terminal emulators.

This commit removes the external RemoteDebug dependency and replaces it
with a lightweight, project-tailored logging and console management
infrastructure.

Key changes:
- Created ConsoleManager and ConsoleSession for multiplexing Serial
  and Telnet I/O with support for ANSI colors and line-ending policies.
- Implemented a custom Logger that hooks into the ESP-IDF esp_log
  vprintf system, ensuring all system and library logs are captured
  and routed to all active console sessions.
- Added a robust, BSD-socket based Telnet server (RFC 854) with
  protocol negotiation (WILL ECHO, WILL SGA) and state-machine based
  IAC/CRLF filtering.
- Rewrote DebugCLI to use the new console system, featuring a
  zero-allocation tokenizer and improved tab completion.
- Updated main.cpp and TaskManager to integrate the new services.
- Removed RemoteDebug from platformio.ini.

This change reduces binary size, improves memory efficiency, and
provides a more reliable and extensible debugging interface.
This fixes the build error where F_GETFL, F_SETFL, and O_NONBLOCK were
undefined in include/globals.h after the removal of RemoteDebug.h,
which previously provided these headers.
…nding

The variadic Logger template was attempting to bind a reference to
packed struct fields in src/network.cpp (esp-now), which is an error.
By passing by value in the default Unwrap case, we avoid this issue
while still correctly specializing for String and std::string types.
The use of Args&&... in the variadic template was still attempting to
bind references to packed struct fields before they reached Unwrap.
By changing the template to take Args... (by value), we ensure all
arguments are copied before binding, satisfying the compiler's
restrictions on packed members.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant