sforkowany z mirror/meshtastic-firmware
MQTT at least talks to server, works in native and esp32
rodzic
2acde3333c
commit
dcf64dfacd
|
@ -15,7 +15,15 @@
|
|||
<component name="ChangeListManager">
|
||||
<list default="true" id="58922733-b05b-4b90-9655-b9b18914977a" name="Default Changelist" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/docs/software/TODO.md" beforeDir="false" afterPath="$PROJECT_DIR$/docs/software/TODO.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/docs/software/mqtt.md" beforeDir="false" afterPath="$PROJECT_DIR$/docs/software/mqtt.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/platformio.ini" beforeDir="false" afterPath="$PROJECT_DIR$/platformio.ini" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/proto" beforeDir="false" afterPath="$PROJECT_DIR$/proto" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.cpp" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/mesh/generated/admin.pb.h" beforeDir="false" afterPath="$PROJECT_DIR$/src/mesh/generated/admin.pb.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/mesh/generated/apponly.pb.c" beforeDir="false" afterPath="$PROJECT_DIR$/src/mesh/generated/apponly.pb.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/mesh/generated/apponly.pb.h" beforeDir="false" afterPath="$PROJECT_DIR$/src/mesh/generated/apponly.pb.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/mesh/generated/radioconfig.pb.h" beforeDir="false" afterPath="$PROJECT_DIR$/src/mesh/generated/radioconfig.pb.h" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -47,6 +55,11 @@
|
|||
<property name="settings.editor.selected.configurable" value="CMakeSettings" />
|
||||
</component>
|
||||
<component name="RunManager" selected="GDB Remote Debug.gdbremote-localhost-2345">
|
||||
<configuration default="true" type="CLionExternalRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" PASS_PARENT_ENVS_2="true">
|
||||
<method v="2">
|
||||
<option name="CLION.EXTERNAL.BUILD" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="CLion_Remote" version="1" remoteCommand="tcp:localhost:2345" symbolFile="" sysroot="">
|
||||
<debugger kind="GDB" isBundled="true" />
|
||||
<method v="2" />
|
||||
|
@ -60,9 +73,9 @@
|
|||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="GradleAppRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" PASS_PARENT_ENVS_2="true">
|
||||
<configuration default="true" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" PASS_PARENT_ENVS_2="true">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.cpp.gradle.execution.GradleNativeBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="PlatformIO Debug" type="platformio" factoryName="PlatformIO Debug" REDIRECT_INPUT="false" ELEVATE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="meshtastic-esp32" TARGET_NAME="Debug" CONFIG_NAME="native" RUN_TARGET_PROJECT_NAME="meshtastic-esp32" RUN_TARGET_NAME="Debug">
|
||||
|
@ -98,6 +111,7 @@
|
|||
<workItem from="1617117632667" duration="307000" />
|
||||
<workItem from="1617160691713" duration="1016000" />
|
||||
<workItem from="1617279002260" duration="1626000" />
|
||||
<workItem from="1617425689081" duration="1896000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
@ -129,6 +143,11 @@
|
|||
<line>37</line>
|
||||
<option name="timeStamp" value="7" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
|
||||
<url>file://$USER_HOME$/.platformio/packages/framework-portduino/libraries/WiFi/src/WiFiClient.cpp</url>
|
||||
<line>49</line>
|
||||
<option name="timeStamp" value="9" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
<watches-manager>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
mosquitto_sub -h test.mosquitto.org -v -t mstat/\# -t mesh/\#
|
|
@ -0,0 +1 @@
|
|||
mosquitto_pub -h test.mosquitto.org -t mstat/FakeNode -m online -d
|
|
@ -53,11 +53,22 @@ You probably don't care about this section - skip to the next one.
|
|||
|
||||
## MQTT
|
||||
|
||||
* DONE have sim provide a fake wifi connection status saying connected
|
||||
* DONE don't start MQTT if we don't have wifi connected
|
||||
* mqtt.meshtastic.org should have VERY basic auth at launch (to prevent abuse)
|
||||
* use MQTT for simulator mesh network
|
||||
* 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
|
||||
* 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
|
||||
* eventually add a MQTTPacket on the ToRadio & FromRadio links
|
||||
* LATER: an android gateway would be useful
|
||||
|
||||
## Multichannel support
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
- [NODEID](#nodeid)
|
||||
- [USERID](#userid)
|
||||
- [CHANNELID](#channelid)
|
||||
- [PORTID](#portid)
|
||||
- [Gateway nodes](#gateway-nodes)
|
||||
- [MQTTSimInterface](#mqttsiminterface)
|
||||
- [Optional web services](#optional-web-services)
|
||||
- [Public MQTT broker service](#public-mqtt-broker-service)
|
||||
- [Riot.im messaging bridge](#riotim-messaging-bridge)
|
||||
|
@ -68,17 +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/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.
|
||||
|
||||
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 local 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.
|
||||
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.
|
||||
|
||||
FIXME, discuss how text message global mirroring could scale (or not)
|
||||
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, discuss possible attacks by griefers and how they can be prvented
|
||||
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.
|
||||
|
||||
#### Service Envelope
|
||||
|
||||
|
@ -88,7 +92,7 @@ ServiceEnvelope will include the message, and full information about arrival tim
|
|||
|
||||
#### NODEID
|
||||
|
||||
The unique ID for a node. A hex string that starts with a ! symbol.
|
||||
The unique ID for a node. A 8 byte (16 character) hex string that starts with a ! symbol.
|
||||
|
||||
#### USERID
|
||||
|
||||
|
@ -96,7 +100,15 @@ A user ID string. This string is either a user ID if known or a nodeid to simply
|
|||
|
||||
#### CHANNELID
|
||||
|
||||
FIXME, figure out how channelids work
|
||||
For the time being we simply use the local "channel name" - which is not quite good enough.
|
||||
|
||||
FIXME, figure out how channelids work in more detail. They should generally be globally unique, but this is not a requirement. If someone accidentially (or maliciously) sends data using a channel ID they do not 'own' they will still lacking a valid AES256 encryption, so it will be ignored by others.
|
||||
|
||||
idea to be pondered: When the user clicks to enable uplink/downlink check the name they entered and 'claim' it on the server?
|
||||
|
||||
#### PORTID
|
||||
|
||||
Portid is used to descriminated between different packet types which are sent over a channel. As used here it is an integer typically (but not necessarily) chosen from portnums.proto.
|
||||
|
||||
### Gateway nodes
|
||||
|
||||
|
@ -107,6 +119,17 @@ Gateway nodes (via code running in the phone) will contain two tables to whiteli
|
|||
Since multiple gateway nodes might be connected to a single mesh, it is possible that duplicate messages will be published on any particular topic. Therefore subscribers to these topics should
|
||||
deduplicate if needed by using the packet ID of each message.
|
||||
|
||||
|
||||
### MQTTSimInterface
|
||||
|
||||
This is a bit orthogonal from the main MQTT feature set, but a special simulated LoRa interface called MQTTSimInterface uses the
|
||||
MQTT messaging infrastructure to send "LoRa" packets between simulated nodes running on Linux. This allows us to test radio topologies and code without having to use real hardware.
|
||||
|
||||
This service uses the standard mesh/crypt/... topic, but it picks a special CHANNEL_ID. That CHANNEL_ID is typcially of the form "simmesh_xxx".
|
||||
|
||||
FIXME: Figure out how to secure the creation and use of well known CHANNEL_IDs.
|
||||
|
||||
|
||||
### Optional web services
|
||||
|
||||
#### Public MQTT broker service
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
default_envs = tbeam
|
||||
;default_envs = tbeam
|
||||
;default_envs = tbeam0.7
|
||||
;default_envs = heltec
|
||||
;default_envs = tlora-v1
|
||||
|
@ -18,7 +18,7 @@ default_envs = tbeam
|
|||
;default_envs = lora-relay-v1 # nrf board
|
||||
;default_envs = eink
|
||||
;default_envs = nrf52840dk-geeksville
|
||||
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||
default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||
|
||||
[common]
|
||||
; common is not currently used
|
||||
|
@ -76,6 +76,7 @@ lib_deps =
|
|||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||
SPI
|
||||
https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
PubSubClient
|
||||
|
||||
; Common settings for conventional (non Portduino) Ardino targets
|
||||
[arduino_base]
|
||||
|
@ -202,7 +203,7 @@ build_flags =
|
|||
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.7
|
||||
;-DCFG_DEBUG=3
|
||||
src_filter =
|
||||
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32>
|
||||
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32> -<mqtt/>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
monitor_port = /dev/ttyACM1
|
||||
|
|
2
proto
2
proto
|
@ -1 +1 @@
|
|||
Subproject commit 2aa14392145c38476bf61fea2c43629e1973af6d
|
||||
Subproject commit 9c16118e59e7318cd8cb92199511c19232939f5f
|
|
@ -32,8 +32,9 @@
|
|||
#include "nimble/BluetoothUtil.h"
|
||||
#endif
|
||||
|
||||
#ifdef PORTDUINO
|
||||
#if defined(HAS_WIFI) || defined(PORTDUINO)
|
||||
#include "mesh/wifi/WiFiServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
|
||||
#include "RF95Interface.h"
|
||||
|
@ -541,6 +542,10 @@ void setup()
|
|||
initApiServer();
|
||||
#endif
|
||||
|
||||
#if defined(PORTDUINO) || defined(HAS_WIFI)
|
||||
mqttInit();
|
||||
#endif
|
||||
|
||||
// Start airtime logger thread.
|
||||
airTime = new AirTime();
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
|
|||
#define AdminMessage_fields &AdminMessage_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define AdminMessage_size 360
|
||||
#define AdminMessage_size 397
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(ServiceEnvelope, ServiceEnvelope, 2)
|
||||
|
||||
|
||||
PB_BIND(ChannelSet, ChannelSet, AUTO)
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#ifndef PB_APPONLY_PB_H_INCLUDED
|
||||
#define PB_APPONLY_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "mesh.pb.h"
|
||||
#include "channel.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
@ -16,54 +15,31 @@ typedef struct _ChannelSet {
|
|||
pb_callback_t settings;
|
||||
} ChannelSet;
|
||||
|
||||
typedef struct _ServiceEnvelope {
|
||||
bool has_packet;
|
||||
MeshPacket packet;
|
||||
pb_callback_t channel_id;
|
||||
pb_callback_t gateway_id;
|
||||
} ServiceEnvelope;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ServiceEnvelope_init_default {false, MeshPacket_init_default, {{NULL}, NULL}, {{NULL}, NULL}}
|
||||
#define ChannelSet_init_default {{{NULL}, NULL}}
|
||||
#define ServiceEnvelope_init_zero {false, MeshPacket_init_zero, {{NULL}, NULL}, {{NULL}, NULL}}
|
||||
#define ChannelSet_init_zero {{{NULL}, NULL}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelSet_settings_tag 1
|
||||
#define ServiceEnvelope_packet_tag 1
|
||||
#define ServiceEnvelope_channel_id_tag 2
|
||||
#define ServiceEnvelope_gateway_id_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ServiceEnvelope_FIELDLIST(X, a) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, packet, 1) \
|
||||
X(a, CALLBACK, SINGULAR, STRING, channel_id, 2) \
|
||||
X(a, CALLBACK, SINGULAR, STRING, gateway_id, 3)
|
||||
#define ServiceEnvelope_CALLBACK pb_default_field_callback
|
||||
#define ServiceEnvelope_DEFAULT NULL
|
||||
#define ServiceEnvelope_packet_MSGTYPE MeshPacket
|
||||
|
||||
#define ChannelSet_FIELDLIST(X, a) \
|
||||
X(a, CALLBACK, REPEATED, MESSAGE, settings, 1)
|
||||
#define ChannelSet_CALLBACK pb_default_field_callback
|
||||
#define ChannelSet_DEFAULT NULL
|
||||
#define ChannelSet_settings_MSGTYPE ChannelSettings
|
||||
|
||||
extern const pb_msgdesc_t ServiceEnvelope_msg;
|
||||
extern const pb_msgdesc_t ChannelSet_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define ServiceEnvelope_fields &ServiceEnvelope_msg
|
||||
#define ChannelSet_fields &ChannelSet_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* ServiceEnvelope_size depends on runtime parameters */
|
||||
/* ChannelSet_size depends on runtime parameters */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.4 */
|
||||
|
||||
#include "mqtt.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(ServiceEnvelope, ServiceEnvelope, AUTO)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.4 */
|
||||
|
||||
#ifndef PB_MQTT_PB_H_INCLUDED
|
||||
#define PB_MQTT_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "mesh.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _ServiceEnvelope {
|
||||
struct _MeshPacket *packet;
|
||||
char *channel_id;
|
||||
char *gateway_id;
|
||||
} ServiceEnvelope;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ServiceEnvelope_init_default {NULL, NULL, NULL}
|
||||
#define ServiceEnvelope_init_zero {NULL, NULL, NULL}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ServiceEnvelope_packet_tag 1
|
||||
#define ServiceEnvelope_channel_id_tag 2
|
||||
#define ServiceEnvelope_gateway_id_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ServiceEnvelope_FIELDLIST(X, a) \
|
||||
X(a, POINTER, OPTIONAL, MESSAGE, packet, 1) \
|
||||
X(a, POINTER, SINGULAR, STRING, channel_id, 2) \
|
||||
X(a, POINTER, SINGULAR, STRING, gateway_id, 3)
|
||||
#define ServiceEnvelope_CALLBACK NULL
|
||||
#define ServiceEnvelope_DEFAULT NULL
|
||||
#define ServiceEnvelope_packet_MSGTYPE MeshPacket
|
||||
|
||||
extern const pb_msgdesc_t ServiceEnvelope_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define ServiceEnvelope_fields &ServiceEnvelope_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* ServiceEnvelope_size depends on runtime parameters */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -87,6 +87,8 @@ typedef struct _RadioConfig_UserPreferences {
|
|||
bool fixed_position;
|
||||
bool serial_disabled;
|
||||
float frequency_offset;
|
||||
char mqtt_server[32];
|
||||
bool mqtt_disabled;
|
||||
bool factory_reset;
|
||||
bool debug_log_enabled;
|
||||
pb_size_t ignore_incoming_count;
|
||||
|
@ -152,9 +154,9 @@ extern "C" {
|
|||
|
||||
/* Initializer values for message structs */
|
||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0}
|
||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0}
|
||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0}
|
||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
|
||||
|
@ -181,6 +183,8 @@ extern "C" {
|
|||
#define RadioConfig_UserPreferences_fixed_position_tag 39
|
||||
#define RadioConfig_UserPreferences_serial_disabled_tag 40
|
||||
#define RadioConfig_UserPreferences_frequency_offset_tag 41
|
||||
#define RadioConfig_UserPreferences_mqtt_server_tag 42
|
||||
#define RadioConfig_UserPreferences_mqtt_disabled_tag 43
|
||||
#define RadioConfig_UserPreferences_factory_reset_tag 100
|
||||
#define RadioConfig_UserPreferences_debug_log_enabled_tag 101
|
||||
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
|
||||
|
@ -243,6 +247,8 @@ X(a, STATIC, SINGULAR, BOOL, is_low_power, 38) \
|
|||
X(a, STATIC, SINGULAR, BOOL, fixed_position, 39) \
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_disabled, 40) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 41) \
|
||||
X(a, STATIC, SINGULAR, STRING, mqtt_server, 42) \
|
||||
X(a, STATIC, SINGULAR, BOOL, mqtt_disabled, 43) \
|
||||
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
|
||||
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 101) \
|
||||
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \
|
||||
|
@ -282,8 +288,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
|
|||
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define RadioConfig_size 357
|
||||
#define RadioConfig_UserPreferences_size 354
|
||||
#define RadioConfig_size 394
|
||||
#define RadioConfig_UserPreferences_size 391
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#include "MQTT.h"
|
||||
#include "NodeDB.h"
|
||||
#include <WiFi.h>
|
||||
#include <assert.h>
|
||||
|
||||
MQTT *mqtt;
|
||||
|
||||
String statusTopic = "mstat/";
|
||||
String packetTopic = "mesh/";
|
||||
|
||||
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");
|
||||
else
|
||||
new MQTT();
|
||||
}
|
||||
|
||||
MQTT::MQTT() : pubSub(mqttClient)
|
||||
{
|
||||
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);
|
||||
auto myStatus = (statusTopic + nodeId);
|
||||
// bool connected = pubSub.connect(nodeId.c_str(), "meshdev", "apes4cats", myStatus.c_str(), 1, true, "offline");
|
||||
bool connected = pubSub.connect(nodeId.c_str(), myStatus.c_str(), 1, true, "offline");
|
||||
if (connected) {
|
||||
DEBUG_MSG("MQTT connected\n");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTT::publish(const MeshPacket *mp, String channelId)
|
||||
{
|
||||
// DEBUG_MSG("publish %s = %s\n", suffix.c_str(), payload.c_str());
|
||||
|
||||
// pubSub.publish(getTopic(suffix), payload.c_str(), retained);
|
||||
}
|
||||
|
||||
const char *MQTT::getTopic(String suffix, const char *direction)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
// "mesh/crypt/CHANNELID/NODEID/PORTID"
|
||||
snprintf(buf, sizeof(buf), "mesh/%s/%s/%s", direction, nodeId.c_str(), suffix.c_str());
|
||||
return buf;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include <PubSubClient.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
class MQTT
|
||||
{
|
||||
/// Our globally unique node ID
|
||||
String nodeId = "fixmemode";
|
||||
|
||||
// supposedly the current version is busted:
|
||||
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
|
||||
// WiFiClientSecure wifiClient;
|
||||
WiFiClient mqttClient;
|
||||
PubSubClient pubSub;
|
||||
|
||||
public:
|
||||
MQTT();
|
||||
|
||||
/**
|
||||
* Publish a packet on the glboal MQTT server.
|
||||
* @param channelId must be a globally unique channel ID
|
||||
*/
|
||||
void publish(const MeshPacket *mp, String channelId);
|
||||
|
||||
private:
|
||||
const char *getTopic(String suffix, const char *direction = "dev");
|
||||
};
|
||||
|
||||
void mqttInit();
|
||||
|
||||
extern MQTT *mqtt;
|
Ładowanie…
Reference in New Issue