mirror of
https://github.com/agessaman/MeshCore.git
synced 2026-08-28 14:04:06 +00:00
Refactor MQTT origin handling to use effective origin logic
Updated MyMesh implementations in simple_repeater and simple_room_server to set mqtt_origin to an empty string, allowing the effective origin to follow node_name during publishing. Introduced new functions in MQTTBridge to manage effective origin retrieval and refresh from preferences, ensuring consistent behavior across MQTT operations. This change simplifies the origin management and enhances clarity in the codebase.
This commit is contained in:
@@ -965,8 +965,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
|
||||
// MQTT defaults
|
||||
StrHelper::strncpy(_prefs.mqtt_origin, "MeshCore-Repeater", sizeof(_prefs.mqtt_origin));
|
||||
// MQTT defaults (mqtt_origin empty => effective origin follows node_name at publish time)
|
||||
_prefs.mqtt_origin[0] = '\0';
|
||||
StrHelper::strncpy(_prefs.mqtt_iata, "SEA", sizeof(_prefs.mqtt_iata));
|
||||
_prefs.mqtt_status_enabled = 1; // enabled
|
||||
_prefs.mqtt_packets_enabled = 1; // enabled
|
||||
@@ -1010,10 +1010,6 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
// load persisted prefs
|
||||
_cli.loadPrefs(_fs);
|
||||
|
||||
// Set MQTT origin to actual device name (not build-time ADVERT_NAME)
|
||||
StrHelper::strncpy(_prefs.mqtt_origin, _prefs.node_name, sizeof(_prefs.mqtt_origin));
|
||||
MESH_DEBUG_PRINTLN("MQTT origin set to device name: %s", _prefs.mqtt_origin);
|
||||
|
||||
acl.load(_fs, self_id);
|
||||
// TODO: key_store.begin();
|
||||
region_map.load(_fs);
|
||||
|
||||
@@ -682,8 +682,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.bridge_baud = 115200; // baud rate
|
||||
_prefs.bridge_channel = 1; // channel 1
|
||||
|
||||
// MQTT defaults (same as repeater)
|
||||
StrHelper::strncpy(_prefs.mqtt_origin, "MeshCore-RoomServer", sizeof(_prefs.mqtt_origin));
|
||||
// MQTT defaults (same as repeater; empty mqtt_origin follows node_name when publishing)
|
||||
_prefs.mqtt_origin[0] = '\0';
|
||||
StrHelper::strncpy(_prefs.mqtt_iata, "SEA", sizeof(_prefs.mqtt_iata));
|
||||
_prefs.mqtt_status_enabled = 1; // enabled
|
||||
_prefs.mqtt_packets_enabled = 1; // enabled
|
||||
@@ -755,10 +755,6 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
// Set MQTT origin to actual device name (not build-time ADVERT_NAME) - same as repeater
|
||||
StrHelper::strncpy(_prefs.mqtt_origin, _prefs.node_name, sizeof(_prefs.mqtt_origin));
|
||||
MESH_DEBUG_PRINTLN("MQTT origin set to device name: %s", _prefs.mqtt_origin);
|
||||
|
||||
if (_prefs.bridge_enabled) {
|
||||
// Defer construction to avoid static init crashes on ESP32 classic
|
||||
bridge = new MQTTBridge(&_prefs, _mgr, getRTCClock(), &self_id);
|
||||
|
||||
@@ -1660,7 +1660,9 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
#endif
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
} else if (memcmp(config, "mqtt.origin", 11) == 0) {
|
||||
sprintf(reply, "> %s", _prefs->mqtt_origin);
|
||||
char effective_origin[32];
|
||||
MQTTBridge::getEffectiveMqttOrigin(_prefs, effective_origin, sizeof(effective_origin));
|
||||
sprintf(reply, "> %s", effective_origin);
|
||||
} else if (memcmp(config, "mqtt.iata", 9) == 0) {
|
||||
sprintf(reply, "> %s", _prefs->mqtt_iata);
|
||||
} else if (memcmp(config, "mqtt.presets", 12) == 0 && (config[12] == '\0' || config[12] == ' ')) {
|
||||
|
||||
@@ -37,6 +37,32 @@ static void stripQuotes(char* str, size_t max_len) {
|
||||
}
|
||||
}
|
||||
|
||||
// Effective MQTT origin: empty mqtt_origin follows node_name; otherwise mqtt_origin override (quotes stripped).
|
||||
static void applyEffectiveOrigin(const NodePrefs* prefs, char* dest, size_t dest_size) {
|
||||
if (!prefs || !dest || dest_size == 0) return;
|
||||
if (prefs->mqtt_origin[0] == '\0') {
|
||||
strncpy(dest, prefs->node_name, dest_size - 1);
|
||||
} else {
|
||||
strncpy(dest, prefs->mqtt_origin, dest_size - 1);
|
||||
}
|
||||
dest[dest_size - 1] = '\0';
|
||||
stripQuotes(dest, dest_size);
|
||||
}
|
||||
|
||||
void MQTTBridge::refreshOriginFromPrefs() {
|
||||
if (!_prefs) return;
|
||||
applyEffectiveOrigin(_prefs, _origin, sizeof(_origin));
|
||||
}
|
||||
|
||||
void MQTTBridge::getEffectiveMqttOrigin(const NodePrefs* prefs, char* buf, size_t buf_size) {
|
||||
if (!buf || buf_size == 0) return;
|
||||
if (!prefs) {
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
}
|
||||
applyEffectiveOrigin(prefs, buf, buf_size);
|
||||
}
|
||||
|
||||
// Helper function to check if WiFi credentials are valid
|
||||
static bool isWiFiConfigValid(const NodePrefs* prefs) {
|
||||
// Check if WiFi SSID is configured (not empty)
|
||||
@@ -457,14 +483,11 @@ void MQTTBridge::begin() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update origin and IATA from preferences
|
||||
strncpy(_origin, _prefs->mqtt_origin, sizeof(_origin) - 1);
|
||||
_origin[sizeof(_origin) - 1] = '\0';
|
||||
refreshOriginFromPrefs();
|
||||
|
||||
strncpy(_iata, _prefs->mqtt_iata, sizeof(_iata) - 1);
|
||||
_iata[sizeof(_iata) - 1] = '\0';
|
||||
|
||||
// Strip quotes from origin and IATA if present
|
||||
stripQuotes(_origin, sizeof(_origin));
|
||||
stripQuotes(_iata, sizeof(_iata));
|
||||
|
||||
// Convert IATA code to uppercase (IATA codes are conventionally uppercase)
|
||||
@@ -1650,6 +1673,8 @@ void MQTTBridge::publishStatusToSlot(int index) {
|
||||
MQTTSlot& slot = _slots[index];
|
||||
if (!slot.client || !slot.connected) return;
|
||||
|
||||
refreshOriginFromPrefs();
|
||||
|
||||
// Build per-slot topic (handles IATA check for meshcore, token check for meshrank)
|
||||
char status_topic[128];
|
||||
if (!buildTopicForSlot(index, MSG_STATUS, status_topic, sizeof(status_topic))) {
|
||||
@@ -2344,6 +2369,8 @@ bool MQTTBridge::publishStatus() {
|
||||
return false;
|
||||
}
|
||||
|
||||
refreshOriginFromPrefs();
|
||||
|
||||
// Reuse pre-allocated buffer to avoid heap alloc/free churn under memory pressure.
|
||||
// _status_json_buffer and _last_raw_data are both Core 0-owned; no mutex needed.
|
||||
char fallback_status_buffer[STATUS_JSON_BUFFER_SIZE];
|
||||
@@ -2432,6 +2459,8 @@ bool MQTTBridge::publishPacket(mesh::Packet* packet, bool is_tx,
|
||||
float snr, float rssi) {
|
||||
if (!packet) return false;
|
||||
|
||||
refreshOriginFromPrefs();
|
||||
|
||||
// Memory pressure check: Skip publishes when there's not enough contiguous
|
||||
// heap for the publish itself (JSON buffer + esp-mqtt outbox frame + WiFi TX
|
||||
// path). Headroom only — NOT an mbedTLS preflight: persistent clients keep
|
||||
@@ -2537,6 +2566,8 @@ bool MQTTBridge::publishPacket(mesh::Packet* packet, bool is_tx,
|
||||
bool MQTTBridge::publishRaw(mesh::Packet* packet) {
|
||||
if (!packet) return false;
|
||||
|
||||
refreshOriginFromPrefs();
|
||||
|
||||
// Use pre-allocated buffer; fallback to single stack buffer if not available
|
||||
char json_buffer_stack[PUBLISH_JSON_BUFFER_SIZE];
|
||||
char* active_buffer;
|
||||
|
||||
@@ -333,6 +333,7 @@ private:
|
||||
void optimizeMqttClientConfig(PsychicMqttClient* client, bool needs_large_buffer = false);
|
||||
void getClientVersion(char* buffer, size_t buffer_size) const;
|
||||
void logMemoryStatus();
|
||||
void refreshOriginFromPrefs();
|
||||
|
||||
public:
|
||||
MQTTBridge(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCClock *rtc, mesh::LocalIdentity *identity);
|
||||
@@ -380,6 +381,8 @@ public:
|
||||
bool isReady() const;
|
||||
|
||||
static unsigned long getWifiConnectedAtMillis();
|
||||
/** Resolved origin for MQTT JSON: node_name when mqtt_origin is empty, else mqtt_origin (with quote stripping). */
|
||||
static void getEffectiveMqttOrigin(const NodePrefs* prefs, char* buf, size_t buf_size);
|
||||
static void formatMqttStatusReply(char* buf, size_t bufsize, const NodePrefs* prefs);
|
||||
/** True when WiFi is set and at least one MQTT slot can run (preset + custom host if needed). */
|
||||
static bool isConfigValid(const NodePrefs* prefs);
|
||||
|
||||
Reference in New Issue
Block a user