2021-04-03 14:54:10 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "configuration.h"
|
|
|
|
|
|
2021-04-03 22:27:06 +08:00
|
|
|
#include "concurrency/OSThread.h"
|
2021-04-04 09:20:37 +08:00
|
|
|
#include "mesh/Channels.h"
|
2023-01-18 08:56:47 -06:00
|
|
|
#include "mesh/generated/meshtastic/mqtt.pb.h"
|
2024-12-20 21:42:54 -06:00
|
|
|
#if !defined(ARCH_NRF52) || NRF52_USE_JSON
|
2024-07-25 20:50:42 -05:00
|
|
|
#include "serialization/JSON.h"
|
2024-12-20 21:42:54 -06:00
|
|
|
#endif
|
2022-10-26 00:07:02 +02:00
|
|
|
#if HAS_WIFI
|
2021-04-03 14:54:10 +08:00
|
|
|
#include <WiFiClient.h>
|
2023-04-04 09:14:47 -04:00
|
|
|
#if !defined(ARCH_PORTDUINO)
|
2024-09-12 22:42:10 +02:00
|
|
|
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3
|
2023-04-04 09:14:47 -04:00
|
|
|
#include <WiFiClientSecure.h>
|
|
|
|
|
#endif
|
2022-10-26 00:07:02 +02:00
|
|
|
#endif
|
2024-09-12 22:42:10 +02:00
|
|
|
#endif
|
2022-10-26 00:07:02 +02:00
|
|
|
#if HAS_ETHERNET
|
|
|
|
|
#include <EthernetClient.h>
|
2023-07-08 20:37:04 -05:00
|
|
|
#endif
|
|
|
|
|
|
2024-07-03 15:39:09 -07:00
|
|
|
#if HAS_NETWORKING
|
2023-07-08 20:37:04 -05:00
|
|
|
#include <PubSubClient.h>
|
2025-01-02 03:32:39 -08:00
|
|
|
#include <memory>
|
2022-10-26 00:07:02 +02:00
|
|
|
#endif
|
2021-04-03 14:54:10 +08:00
|
|
|
|
2023-01-09 23:26:47 +01:00
|
|
|
#define MAX_MQTT_QUEUE 16
|
2023-01-04 14:41:58 +01:00
|
|
|
|
2021-04-03 14:54:10 +08:00
|
|
|
/**
|
|
|
|
|
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
|
|
|
|
|
* the two components that use it: MQTTPlugin and MQTTSimInterface.
|
|
|
|
|
*/
|
2021-04-03 22:27:06 +08:00
|
|
|
class MQTT : private concurrency::OSThread
|
2021-04-03 14:54:10 +08:00
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
MQTT();
|
|
|
|
|
|
|
|
|
|
/**
|
2024-01-25 11:42:34 -03:00
|
|
|
* Publish a packet on the global MQTT server.
|
2024-10-10 22:11:58 +02:00
|
|
|
* @param mp_encrypted the encrypted packet to publish
|
2024-02-21 20:00:14 +01:00
|
|
|
* @param mp_decoded the decrypted packet to publish
|
2021-04-04 09:20:37 +08:00
|
|
|
* @param chIndex the index of the channel for this message
|
|
|
|
|
*
|
|
|
|
|
* Note: for messages we are forwarding on the mesh that we can't find the channel for (because we don't have the keys), we
|
2023-07-14 17:25:20 -04:00
|
|
|
* can not forward those messages to the cloud - because no way to find a global channel ID.
|
2021-04-03 14:54:10 +08:00
|
|
|
*/
|
2024-10-10 22:11:58 +02:00
|
|
|
void onSend(const meshtastic_MeshPacket &mp_encrypted, const meshtastic_MeshPacket &mp_decoded, ChannelIndex chIndex);
|
2021-04-03 14:54:10 +08:00
|
|
|
|
2023-07-08 20:37:04 -05:00
|
|
|
bool isConnectedDirectly();
|
|
|
|
|
|
|
|
|
|
bool publish(const char *topic, const char *payload, bool retained);
|
|
|
|
|
|
|
|
|
|
bool publish(const char *topic, const uint8_t *payload, size_t length, const bool retained);
|
|
|
|
|
|
|
|
|
|
void onClientProxyReceive(meshtastic_MqttClientProxyMessage msg);
|
2023-01-18 14:51:48 -06:00
|
|
|
|
2024-03-15 16:17:47 -05:00
|
|
|
bool isEnabled() { return this->enabled; };
|
|
|
|
|
|
|
|
|
|
void start() { setIntervalFromNow(0); };
|
|
|
|
|
|
2024-12-25 06:33:53 -08:00
|
|
|
bool isUsingDefaultServer() { return isConfiguredForDefaultServer; }
|
|
|
|
|
|
2021-04-03 22:27:06 +08:00
|
|
|
protected:
|
2024-12-20 12:59:23 -08:00
|
|
|
struct QueueEntry {
|
|
|
|
|
std::string topic;
|
|
|
|
|
std::basic_string<uint8_t> envBytes; // binary/pb_encode_to_bytes ServiceEnvelope
|
|
|
|
|
};
|
|
|
|
|
PointerQueue<QueueEntry> mqttQueue;
|
2022-12-16 20:28:28 +01:00
|
|
|
|
|
|
|
|
int reconnectCount = 0;
|
2024-12-25 06:33:53 -08:00
|
|
|
bool isConfiguredForDefaultServer = true;
|
2023-01-12 16:09:03 +01:00
|
|
|
|
2022-01-24 17:24:40 +00:00
|
|
|
virtual int32_t runOnce() override;
|
2021-04-03 22:27:06 +08:00
|
|
|
|
2025-01-02 03:32:39 -08:00
|
|
|
#ifndef PIO_UNIT_TESTING
|
2021-04-03 14:54:10 +08:00
|
|
|
private:
|
2025-01-02 03:32:39 -08:00
|
|
|
#endif
|
|
|
|
|
// supposedly the current version is busted:
|
|
|
|
|
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
|
|
|
|
|
#if HAS_WIFI
|
|
|
|
|
using MQTTClient = WiFiClient;
|
|
|
|
|
#if !defined(ARCH_PORTDUINO)
|
|
|
|
|
#if (defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3) || defined(RPI_PICO)
|
|
|
|
|
WiFiClientSecure wifiSecureClient;
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
#if HAS_ETHERNET
|
|
|
|
|
using MQTTClient = EthernetClient;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if HAS_NETWORKING
|
|
|
|
|
std::unique_ptr<MQTTClient> mqttClient;
|
|
|
|
|
PubSubClient pubSub;
|
|
|
|
|
explicit MQTT(std::unique_ptr<MQTTClient> mqttClient);
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-07-21 07:09:10 -05:00
|
|
|
std::string cryptTopic = "/2/e/"; // msh/2/e/CHANNELID/NODEID
|
|
|
|
|
std::string jsonTopic = "/2/json/"; // msh/2/json/CHANNELID/NODEID
|
|
|
|
|
std::string mapTopic = "/2/map/"; // For protobuf-encoded MapReport messages
|
2024-03-10 14:52:37 +01:00
|
|
|
|
|
|
|
|
// For map reporting (only applies when enabled)
|
2024-03-21 22:20:20 +01:00
|
|
|
const uint32_t default_map_position_precision = 14; // defaults to max. offset of ~1459m
|
|
|
|
|
const uint32_t default_map_publish_interval_secs = 60 * 15; // defaults to 15 minutes
|
2024-03-10 14:52:37 +01:00
|
|
|
uint32_t last_report_to_map = 0;
|
2024-03-21 22:20:20 +01:00
|
|
|
uint32_t map_position_precision = default_map_position_precision;
|
|
|
|
|
uint32_t map_publish_interval_msecs = default_map_publish_interval_secs * 1000;
|
2024-03-10 14:52:37 +01:00
|
|
|
|
|
|
|
|
/** return true if we have a channel that wants uplink/downlink or map reporting is enabled
|
2021-04-05 07:48:46 +08:00
|
|
|
*/
|
|
|
|
|
bool wantsLink() const;
|
|
|
|
|
|
2025-02-14 18:32:41 -08:00
|
|
|
/** Attempt to connect to server if necessary
|
|
|
|
|
*/
|
|
|
|
|
void reconnect();
|
|
|
|
|
|
2021-04-05 08:42:52 +08:00
|
|
|
/** Tell the server what subscriptions we want (based on channels.downlink_enabled)
|
|
|
|
|
*/
|
|
|
|
|
void sendSubscriptions();
|
|
|
|
|
|
2023-07-08 20:37:04 -05:00
|
|
|
/// Callback for direct mqtt subscription messages
|
2021-04-05 08:42:52 +08:00
|
|
|
static void mqttCallback(char *topic, byte *payload, unsigned int length);
|
|
|
|
|
|
|
|
|
|
/// Called when a new publish arrives from the MQTT server
|
2023-07-08 20:37:04 -05:00
|
|
|
void onReceive(char *topic, byte *payload, size_t length);
|
2021-08-02 17:42:44 -07:00
|
|
|
|
2023-07-08 20:37:04 -05:00
|
|
|
void publishQueuedMessages();
|
2022-03-12 15:08:57 +01:00
|
|
|
|
2024-07-21 07:09:10 -05:00
|
|
|
void publishNodeInfo();
|
|
|
|
|
|
2024-03-10 14:52:37 +01:00
|
|
|
// Check if we should report unencrypted information about our node for consumption by a map
|
|
|
|
|
void perhapsReportToMap();
|
|
|
|
|
|
2021-08-02 17:42:44 -07:00
|
|
|
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
|
2023-01-18 14:51:48 -06:00
|
|
|
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
|
2021-04-03 14:54:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void mqttInit();
|
|
|
|
|
|
2024-12-20 21:42:54 -06:00
|
|
|
extern MQTT *mqtt;
|