# Conflicts: # MQTT_INTERNALS.md # build.sh # docs/cli_commands.md # examples/simple_repeater/MyMesh.cpp # examples/simple_repeater/MyMesh.h # examples/simple_repeater/UITask.cpp # examples/simple_room_server/MyMesh.cpp # examples/simple_room_server/MyMesh.h # examples/simple_room_server/UITask.cpp # examples/simple_sensor/SensorMesh.cpp # platformio.ini # scripts/generate_webconfig_html.py # src/MeshCore.h # src/helpers/CommonCLI.cpp # src/helpers/CommonCLI.h # src/helpers/CommonCLI_Observer.cpp # src/helpers/ESP32Board.h # src/helpers/MQTTMessageBuilder.cpp # src/helpers/MQTTPresets.h # src/helpers/NRF52Board.cpp # src/helpers/NRF52Board.h # src/helpers/bridges/MQTTBridge.cpp # src/helpers/bridges/MQTTBridge.h # src/helpers/esp32/WebConfigServer.cpp # src/helpers/esp32/WebConfigServer.h # src/helpers/radiolib/RadioLibWrappers.cpp # src/helpers/radiolib/RadioLibWrappers.h # variants/lilygo_tbeam_SX1262/platformio.ini # variants/lilygo_tbeam_SX1276/platformio.ini # variants/lilygo_tlora_v2_1/platformio.ini # webui/index.html
87 lines
3.1 KiB
C
87 lines
3.1 KiB
C
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "MQTTObserverValidation.h"
|
|
#include "MQTTTopicTemplate.h"
|
|
|
|
// Pure MQTT publication-topic policy shared by MQTTBridge and the native tests.
|
|
// Keep these values aligned with MQTTBridge::MQTTMessageType; the bridge passes
|
|
// its enum value as an int so this helper stays independent of ESP/Arduino types.
|
|
enum MQTTPublicationType {
|
|
MQTT_PUBLICATION_STATUS = 0,
|
|
MQTT_PUBLICATION_PACKETS = 1,
|
|
MQTT_PUBLICATION_RAW = 2,
|
|
MQTT_PUBLICATION_NEIGHBORS = 3,
|
|
};
|
|
|
|
enum MQTTTopicRouteStyle {
|
|
MQTT_ROUTE_MESHCORE,
|
|
MQTT_ROUTE_MESHRANK,
|
|
MQTT_ROUTE_CUSTOM,
|
|
};
|
|
|
|
static inline bool mqttTopicSlotIndexValid(int index, size_t slot_count) {
|
|
return index >= 0 && (size_t)index < slot_count;
|
|
}
|
|
|
|
static inline const char* mqttPublicationTypeName(int type) {
|
|
switch (type) {
|
|
case MQTT_PUBLICATION_STATUS: return "status";
|
|
case MQTT_PUBLICATION_PACKETS: return "packets";
|
|
case MQTT_PUBLICATION_RAW: return "raw";
|
|
case MQTT_PUBLICATION_NEIGHBORS: return "neighbors";
|
|
default: return NULL;
|
|
}
|
|
}
|
|
static inline bool mqttWriteTopic(char* buf, size_t buf_size, const char* format,
|
|
const char* first, const char* second,
|
|
const char* third) {
|
|
if (!buf || buf_size == 0 || !format || !first || !second || !third) return false;
|
|
buf[0] = '\0';
|
|
int written = snprintf(buf, buf_size, format, first, second, third);
|
|
return written > 0 && (size_t)written < buf_size;
|
|
}
|
|
|
|
// Build the complete topic for one publication. MeshRank is deliberately
|
|
// packets-only; status, raw, and neighbors are unsupported by the current
|
|
// broker contract (the type != PACKETS guard below rejects them all).
|
|
// MeshCore routes require a configured IATA and device id. Custom templates may
|
|
// omit either placeholder, so their individual values are allowed to be empty.
|
|
static inline bool mqttBuildPublicationTopic(MQTTTopicRouteStyle style, int type,
|
|
const char* custom_template,
|
|
const char* iata, const char* device,
|
|
const char* token,
|
|
char* buf, size_t buf_size) {
|
|
if (!buf || buf_size == 0) return false;
|
|
buf[0] = '\0';
|
|
|
|
const char* type_name = mqttPublicationTypeName(type);
|
|
if (!type_name) return false;
|
|
|
|
switch (style) {
|
|
case MQTT_ROUTE_MESHCORE:
|
|
if (!mqttIataValid(iata) || strcmp(iata, "XXX") == 0 || !device || device[0] == '\0') {
|
|
return false;
|
|
}
|
|
return mqttWriteTopic(buf, buf_size, "meshcore/%s/%s/%s", iata, device, type_name);
|
|
|
|
case MQTT_ROUTE_MESHRANK:
|
|
if (type != MQTT_PUBLICATION_PACKETS || !token || token[0] == '\0' ||
|
|
!device || device[0] == '\0') {
|
|
return false;
|
|
}
|
|
return mqttWriteTopic(buf, buf_size, "meshrank/uplink/%s/%s/%s",
|
|
token, device, type_name);
|
|
|
|
case MQTT_ROUTE_CUSTOM:
|
|
return mqttSubstituteTopic(custom_template, iata, device, token, type_name,
|
|
buf, buf_size);
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|