firmware/src/mqtt/MQTT.h

114 lines
3.3 KiB
C
Raw Normal View History

#pragma once
#include "configuration.h"
2021-04-03 14:27:06 +00:00
#include "concurrency/OSThread.h"
#include "mesh/Channels.h"
2023-01-18 14:56:47 +00:00
#include "mesh/generated/meshtastic/mqtt.pb.h"
#include "mqtt/JSON.h"
2022-10-25 22:07:02 +00:00
#if HAS_WIFI
#include <WiFiClient.h>
#define HAS_NETWORKING 1
#if !defined(ARCH_PORTDUINO)
#include <WiFiClientSecure.h>
#endif
2022-10-25 22:07:02 +00:00
#endif
#if HAS_ETHERNET
#include <EthernetClient.h>
#define HAS_NETWORKING 1
#endif
#ifdef HAS_NETWORKING
#include <PubSubClient.h>
2022-10-25 22:07:02 +00:00
#endif
#define MAX_MQTT_QUEUE 16
/**
* 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 14:27:06 +00:00
class MQTT : private concurrency::OSThread
{
// supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
2022-10-25 22:07:02 +00:00
#if HAS_WIFI
WiFiClient mqttClient;
#if !defined(ARCH_PORTDUINO)
WiFiClientSecure wifiSecureClient;
#endif
2022-10-25 22:07:02 +00:00
#endif
#if HAS_ETHERNET
EthernetClient mqttClient;
#endif
public:
#ifdef HAS_NETWORKING
2023-03-06 11:47:29 +00:00
PubSubClient pubSub;
#endif
MQTT();
/**
* Publish a packet on the global MQTT server.
* @param mp the encrypted packet to publish
* @param mp_decoded the decrypted packet to publish
* @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
* can not forward those messages to the cloud - because no way to find a global channel ID.
*/
void onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &mp_decoded, ChannelIndex chIndex);
/** Attempt to connect to server if necessary
*/
void reconnect();
2022-10-26 09:09:59 +00: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);
2021-04-03 14:27:06 +00:00
protected:
PointerQueue<meshtastic_ServiceEnvelope> mqttQueue;
int reconnectCount = 0;
2023-01-12 15:09:03 +00:00
2022-01-24 17:24:40 +00:00
virtual int32_t runOnce() override;
2021-04-03 14:27:06 +00:00
private:
2023-04-13 20:20:49 +00:00
std::string statusTopic = "/2/stat/";
std::string cryptTopic = "/2/c/"; // msh/2/c/CHANNELID/NODEID
std::string jsonTopic = "/2/json/"; // msh/2/json/CHANNELID/NODEID
/** return true if we have a channel that wants uplink/downlink
*/
bool wantsLink() const;
2021-04-05 00:42:52 +00:00
/** Tell the server what subscriptions we want (based on channels.downlink_enabled)
*/
void sendSubscriptions();
/// Callback for direct mqtt subscription messages
2021-04-05 00:42:52 +00:00
static void mqttCallback(char *topic, byte *payload, unsigned int length);
/// Called when a new publish arrives from the MQTT server
void onReceive(char *topic, byte *payload, size_t length);
/// Called when a new publish arrives from the MQTT server
std::string meshPacketToJson(meshtastic_MeshPacket *mp);
void publishStatus();
void publishQueuedMessages();
// returns true if this is a valid JSON envelope which we accept on downlink
bool isValidJsonEnvelope(JSONObject &json);
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
};
void mqttInit();
extern MQTT *mqtt;