Merge branch 'main' of https://github.com/xJARiD/MeshCore-EastMesh
* 'main' of https://github.com/xJARiD/MeshCore-EastMesh: docs: updated release notes for waev feat(mqtt): add Waev broker # Conflicts: # release-notes.yml
This commit is contained in:
commit
b2365c4ac0
8 files changed
+86
-13
No files matched your search
@@ -80,7 +80,7 @@ bool MQTTPrefsStore::load(FILESYSTEM* fs, MQTTPrefs& prefs) {
|
||||
prefs.custom_transport = 0;
|
||||
}
|
||||
prefs.status_interval_ms = kFixedStatusIntervalMs;
|
||||
prefs.enabled_mask &= 0x1F;
|
||||
prefs.enabled_mask &= 0x3F;
|
||||
if (!prefs.brokers_migrated) {
|
||||
// LetsMesh is retired. Clear any saved EU/US selections once so dead brokers
|
||||
// stop retrying; the endpoints remain re-selectable afterwards.
|
||||
|
||||
@@ -128,14 +128,16 @@ void logMqttMemorySnapshot(const char*, const char* = nullptr) {
|
||||
}
|
||||
|
||||
const MQTTUplink::BrokerSpec MQTTUplink::kBrokerSpecs[kBrokerCount] = {
|
||||
{"eastmesh-au", "eastmesh-au", "mqtt2.eastmesh.au", "wss://mqtt2.eastmesh.au:443/mqtt", kEastmeshBit, false},
|
||||
{"meshmapper", "meshmapper", "mqtt.meshmapper.net", "wss://mqtt.meshmapper.net:443/mqtt", kMeshmapperBit, false},
|
||||
{"eastmesh-au", "eastmesh-au", "mqtt2.eastmesh.au", "wss://mqtt2.eastmesh.au:443/mqtt", kEastmeshBit, false, 0},
|
||||
{"meshmapper", "meshmapper", "mqtt.meshmapper.net", "wss://mqtt.meshmapper.net:443/mqtt", kMeshmapperBit, false, 0},
|
||||
// waev enforces a shorter max token lifetime than the curated default; match its documented config.
|
||||
{"waev", "waev", "mqtt.waev.app", "wss://mqtt.waev.app:443/mqtt", kWaevBit, false, 3600},
|
||||
// Retired: LetsMesh is no longer maintained. Kept selectable for legacy nodes; new nodes should use meshmapper.
|
||||
{"letsmesh-eu", "letsmesh-eu", "mqtt-eu-v1.letsmesh.net", "wss://mqtt-eu-v1.letsmesh.net:443/mqtt",
|
||||
kLetsmeshEuBit, false},
|
||||
kLetsmeshEuBit, false, 0},
|
||||
{"letsmesh-us", "letsmesh-us", "mqtt-us-v1.letsmesh.net", "wss://mqtt-us-v1.letsmesh.net:443/mqtt",
|
||||
kLetsmeshUsBit, false},
|
||||
{"custom", "custom", nullptr, nullptr, kCustomBit, true},
|
||||
kLetsmeshUsBit, false, 0},
|
||||
{"custom", "custom", nullptr, nullptr, kCustomBit, true, 0},
|
||||
};
|
||||
|
||||
MQTTUplink::MQTTUplink(mesh::RTCClock& rtc, mesh::LocalIdentity& identity)
|
||||
@@ -202,7 +204,8 @@ const char* MQTTUplink::brokerCaCert(const BrokerSpec& spec) {
|
||||
if (spec.bit == kEastmeshBit || spec.bit == kMeshmapperBit) {
|
||||
return mqtt_ca_certs::kEastmeshIsrgRootX1Pem; // Let's Encrypt ISRG Root X1
|
||||
}
|
||||
return mqtt_ca_certs::kLetsmeshWe1Pem;
|
||||
// waev (mqtt.waev.app) presents a Google Trust Services WE1 chain, same issuer as LetsMesh.
|
||||
return mqtt_ca_certs::kLetsmeshWe1Pem; // Google Trust Services WE1
|
||||
}
|
||||
|
||||
const char* MQTTUplink::brokerHost(const BrokerState& broker) const {
|
||||
@@ -572,7 +575,8 @@ bool MQTTUplink::refreshToken(BrokerState& broker) {
|
||||
}
|
||||
}
|
||||
|
||||
time_t expires_at = now + kTokenLifetimeSecs;
|
||||
time_t ttl = broker.spec->token_ttl_secs != 0 ? static_cast<time_t>(broker.spec->token_ttl_secs) : kTokenLifetimeSecs;
|
||||
time_t expires_at = now + ttl;
|
||||
const char* owner = _prefs.owner_public_key[0] ? _prefs.owner_public_key : nullptr;
|
||||
const char* email = _prefs.owner_email[0] ? _prefs.owner_email : nullptr;
|
||||
if (!JWTHelper::createAuthToken(*_identity, brokerHost(broker), now, expires_at, broker.token, kBrokerTokenSize,
|
||||
@@ -583,8 +587,9 @@ bool MQTTUplink::refreshToken(BrokerState& broker) {
|
||||
return false;
|
||||
}
|
||||
broker.token_expires_at = expires_at;
|
||||
MQTT_LOG("%s token ready exp=%lu owner=%s email=%s", broker.spec->label,
|
||||
static_cast<unsigned long>(expires_at), owner != nullptr ? "yes" : "no", email != nullptr ? "yes" : "no");
|
||||
MQTT_LOG("%s token ready exp=%lu ttl=%ld owner=%s email=%s", broker.spec->label,
|
||||
static_cast<unsigned long>(expires_at), static_cast<long>(ttl),
|
||||
owner != nullptr ? "yes" : "no", email != nullptr ? "yes" : "no");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,9 @@ private:
|
||||
const char* uri;
|
||||
uint8_t bit;
|
||||
bool custom;
|
||||
// Per-broker JWT lifetime in seconds; 0 = use the default kTokenLifetimeSecs. waev enforces a
|
||||
// shorter max token lifetime than the curated default, so it gets its own (matches its config).
|
||||
uint32_t token_ttl_secs;
|
||||
};
|
||||
|
||||
struct BrokerState {
|
||||
@@ -131,9 +134,10 @@ private:
|
||||
static constexpr uint8_t kLetsmeshUsBit = 0x04;
|
||||
static constexpr uint8_t kCustomBit = 0x08;
|
||||
static constexpr uint8_t kMeshmapperBit = 0x10;
|
||||
static constexpr uint8_t kBrokerMask = 0x1F;
|
||||
static constexpr uint8_t kWaevBit = 0x20;
|
||||
static constexpr uint8_t kBrokerMask = 0x3F;
|
||||
static constexpr uint8_t kMaxEnabledBrokers = 2;
|
||||
static constexpr size_t kBrokerCount = 5;
|
||||
static constexpr size_t kBrokerCount = 6;
|
||||
static const BrokerSpec kBrokerSpecs[kBrokerCount];
|
||||
static bool isUnsetIataValue(const char* iata);
|
||||
static const char* brokerCaCert(const BrokerSpec& spec);
|
||||
|
||||
@@ -977,12 +977,13 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
</div>
|
||||
<input id="mqttEastmeshAu" class="visually-hidden" type="checkbox" tabindex="-1" aria-hidden="true">
|
||||
<input id="mqttMeshmapper" class="visually-hidden" type="checkbox" tabindex="-1" aria-hidden="true">
|
||||
<input id="mqttWaev" class="visually-hidden" type="checkbox" tabindex="-1" aria-hidden="true">
|
||||
<input id="mqttLetsmeshEu" class="visually-hidden" type="checkbox" tabindex="-1" aria-hidden="true">
|
||||
<input id="mqttLetsmeshUs" class="visually-hidden" type="checkbox" tabindex="-1" aria-hidden="true">
|
||||
<input id="mqttCustom" class="visually-hidden" type="checkbox" tabindex="-1" aria-hidden="true">
|
||||
<div class="broker-group wide" id="mqttCustomConfig" style="display:none">
|
||||
<div class="broker-group-title">Custom MQTT settings</div>
|
||||
<div class="broker-grid">
|
||||
<div class="broker-grid single">
|
||||
<div class="broker-card">
|
||||
<div class="field-card">
|
||||
<label class="label" for="mqttCustomEndpoint">Host:Port</label>
|
||||
@@ -2732,6 +2733,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
const MQTT_BROKERS = [
|
||||
{ key:"eastmesh-au", input:"mqttEastmeshAu", label:"EastMesh AU", set:"set mqtt.eastmesh-au" },
|
||||
{ key:"meshmapper", input:"mqttMeshmapper", label:"MeshMapper", set:"set mqtt.meshmapper" },
|
||||
{ key:"waev", input:"mqttWaev", label:"Waev", set:"set mqtt.waev" },
|
||||
{ key:"custom", input:"mqttCustom", label:"Custom", set:"set mqtt.custom", custom:true },
|
||||
{ key:"letsmesh-eu", input:"mqttLetsmeshEu", label:"LetsMesh EU (retired)", set:"set mqtt.letsmesh-eu" },
|
||||
{ key:"letsmesh-us", input:"mqttLetsmeshUs", label:"LetsMesh US (retired)", set:"set mqtt.letsmesh-us" }
|
||||
@@ -3261,6 +3263,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
() => loadField("get mqtt.email", "mqttEmail", null, quiet),
|
||||
() => loadBrokerState("get mqtt.eastmesh-au", "mqttEastmeshAu", quiet),
|
||||
() => loadBrokerState("get mqtt.meshmapper", "mqttMeshmapper", quiet),
|
||||
() => loadBrokerState("get mqtt.waev", "mqttWaev", quiet),
|
||||
() => loadBrokerState("get mqtt.letsmesh-eu", "mqttLetsmeshEu", quiet),
|
||||
() => loadBrokerState("get mqtt.letsmesh-us", "mqttLetsmeshUs", quiet),
|
||||
() => loadBrokerState("get mqtt.custom", "mqttCustom", quiet),
|
||||
|
||||
Reference in new issue
Block a user