Public Access
One firmware: the Debug Console in every build, off until switched on, with the device's own token
There is no Debug Build any more (ADR 0010, issue #68, Q188 to Q195). The console and the test commands are compiled into every firmware. It listens only while Settings > Debug Console is on, which isn't the default; off, neither its task nor its 4 KB ring exists. The token is made by the device and shown on that page; a client proves it knows it by answering a challenge with an HMAC, so it never crosses the network, and five wrong answers close the console for a minute. DBG in the Status Bar while it listens. Over USB serial only: debug on, debug token <value>, debug token new. scripts/flash.sh --debug uses them to set a device up with the developer's token. scripts/rdbg.py takes the token from -t, $RORO_DEBUG_TOKEN or the file, answers the challenge, and fetches a release's ELF to decode a crash. Gone: the cardputer-adv-debug environment, RORO_DEBUG, the +debug version, scripts/debug_flags.py, update install ... force, and the rule that a Debug Build doesn't install releases. Old clients and old firmwares don't talk to each other. Against the builds it replaces: 30 KB more flash and 88 bytes more static RAM than the release, 4 KB less RAM than the Debug Build. 468 host tests. Checked on the device: off by default, login, the pause after wrong tokens, Safe Mode with the console, the setting surviving an update, debug off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef RORO_DEBUG
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
@@ -9,18 +7,22 @@
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "debug_auth.h"
|
||||
#include "service.h"
|
||||
#include "services/storage_service.h"
|
||||
#include "services/wifi_service.h"
|
||||
#include "settings.h"
|
||||
#include "ui/canvas.h"
|
||||
|
||||
class NetworkClient;
|
||||
|
||||
namespace roro {
|
||||
|
||||
// Debug Builds only (ADR 0004): the console over Wi-Fi, on TCP 2323 while Wi-Fi is Connected. A
|
||||
// client sends the debug token as its first line, then gets the recent console backlog, every new
|
||||
// console line, and runs the same commands as the serial port. One client at a time.
|
||||
// The console over Wi-Fi, on TCP 2323 while Wi-Fi is Connected, in every build but only while it's
|
||||
// switched on in Settings (ADR 0010): off, nothing listens, and neither its task nor the console's
|
||||
// ring exists. A client answers a challenge with its token (debug_auth.h), then gets the recent
|
||||
// console backlog, every new console line, and runs the same commands as the serial port. One
|
||||
// client at a time.
|
||||
//
|
||||
// The socket lives on this Service's own task; commands are handed to the main loop (takeCommand),
|
||||
// which runs them where touching Apps and Services is safe. Their output reaches the client
|
||||
@@ -29,18 +31,29 @@ class DebugConsole : public Service {
|
||||
public:
|
||||
static constexpr uint16_t kPort = 2323;
|
||||
|
||||
DebugConsole(WifiService& wifi, StorageService& storage);
|
||||
DebugConsole(WifiService& wifi, StorageService& storage, Settings& settings);
|
||||
// The off-screen frame the UI composes into: `screenshot` sends it as it stands.
|
||||
void setFrame(Canvas& frame) { frame_ = &frame; }
|
||||
const char* name() const override { return "debug"; }
|
||||
void start() override;
|
||||
void start() override { apply(); }
|
||||
// Follows the settings: starts or stops listening, and takes a changed token (which drops a client).
|
||||
void tick(uint32_t nowMs) override;
|
||||
|
||||
// Switches the console on, making a token first if there's none (Q191). The settings are what
|
||||
// counts: this only writes them.
|
||||
static void switchOn(Settings& settings);
|
||||
static std::string freshToken();
|
||||
|
||||
// The next command line a client sent, for the main loop to run.
|
||||
bool takeCommand(std::string& line);
|
||||
// News for the user that the task can't publish itself (a pause after wrong tokens).
|
||||
bool takeAlert(std::string& text);
|
||||
bool on() const { return wanted_; }
|
||||
bool clientConnected() const { return connected_; }
|
||||
|
||||
private:
|
||||
static void taskEntry(void* self);
|
||||
void apply();
|
||||
void listen();
|
||||
void serve(::NetworkClient& client);
|
||||
bool authenticate(::NetworkClient& client);
|
||||
@@ -55,13 +68,16 @@ class DebugConsole : public Service {
|
||||
|
||||
WifiService& wifi_;
|
||||
StorageService& storage_;
|
||||
Settings& settings_;
|
||||
Canvas* frame_ = nullptr;
|
||||
TaskHandle_t task_ = nullptr;
|
||||
SemaphoreHandle_t lock_;
|
||||
volatile TaskHandle_t task_ = nullptr; // null once the task has freed everything and gone
|
||||
SemaphoreHandle_t lock_; // commands_, token_, alert_
|
||||
std::deque<std::string> commands_;
|
||||
std::string token_, alert_;
|
||||
volatile uint32_t tokenSeq_ = 0; // changes with the token: an open connection ends
|
||||
volatile bool wanted_ = false;
|
||||
volatile bool connected_ = false;
|
||||
debug::AuthGate gate_; // the task's own
|
||||
};
|
||||
|
||||
} // namespace roro
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user