Public Access
IrcService::disconnect() stops the session from any state: QUIT if connected, then no more retries. /quit goes through it (before, it only stopped a connected session; while waiting for Wi-Fi or retrying it did nothing), and so does the new `irc stop` command. Stopped by hand, opening the IRC App no longer reconnects; typing a line does. mDNS is gone: it never crossed the dev box's routed network, and it cost about 7.5 KB of RAM. Pushes go to the IP shown in Settings -> Firmware, which drops its Name row. OTA Q54 records the change. On the device, Debug Build: 105.6 KB free with Wi-Fi (was 98); with IRC on TLS 54 KB free (was 46); after `irc stop`, back to 99 KB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
68 lines
2.4 KiB
C++
68 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include <freertos/FreeRTOS.h>
|
|
|
|
#include <string>
|
|
|
|
#include "event_bus.h"
|
|
#include "key_value_store.h"
|
|
#include "service.h"
|
|
#include "services/storage_service.h"
|
|
#include "services/wifi_service.h"
|
|
|
|
namespace roro {
|
|
|
|
// Firmware Updates (see CONTEXT.md and docs/milestones/OTA.md): listens for signed Update Files on
|
|
// TCP 3232 while Wi-Fi is Connected, installs them from the SD card on request, keeps new firmware
|
|
// on Probation until it proves healthy, and reports a Rollback after the reboot.
|
|
class UpdateService : public Service {
|
|
public:
|
|
enum class Phase { Idle, Receiving, Installed, Failed };
|
|
static constexpr uint16_t kPort = 3232;
|
|
|
|
// Call first in setup(): rolls back new firmware that already died once on Probation.
|
|
static void bootGuard(KeyValueStore& store);
|
|
|
|
UpdateService(KeyValueStore& store, WifiService& wifi, SavedNetworks& saved, StorageService& storage,
|
|
EventBus& bus, const Settings& settings);
|
|
const char* name() const override { return "update"; }
|
|
uint32_t tickIntervalMs() const override { return 1000; }
|
|
void start() override;
|
|
void tick(uint32_t nowMs) override;
|
|
|
|
// For the progress screen and the Firmware page.
|
|
Phase phase() const { return phase_; }
|
|
int percent() const { return percent_; }
|
|
std::string incomingVersion() const;
|
|
bool onProbation() const { return probation_; }
|
|
|
|
// Installs an Update File from the SD card (runs on the storage task).
|
|
void installFromSd(const std::string& path);
|
|
|
|
// The main loop calls this once it has drawn a frame (part of Probation).
|
|
void firstFrameDrawn() { firstFrame_ = true; }
|
|
// True when an installed update is waiting to reboot; the main loop reboots when it's safe.
|
|
bool rebootPending() const { return phase_ == Phase::Installed; }
|
|
|
|
private:
|
|
static void taskEntry(void* self);
|
|
void listen();
|
|
void install(class UpdateSource& source, const char* via);
|
|
void notify(const std::string& text, NotificationLevel level);
|
|
|
|
KeyValueStore& store_;
|
|
WifiService& wifi_;
|
|
SavedNetworks& saved_;
|
|
StorageService& storage_;
|
|
EventBus& bus_;
|
|
const Settings& settings_;
|
|
TaskHandle_t task_ = nullptr;
|
|
volatile Phase phase_ = Phase::Idle;
|
|
volatile int percent_ = 0;
|
|
std::string incoming_;
|
|
bool probation_ = false;
|
|
volatile bool firstFrame_ = false;
|
|
};
|
|
|
|
} // namespace roro
|