emdashes begone (#10847)

This commit is contained in:
Tom
2026-07-01 19:01:27 -05:00
committed by GitHub
co-authored by GitHub
parent dee94e0758
commit 3becaf2d95
276 changed files with 1795 additions and 1793 deletions
+4 -4
View File
@@ -26,7 +26,7 @@ static constexpr const char *PROTOBUF_SCHEMA =
// PhoneAPI subclass for the Ethernet HTTP transport. Mirrors mesh/http/HttpAPI
// but lives outside the MESHTASTIC_EXCLUDE_WEBSERVER gate (which is ESP32-only).
// A single instance is shared between the HTTP and HTTPS servers since they
// represent the same logical "phone" same state machine, same packet queue.
// represent the same logical "phone" - same state machine, same packet queue.
class EthHttpAPI : public PhoneAPI
{
public:
@@ -192,7 +192,7 @@ static bool handleFromRadio(IStreamReadWrite &client, const Request &req)
// Buffer all packets first so we can emit an accurate Content-Length and
// keep the connection alive. Phase 2 used Connection: close framing, which
// forced clients to redo the TLS handshake (~625 ms) for every single
// /fromradio poll client.meshtastic.org needs dozens of those during
// /fromradio poll - client.meshtastic.org needs dozens of those during
// initial sync, so the user-visible load time was 15-30 s of pure
// handshakes. With Content-Length + keep-alive a whole sync rides one
// handshake. Buffer is dynamic (std::vector) so the common 1-packet case
@@ -290,7 +290,7 @@ void handleApiClient(IStreamReadWrite &client)
// the parent OSThread is not returning to mainController, and the
// RP2350 hardware watchdog (8 s default in arduino-pico) only gets
// pet by the main loop. A client.meshtastic.org sync produces ~80
// back-to-back requests over a single TLS session well past the
// back-to-back requests over a single TLS session - well past the
// watchdog deadline. yield() between requests lets the rest of core0
// (Periodic ticks, NTP, MQTT, LoRa packet pump) run + pets the
// watchdog; the cap puts a hard ceiling so a chatty client can never
@@ -320,7 +320,7 @@ void handleApiClient(IStreamReadWrite &client)
keepAlive = handleToRadio(client, req);
} else {
sendError(client, 404, "Not Found", "unknown endpoint");
return; // errors are terminal Connection: close framing
return; // errors are terminal - Connection: close framing
}
// A handler that emitted an error advertised Connection: close. Stop the
// keep-alive loop so any unread/leftover body bytes (e.g. after a 408
+3 -3
View File
@@ -13,14 +13,14 @@
// transports without recompiling the handlers.
//
// Inherits Print so all `print(int)`, `print(const char *)`, `print(char)`
// helpers are available for free the only thing implementations have to
// helpers are available for free - the only thing implementations have to
// supply on the write side is `write(uint8_t)` + the bulk `write(buf, len)`.
class IStreamReadWrite : public Print
{
public:
virtual ~IStreamReadWrite() = default;
// Write side Print pure virtual + bulk override
// Write side - Print pure virtual + bulk override
size_t write(uint8_t b) override = 0;
size_t write(const uint8_t *buf, size_t len) override = 0;
using Print::write; // bring in write(const char *str) and friends
@@ -34,7 +34,7 @@ class IStreamReadWrite : public Print
virtual bool connected() = 0;
void flush() override = 0; // Print::flush is virtual void with empty default
// Logging helper used by request log line
// Logging helper - used by request log line
virtual IPAddress remoteIP() = 0;
};
+2 -2
View File
@@ -83,7 +83,7 @@ static EthApiServerThread *apiThread = nullptr;
void initEthApiServer()
{
// Bind the listener (idempotent deInitEthApiServer() drops apiServer on a
// Bind the listener (idempotent - deInitEthApiServer() drops apiServer on a
// W5500 reset, and this rebinds it on the restart path).
if (!apiServer) {
apiServer = new EthernetServer(ETH_API_PORT);
@@ -92,7 +92,7 @@ void initEthApiServer()
}
// The worker is created once and kept for the lifetime of the process. It
// idles harmlessly while apiServer is null (runOnce guards on it), so we
// never delete it from another thread's runOnce that would corrupt the
// never delete it from another thread's runOnce - that would corrupt the
// scheduler's thread list mid-iteration.
if (!apiThread)
apiThread = new EthApiServerThread(); // OSThread base auto-registers with the scheduler
+1 -1
View File
@@ -8,7 +8,7 @@
/// Initialize the Ethernet HTTP API server (call after Ethernet is connected).
/// Spawns an internal OSThread that polls accept() on a sub-second cadence,
/// independent of the 5s Ethernet client periodic needed because the web
/// independent of the 5s Ethernet client periodic - needed because the web
/// client makes many small back-to-back requests.
void initEthApiServer();
+6 -6
View File
@@ -30,7 +30,7 @@ static constexpr const char *CERT_PATH = "/eth_cert_v2.der";
static constexpr const char *KEY_PATH = "/eth_key_v2.der";
static constexpr const char *IP_PATH = "/eth_cert_ip_v2.txt";
// Random callback for mbedtls sources entropy from the RP2350 ROSC TRNG via
// Random callback for mbedtls - sources entropy from the RP2350 ROSC TRNG via
// pico-sdk get_rand_64(). Used directly as f_rng in mbedtls calls so we don't
// have to plumb a full mbedtls_entropy_context + ctr_drbg. The hardware TRNG
// is cryptographically suitable per pico-sdk docs (ROSC + whitening).
@@ -175,7 +175,7 @@ static bool generateCert(IPAddress ip, EthCertMaterial &out)
}
// ExtendedKeyUsage: serverAuth. NSS / Firefox refuse to treat a cert
// as a TLS server cert without this extension since 2023 the error
// as a TLS server cert without this extension since 2023 - the error
// surfaces as a non-overridable "Secure Connection Failed" with no
// "Accept the Risk" path.
mbedtls_asn1_sequence ekuSeq;
@@ -293,13 +293,13 @@ bool ensureCertForIp(IPAddress ip, EthCertMaterial &out)
// current process still has the in-memory cert ready for use.
//
// Clear the IP commit-marker FIRST so a reset mid-write can't leave the marker
// pointing at a half-written (or stale-paired) cert/key the load path only
// pointing at a half-written (or stale-paired) cert/key - the load path only
// trusts the cache when the marker matches. Writing the marker LAST commits the
// new pair atomically w.r.t. the loader.
writeText(IP_PATH, "");
if (!writeBinary(CERT_PATH, out.certDer.data(), out.certDer.size()) ||
!writeBinary(KEY_PATH, out.keyDer.data(), out.keyDer.size()) || !writeText(IP_PATH, ipStr)) {
LOG_WARN("ETH CERT: persist failed will regenerate next boot");
LOG_WARN("ETH CERT: persist failed - will regenerate next boot");
} else {
LOG_INFO("ETH CERT: persisted to LittleFS");
}
@@ -310,7 +310,7 @@ bool ensureCertForIp(IPAddress ip, EthCertMaterial &out)
// Worker that defers cert gen off the Periodic thread (which has a tight stack
// and ticks every 5s alongside reconnect / NTP / MQTT). Waits for a non-zero IP,
// generates/loads the cert for it, then keeps polling at CERT_RECHECK_MS so a
// DHCP lease change to a new IP regenerates the cert the SAN must track the
// DHCP lease change to a new IP regenerates the cert - the SAN must track the
// current address or browsers reject the new one. The steady-state poll is just
// localIP() + compare; ECDSA keygen only reruns when the IP actually changes,
// and it runs on this thread's own stack (not the Periodic's).
@@ -337,7 +337,7 @@ class EthCertThread : public concurrency::OSThread
// regenerates whenever its saved IP != ip, so the cert SAN follows.
bool ok = ensureCertForIp(ip, material_);
if (!ok) {
LOG_ERROR("ETH CERT: pipeline FAILED TLS server will not start");
LOG_ERROR("ETH CERT: pipeline FAILED - TLS server will not start");
// Don't leave isReady() reporting true with empty material: a later TLS
// teardown (e.g. a W5500 reset) would then fail initTlsContext() and stay
// disabled. Clear readiness so the TLS worker waits and the next poll
+1 -1
View File
@@ -35,7 +35,7 @@ bool isEthCertReady();
// Snapshot of the generated material once isEthCertReady(). Empty otherwise.
const EthCertMaterial &getEthCert();
// Monotonic counter bumped each time the cert is (re)generated e.g. when a DHCP
// Monotonic counter bumped each time the cert is (re)generated - e.g. when a DHCP
// lease change moves us to a new IP. The TLS server reloads when this changes.
uint32_t getEthCertGeneration();
+4 -4
View File
@@ -17,7 +17,7 @@
#include "mesh/eth/ethTlsApiServer.h"
#endif
#ifdef USE_ARDUINO_ETHERNET
#include <Ethernet.h> // arduino-libraries/Ethernet supports W5100/W5200/W5500
#include <Ethernet.h> // arduino-libraries/Ethernet - supports W5100/W5200/W5500
// Shorter DHCP timeout so LoRa startup isn't blocked when no DHCP server is present.
#define ETH_DHCP_TIMEOUT_MS 10000
#else
@@ -181,12 +181,12 @@ static int32_t reconnectETH()
initEthApiServer();
#endif
#if HAS_ETHERNET && defined(HAS_ETHERNET_TLS_API) && defined(ARCH_RP2040)
// Phase 2.1-bis cert gen runs on its own OSThread so ECDSA keygen
// Phase 2.1-bis - cert gen runs on its own OSThread so ECDSA keygen
// + DER encoding + LittleFS write don't share the Periodic stack
// (which overflowed in the original inline attempt). The thread
// polls for a non-zero IP itself and runs once.
initEthCertThread();
// Phase 2.2 TLS server skeleton on TCP/443. The worker waits
// Phase 2.2 - TLS server skeleton on TCP/443. The worker waits
// until the cert thread signals isEthCertReady() before binding.
initEthTlsApiServer();
#endif
@@ -220,7 +220,7 @@ static int32_t reconnectETH()
#if HAS_ETHERNET && defined(HAS_ETHERNET_OTA)
ethOTALoop();
#endif
// ethApiServer runs on its own OSThread (20ms ticks) not polled here.
// ethApiServer runs on its own OSThread (20ms ticks) - not polled here.
return 5000; // every 5 seconds
}
+7 -7
View File
@@ -39,7 +39,7 @@ static const uint32_t OTA_AUTH_COOLDOWN_MS = 5000; // 5s cooldown after failed a
static const size_t OTA_NONCE_SIZE = 32;
static const size_t OTA_HASH_SIZE = 32;
// OTA PSK override via USERPREFS_OTA_PSK in userPrefs.jsonc
// OTA PSK - override via USERPREFS_OTA_PSK in userPrefs.jsonc
// USERPREFS_OTA_PSK is stringified by PlatformIO (wrapped in quotes), so we
// use a char[] and sizeof-1 to exclude the trailing NUL byte from the hash.
#ifdef USERPREFS_OTA_PSK
@@ -96,7 +96,7 @@ static void computeAuthHash(const uint8_t *nonce, size_t nonceLen, const uint8_t
/// Challenge-response authentication. Returns true if client is authenticated.
static bool authenticateClient(EthernetClient &client)
{
// Rate-limit after failed auth close silently so the error byte is not
// Rate-limit after failed auth - close silently so the error byte is not
// misinterpreted as part of the nonce by a re-trying client.
if (lastAuthFailure != 0 && (millis() - lastAuthFailure) < OTA_AUTH_COOLDOWN_MS) {
LOG_WARN("ETH OTA: Auth cooldown active, rejecting connection");
@@ -140,7 +140,7 @@ static bool authenticateClient(EthernetClient &client)
return false;
}
// Auth success send ACK
// Auth success - send ACK
client.write(OTA_ACK);
LOG_INFO("ETH OTA: Authentication successful");
return true;
@@ -179,14 +179,14 @@ static void handleOTAClient(EthernetClient &client)
return;
}
// Begin the update this opens firmware.bin on LittleFS
// Begin the update - this opens firmware.bin on LittleFS
if (!Update.begin(hdr.firmwareSize)) {
LOG_ERROR("ETH OTA: Update.begin() failed, error=%u", Update.getError());
client.write(OTA_ERR_BEGIN);
return;
}
// ACK the header client can start sending firmware data
// ACK the header - client can start sending firmware data
client.write(OTA_ACK);
// Receive firmware in chunks
@@ -252,7 +252,7 @@ static void handleOTAClient(EthernetClient &client)
return;
}
// Finalize this calls picoOTA.commit() which stages the update for the
// Finalize - this calls picoOTA.commit() which stages the update for the
// bootloader
if (!Update.end(true)) {
LOG_ERROR("ETH OTA: Update.end() failed, error=%u", Update.getError());
@@ -265,7 +265,7 @@ static void handleOTAClient(EthernetClient &client)
client.flush();
delay(500);
// Reboot the built-in bootloader will apply the update from LittleFS
// Reboot - the built-in bootloader will apply the update from LittleFS
rp2040.reboot();
}
+8 -8
View File
@@ -32,7 +32,7 @@ static constexpr uint32_t MEDIUM_THRESHOLD_MS = 30000;
static constexpr int32_t ACTIVE_INTERVAL_MS = 20;
static constexpr int32_t MEDIUM_INTERVAL_MS = 100;
static constexpr int32_t IDLE_INTERVAL_MS = 500;
// Matches the keep-alive idle window in ethApiHandlers if the handler
// Matches the keep-alive idle window in ethApiHandlers - if the handler
// loop calls read() and netRecv blocked for 10 s, the 3 s idle deadline
// inside parseRequest would be irrelevant and the OSThread would stay stuck
// long after a quiet browser closed its end of the TCP socket.
@@ -52,7 +52,7 @@ static int picoRand(void * /*ctx*/, unsigned char *out, size_t len)
return 0;
}
// One-shot TLS context lives in BSS keeps mbedtls allocations off the
// One-shot TLS context lives in BSS - keeps mbedtls allocations off the
// OSThread stack (lesson from Phase 2.1-bis: stack budget is tight on M33).
static EthernetServer *tlsServer = nullptr;
static mbedtls_x509_crt certChain;
@@ -73,7 +73,7 @@ static int netSend(void *ctx, const unsigned char *buf, size_t len)
// Block-with-yield until the W5500 TX buffer can absorb the chunk.
// Returning WANT_WRITE without delay made mbedtls_ssl_handshake() spin
// at ~180k iter/s when Chrome was slow to drain the socket during the
// ECDHE-ECDSA ServerKeyExchange the original code logged exactly that
// ECDHE-ECDSA ServerKeyExchange - the original code logged exactly that
// signature (ret=-0x6880 / WANT_WRITE) tight-looping forever. Firefox
// happened to read fast enough that the buffer never filled.
uint32_t t0 = millis();
@@ -96,12 +96,12 @@ static int netRecv(void *ctx, unsigned char *buf, size_t len)
// Block-with-timeout: spin until bytes arrive, the peer closes, or we
// exceed the per-recv budget. Pure non-blocking (return WANT_READ) would
// require mbedtls_ssl_handshake to be driven from the runOnce dispatcher
// overkill for the Phase 2.2 skeleton with a single in-flight session.
// - overkill for the Phase 2.2 skeleton with a single in-flight session.
//
// Pet the 8 s hardware watchdog from inside the poll loop. We sit here
// for up to RECV_TIMEOUT_MS waiting for the next keep-alive request, and
// a quiet client can string two such waits back-to-back (6 s) plus the
// earlier handshake/handler time easily past the watchdog deadline.
// earlier handshake/handler time - easily past the watchdog deadline.
// The main loop()'s watchdog_update() never runs while the OSThread is
// inside serveClient(), so it has to be done here.
uint32_t t0 = millis();
@@ -152,7 +152,7 @@ class MbedTlsStream : public IStreamReadWrite
size_t pending = mbedtls_ssl_get_bytes_avail(ssl_);
if (pending > 0)
return (int)pending;
// Best-effort: report network bytes (rough proxy handlers usually
// Best-effort: report network bytes (rough proxy - handlers usually
// call read() in a loop and tolerate slow streams).
return client_->available();
}
@@ -197,7 +197,7 @@ class EthTlsApiServerThread : public concurrency::OSThread
if (!isEthCertReady())
return 500;
if (!initTlsContext())
return INT32_MAX; // hard fail TLS server stays disabled
return INT32_MAX; // hard fail - TLS server stays disabled
loadedCertGen_ = getEthCertGeneration();
tlsReady = true;
}
@@ -330,7 +330,7 @@ void deInitEthTlsApiServer()
{
// A W5500 chip reset leaves tlsServer bound to a dead socket and the cached
// mbedTLS context stale. Reset the worker back to Phase A (free the context,
// drop the listener, clear tlsReady) WITHOUT deleting the OSThread its next
// drop the listener, clear tlsReady) WITHOUT deleting the OSThread - its next
// runOnce re-waits for isEthCertReady() and rebuilds the context + rebinds
// TCP/443. Safe to free here: this runs in reconnectETH (ethConnect thread),
// and the cooperative scheduler guarantees tlsThread is not mid-runOnce, so