2021-04-03 06:54:10 +00:00
|
|
|
#include "MQTT.h"
|
|
|
|
#include "NodeDB.h"
|
2021-04-03 14:27:06 +00:00
|
|
|
#include "main.h"
|
2021-04-04 01:20:37 +00:00
|
|
|
#include "mesh/Channels.h"
|
2021-04-03 08:06:40 +00:00
|
|
|
#include "mesh/generated/mqtt.pb.h"
|
2021-04-03 06:54:10 +00:00
|
|
|
#include <WiFi.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
MQTT *mqtt;
|
|
|
|
|
2021-04-03 08:06:40 +00:00
|
|
|
String statusTopic = "mesh/stat/";
|
2021-04-03 06:54:10 +00:00
|
|
|
|
|
|
|
void mqttCallback(char *topic, byte *payload, unsigned int length)
|
|
|
|
{
|
|
|
|
DEBUG_MSG("MQTT topic %s\n", topic);
|
|
|
|
|
|
|
|
// After parsing ServiceEnvelope
|
|
|
|
// FIXME - make sure to free both strings and the MeshPacket
|
|
|
|
}
|
|
|
|
|
|
|
|
void mqttInit()
|
|
|
|
{
|
|
|
|
// FIXME, for now we require the user to specifically set a MQTT server (till tested)
|
|
|
|
if (radioConfig.preferences.mqtt_disabled || !*radioConfig.preferences.mqtt_server)
|
|
|
|
DEBUG_MSG("MQTT disabled...\n");
|
|
|
|
else if (!WiFi.isConnected())
|
|
|
|
DEBUG_MSG("WiFi is not connected, can not start MQTT\n");
|
2021-04-03 08:06:40 +00:00
|
|
|
else {
|
2021-04-03 06:54:10 +00:00
|
|
|
new MQTT();
|
2021-04-03 08:06:40 +00:00
|
|
|
}
|
2021-04-03 06:54:10 +00:00
|
|
|
}
|
|
|
|
|
2021-04-03 14:27:06 +00:00
|
|
|
MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient)
|
2021-04-03 06:54:10 +00:00
|
|
|
{
|
|
|
|
assert(!mqtt);
|
|
|
|
mqtt = this;
|
|
|
|
|
|
|
|
// pubSub.setServer("devsrv.ezdevice.net", 1883); or 192.168.10.188
|
|
|
|
const char *serverAddr = "test.mosquitto.org"; // "mqtt.meshtastic.org"; // default hostname
|
|
|
|
|
|
|
|
if (*radioConfig.preferences.mqtt_server)
|
|
|
|
serverAddr = radioConfig.preferences.mqtt_server; // Override the default
|
|
|
|
|
|
|
|
pubSub.setServer(serverAddr, 1883);
|
|
|
|
pubSub.setCallback(mqttCallback);
|
|
|
|
|
|
|
|
DEBUG_MSG("Connecting to MQTT server: %s\n", serverAddr);
|
2021-04-03 07:04:03 +00:00
|
|
|
auto myStatus = (statusTopic + owner.id);
|
2021-04-03 06:54:10 +00:00
|
|
|
// bool connected = pubSub.connect(nodeId.c_str(), "meshdev", "apes4cats", myStatus.c_str(), 1, true, "offline");
|
2021-04-03 07:04:03 +00:00
|
|
|
bool connected = pubSub.connect(owner.id, myStatus.c_str(), 1, true, "offline");
|
2021-04-03 06:54:10 +00:00
|
|
|
if (connected) {
|
|
|
|
DEBUG_MSG("MQTT connected\n");
|
2021-04-03 14:27:06 +00:00
|
|
|
enabled = true; // Start running background process again
|
|
|
|
runASAP = true;
|
2021-04-03 06:54:10 +00:00
|
|
|
|
|
|
|
static char subsStr[64]; /* We keep this static because the mqtt lib
|
|
|
|
might not be copying it */
|
|
|
|
// snprintf(subsStr, sizeof(subsStr), "/ezd/todev/%s/#", clientId);
|
|
|
|
// mqtt.subscribe(subsStr, 1); // we use qos 1 because we don't want to miss messages
|
|
|
|
|
|
|
|
/// FIXME, include more information in the status text
|
|
|
|
bool ok = pubSub.publish(myStatus.c_str(), "online", true);
|
|
|
|
DEBUG_MSG("published %d\n", ok);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-03 14:27:06 +00:00
|
|
|
int32_t MQTT::runOnce()
|
|
|
|
{
|
|
|
|
// If connected poll rapidly, otherwise sleep forever
|
|
|
|
if (!pubSub.loop())
|
|
|
|
enabled = false;
|
|
|
|
|
|
|
|
return 20;
|
|
|
|
}
|
|
|
|
|
2021-04-04 01:20:37 +00:00
|
|
|
void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex)
|
2021-04-03 06:54:10 +00:00
|
|
|
{
|
2021-04-03 08:06:40 +00:00
|
|
|
// don't bother sending if not connected...
|
|
|
|
if (pubSub.connected()) {
|
|
|
|
// FIXME - check uplink enabled
|
|
|
|
|
2021-04-04 01:20:37 +00:00
|
|
|
const char *channelId = channels.getName(chIndex); // FIXME, for now we just use the human name for the channel
|
2021-04-03 08:06:40 +00:00
|
|
|
|
|
|
|
ServiceEnvelope env = ServiceEnvelope_init_default;
|
|
|
|
env.channel_id = (char *)channelId;
|
|
|
|
env.gateway_id = owner.id;
|
|
|
|
env.packet = (MeshPacket *)∓
|
2021-04-03 06:54:10 +00:00
|
|
|
|
2021-04-03 08:06:40 +00:00
|
|
|
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
|
|
|
static uint8_t bytes[MeshPacket_size + 64];
|
|
|
|
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), ServiceEnvelope_fields, &env);
|
|
|
|
|
|
|
|
const char *topic = getCryptTopic(channelId);
|
|
|
|
DEBUG_MSG("publish %s, %u bytes\n", topic, numBytes);
|
|
|
|
|
|
|
|
pubSub.publish(topic, bytes, numBytes, false);
|
|
|
|
}
|
2021-04-03 06:54:10 +00:00
|
|
|
}
|
|
|
|
|
2021-04-03 08:06:40 +00:00
|
|
|
const char *MQTT::getCryptTopic(const char *channelId)
|
2021-04-03 06:54:10 +00:00
|
|
|
{
|
|
|
|
static char buf[128];
|
|
|
|
|
|
|
|
// "mesh/crypt/CHANNELID/NODEID/PORTID"
|
2021-04-03 08:06:40 +00:00
|
|
|
snprintf(buf, sizeof(buf), "mesh/crypt/%s/%s", channelId, owner.id);
|
2021-04-03 06:54:10 +00:00
|
|
|
return buf;
|
|
|
|
}
|