commit f6fe5a198791ac85fd14f22703c43df3f6c51feb Author: Eric Liu Date: Mon Sep 7 18:15:58 2026 -0700 feat: initial setup for Meshtastic Heltec V4 node, custom CA HTTPS firmware, backups, and tooling diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca8d7ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +*.zip +*.tar +.pio/ +*.log diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6bbf17 --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# Meshtastic Node Setup & Web Client Integration + +This repository maintains the firmware build artifacts, local CA TLS provisioning, device configuration backups, and Kubernetes deployment integration for the local Meshtastic node. + +--- + +## 1. Hardware & Network Overview + +* **Hardware**: Heltec WiFi LoRa 32 (V4) / ESP32-S3 (16MB Flash, 2MB PSRAM, 0.96" OLED display) +* **Node MAC**: `f8:5b:1b:a1:bc:60` (Node ID: `!1ba1bc60`, Name: `Meshtastic bc60`) +* **Firmware Base**: Meshtastic `v2.7.26.54e0d8d` +* **Network Connectivity**: + * Wi-Fi DHCP IP: `192.168.20.140` + * mDNS Hostname: `meshtastic.local` + * TCP Port 4403: Meshtastic Protobuf API (CLI and internal RPC) + * TCP Port 443: Native HTTPS server serving `/api/v1/fromradio` and `/api/v1/toradio` with CORS enabled + +--- + +## 2. Architecture & Challenges Solved + +### A. Mixed Content & Browser Security +The self-hosted Meshtastic Web Client runs on Kubernetes at `https://meshtastic-web.ericxliu.local` via internal Nginx ingress with TLS. Because the Web Client is a client-side Single Page Application (SPA), the browser makes direct API requests to the radio on LAN: +* **Mixed Content Blocking**: The browser forbids plain HTTP calls from an HTTPS origin. +* **Self-Signed TLS Rejection**: Stock Meshtastic firmware generates a self-signed certificate (`CN=meshtastic.local, O=Meshtastic`), which browsers reject with `NET::ERR_CERT_AUTHORITY_INVALID`. + +### B. Custom Local CA Provisioning +* A leaf certificate and private key were issued for `DNS:meshtastic.local` and `DNS:*.meshtastic.local` by Eric's private root CA (`ericxliu.local`, trusted in macOS Keychain). +* Stock Meshtastic stores its HTTPS key and certificate in ESP32 NVS preferences under the `MeshtasticHTTPS` namespace (`PK` and `cert`). +* The custom firmware in [`firmware-custom/`](./firmware-custom/) writes the DER-encoded CA-signed certificate and key directly into these NVS keys on startup. Because stock Meshtastic checks for existing keys before generating a self-signed pair, this CA certificate survives future upgrades. + +### C. Handshake Latency & Web Client Timeout +* **Handshake Bottleneck**: In stock firmware (`WebServer.cpp`), `IDLE_INTERVAL_MS` was set to `1000ms`. The multi-round-trip TLS handshake plus 2048-bit RSA computation took **~4.5 to 5.4 seconds**. +* **Hardcoded Client Timeout**: The official web client bundle (`apps/web/src/pages/Connections/utils.ts`) had a hardcoded `2500ms` timeout on `testHttpReachable`. Every test attempt was aborted at 2.5s, marking the device as "Not reachable". +* **The Fix**: + 1. Reduced `IDLE_INTERVAL_MS` in firmware to `50ms` (dropping handshake and response time to **~1.34 seconds**). + 2. In [`k8s-flux`](https://github.com/eric-x-liu/k8s-flux), added an `initContainer` in `apps/myapp/meshtastic-web/release.yaml` that patches `testHttpReachable` timeout in the bundle from `t=2500` to `t=15000` (15s). + +--- + +## 3. Directory Layout + +``` +. +├── README.md +├── certs/ +│ ├── meshtastic.local.crt # Signed leaf certificate (valid to Oct 2027) +│ └── meshtastic.local.csr # Certificate Signing Request +├── firmware-custom/ +│ ├── firmware-heltec-v4-2.7.26.54e0d8d.bin # Custom app0 image with CA cert + 50ms loop +│ ├── firmware-heltec-v4-2.7.26.54e0d8d.factory.bin # Full factory image (bootloader + part + app) +│ ├── MeshtasticTlsCertificate.h # DER cert & key header embedded into build +│ └── patches/ +│ └── WebServer.cpp.patch # Diff applied to stock v2.7.26.54e0d8d +├── firmware-2.7.26/ # Stock vendor 2.7.26 firmware binaries +│ ├── firmware-heltec-v4-2.7.26.54e0d8d.factory.bin +│ ├── firmware-heltec-v4-2.7.26.54e0d8d.mt.json +│ ├── littlefs-heltec-v4-2.7.26.54e0d8d.bin +│ └── mt-esp32s3-ota.bin +├── backups/ +│ ├── aideepen-lora-v4-factory-f85b1ba1bc60.bin # Original factory 16MB flash dump +│ └── nvs_backup_before_flash.bin # Live NVS partition backup (0x9000, 20KB) +├── docs/ +│ └── 91Qt4C5SZBL.pdf # Heltec V4 board schematic and pinouts +└── scripts/ + ├── flash_custom_firmware.sh # Flash custom firmware to app0 over USB + └── backup_nvs.sh # Backup device NVS partition over USB +``` + +--- + +## 4. Maintenance & Operations + +### Flash Custom Firmware via USB +Connect the Heltec V4 via USB-C: +```bash +./scripts/flash_custom_firmware.sh /dev/cu.usbmodem1101 +``` +Or directly with `esptool`: +```bash +esptool --port /dev/cu.usbmodem1101 --baud 921600 write_flash 0x10000 firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.bin +``` + +### Backup NVS Configuration +```bash +./scripts/backup_nvs.sh /dev/cu.usbmodem1101 +``` + +### Verify TLS Handshake & API Endpoints +Verify certificate validity using macOS system trust: +```bash +# Must verify without -k / insecure flags +curl -v https://meshtastic.local/api/v1/fromradio +``` + +Verify CLI over Wi-Fi: +```bash +meshtastic --host meshtastic.local --info +``` + +### Accessing the Web Client +1. Open **[https://meshtastic-web.ericxliu.local](https://meshtastic-web.ericxliu.local)**. +2. Select **HTTP** connection and set URL to `meshtastic.local` (with **Use HTTPS** enabled). +3. Connection tests complete in ~1.3s and save cleanly. diff --git a/backups/aideepen-lora-v4-factory-f85b1ba1bc60.bin b/backups/aideepen-lora-v4-factory-f85b1ba1bc60.bin new file mode 100644 index 0000000..17cd9c3 Binary files /dev/null and b/backups/aideepen-lora-v4-factory-f85b1ba1bc60.bin differ diff --git a/backups/nvs_backup_before_flash.bin b/backups/nvs_backup_before_flash.bin new file mode 100644 index 0000000..4172ea9 Binary files /dev/null and b/backups/nvs_backup_before_flash.bin differ diff --git a/certs/meshtastic.local.crt b/certs/meshtastic.local.crt new file mode 100644 index 0000000..87c0b6b --- /dev/null +++ b/certs/meshtastic.local.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE2zCCAsOgAwIBAgIUHTvCtNS24Fa7p9RspSBHuAtif3IwDQYJKoZIhvcNAQEL +BQAwcjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRowGAYDVQQKDBFlcmljeGxp +dS5tZSwgSW5jLjEXMBUGA1UEAwwOZXJpY3hsaXUubG9jYWwxITAfBgkqhkiG9w0B +CQEWEm1hc3RlckBlcmljeGxpdS5tZTAeFw0yNjA5MDgwMDM5MDlaFw0yNzEwMTAw +MDM5MDlaMG4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UECgwLZXJp +Y3hsaXUubWUxITAfBgkqhkiG9w0BCQEWEm1hc3RlckBlcmljeGxpdS5tZTEZMBcG +A1UEAwwQbWVzaHRhc3RpYy5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAL0O1yZv43hv94PQFiCesNLKkFWKOnwG2DLBMU7lyL46rP43zDOjXG6j ++rW5HE6ZunRF7LR6h9OpFdw2zFOH2KRQ3v4RyS/Islr2bTMnFbtrtL/j03BzqFOD +Fjbz3Q6OLzIigg7gXsJHsAuifDqRh+fp7x2i6Rraew5L1Id5UXIqD5aCCicd3AZT +8sfMgDg613F7rY9E8u3/Ct7mLG5h+iQ+bv8BAYm8hPlxx1wLulaLvE5D61OA0REn +XjulcnOs5kuGlq65cDupLnHKsTCGIa/276dcwIcPtRNOQSyZzElHnXeQHCGaVTGd +1/y3qnSJvGdDZDTfxLOQvl58nYu9U5UCAwEAAaNtMGswLwYDVR0RBCgwJoIQbWVz +aHRhc3RpYy5sb2NhbIISKi5tZXNodGFzdGljLmxvY2FsMA4GA1UdDwEB/wQEAwIF +oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwCQYDVR0TBAIwADANBgkq +hkiG9w0BAQsFAAOCAgEAje2idkjlcQMxGrxriD/bLPul7TaBQjErvt6AOnM7AdsT +6cbL3hHLSrmTc8zfx+a3NHqQA9KHN3qTOpIiMBchtB60wfB/QfmIosY4dngH6OWD +78vY0lb/Gc4XS0RViYDg+pd7LelrS1qTEeAT0oHszpJ4rxkaM08BP6p3ELSszHhp +z7vCWG7lxBwiBJTTr2+WvBHr3YnMRTqxivrA9V1hhBjomSd35MK7eIzQqO9HHKe4 +IRo96zgvABquxy9BpxO5XOVgbkJ01Lku7niz6rcYNujGQe2i865eTbt/rbAdPK5U +xaJE/TqvFdm019CPpOXUfFx6NQfH8mp4IudsI9K6PKQnGzmlbqIjhqJqFjqejB5I +NIFDXX+qnFsVcO/ST4I6skoeYFPLxcuNFvjRAHUaIUwiRkR1uNk3Xlq06BKRRaYf +JnZQEctA5jAAbx4dGkWzAW1UCOLXYq9HDZThUE71KCpUe5H+nVjKr/9w/BIaj4Y0 +2II8H+SwRK44M2d7dBpvtor23/fCxFOTXiZ/IC50tRyLmTGwf+lC//1UvHdbXs6t +y0UNnKDE85lGvs3IRwpPIGKP9lnHEc+693YruB2iXVhM29Jafk6Epca7jYgR6n5/ +Cv9kHXebwRxKf0ri/NPwBNv2ThGj3QpryvtJXu6eujqIr8l7M6Ne3v89HX0JvA0= +-----END CERTIFICATE----- diff --git a/certs/meshtastic.local.csr b/certs/meshtastic.local.csr new file mode 100644 index 0000000..848adfe --- /dev/null +++ b/certs/meshtastic.local.csr @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDLzCCAhcCAQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQK +DAtlcmljeGxpdS5tZTEhMB8GCSqGSIb3DQEJARYSbWFzdGVyQGVyaWN4bGl1Lm1l +MRkwFwYDVQQDDBBtZXNodGFzdGljLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAvQ7XJm/jeG/3g9AWIJ6w0sqQVYo6fAbYMsExTuXIvjqs/jfM +M6NcbqP6tbkcTpm6dEXstHqH06kV3DbMU4fYpFDe/hHJL8iyWvZtMycVu2u0v+PT +cHOoU4MWNvPdDo4vMiKCDuBewkewC6J8OpGH5+nvHaLpGtp7DkvUh3lRcioPloIK +Jx3cBlPyx8yAODrXcXutj0Ty7f8K3uYsbmH6JD5u/wEBibyE+XHHXAu6Vou8TkPr +U4DRESdeO6Vyc6zmS4aWrrlwO6kuccqxMIYhr/bvp1zAhw+1E05BLJnMSUedd5Ac +IZpVMZ3X/LeqdIm8Z0NkNN/Es5C+Xnydi71TlQIDAQABoHwwegYJKoZIhvcNAQkO +MW0wazAvBgNVHREEKDAmghBtZXNodGFzdGljLmxvY2FsghIqLm1lc2h0YXN0aWMu +bG9jYWwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +BQcDAjAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBmKnznPIzLbhOJ7r+v +HxHHAEws73Dv11UyAnBY5wh1TRJgiN0JvZGGXryuwPy1vOslGtLda6HnjOg5K4+8 +3m+KOyIEY5Ouj8KmAEHorSus8U1GkaiY5YaqZJpSs363EZZmqlqrOMXK7IBtjJFw +IFQGRx3Am1OnLMRTpsQhWDURCMw53Mx4FGH0YdeOdis3vPYUPNLoD+Pjzu2vTC2Z +NvmaklBk/tnZL4//3xt3jhuOMdMZnoR1uQ7Y2ZRdlZXm9czRPFiXSzG43dvK8mio +R3WVe6stUTHV7raFX4VMWT+zQa7mLjV6zyaDGDM6NsYdxyduGutodMfg0rKriuKq +HJ8X +-----END CERTIFICATE REQUEST----- diff --git a/docs/91Qt4C5SZBL.pdf b/docs/91Qt4C5SZBL.pdf new file mode 100644 index 0000000..ea0a8a3 Binary files /dev/null and b/docs/91Qt4C5SZBL.pdf differ diff --git a/firmware-2.7.26/firmware-heltec-v4-2.7.26.54e0d8d.factory.bin b/firmware-2.7.26/firmware-heltec-v4-2.7.26.54e0d8d.factory.bin new file mode 100644 index 0000000..80e8ed5 Binary files /dev/null and b/firmware-2.7.26/firmware-heltec-v4-2.7.26.54e0d8d.factory.bin differ diff --git a/firmware-2.7.26/firmware-heltec-v4-2.7.26.54e0d8d.mt.json b/firmware-2.7.26/firmware-heltec-v4-2.7.26.54e0d8d.mt.json new file mode 100644 index 0000000..98b63bb --- /dev/null +++ b/firmware-2.7.26/firmware-heltec-v4-2.7.26.54e0d8d.mt.json @@ -0,0 +1,103 @@ +{ + "version": "2.7.26.54e0d8d", + "build_epoch": 1782172800, + "platformioTarget": "heltec-v4", + "mcu": "esp32s3", + "repo": "meshtastic/firmware", + "files": [ + { + "name": "firmware-heltec-v4-2.7.26.54e0d8d.elf", + "md5": "da898d4a96156262756bb491c0d35023", + "bytes": 22342760 + }, + { + "name": "firmware-heltec-v4-2.7.26.54e0d8d.bin", + "md5": "373b8d2260799b9253d0e63b4944db85", + "bytes": 2117408, + "part_name": "app0" + }, + { + "name": "firmware-heltec-v4-2.7.26.54e0d8d.factory.bin", + "md5": "f5e2824628c79aca5ae08f5952b35eee", + "bytes": 2182944 + }, + { + "name": "littlefs-heltec-v4-2.7.26.54e0d8d.bin", + "md5": "ea2ab5630cef965beee23c75b881d534", + "bytes": 3538944, + "part_name": "spiffs" + }, + { + "name": "mt-esp32s3-ota.bin", + "md5": "497d3108c038f8a6b5f4e234a1156c8a", + "bytes": 636544, + "part_name": "app1" + } + ], + "has_mui": false, + "has_inkhud": false, + "part": [ + { + "name": "nvs", + "type": "data", + "subtype": "nvs", + "offset": "0x9000", + "size": "0x5000", + "flags": "" + }, + { + "name": "otadata", + "type": "data", + "subtype": "ota", + "offset": "0xe000", + "size": "0x2000", + "flags": "" + }, + { + "name": "app0", + "type": "app", + "subtype": "ota_0", + "offset": "0x10000", + "size": "0x640000", + "flags": "" + }, + { + "name": "app1", + "type": "app", + "subtype": "ota_1", + "offset": "0x650000", + "size": "0x640000", + "flags": "" + }, + { + "name": "spiffs", + "type": "data", + "subtype": "spiffs", + "offset": "0xc90000", + "size": "0x360000", + "flags": "" + }, + { + "name": "coredump", + "type": "data", + "subtype": "coredump", + "offset": "0xFF0000", + "size": "0x10000", + "flags": "" + } + ], + "hwModel": 110, + "hwModelSlug": "HELTEC_V4", + "architecture": "esp32-s3", + "activelySupported": true, + "displayName": "Heltec V4", + "supportLevel": 1, + "images": [ + "heltec_v4.svg" + ], + "tags": [ + "Heltec" + ], + "requiresDfu": true, + "partitionScheme": "16MB" +} diff --git a/firmware-2.7.26/littlefs-heltec-v4-2.7.26.54e0d8d.bin b/firmware-2.7.26/littlefs-heltec-v4-2.7.26.54e0d8d.bin new file mode 100644 index 0000000..e0b3567 Binary files /dev/null and b/firmware-2.7.26/littlefs-heltec-v4-2.7.26.54e0d8d.bin differ diff --git a/firmware-2.7.26/mt-esp32s3-ota.bin b/firmware-2.7.26/mt-esp32s3-ota.bin new file mode 100644 index 0000000..360581e Binary files /dev/null and b/firmware-2.7.26/mt-esp32s3-ota.bin differ diff --git a/firmware-custom/MeshtasticTlsCertificate.h b/firmware-custom/MeshtasticTlsCertificate.h new file mode 100644 index 0000000..c7b4bae --- /dev/null +++ b/firmware-custom/MeshtasticTlsCertificate.h @@ -0,0 +1,211 @@ +#pragma once + +inline constexpr unsigned char meshtasticTlsCertificateDer[] = { + 0x30, 0x82, 0x04, 0xdb, 0x30, 0x82, 0x02, 0xc3, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x1d, 0x3b, 0xc2, 0xb4, 0xd4, 0xb6, 0xe0, 0x56, 0xbb, + 0xa7, 0xd4, 0x6c, 0xa5, 0x20, 0x47, 0xb8, 0x0b, 0x62, 0x7f, 0x72, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x65, 0x72, 0x69, 0x63, 0x78, 0x6c, 0x69, + 0x75, 0x2e, 0x6d, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x65, 0x72, 0x69, + 0x63, 0x78, 0x6c, 0x69, 0x75, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x12, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x40, 0x65, + 0x72, 0x69, 0x63, 0x78, 0x6c, 0x69, 0x75, 0x2e, 0x6d, 0x65, 0x30, 0x1e, + 0x17, 0x0d, 0x32, 0x36, 0x30, 0x39, 0x30, 0x38, 0x30, 0x30, 0x33, 0x39, + 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x31, 0x30, 0x31, 0x30, 0x30, + 0x30, 0x33, 0x39, 0x30, 0x39, 0x5a, 0x30, 0x6e, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x14, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x65, 0x72, 0x69, + 0x63, 0x78, 0x6c, 0x69, 0x75, 0x2e, 0x6d, 0x65, 0x31, 0x21, 0x30, 0x1f, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x40, 0x65, 0x72, 0x69, 0x63, + 0x78, 0x6c, 0x69, 0x75, 0x2e, 0x6d, 0x65, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x6d, 0x65, 0x73, 0x68, 0x74, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0x0e, 0xd7, 0x26, 0x6f, + 0xe3, 0x78, 0x6f, 0xf7, 0x83, 0xd0, 0x16, 0x20, 0x9e, 0xb0, 0xd2, 0xca, + 0x90, 0x55, 0x8a, 0x3a, 0x7c, 0x06, 0xd8, 0x32, 0xc1, 0x31, 0x4e, 0xe5, + 0xc8, 0xbe, 0x3a, 0xac, 0xfe, 0x37, 0xcc, 0x33, 0xa3, 0x5c, 0x6e, 0xa3, + 0xfa, 0xb5, 0xb9, 0x1c, 0x4e, 0x99, 0xba, 0x74, 0x45, 0xec, 0xb4, 0x7a, + 0x87, 0xd3, 0xa9, 0x15, 0xdc, 0x36, 0xcc, 0x53, 0x87, 0xd8, 0xa4, 0x50, + 0xde, 0xfe, 0x11, 0xc9, 0x2f, 0xc8, 0xb2, 0x5a, 0xf6, 0x6d, 0x33, 0x27, + 0x15, 0xbb, 0x6b, 0xb4, 0xbf, 0xe3, 0xd3, 0x70, 0x73, 0xa8, 0x53, 0x83, + 0x16, 0x36, 0xf3, 0xdd, 0x0e, 0x8e, 0x2f, 0x32, 0x22, 0x82, 0x0e, 0xe0, + 0x5e, 0xc2, 0x47, 0xb0, 0x0b, 0xa2, 0x7c, 0x3a, 0x91, 0x87, 0xe7, 0xe9, + 0xef, 0x1d, 0xa2, 0xe9, 0x1a, 0xda, 0x7b, 0x0e, 0x4b, 0xd4, 0x87, 0x79, + 0x51, 0x72, 0x2a, 0x0f, 0x96, 0x82, 0x0a, 0x27, 0x1d, 0xdc, 0x06, 0x53, + 0xf2, 0xc7, 0xcc, 0x80, 0x38, 0x3a, 0xd7, 0x71, 0x7b, 0xad, 0x8f, 0x44, + 0xf2, 0xed, 0xff, 0x0a, 0xde, 0xe6, 0x2c, 0x6e, 0x61, 0xfa, 0x24, 0x3e, + 0x6e, 0xff, 0x01, 0x01, 0x89, 0xbc, 0x84, 0xf9, 0x71, 0xc7, 0x5c, 0x0b, + 0xba, 0x56, 0x8b, 0xbc, 0x4e, 0x43, 0xeb, 0x53, 0x80, 0xd1, 0x11, 0x27, + 0x5e, 0x3b, 0xa5, 0x72, 0x73, 0xac, 0xe6, 0x4b, 0x86, 0x96, 0xae, 0xb9, + 0x70, 0x3b, 0xa9, 0x2e, 0x71, 0xca, 0xb1, 0x30, 0x86, 0x21, 0xaf, 0xf6, + 0xef, 0xa7, 0x5c, 0xc0, 0x87, 0x0f, 0xb5, 0x13, 0x4e, 0x41, 0x2c, 0x99, + 0xcc, 0x49, 0x47, 0x9d, 0x77, 0x90, 0x1c, 0x21, 0x9a, 0x55, 0x31, 0x9d, + 0xd7, 0xfc, 0xb7, 0xaa, 0x74, 0x89, 0xbc, 0x67, 0x43, 0x64, 0x34, 0xdf, + 0xc4, 0xb3, 0x90, 0xbe, 0x5e, 0x7c, 0x9d, 0x8b, 0xbd, 0x53, 0x95, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6d, 0x30, 0x6b, 0x30, 0x2f, 0x06, 0x03, + 0x55, 0x1d, 0x11, 0x04, 0x28, 0x30, 0x26, 0x82, 0x10, 0x6d, 0x65, 0x73, + 0x68, 0x74, 0x61, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x82, 0x12, 0x2a, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x74, 0x61, 0x73, + 0x74, 0x69, 0x63, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, + 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x02, 0x01, 0x00, 0x8d, 0xed, 0xa2, 0x76, 0x48, 0xe5, 0x71, 0x03, 0x31, + 0x1a, 0xbc, 0x6b, 0x88, 0x3f, 0xdb, 0x2c, 0xfb, 0xa5, 0xed, 0x36, 0x81, + 0x42, 0x31, 0x2b, 0xbe, 0xde, 0x80, 0x3a, 0x73, 0x3b, 0x01, 0xdb, 0x13, + 0xe9, 0xc6, 0xcb, 0xde, 0x11, 0xcb, 0x4a, 0xb9, 0x93, 0x73, 0xcc, 0xdf, + 0xc7, 0xe6, 0xb7, 0x34, 0x7a, 0x90, 0x03, 0xd2, 0x87, 0x37, 0x7a, 0x93, + 0x3a, 0x92, 0x22, 0x30, 0x17, 0x21, 0xb4, 0x1e, 0xb4, 0xc1, 0xf0, 0x7f, + 0x41, 0xf9, 0x88, 0xa2, 0xc6, 0x38, 0x76, 0x78, 0x07, 0xe8, 0xe5, 0x83, + 0xef, 0xcb, 0xd8, 0xd2, 0x56, 0xff, 0x19, 0xce, 0x17, 0x4b, 0x44, 0x55, + 0x89, 0x80, 0xe0, 0xfa, 0x97, 0x7b, 0x2d, 0xe9, 0x6b, 0x4b, 0x5a, 0x93, + 0x11, 0xe0, 0x13, 0xd2, 0x81, 0xec, 0xce, 0x92, 0x78, 0xaf, 0x19, 0x1a, + 0x33, 0x4f, 0x01, 0x3f, 0xaa, 0x77, 0x10, 0xb4, 0xac, 0xcc, 0x78, 0x69, + 0xcf, 0xbb, 0xc2, 0x58, 0x6e, 0xe5, 0xc4, 0x1c, 0x22, 0x04, 0x94, 0xd3, + 0xaf, 0x6f, 0x96, 0xbc, 0x11, 0xeb, 0xdd, 0x89, 0xcc, 0x45, 0x3a, 0xb1, + 0x8a, 0xfa, 0xc0, 0xf5, 0x5d, 0x61, 0x84, 0x18, 0xe8, 0x99, 0x27, 0x77, + 0xe4, 0xc2, 0xbb, 0x78, 0x8c, 0xd0, 0xa8, 0xef, 0x47, 0x1c, 0xa7, 0xb8, + 0x21, 0x1a, 0x3d, 0xeb, 0x38, 0x2f, 0x00, 0x1a, 0xae, 0xc7, 0x2f, 0x41, + 0xa7, 0x13, 0xb9, 0x5c, 0xe5, 0x60, 0x6e, 0x42, 0x74, 0xd4, 0xb9, 0x2e, + 0xee, 0x78, 0xb3, 0xea, 0xb7, 0x18, 0x36, 0xe8, 0xc6, 0x41, 0xed, 0xa2, + 0xf3, 0xae, 0x5e, 0x4d, 0xbb, 0x7f, 0xad, 0xb0, 0x1d, 0x3c, 0xae, 0x54, + 0xc5, 0xa2, 0x44, 0xfd, 0x3a, 0xaf, 0x15, 0xd9, 0xb4, 0xd7, 0xd0, 0x8f, + 0xa4, 0xe5, 0xd4, 0x7c, 0x5c, 0x7a, 0x35, 0x07, 0xc7, 0xf2, 0x6a, 0x78, + 0x22, 0xe7, 0x6c, 0x23, 0xd2, 0xba, 0x3c, 0xa4, 0x27, 0x1b, 0x39, 0xa5, + 0x6e, 0xa2, 0x23, 0x86, 0xa2, 0x6a, 0x16, 0x3a, 0x9e, 0x8c, 0x1e, 0x48, + 0x34, 0x81, 0x43, 0x5d, 0x7f, 0xaa, 0x9c, 0x5b, 0x15, 0x70, 0xef, 0xd2, + 0x4f, 0x82, 0x3a, 0xb2, 0x4a, 0x1e, 0x60, 0x53, 0xcb, 0xc5, 0xcb, 0x8d, + 0x16, 0xf8, 0xd1, 0x00, 0x75, 0x1a, 0x21, 0x4c, 0x22, 0x46, 0x44, 0x75, + 0xb8, 0xd9, 0x37, 0x5e, 0x5a, 0xb4, 0xe8, 0x12, 0x91, 0x45, 0xa6, 0x1f, + 0x26, 0x76, 0x50, 0x11, 0xcb, 0x40, 0xe6, 0x30, 0x00, 0x6f, 0x1e, 0x1d, + 0x1a, 0x45, 0xb3, 0x01, 0x6d, 0x54, 0x08, 0xe2, 0xd7, 0x62, 0xaf, 0x47, + 0x0d, 0x94, 0xe1, 0x50, 0x4e, 0xf5, 0x28, 0x2a, 0x54, 0x7b, 0x91, 0xfe, + 0x9d, 0x58, 0xca, 0xaf, 0xff, 0x70, 0xfc, 0x12, 0x1a, 0x8f, 0x86, 0x34, + 0xd8, 0x82, 0x3c, 0x1f, 0xe4, 0xb0, 0x44, 0xae, 0x38, 0x33, 0x67, 0x7b, + 0x74, 0x1a, 0x6f, 0xb6, 0x8a, 0xf6, 0xdf, 0xf7, 0xc2, 0xc4, 0x53, 0x93, + 0x5e, 0x26, 0x7f, 0x20, 0x2e, 0x74, 0xb5, 0x1c, 0x8b, 0x99, 0x31, 0xb0, + 0x7f, 0xe9, 0x42, 0xff, 0xfd, 0x54, 0xbc, 0x77, 0x5b, 0x5e, 0xce, 0xad, + 0xcb, 0x45, 0x0d, 0x9c, 0xa0, 0xc4, 0xf3, 0x99, 0x46, 0xbe, 0xcd, 0xc8, + 0x47, 0x0a, 0x4f, 0x20, 0x62, 0x8f, 0xf6, 0x59, 0xc7, 0x11, 0xcf, 0xba, + 0xf7, 0x76, 0x2b, 0xb8, 0x1d, 0xa2, 0x5d, 0x58, 0x4c, 0xdb, 0xd2, 0x5a, + 0x7e, 0x4e, 0x84, 0xa5, 0xc6, 0xbb, 0x8d, 0x88, 0x11, 0xea, 0x7e, 0x7f, + 0x0a, 0xff, 0x64, 0x1d, 0x77, 0x9b, 0xc1, 0x1c, 0x4a, 0x7f, 0x4a, 0xe2, + 0xfc, 0xd3, 0xf0, 0x04, 0xdb, 0xf6, 0x4e, 0x11, 0xa3, 0xdd, 0x0a, 0x6b, + 0xca, 0xfb, 0x49, 0x5e, 0xee, 0x9e, 0xba, 0x3a, 0x88, 0xaf, 0xc9, 0x7b, + 0x33, 0xa3, 0x5e, 0xde, 0xff, 0x3d, 0x1d, 0x7d, 0x09, 0xbc, 0x0d, +}; + +inline constexpr unsigned char meshtasticTlsPrivateKeyDer[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xbd, 0x0e, 0xd7, 0x26, 0x6f, 0xe3, 0x78, 0x6f, 0xf7, 0x83, 0xd0, 0x16, + 0x20, 0x9e, 0xb0, 0xd2, 0xca, 0x90, 0x55, 0x8a, 0x3a, 0x7c, 0x06, 0xd8, + 0x32, 0xc1, 0x31, 0x4e, 0xe5, 0xc8, 0xbe, 0x3a, 0xac, 0xfe, 0x37, 0xcc, + 0x33, 0xa3, 0x5c, 0x6e, 0xa3, 0xfa, 0xb5, 0xb9, 0x1c, 0x4e, 0x99, 0xba, + 0x74, 0x45, 0xec, 0xb4, 0x7a, 0x87, 0xd3, 0xa9, 0x15, 0xdc, 0x36, 0xcc, + 0x53, 0x87, 0xd8, 0xa4, 0x50, 0xde, 0xfe, 0x11, 0xc9, 0x2f, 0xc8, 0xb2, + 0x5a, 0xf6, 0x6d, 0x33, 0x27, 0x15, 0xbb, 0x6b, 0xb4, 0xbf, 0xe3, 0xd3, + 0x70, 0x73, 0xa8, 0x53, 0x83, 0x16, 0x36, 0xf3, 0xdd, 0x0e, 0x8e, 0x2f, + 0x32, 0x22, 0x82, 0x0e, 0xe0, 0x5e, 0xc2, 0x47, 0xb0, 0x0b, 0xa2, 0x7c, + 0x3a, 0x91, 0x87, 0xe7, 0xe9, 0xef, 0x1d, 0xa2, 0xe9, 0x1a, 0xda, 0x7b, + 0x0e, 0x4b, 0xd4, 0x87, 0x79, 0x51, 0x72, 0x2a, 0x0f, 0x96, 0x82, 0x0a, + 0x27, 0x1d, 0xdc, 0x06, 0x53, 0xf2, 0xc7, 0xcc, 0x80, 0x38, 0x3a, 0xd7, + 0x71, 0x7b, 0xad, 0x8f, 0x44, 0xf2, 0xed, 0xff, 0x0a, 0xde, 0xe6, 0x2c, + 0x6e, 0x61, 0xfa, 0x24, 0x3e, 0x6e, 0xff, 0x01, 0x01, 0x89, 0xbc, 0x84, + 0xf9, 0x71, 0xc7, 0x5c, 0x0b, 0xba, 0x56, 0x8b, 0xbc, 0x4e, 0x43, 0xeb, + 0x53, 0x80, 0xd1, 0x11, 0x27, 0x5e, 0x3b, 0xa5, 0x72, 0x73, 0xac, 0xe6, + 0x4b, 0x86, 0x96, 0xae, 0xb9, 0x70, 0x3b, 0xa9, 0x2e, 0x71, 0xca, 0xb1, + 0x30, 0x86, 0x21, 0xaf, 0xf6, 0xef, 0xa7, 0x5c, 0xc0, 0x87, 0x0f, 0xb5, + 0x13, 0x4e, 0x41, 0x2c, 0x99, 0xcc, 0x49, 0x47, 0x9d, 0x77, 0x90, 0x1c, + 0x21, 0x9a, 0x55, 0x31, 0x9d, 0xd7, 0xfc, 0xb7, 0xaa, 0x74, 0x89, 0xbc, + 0x67, 0x43, 0x64, 0x34, 0xdf, 0xc4, 0xb3, 0x90, 0xbe, 0x5e, 0x7c, 0x9d, + 0x8b, 0xbd, 0x53, 0x95, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xae, 0x26, 0x4a, 0x77, 0xa4, 0x9f, 0x83, 0xa4, 0x97, 0xfa, + 0x7a, 0xa6, 0xb7, 0x5b, 0x96, 0x84, 0x45, 0x85, 0x98, 0xd6, 0x20, 0xb3, + 0x78, 0xd6, 0x94, 0x42, 0x33, 0xba, 0x7a, 0x9e, 0x64, 0xe4, 0xc5, 0xcf, + 0xd2, 0xf4, 0x2e, 0x28, 0xf0, 0x0f, 0x16, 0xcb, 0xed, 0xb3, 0x5b, 0x68, + 0xe7, 0xe0, 0xc2, 0x14, 0x5b, 0x4b, 0x90, 0x87, 0x27, 0xa8, 0xdc, 0x73, + 0x22, 0xa3, 0x2a, 0xda, 0xba, 0xeb, 0xf9, 0x76, 0xbf, 0xd1, 0x00, 0x63, + 0x1c, 0xdb, 0x76, 0x41, 0x03, 0x2c, 0x18, 0x77, 0xc3, 0x52, 0x1e, 0x88, + 0x98, 0x43, 0x7f, 0x95, 0x7a, 0x5b, 0x9b, 0x27, 0xce, 0x6c, 0xea, 0x96, + 0xea, 0xd0, 0x7c, 0xbd, 0x1e, 0xd2, 0xb7, 0x49, 0x72, 0x6a, 0xf8, 0xb6, + 0x6e, 0xf1, 0x42, 0x3e, 0x26, 0x53, 0xb1, 0xc0, 0xca, 0xaa, 0xf3, 0x51, + 0x02, 0x2a, 0x52, 0x6b, 0xf5, 0x94, 0xe9, 0x62, 0xe5, 0xe6, 0x53, 0x77, + 0xc8, 0x76, 0x00, 0xfc, 0xe0, 0x6e, 0xe9, 0x3f, 0xe4, 0x71, 0x23, 0xf4, + 0xc0, 0x5e, 0x34, 0x96, 0x1e, 0x3b, 0xda, 0xfa, 0xa1, 0xb3, 0xf9, 0x28, + 0xef, 0x88, 0xc2, 0xf0, 0x00, 0x71, 0x6c, 0x22, 0xe5, 0x27, 0xa8, 0xe8, + 0xc2, 0x54, 0x65, 0x9c, 0x14, 0x48, 0x5e, 0x90, 0x10, 0xd4, 0xa6, 0x81, + 0xca, 0xbd, 0x8d, 0xc5, 0xbc, 0xb9, 0x40, 0xbb, 0x3d, 0x99, 0xfa, 0x5c, + 0x1e, 0x28, 0x0f, 0xf0, 0x9f, 0xd9, 0x31, 0x38, 0x3e, 0x3e, 0x91, 0x3c, + 0x68, 0xab, 0x75, 0x43, 0xa3, 0xeb, 0x2b, 0xec, 0xd5, 0xa8, 0x4f, 0x2b, + 0xfa, 0x3e, 0xbd, 0x81, 0x47, 0x2b, 0x49, 0x12, 0x23, 0xc9, 0x65, 0xf3, + 0xef, 0xb3, 0xa7, 0xd1, 0xb3, 0x11, 0x4e, 0xe7, 0x88, 0x68, 0x51, 0xd9, + 0x73, 0x4c, 0x59, 0xc7, 0x4a, 0x50, 0x78, 0x3b, 0xef, 0x45, 0x93, 0x37, + 0xf8, 0x7a, 0x36, 0x0f, 0xec, 0x81, 0x02, 0x81, 0x81, 0x00, 0xf2, 0xd1, + 0xa3, 0x5e, 0x05, 0xc3, 0xa5, 0x76, 0x37, 0x0b, 0x3f, 0x36, 0x65, 0xfb, + 0xd9, 0x6b, 0x04, 0xb6, 0xa9, 0xe5, 0xc3, 0x45, 0xf9, 0xb4, 0xec, 0x18, + 0xe6, 0x17, 0xd4, 0x73, 0x0d, 0x71, 0x68, 0x9b, 0x0e, 0x56, 0x63, 0x60, + 0xc2, 0xe7, 0xe2, 0x6a, 0x4c, 0x04, 0x39, 0x57, 0x6f, 0x09, 0x1c, 0xc0, + 0x43, 0x73, 0xf4, 0x8e, 0x44, 0xee, 0xf1, 0x26, 0xc6, 0xd1, 0x37, 0x90, + 0x42, 0x05, 0xbe, 0xee, 0x18, 0xdd, 0x93, 0xf0, 0x78, 0xb6, 0x81, 0x2d, + 0xe9, 0x4d, 0x78, 0x76, 0xd9, 0x10, 0x63, 0xe5, 0xbc, 0x60, 0xc4, 0x6e, + 0xad, 0x6b, 0x67, 0x4d, 0x04, 0x18, 0x3d, 0x63, 0xe5, 0x87, 0xb5, 0x7c, + 0x29, 0xd3, 0x2d, 0xa2, 0x82, 0x66, 0x07, 0x1a, 0x64, 0x6a, 0x1e, 0x00, + 0x11, 0x1d, 0xcf, 0x4e, 0x3f, 0x46, 0x05, 0xf8, 0x8a, 0xe2, 0x75, 0xb2, + 0xae, 0x66, 0x9f, 0x9c, 0x3b, 0x75, 0x02, 0x81, 0x81, 0x00, 0xc7, 0x52, + 0x1b, 0x6b, 0x71, 0x45, 0x60, 0x99, 0xcc, 0xbc, 0xa9, 0x9a, 0x79, 0x0c, + 0x20, 0x23, 0xcf, 0x2b, 0xc9, 0x23, 0x4d, 0xc4, 0xcc, 0xe8, 0xac, 0x0e, + 0xb5, 0xf1, 0x8e, 0x1a, 0x62, 0x80, 0x12, 0xae, 0xe6, 0xce, 0x04, 0x99, + 0x1f, 0xf5, 0xe9, 0xde, 0x83, 0x92, 0x77, 0x2e, 0xa4, 0x44, 0xb9, 0xe9, + 0x8d, 0x01, 0xa0, 0xf9, 0xf5, 0x34, 0xfa, 0x8b, 0x94, 0x68, 0x62, 0x32, + 0xbc, 0x48, 0x6e, 0x32, 0x3c, 0x1f, 0x61, 0x7a, 0xf6, 0xa4, 0x3a, 0x68, + 0xb1, 0x80, 0x4a, 0xd6, 0xb6, 0xa6, 0x81, 0x10, 0x18, 0x0e, 0x91, 0x56, + 0x56, 0x4f, 0x2f, 0x8b, 0x24, 0xd4, 0x58, 0x13, 0x8a, 0x54, 0x05, 0xc3, + 0x23, 0x0c, 0x46, 0xc6, 0xd8, 0x59, 0xb4, 0x28, 0x81, 0xdd, 0xd9, 0xba, + 0x58, 0xd0, 0xe1, 0xe3, 0xb7, 0x0e, 0x61, 0xa6, 0xc6, 0xa7, 0x39, 0xb7, + 0x6b, 0xf9, 0xf0, 0xc1, 0x53, 0xa1, 0x02, 0x81, 0x81, 0x00, 0x91, 0x45, + 0x9c, 0xf0, 0xbe, 0x90, 0x1b, 0xa9, 0x0b, 0x2b, 0x7e, 0x69, 0x24, 0x40, + 0xb6, 0x06, 0x11, 0xee, 0xda, 0xdc, 0xac, 0xa4, 0x6b, 0xcd, 0xb3, 0x46, + 0xfe, 0x3a, 0x19, 0x8f, 0xaf, 0xe6, 0x3e, 0xc8, 0x2d, 0x9e, 0xbf, 0x9b, + 0xff, 0x5f, 0xce, 0x14, 0xfc, 0x5f, 0xb6, 0x92, 0xb9, 0xca, 0x80, 0xda, + 0x02, 0x41, 0x18, 0x7a, 0x19, 0x81, 0xbe, 0xe3, 0x0d, 0x25, 0xd4, 0x91, + 0x48, 0xfe, 0xb9, 0x09, 0x27, 0xf5, 0x40, 0xf2, 0x28, 0xb6, 0x3f, 0xb8, + 0xe1, 0x10, 0xc9, 0x56, 0x89, 0x6d, 0x05, 0xe7, 0x47, 0x79, 0xb9, 0x6b, + 0xe1, 0xf3, 0x14, 0xfd, 0x7d, 0xca, 0xa6, 0xc7, 0xe2, 0x65, 0xfb, 0xcd, + 0x4a, 0x14, 0x9f, 0x03, 0xcf, 0xf2, 0x0c, 0xa3, 0xdc, 0x99, 0xa4, 0x53, + 0x33, 0xea, 0x5a, 0xc1, 0x9c, 0x97, 0x5f, 0x31, 0x20, 0x9e, 0x75, 0xfe, + 0x2d, 0xdb, 0x15, 0xf8, 0xd9, 0x95, 0x02, 0x81, 0x80, 0x5e, 0x3d, 0x39, + 0xed, 0xa0, 0xce, 0x96, 0x8f, 0xe1, 0x37, 0x4a, 0x51, 0x58, 0xee, 0x1c, + 0xbc, 0x11, 0x95, 0xb8, 0x31, 0xd2, 0xf1, 0x3b, 0x98, 0xbe, 0xd0, 0xed, + 0xc1, 0x59, 0xd8, 0xab, 0xbd, 0xb6, 0x17, 0xaf, 0xd4, 0xb4, 0x63, 0xd9, + 0xb2, 0xa1, 0x72, 0xad, 0x6e, 0xb0, 0x9f, 0x02, 0xd7, 0xe3, 0xb6, 0xc3, + 0x0e, 0x84, 0x17, 0xea, 0x91, 0xb3, 0xec, 0x0e, 0xad, 0x13, 0xd0, 0xbd, + 0x28, 0xd9, 0xc1, 0x32, 0x9f, 0xfb, 0xac, 0xf1, 0xb4, 0x50, 0x51, 0x73, + 0xab, 0x1e, 0xb7, 0x4a, 0x00, 0x8b, 0x81, 0x1a, 0x7e, 0xb8, 0xc4, 0xc3, + 0x66, 0x09, 0x2a, 0x96, 0xad, 0x37, 0x3f, 0x75, 0xe5, 0xa8, 0x1b, 0xcd, + 0x14, 0x5e, 0xda, 0x61, 0x2c, 0x78, 0x7b, 0xb6, 0x7b, 0x38, 0x18, 0x5d, + 0x29, 0xd5, 0xc3, 0x9e, 0xa7, 0x54, 0x10, 0x50, 0x58, 0x7c, 0x77, 0x76, + 0xbb, 0xe3, 0xd2, 0xe4, 0x41, 0x02, 0x81, 0x80, 0x26, 0xb2, 0xde, 0x69, + 0xb8, 0x48, 0x01, 0x1c, 0x90, 0x9b, 0x4b, 0x67, 0x70, 0x6a, 0x4e, 0xb5, + 0xfe, 0x9a, 0x5a, 0xb3, 0x2b, 0x60, 0x1f, 0xf7, 0xa3, 0x25, 0xd2, 0x3e, + 0x9e, 0x90, 0xf9, 0x5b, 0x88, 0x55, 0x6c, 0x61, 0x7a, 0x24, 0x6e, 0x97, + 0x78, 0x4d, 0x26, 0xd7, 0x87, 0xc8, 0x75, 0xec, 0xdd, 0x24, 0xfd, 0x81, + 0x24, 0x76, 0xa3, 0x23, 0x73, 0x26, 0xe3, 0x89, 0xba, 0x08, 0xbc, 0x99, + 0x2b, 0xd0, 0xee, 0x4b, 0xe5, 0x2b, 0x8a, 0x34, 0xf6, 0xdb, 0x33, 0xad, + 0x12, 0xd1, 0x3b, 0x50, 0xb2, 0x0e, 0x12, 0xc3, 0x52, 0xdf, 0xbf, 0x26, + 0x40, 0x0d, 0x09, 0x09, 0xb1, 0x36, 0x66, 0x1c, 0xb4, 0x12, 0xdb, 0x79, + 0x3d, 0x16, 0x5a, 0xe2, 0xee, 0x96, 0x96, 0x56, 0xf0, 0x21, 0x07, 0x20, + 0xda, 0xdc, 0x52, 0x97, 0x3a, 0xa9, 0xfa, 0xc5, 0x68, 0x45, 0xe4, 0xc6, + 0x0f, 0x2c, 0xa4, 0x05, +}; diff --git a/firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.bin b/firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.bin new file mode 100644 index 0000000..11ba038 Binary files /dev/null and b/firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.bin differ diff --git a/firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.factory.bin b/firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.factory.bin new file mode 100644 index 0000000..3331bf1 Binary files /dev/null and b/firmware-custom/firmware-heltec-v4-2.7.26.54e0d8d.factory.bin differ diff --git a/firmware-custom/patches/WebServer.cpp.patch b/firmware-custom/patches/WebServer.cpp.patch new file mode 100644 index 0000000..5f87100 --- /dev/null +++ b/firmware-custom/patches/WebServer.cpp.patch @@ -0,0 +1,38 @@ +diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp +index 90fd8b0..c47f50a 100644 +--- a/src/mesh/http/WebServer.cpp ++++ b/src/mesh/http/WebServer.cpp +@@ -3,6 +3,7 @@ + #include "NodeDB.h" + #include "graphics/Screen.h" + #include "main.h" ++#include "mesh/http/MeshtasticTlsCertificate.h" + #include "mesh/http/WebServer.h" + #include "mesh/wifi/WiFiAPClient.h" + #include "sleep.h" +@@ -52,9 +53,9 @@ using namespace httpsserver; + + static const uint32_t ACTIVE_THRESHOLD_MS = 5000; + static const uint32_t MEDIUM_THRESHOLD_MS = 30000; +-static const int32_t ACTIVE_INTERVAL_MS = 50; +-static const int32_t MEDIUM_INTERVAL_MS = 200; +-static const int32_t IDLE_INTERVAL_MS = 1000; ++static const int32_t ACTIVE_INTERVAL_MS = 20; ++static const int32_t MEDIUM_INTERVAL_MS = 50; ++static const int32_t IDLE_INTERVAL_MS = 50; + + // Maximum concurrent HTTPS connections (reduced from default 4 to save memory) + static const uint8_t MAX_HTTPS_CONNECTIONS = 2; +@@ -97,6 +98,12 @@ static void taskCreateCert(void *parameter) + { + prefs.begin("MeshtasticHTTPS", false); + ++ // Provision the CA-signed meshtastic.local certificate into the same NVS ++ // keys used by the stock firmware. The certificate survives later OTA ++ // upgrades back to an unmodified Meshtastic build. ++ prefs.putBytes("PK", meshtasticTlsPrivateKeyDer, sizeof(meshtasticTlsPrivateKeyDer)); ++ prefs.putBytes("cert", meshtasticTlsCertificateDer, sizeof(meshtasticTlsCertificateDer)); ++ + #if 0 + // Delete the saved certs (used in debugging) + LOG_DEBUG("Delete any saved SSL keys"); diff --git a/scripts/backup_nvs.sh b/scripts/backup_nvs.sh new file mode 100755 index 0000000..e42640a --- /dev/null +++ b/scripts/backup_nvs.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +PORT="${1:-/dev/cu.usbmodem1101}" +BACKUP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/backups" +TIMESTAMP="$(date +%Y%m%d_%H%M%S)" +TARGET_FILE="${BACKUP_DIR}/nvs_backup_${TIMESTAMP}.bin" + +ESPTOOL_BIN="$(which esptool || which esptool.py || echo "${HOME}/.local/bin/esptool.py")" + +mkdir -p "$BACKUP_DIR" +echo "Backing up NVS partition (0x9000, 0x5000) to $TARGET_FILE..." +"$ESPTOOL_BIN" --port "$PORT" read_flash 0x9000 0x5000 "$TARGET_FILE" +echo "NVS backup complete: $TARGET_FILE" diff --git a/scripts/flash_custom_firmware.sh b/scripts/flash_custom_firmware.sh new file mode 100755 index 0000000..4856b51 --- /dev/null +++ b/scripts/flash_custom_firmware.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +PORT="${1:-/dev/cu.usbmodem1101}" +OFFSET="${2:-0x10000}" +BIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/firmware-custom" +BIN_FILE="${BIN_DIR}/firmware-heltec-v4-2.7.26.54e0d8d.bin" + +if [[ ! -f "$BIN_FILE" ]]; then + echo "Error: Firmware binary not found at $BIN_FILE" >&2 + exit 1 +fi + +ESPTOOL_BIN="$(which esptool || which esptool.py || echo "${HOME}/.local/bin/esptool.py")" + +echo "Flashing $BIN_FILE to $PORT at offset $OFFSET..." +"$ESPTOOL_BIN" --port "$PORT" --baud 921600 write_flash "$OFFSET" "$BIN_FILE" +echo "Flash completed successfully."