mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-23 17:13:38 +00:00
MQTT WIP
This commit is contained in:
parent
8890ca759d
commit
f3f09f0dcf
@ -1 +1 @@
|
||||
mosquitto_sub -h test.mosquitto.org -v -t mstat/\# -t mesh/\#
|
||||
mosquitto_sub -h test.mosquitto.org -v -t mesh/\#
|
||||
|
@ -1 +1 @@
|
||||
mosquitto_pub -h test.mosquitto.org -t mstat/FakeNode -m online -d
|
||||
mosquitto_pub -h test.mosquitto.org -t mesh/stat/FakeNode -m online -d
|
||||
|
@ -55,18 +55,22 @@ You probably don't care about this section - skip to the next one.
|
||||
|
||||
* DONE have sim provide a fake wifi connection status saying connected
|
||||
* DONE don't start MQTT if we don't have wifi connected
|
||||
* have plugin send uplinks from mesh
|
||||
* have plugin send downlinks to mesh
|
||||
* don't decrypt messages before uplinking them to MQTT (move out of plugin)
|
||||
* mqtt.meshtastic.org should have VERY basic auth at launch (to prevent abuse)
|
||||
* make a GlobalChat channel as an initial test (with a well known AES128 key), figure out how globally unique IDs work
|
||||
* Give place in android app for users to select which channel they are sending on (and which channels they are watching)
|
||||
* attempt reconnect to server if internet connectivity changes
|
||||
* don't bother contacting server if we don't have any uplink/downlink channels
|
||||
* test on ESP32
|
||||
* DONE test on ESP32
|
||||
* no need for python gateway to web initially: because both the simulator and ESP32 can talk wifi directly
|
||||
* if simmesh_name is set in preferences, create the MQTTSimInterface using that as the global channel_id
|
||||
* figure out how to use MQTT for simulator mesh network, use a special simmesh_name global channel_id? (because this would allow all nodes in simnet_xxx to subscribe only to those packets)
|
||||
* do initial development inside of portduino
|
||||
* do as much possible on the device side (so we can eventually just have ESP32 talk directly to server)
|
||||
* add mqtt_server to radio prefs
|
||||
* figure out legality of hosting public mqtt servers with chat msgs
|
||||
* DONE do initial development inside of portduino
|
||||
* DONE do as much possible on the device side (so we can eventually just have ESP32 talk directly to server)
|
||||
* DONE add mqtt_server to radio prefs
|
||||
* eventually add a MQTTPacket on the ToRadio & FromRadio links
|
||||
* LATER: an android gateway would be useful
|
||||
|
||||
|
@ -70,19 +70,19 @@ Any gateway-device will contact the MQTT broker.
|
||||
|
||||
### Topics
|
||||
|
||||
* The "/mesh/crypt/CHANNELID/NODEID/PORTID" [topic](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/) will be used for messages sent from/to a mesh.
|
||||
* The "/mesh/crypt/CHANNELID/NODEID" [topic](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/) will be used for (encrypted) messages sent from/to a mesh.
|
||||
|
||||
Gateway nodes will foward any MeshPacket from a local mesh channel with uplink_enabled. The packet (encapsulated in a ServiceEnvelope) will remain encrypted with the key for the specified channel.
|
||||
|
||||
For any channels in the gateway node with downlink_enabled, the gateway node will forward packets from MQTT to the local mesh. It will do this by subscribing to mesh/crypt/CHANNELID/# and forwarding relevant packets.
|
||||
|
||||
If the channelid 'well known'/public it could be decrypted by a web service (if the web service was provided with the associated channel key), in which case it will be decrypted by a web service and appear at "mesh/clear/CHANNELID/NODEID/PORTID". Note: This is not in the initial deliverable.
|
||||
* If the channelid 'well known'/public it could be decrypted by a web service (if the web service was provided with the associated channel key), in which case it will be decrypted by a web service and appear at "mesh/clear/CHANNELID/NODEID/PORTID". Note: This is not in the initial deliverable.
|
||||
|
||||
FIXME, consider how text message global mirroring could scale (or not)
|
||||
FIXME, possibly don't global mirror text messages - instead rely on matrix/riot?
|
||||
FIXME, consider possible attacks by griefers and how they can be prvented
|
||||
|
||||
* The "/mstat/NODEID" topic contains a simple string showing connection status of nodes. We rely on the MQTT feature for automatically publishing special failrue messages to this topic when the device disconnects.
|
||||
* The "/mesh/stat/NODEID" topic contains a simple string showing connection status of nodes. We rely on the MQTT feature for automatically publishing special failrue messages to this topic when the device disconnects.
|
||||
|
||||
#### Service Envelope
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
#include "MQTT.h"
|
||||
#include "MQTTPlugin.h"
|
||||
#include "NodeDB.h"
|
||||
#include "mesh/generated/mqtt.pb.h"
|
||||
#include <WiFi.h>
|
||||
#include <assert.h>
|
||||
|
||||
MQTT *mqtt;
|
||||
|
||||
String statusTopic = "mstat/";
|
||||
String packetTopic = "mesh/";
|
||||
String statusTopic = "mesh/stat/";
|
||||
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
{
|
||||
@ -23,8 +24,10 @@ void mqttInit()
|
||||
DEBUG_MSG("MQTT disabled...\n");
|
||||
else if (!WiFi.isConnected())
|
||||
DEBUG_MSG("WiFi is not connected, can not start MQTT\n");
|
||||
else
|
||||
else {
|
||||
new MQTT();
|
||||
new MQTTPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
MQTT::MQTT() : pubSub(mqttClient)
|
||||
@ -59,18 +62,35 @@ MQTT::MQTT() : pubSub(mqttClient)
|
||||
}
|
||||
}
|
||||
|
||||
void MQTT::publish(const MeshPacket *mp)
|
||||
void MQTT::publish(const MeshPacket &mp)
|
||||
{
|
||||
// DEBUG_MSG("publish %s = %s\n", suffix.c_str(), payload.c_str());
|
||||
// don't bother sending if not connected...
|
||||
if (pubSub.connected()) {
|
||||
// FIXME - check uplink enabled
|
||||
|
||||
// pubSub.publish(getTopic(suffix), payload.c_str(), retained);
|
||||
const char *channelId = "fixmechan";
|
||||
|
||||
ServiceEnvelope env = ServiceEnvelope_init_default;
|
||||
env.channel_id = (char *)channelId;
|
||||
env.gateway_id = owner.id;
|
||||
env.packet = (MeshPacket *)∓
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
const char *MQTT::getTopic(String suffix, const char *direction)
|
||||
const char *MQTT::getCryptTopic(const char *channelId)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
// "mesh/crypt/CHANNELID/NODEID/PORTID"
|
||||
snprintf(buf, sizeof(buf), "mesh/%s/%s/%s", direction, owner.id, suffix.c_str());
|
||||
snprintf(buf, sizeof(buf), "mesh/crypt/%s/%s", channelId, owner.id);
|
||||
return buf;
|
||||
}
|
@ -23,10 +23,10 @@ class MQTT
|
||||
/**
|
||||
* Publish a packet on the glboal MQTT server.
|
||||
*/
|
||||
void publish(const MeshPacket *mp);
|
||||
void publish(const MeshPacket &mp);
|
||||
|
||||
private:
|
||||
const char *getTopic(String suffix, const char *direction = "dev");
|
||||
const char *getCryptTopic(const char *channelId);
|
||||
};
|
||||
|
||||
void mqttInit();
|
||||
|
18
src/mqtt/MQTTPlugin.cpp
Normal file
18
src/mqtt/MQTTPlugin.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "MQTTPlugin.h"
|
||||
#include "MQTT.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
|
||||
MQTTPlugin::MQTTPlugin() : MeshPlugin("mqtt")
|
||||
{
|
||||
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
|
||||
}
|
||||
|
||||
bool MQTTPlugin::handleReceived(const MeshPacket &mp)
|
||||
{
|
||||
mqtt->publish(mp);
|
||||
return false; // never claim handled
|
||||
}
|
17
src/mqtt/MQTTPlugin.h
Normal file
17
src/mqtt/MQTTPlugin.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "MeshPlugin.h"
|
||||
|
||||
/**
|
||||
* NodeInfo plugin for sending/receiving NodeInfos into the mesh
|
||||
*/
|
||||
class MQTTPlugin : public MeshPlugin
|
||||
{
|
||||
public:
|
||||
MQTTPlugin();
|
||||
|
||||
protected:
|
||||
/** We sniff all packets */
|
||||
virtual bool handleReceived(const MeshPacket &mp);
|
||||
|
||||
virtual bool wantPacket(const MeshPacket *p) { return true; }
|
||||
};
|
Loading…
Reference in New Issue
Block a user