Enhance MQTT implementation with updated partition table guidance and merged firmware flashing instructions. Add support for new SSL certificate sources in the generate_cert_bundle script, and integrate embedded CA bundle handling in MQTTBridge and CommonCLI. Update platformio.ini files across multiple variants to include new certificate bundle configurations and scripts for improved SSL support.

This commit is contained in:
agessaman committed 2026-03-30 17:05:01 -07:00
1 parent 384b80fc05
commit da775bb281
16 files changed
+3881 -3390

No files matched your search

+27
View File
@@ -148,6 +148,33 @@ pio run -e heltec_v4_repeater_observer_mqtt
pio run -e Station_G2_repeater_observer_mqtt
```
### Partition Table Changes — Merged Firmware Required
Some MQTT observer builds use a non-default partition table to accommodate the larger firmware size (MQTT libraries, TLS, cert bundle, etc.). **When a board's partition table changes, you must flash the merged firmware (`*-merged.bin`) the first time** so the new partition layout and bootloader are written together. After that initial flash, standard OTA or non-merged updates will work normally.
| Environment | Partition Table | Flash Size | App Slot Size | Notes |
|-------------|----------------|------------|---------------|-------|
| `LilyGo_T3S3_sx1262_repeater_observer_mqtt` | `min_spiffs.csv` | 4 MB | 1.875 MB | Changed from default (1.25 MB) |
| `LilyGo_T3S3_sx1262_room_server_observer_mqtt` | `min_spiffs.csv` | 4 MB | 1.875 MB | Changed from default (1.25 MB) |
| `Station_G2_repeater_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | 16 MB flash board |
| `Station_G2_room_server_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | 16 MB flash board |
**How to flash the merged firmware:**
You can flash the merged firmware using either the web flasher or the command line:
- **Web flasher (recommended):** Use the [MeshCore Web Flasher](https://flasher.meshcore.co.uk/) to flash the `*-merged.bin` file directly from your browser — no tools to install.
- **Command line:**
```bash
# Build the merged binary
pio run -t mergebin -e LilyGo_T3S3_sx1262_repeater_observer_mqtt
# Flash at offset 0x0 (overwrites bootloader + partition table)
esptool.py write_flash 0x0 .pio/build/LilyGo_T3S3_sx1262_repeater_observer_mqtt/firmware-merged.bin
```
> **Note:** Flashing the merged firmware will erase Bluetooth pairings but preserves device configuration stored in NVS. After the first merged flash, subsequent updates can use OTA or the standard non-merged binary.
### Build Flags
- `WITH_MQTT_BRIDGE=1` - Enable MQTT bridge (required)
- `WITH_SNMP=1` - Enable SNMP agent (optional, see [MQTT_SNMP.md](MQTT_SNMP.md))
+17 -1
View File
@@ -184,7 +184,7 @@ def main():
try:
cert_source = env.GetProjectOption("board_ssl_cert_source")
if (cert_source == "mozilla" or cert_source == "adafruit"):
if (cert_source == "mozilla" or cert_source == "adafruit" or cert_source == "adafruit-full"):
download_cacert_file(cert_source)
bundle.add_from_file(os.path.join(certs_dir, "cacert.pem"))
elif (cert_source == "folder"):
@@ -193,6 +193,22 @@ def main():
critical('Invalid configuration option: use \'board_ssl_cert_source\' parameter in platformio.ini' )
raise InputError('Invalid certificate')
# Also include any extra .pem/.der files in the certs directory (excluding
# the downloaded cacert.pem bundle). This allows adding root CAs that have
# been removed from upstream trust stores but are still needed by ESP-IDF's
# cert bundle verification (e.g. GlobalSign Root CA R1 for GTS cross-signs).
if os.path.isdir(certs_dir):
for file_name in sorted(os.listdir(certs_dir)):
if file_name == 'cacert.pem':
continue
file_path = os.path.join(certs_dir, file_name)
if os.path.isfile(file_path) and (file_name.endswith('.pem') or file_name.endswith('.der')):
try:
bundle.add_from_file(file_path)
status('Added extra certificate from %s' % file_name)
except Exception as e:
critical('Skipping %s: %s' % (file_name, str(e)))
status('Successfully added %d certificates in total' % len(bundle.certificates))
crt_bundle = bundle.create_bundle()
Binary file not shown.
+93
View File
@@ -9,6 +9,7 @@
#endif
#ifdef ESP_PLATFORM
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <esp_wifi.h>
#endif
#ifdef WITH_MQTT_BRIDGE
@@ -47,6 +48,59 @@ static bool isValidName(const char *n) {
return true;
}
#ifdef ESP_PLATFORM
// Optional embedded CA bundle symbols produced by board_build.embed_files.
// Weak linkage keeps non-bundle builds linkable.
extern const uint8_t rootca_crt_bundle_start[] asm("_binary_src_certs_x509_crt_bundle_bin_start") __attribute__((weak));
extern const uint8_t rootca_crt_bundle_end[] asm("_binary_src_certs_x509_crt_bundle_bin_end") __attribute__((weak));
static bool parseTlsBundleTarget(const char* input, char* host_out, size_t host_out_size, uint16_t* port_out) {
if (!input || !host_out || host_out_size == 0 || !port_out) return false;
while (*input == ' ') input++;
if (*input == '\0') return false;
const char* start = input;
const char* scheme = strstr(input, "://");
if (scheme) start = scheme + 3;
const char* end = start;
while (*end && *end != '/' && *end != '?' && *end != '#') end++;
if (end <= start) return false;
uint16_t port = 443;
const char* host_start = start;
const char* host_end = end;
if (*host_start == '[') {
const char* close = (const char*)memchr(host_start, ']', host_end - host_start);
if (!close) return false;
if ((close + 1) < host_end && *(close + 1) == ':') {
int p = atoi(close + 2);
if (p <= 0 || p > 65535) return false;
port = (uint16_t)p;
}
host_start++;
host_end = close;
} else {
const char* colon = (const char*)memchr(host_start, ':', host_end - host_start);
if (colon) {
int p = atoi(colon + 1);
if (p <= 0 || p > 65535) return false;
port = (uint16_t)p;
host_end = colon;
}
}
size_t host_len = (size_t)(host_end - host_start);
if (host_len == 0 || host_len >= host_out_size) return false;
memcpy(host_out, host_start, host_len);
host_out[host_len] = '\0';
*port_out = port;
return true;
}
#endif
void CommonCLI::loadPrefs(FILESYSTEM* fs) {
bool is_fresh_install = false;
bool is_upgrade = false;
@@ -584,6 +638,45 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
sprintf(reply, "Free: %d, Min: %d, Max: %d, Queue: %d",
ESP.getFreeHeap(), ESP.getMinFreeHeap(), ESP.getMaxAllocHeap(),
_callbacks->getQueueSize());
} else if (memcmp(command, "tls.bundletest ", 15) == 0) {
#ifdef ESP_PLATFORM
if (WiFi.status() != WL_CONNECTED) {
strcpy(reply, "ERR: WiFi not connected");
} else {
size_t bundle_len = 0;
if (rootca_crt_bundle_start != nullptr &&
rootca_crt_bundle_end != nullptr &&
rootca_crt_bundle_end > rootca_crt_bundle_start) {
bundle_len = static_cast<size_t>(rootca_crt_bundle_end - rootca_crt_bundle_start);
}
if (bundle_len == 0) {
strcpy(reply, "ERR: no embedded cert bundle");
} else {
char host[96];
uint16_t port = 443;
if (!parseTlsBundleTarget(command + 15, host, sizeof(host), &port)) {
strcpy(reply, "ERR: usage tls.bundletest <host[:port]|url>");
} else {
WiFiClientSecure client;
#if ESP_ARDUINO_VERSION_MAJOR >= 3
client.setCACertBundle(rootca_crt_bundle_start, bundle_len);
#else
client.setCACertBundle(rootca_crt_bundle_start);
#endif
client.setTimeout(8000);
bool ok = client.connect(host, port);
if (ok) {
client.stop();
snprintf(reply, 160, "OK: TLS bundle verified %s:%u", host, (unsigned)port);
} else {
snprintf(reply, 160, "ERR: TLS bundle failed %s:%u", host, (unsigned)port);
}
}
}
}
#else
strcpy(reply, "ERR: unsupported on this platform");
#endif
} else if (memcmp(command, "start ota", 9) == 0) {
if (!_board->startOTAUpdate(_prefs->node_name, reply)) {
strcpy(reply, "Error");
+76 -4
View File
@@ -51,6 +51,16 @@ static bool isWiFiConfigValid(const NodePrefs* prefs) {
#ifdef WITH_MQTT_BRIDGE
// Optional embedded CA bundle symbols produced by board_build.embed_files.
// Weak linkage keeps non-bundle builds linkable and allows runtime fallback.
extern const uint8_t rootca_crt_bundle_start[] asm("_binary_src_certs_x509_crt_bundle_bin_start") __attribute__((weak));
extern const uint8_t rootca_crt_bundle_end[] asm("_binary_src_certs_x509_crt_bundle_bin_end") __attribute__((weak));
// Track whether the global cert bundle has been loaded into s_crt_bundle.
// Loading must happen exactly once to avoid a use-after-free race when multiple
// TLS slots are set up in sequence (each connect() launches an async task).
static bool s_ca_bundle_loaded = false;
// PSRAM-aware allocation: prefer PSRAM on ESP32 when BOARD_HAS_PSRAM, fallback to internal heap or malloc.
// Use psram_free() for any pointer returned by psram_malloc().
static void* psram_malloc(size_t size) {
@@ -870,14 +880,45 @@ void MQTTBridge::setupSlot(int index) {
}
} else {
// Custom broker slot — build persistent URI
// If host already has a scheme (mqtt://, mqtts://, ws://, wss://), use as-is with port.
// If host already has a scheme (mqtt://, mqtts://, ws://, wss://), preserve the full URI
// (including optional path/query) and only inject :port when the authority has no explicit port.
// Otherwise, infer protocol from port number.
bool has_scheme = (strncmp(slot.host, "mqtt://", 7) == 0 ||
strncmp(slot.host, "mqtts://", 8) == 0 ||
strncmp(slot.host, "ws://", 5) == 0 ||
strncmp(slot.host, "wss://", 6) == 0);
if (has_scheme) {
snprintf(slot.broker_uri, sizeof(slot.broker_uri), "%s:%d", slot.host, slot.port);
const char* authority = strstr(slot.host, "://");
authority = authority ? authority + 3 : slot.host;
const char* path = strchr(authority, '/');
const char* authority_end = path ? path : slot.host + strlen(slot.host);
bool has_explicit_port = false;
// Detect host:port in URI authority (IPv6 literals in [addr]:port are supported).
if (authority < authority_end) {
if (*authority == '[') {
const char* close = (const char*)memchr(authority, ']', authority_end - authority);
if (close && (close + 1) < authority_end && *(close + 1) == ':') {
has_explicit_port = true;
}
} else {
const char* colon = (const char*)memchr(authority, ':', authority_end - authority);
if (colon != nullptr) {
has_explicit_port = true;
}
}
}
if (has_explicit_port || slot.port == 0) {
snprintf(slot.broker_uri, sizeof(slot.broker_uri), "%s", slot.host);
} else {
const size_t authority_len = (size_t)(authority_end - slot.host);
snprintf(slot.broker_uri, sizeof(slot.broker_uri), "%.*s:%u%s",
(int)authority_len,
slot.host,
(unsigned)slot.port,
path ? path : "");
}
} else {
const char* proto = "mqtt";
if (slot.port == 8883) {
@@ -888,12 +929,43 @@ void MQTTBridge::setupSlot(int index) {
snprintf(slot.broker_uri, sizeof(slot.broker_uri), "%s://%s:%d", proto, slot.host, slot.port);
}
slot.client->setServer(slot.broker_uri);
MQTT_DEBUG_PRINTLN("MQTT%d custom broker URI: %s (host='%s', port=%u)",
index + 1, slot.broker_uri, slot.host, (unsigned)slot.port);
// Custom TLS/WSS slots need the system CA cert bundle for server verification
// Custom TLS/WSS slots need a CA bundle for server verification.
// The bundle is loaded into the global s_crt_bundle exactly once to avoid
// a use-after-free race: connect() launches an async FreeRTOS task, and
// calling setCACertBundle() again from a later slot would free the global
// crts array while a prior slot's TLS handshake may still be reading it.
bool needs_tls = (strncmp(slot.broker_uri, "mqtts://", 8) == 0 ||
strncmp(slot.broker_uri, "wss://", 6) == 0);
if (needs_tls) {
slot.client->attachArduinoCACertBundle(true);
if (!s_ca_bundle_loaded) {
size_t bundle_len = 0;
if (rootca_crt_bundle_start != nullptr &&
rootca_crt_bundle_end != nullptr &&
rootca_crt_bundle_end > rootca_crt_bundle_start) {
bundle_len = static_cast<size_t>(rootca_crt_bundle_end - rootca_crt_bundle_start);
}
if (bundle_len > 0) {
MQTT_DEBUG_PRINTLN("MQTT global CA bundle init: embedded bundle (%u bytes)",
(unsigned)bundle_len);
// Load the bundle into the global s_crt_bundle via the first client.
// This is a one-time operation; subsequent clients reuse via attachArduinoCACertBundle.
slot.client->setCACertBundle(rootca_crt_bundle_start, bundle_len);
s_ca_bundle_loaded = true;
} else {
MQTT_DEBUG_PRINTLN("MQTT%d TLS: no embedded cert bundle available", index + 1);
}
} else {
// Global bundle already loaded — just attach the callback for this client.
slot.client->attachArduinoCACertBundle(true);
}
MQTT_DEBUG_PRINTLN("MQTT%d TLS verify: CA bundle %s", index + 1,
s_ca_bundle_loaded ? "active" : "unavailable");
} else {
MQTT_DEBUG_PRINTLN("MQTT%d custom broker uses non-TLS transport", index + 1);
}
if (strlen(slot.username) > 0) {
+3555 -3385
View File
File diff suppressed because it is too large. Load diff
+26
View File
@@ -0,0 +1,26 @@
# GlobalSign Root CA - R1
# Cross-signs GTS Root R4, which is used by Google-managed ACME certificates.
# Removed from modern browser trust stores (expires Jan 2028) but still needed
# by ESP-IDF's cert bundle verification, which matches on the issuer field of
# cross-signed intermediate chains.
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----
+5
View File
@@ -99,6 +99,11 @@ lib_deps =
[env:Heltec_T190_repeater_observer_mqtt]
extends = Heltec_T190_base
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Heltec_T190_base.build_flags}
-D ADVERT_NAME='"MQTT Observer"'
+10
View File
@@ -109,6 +109,11 @@ lib_deps =
[env:Heltec_v3_repeater_observer_mqtt]
extends = Heltec_lora32_v3
upload_port = /dev/cu.usbserial-4
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Heltec_lora32_v3.build_flags}
-D DISPLAY_CLASS=SSD1306Display
@@ -171,6 +176,11 @@ lib_deps =
[env:Heltec_v3_room_server_observer_mqtt]
extends = Heltec_lora32_v3
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Heltec_lora32_v3.build_flags}
-D DISPLAY_CLASS=SSD1306Display
+10
View File
@@ -126,6 +126,11 @@ lib_deps =
[env:heltec_v4_repeater_observer_mqtt]
extends = heltec_v4_oled
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${heltec_v4_oled.build_flags}
-D DISPLAY_CLASS=SSD1306Display
@@ -170,6 +175,11 @@ lib_deps =
[env:heltec_v4_room_server_observer_mqtt]
extends = heltec_v4_oled
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${heltec_v4_oled.build_flags}
-D DISPLAY_CLASS=SSD1306Display
+12
View File
@@ -101,6 +101,12 @@ lib_deps =
[env:LilyGo_T3S3_sx1262_repeater_observer_mqtt]
extends = LilyGo_T3S3_sx1262
board_build.partitions = min_spiffs.csv
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${LilyGo_T3S3_sx1262.build_flags}
-D DISPLAY_CLASS=SSD1306Display
@@ -140,6 +146,12 @@ lib_deps =
[env:LilyGo_T3S3_sx1262_room_server_observer_mqtt]
extends = LilyGo_T3S3_sx1262
board_build.partitions = min_spiffs.csv
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${LilyGo_T3S3_sx1262.build_flags}
-D DISPLAY_CLASS=SSD1306Display
@@ -136,6 +136,11 @@ lib_deps =
[env:Tbeam_SX1262_repeater_observer_mqtt]
extends = LilyGo_TBeam_SX1262
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${LilyGo_TBeam_SX1262.build_flags}
-D ADVERT_NAME='"Tbeam SX1262 MQTT Observer"'
@@ -173,6 +178,11 @@ lib_deps =
[env:Tbeam_SX1262_room_server_observer_mqtt]
extends = LilyGo_TBeam_SX1262
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${LilyGo_TBeam_SX1262.build_flags}
-D ADVERT_NAME='"Tbeam SX1262 Room Observer"'
@@ -134,6 +134,11 @@ lib_deps =
[env:Tbeam_SX1276_repeater_observer_mqtt]
extends = LilyGo_TBeam_SX1276
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${LilyGo_TBeam_SX1276.build_flags}
-D ADVERT_NAME='"Tbeam SX1276 MQTT Observer"'
@@ -172,6 +177,11 @@ lib_deps =
[env:Tbeam_SX1276_room_server_observer_mqtt]
extends = LilyGo_TBeam_SX1276
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${LilyGo_TBeam_SX1276.build_flags}
-D ADVERT_NAME='"Tbeam SX1276 Room Observer"'
@@ -99,6 +99,11 @@ lib_deps =
[env:T_Beam_S3_Supreme_SX1262_repeater_observer_mqtt]
extends = T_Beam_S3_Supreme_SX1262
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${T_Beam_S3_Supreme_SX1262.build_flags}
-D ADVERT_NAME='"MQTT Observer"'
@@ -136,6 +141,11 @@ lib_deps =
[env:T_Beam_S3_Supreme_SX1262_room_server_observer_mqtt]
extends = T_Beam_S3_Supreme_SX1262
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${T_Beam_S3_Supreme_SX1262.build_flags}
-D ADVERT_NAME='"T_Beam_S3_Supreme_SX1262 Room Observer"'
+10
View File
@@ -174,6 +174,11 @@ lib_deps =
[env:Station_G2_room_server_observer_mqtt]
extends = Station_G2
board_build.partitions = default_16MB.csv ; standard 16MB partition table
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Station_G2.build_flags}
-D ADVERT_NAME='"Station G2 Room Observer"'
@@ -282,6 +287,11 @@ lib_deps =
[env:Station_G2_repeater_observer_mqtt]
extends = Station_G2
board_build.partitions = default_16MB.csv ; standard 16MB partition table
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Station_G2.build_flags}
-D ADVERT_NAME='"MQTT Observer"'
+10
View File
@@ -90,6 +90,11 @@ lib_deps =
[env:Xiao_S3_WIO_repeater_observer_mqtt]
extends = Xiao_S3_WIO
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Xiao_S3_WIO.build_flags}
-D ADVERT_NAME='"MQTT Observer"'
@@ -128,6 +133,11 @@ lib_deps =
[env:Xiao_S3_WIO_room_server_observer_mqtt]
extends = Xiao_S3_WIO
extra_scripts =
${esp32_base.extra_scripts}
pre:scripts/generate_cert_bundle.py
board_ssl_cert_source = adafruit-full
board_build.embed_files = src/certs/x509_crt_bundle.bin
build_flags =
${Xiao_S3_WIO.build_flags}
-D ADVERT_NAME='"XiaoS3 Room Observer"'