From 990d418dc8f1b9801ae0414bdf1622d774dc4c4b Mon Sep 17 00:00:00 2001 From: ghostop14 Date: Tue, 4 Apr 2023 09:14:47 -0400 Subject: [PATCH 1/7] Add MQTT TLS Support for WIFI-Enabled Devices (#2410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Testing TLS MQTT Support * Working TLS connections * Testing TLS MQTT Support * Working TLS connections * Added protobuf support for mqtt.tls_enabled * fix 'em up good * don't commit this stuff, jeeez * there i fixed it --------- Co-authored-by: Ben Meadors Co-authored-by: Thomas Göttgens --- src/mqtt/MQTT.cpp | 22 +++++++++++++++++++++- src/mqtt/MQTT.h | 9 +++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 56bdf300f..260a70c3f 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -192,6 +192,26 @@ void MQTT::reconnect() mqttPassword = moduleConfig.mqtt.password; } +#if HAS_WIFI && !defined(ARCH_PORTDUINO) + if (moduleConfig.mqtt.tls_enabled) { + // change default for encrypted to 8883 + try { + serverPort = 8883; + wifiSecureClient.setInsecure(); + + pubSub.setClient(wifiSecureClient); + LOG_INFO("Using TLS-encrypted session\n"); + } catch (const std::exception &e) { + LOG_ERROR("MQTT ERROR: %s\n", e.what()); + } + } else { + LOG_INFO("Using non-TLS-encrypted session\n"); + pubSub.setClient(mqttClient); + } +#else + pubSub.setClient(mqttClient); +#endif + String server = String(serverAddr); int delimIndex = server.indexOf(':'); if (delimIndex > 0) { @@ -528,4 +548,4 @@ std::string MQTT::downstreamPacketToJson(meshtastic_MeshPacket *mp) delete value; return jsonStr; -} +} \ No newline at end of file diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index 2b38868be..3065cc08e 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -8,6 +8,9 @@ #include #if HAS_WIFI #include +#if !defined(ARCH_PORTDUINO) +#include +#endif #endif #if HAS_ETHERNET #include @@ -23,9 +26,11 @@ 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 - // WiFiClientSecure wifiClient; #if HAS_WIFI WiFiClient mqttClient; +#if !defined(ARCH_PORTDUINO) + WiFiClientSecure wifiSecureClient; +#endif #endif #if HAS_ETHERNET EthernetClient mqttClient; @@ -87,4 +92,4 @@ class MQTT : private concurrency::OSThread void mqttInit(); -extern MQTT *mqtt; +extern MQTT *mqtt; \ No newline at end of file From de083602718d683d26718e46d0557d718974b14f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 4 Apr 2023 08:15:59 -0500 Subject: [PATCH 2/7] Protos tag for release --- protobufs | 2 +- src/mesh/generated/meshtastic/channel.pb.h | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/protobufs b/protobufs index 641d7c3a4..3e5ab67ff 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 641d7c3a460de9cc580bc2b8a0812e8b9d417b05 +Subproject commit 3e5ab67ff6659476df66bde6bbbae3c520460db9 diff --git a/src/mesh/generated/meshtastic/channel.pb.h b/src/mesh/generated/meshtastic/channel.pb.h index 83ef7b5fc..535962ae6 100644 --- a/src/mesh/generated/meshtastic/channel.pb.h +++ b/src/mesh/generated/meshtastic/channel.pb.h @@ -31,11 +31,9 @@ typedef enum _meshtastic_Channel_Role { /* Struct definitions */ typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t; -/* Full settings (center freq, spread factor, pre-shared secret key etc...) - needed to configure a radio for speaking on a particular channel This - information can be encoded as a QRcode/url so that other users can configure +/* This information can be encoded as a QRcode/url so that other users can configure their radio to join the same channel. - A note about how channel names are shown to users: channelname-Xy + A note about how channel names are shown to users: channelname-X poundsymbol is a prefix used to indicate this is a channel name (idea from @professr). Where X is a letter from A-Z (base 26) representing a hash of the PSK for this channel - so that if the user changes anything about the channel (which does @@ -45,8 +43,6 @@ typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t; The PSK is hashed into this letter by "0x41 + [xor all bytes of the psk ] modulo 26" This also allows the option of someday if people have the PSK off (zero), the users COULD type in a channel name and be able to talk. - Y is a lower case letter from a-z that represents the channel 'speed' settings - (for some future definition of speed) FIXME: Add description of multi-channel support and how primary vs secondary channels are used. FIXME: explain how apps use channels for security. explain how remote settings and remote gpio are managed as an example */ @@ -60,7 +56,7 @@ typedef struct _meshtastic_ChannelSettings { because they are listed in this source code. Those bytes are mapped using the following scheme: `0` = No crypto - `1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf} + `1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01} `2` through 10 = The default channel key, except with 1 through 9 added to the last byte. Shown to user as simple1 through 10 */ meshtastic_ChannelSettings_psk_t psk; From 242f880764a6217cecf4c48fe8bd7d87132077d5 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 4 Apr 2023 09:42:12 -0500 Subject: [PATCH 3/7] Dear trunk, please don't be petty --- .github/workflows/main_matrix.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index ccc7c4ca8..a6fb39b29 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -42,6 +42,7 @@ jobs: uses: ./.github/actions/setup-base - name: Trunk Check + if: ${{ github.event_name != 'workflow_dispatch' }} uses: trunk-io/trunk-action@v1 - name: Check ${{ matrix.board }} From aa96ea02c6ad7724fe894b0d14e2be1bf1c4c0c7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 14:13:26 -0500 Subject: [PATCH 4/7] [create-pull-request] automated change (#2411) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index b26a5f4c0..909888740 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 1 -build = 7 +build = 8 From 82ab38d3e6cb2bfeef280ee5529645c5ffcab159 Mon Sep 17 00:00:00 2001 From: Manuel Verch Date: Tue, 4 Apr 2023 22:13:13 +0200 Subject: [PATCH 5/7] Revert changes on wakeup --- src/PowerFSM.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 2139d9d8f..e6ebdcc93 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -93,18 +93,23 @@ static void lsIdle() powerFSM.trigger(EVENT_SERIAL_CONNECTED); break; - case ESP_SLEEP_WAKEUP_GPIO: - // GPIO of BUTTON_PIN (if available) triggered the wakeup - powerFSM.trigger(EVENT_PRESS); - break; - default: - // We woke for some other reason (device interrupt) + // We woke for some other reason (button press, device interrupt) // uint64_t status = esp_sleep_get_ext1_wakeup_status(); LOG_INFO("wakeCause2 %d\n", wakeCause2); - // Let the NB state handle the IRQ (and that state will handle stuff like IRQs etc) - // we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code - powerFSM.trigger(EVENT_WAKE_TIMER); + +#ifdef BUTTON_PIN + bool pressed = !digitalRead(BUTTON_PIN); +#else + bool pressed = false; +#endif + if (pressed) { // If we woke because of press, instead generate a PRESS event. + powerFSM.trigger(EVENT_PRESS); + } else { + // Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc) + // we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code + powerFSM.trigger(EVENT_WAKE_TIMER); + } break; } } else { @@ -348,4 +353,4 @@ void PowerFSM_setup() #endif powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state -} +} \ No newline at end of file From d4e42898b1e3a5ca129ea4dfe46a2df2161aa3aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 07:14:40 -0500 Subject: [PATCH 6/7] [create-pull-request] automated change (#2417) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- src/mesh/generated/meshtastic/module_config.pb.h | 15 ++++++++++----- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/protobufs b/protobufs index 3e5ab67ff..5f00ad569 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 3e5ab67ff6659476df66bde6bbbae3c520460db9 +Subproject commit 5f00ad5691ae7d8a03fd92437b81e9a424e3483f diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index 6788bd426..56beee95e 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -188,7 +188,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg; /* Maximum encoded size of messages (where known) */ #define meshtastic_ChannelFile_size 638 #define meshtastic_DeviceState_size 22040 -#define meshtastic_OEMStore_size 3024 +#define meshtastic_OEMStore_size 3041 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 23865f47d..0cfcb2491 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -157,7 +157,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define meshtastic_LocalConfig_size 456 -#define meshtastic_LocalModuleConfig_size 422 +#define meshtastic_LocalModuleConfig_size 439 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index f94114e15..e59d33dd0 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -98,6 +98,9 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig { bool json_enabled; /* If true, we attempt to establish a secure connection using TLS */ bool tls_enabled; + /* The root topic to use for MQTT messages. Default is "msh". + This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs */ + char root[16]; } meshtastic_ModuleConfig_MQTTConfig; /* RemoteHardwareModule Config */ @@ -325,7 +328,7 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}} -#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0} +#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, ""} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0} #define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN} @@ -335,7 +338,7 @@ extern "C" { #define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0} #define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0} #define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}} -#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0} +#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, ""} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0} #define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN} @@ -353,6 +356,7 @@ extern "C" { #define meshtastic_ModuleConfig_MQTTConfig_encryption_enabled_tag 5 #define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6 #define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7 +#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8 #define meshtastic_ModuleConfig_RemoteHardwareConfig_enabled_tag 1 #define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1 #define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2 @@ -448,7 +452,8 @@ X(a, STATIC, SINGULAR, STRING, username, 3) \ X(a, STATIC, SINGULAR, STRING, password, 4) \ X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) \ X(a, STATIC, SINGULAR, BOOL, json_enabled, 6) \ -X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) +X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) \ +X(a, STATIC, SINGULAR, STRING, root, 8) #define meshtastic_ModuleConfig_MQTTConfig_CALLBACK NULL #define meshtastic_ModuleConfig_MQTTConfig_DEFAULT NULL @@ -566,13 +571,13 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg; #define meshtastic_ModuleConfig_AudioConfig_size 19 #define meshtastic_ModuleConfig_CannedMessageConfig_size 49 #define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40 -#define meshtastic_ModuleConfig_MQTTConfig_size 203 +#define meshtastic_ModuleConfig_MQTTConfig_size 220 #define meshtastic_ModuleConfig_RangeTestConfig_size 10 #define meshtastic_ModuleConfig_RemoteHardwareConfig_size 2 #define meshtastic_ModuleConfig_SerialConfig_size 26 #define meshtastic_ModuleConfig_StoreForwardConfig_size 22 #define meshtastic_ModuleConfig_TelemetryConfig_size 26 -#define meshtastic_ModuleConfig_size 206 +#define meshtastic_ModuleConfig_size 223 #ifdef __cplusplus } /* extern "C" */ From 43cff7adc9497a551390e1913f247312470ea3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 7 Apr 2023 14:52:23 +0200 Subject: [PATCH 7/7] Implement #2380 (#2418) --- bin/regen-protos.bat | 6 +----- src/mqtt/MQTT.cpp | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/bin/regen-protos.bat b/bin/regen-protos.bat index aa2a2684f..1422f7914 100644 --- a/bin/regen-protos.bat +++ b/bin/regen-protos.bat @@ -1,5 +1 @@ -cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto - -@REM cd ../src/mesh/generated/meshtastic -@REM sed -i 's/#include "meshtastic/#include "./g' * -@REM sed -i 's/meshtastic_//g' * +cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --experimental_allow_proto3_optional --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 260a70c3f..c0758019a 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -19,9 +19,9 @@ const int reconnectMax = 5; MQTT *mqtt; -std::string statusTopic = "msh/2/stat/"; -std::string cryptTopic = "msh/2/c/"; // msh/2/c/CHANNELID/NODEID -std::string jsonTopic = "msh/2/json/"; // msh/2/json/CHANNELID/NODEID +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 static MemoryDynamic staticMqttPool; @@ -164,6 +164,16 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient), mqttQueue(MAX_ assert(!mqtt); mqtt = this; + if (moduleConfig.mqtt.root) { + statusTopic = moduleConfig.mqtt.root + statusTopic; + cryptTopic = moduleConfig.mqtt.root + cryptTopic; + jsonTopic = moduleConfig.mqtt.root + jsonTopic; + } else { + statusTopic = "msh" + statusTopic; + cryptTopic = "msh" + cryptTopic; + jsonTopic = "msh" + jsonTopic; + } + pubSub.setCallback(mqttCallback); // preflightSleepObserver.observe(&preflightSleep);