From 42b24d45105b9c352e7ee3b5018eee21e6a6f0e8 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 3 Jan 2023 14:32:28 -0600 Subject: [PATCH 01/32] Yank mqtt service envelope queue --- src/mqtt/MQTT.cpp | 55 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 49 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index f4004139a..f72271324 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -21,10 +21,6 @@ String statusTopic = "msh/2/stat/"; String cryptTopic = "msh/2/c/"; // msh/2/c/CHANNELID/NODEID String jsonTopic = "msh/2/json/"; // msh/2/json/CHANNELID/NODEID -static MemoryDynamic staticMqttPool; - -Allocator &mqttPool = staticMqttPool; - void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length) { mqtt->onPublish(topic, payload, length); @@ -126,7 +122,7 @@ void mqttInit() new MQTT(); } -MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient), mqttQueue(MAX_MQTT_QUEUE) +MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient) { if(moduleConfig.mqtt.enabled) { @@ -253,36 +249,9 @@ int32_t MQTT::runOnce() if (!pubSub.loop()) { if (wantConnection) { reconnect(); - - // If we succeeded, empty the queue one by one and start reading rapidly, else try again in 30 seconds (TCP connections are EXPENSIVE so try rarely) - if (pubSub.connected()) { - if (!mqttQueue.isEmpty()) { - // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets - ServiceEnvelope *env = mqttQueue.dequeuePtr(0); - static uint8_t bytes[MeshPacket_size + 64]; - size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &ServiceEnvelope_msg, env); - - String topic = cryptTopic + env->channel_id + "/" + owner.id; - LOG_INFO("publish %s, %u bytes from queue\n", topic.c_str(), numBytes); - - - pubSub.publish(topic.c_str(), bytes, numBytes, false); - - if (moduleConfig.mqtt.json_enabled) { - // handle json topic - auto jsonString = this->downstreamPacketToJson(env->packet); - if (jsonString.length() != 0) { - String topicJson = jsonTopic + env->channel_id + "/" + owner.id; - LOG_INFO("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(), jsonString.c_str()); - pubSub.publish(topicJson.c_str(), jsonString.c_str(), false); - } - } - mqttPool.release(env); - } - return 20; - } else { - return 30000; - } + + // If we succeeded, start reading rapidly, else try again in 30 seconds (TCP connections are EXPENSIVE so try rarely) + return pubSub.connected() ? 20 : 30000; } else return 5000; // If we don't want connection now, check again in 5 secs } else { @@ -304,7 +273,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex) if (ch.settings.uplink_enabled) { const char *channelId = channels.getGlobalId(chIndex); // FIXME, for now we just use the human name for the channel - ServiceEnvelope *env = mqttPool.allocZeroed(); + ServiceEnvelope env = ServiceEnvelope_init_default; env->channel_id = (char *)channelId; env->gateway_id = owner.id; env->packet = (MeshPacket *)∓ @@ -314,7 +283,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex) // 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_msg, env); + size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &ServiceEnvelope_msg, &env); String topic = cryptTopic + channelId + "/" + owner.id; LOG_DEBUG("publish %s, %u bytes\n", topic.c_str(), numBytes); @@ -330,19 +299,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex) pubSub.publish(topicJson.c_str(), jsonString.c_str(), false); } } - } else { - LOG_INFO("MQTT not connected, queueing packet\n"); - if (mqttQueue.numFree() == 0) { - LOG_WARN("NOTE: MQTT queue is full, discarding oldest\n"); - ServiceEnvelope *d = mqttQueue.dequeuePtr(0); - if (d) - mqttPool.release(d); - } - // make a copy of serviceEnvelope and queue it - ServiceEnvelope *copied = mqttPool.allocCopy(*env); - assert(mqttQueue.enqueue(copied, 0)); } - mqttPool.release(env); } } From 5867038abf196cfd99580ff7f19fcf6b886e047e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 3 Jan 2023 22:09:35 +0100 Subject: [PATCH 02/32] trybuildfix mqtt system --- src/mqtt/MQTT.cpp | 6 +++--- src/mqtt/MQTT.h | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index f72271324..49ad586dd 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -274,9 +274,9 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex) const char *channelId = channels.getGlobalId(chIndex); // FIXME, for now we just use the human name for the channel ServiceEnvelope env = ServiceEnvelope_init_default; - env->channel_id = (char *)channelId; - env->gateway_id = owner.id; - env->packet = (MeshPacket *)∓ + env.channel_id = (char *)channelId; + env.gateway_id = owner.id; + env.packet = (MeshPacket *)∓ // don't bother sending if not connected... if (pubSub.connected()) { diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index ddbacbcc4..9c813711a 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -13,8 +13,6 @@ #include #endif -#define MAX_MQTT_QUEUE 32 - /** * 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. @@ -55,10 +53,6 @@ class MQTT : private concurrency::OSThread bool connected(); protected: - PointerQueue mqttQueue; - - int reconnectCount = 0; - virtual int32_t runOnce() override; private: From cad5c9b70c7d242eb897bc624e2eade9497261cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 3 Jan 2023 22:17:04 +0100 Subject: [PATCH 03/32] removed too much --- src/mqtt/MQTT.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index 9c813711a..33fbbb8eb 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -53,6 +53,9 @@ class MQTT : private concurrency::OSThread bool connected(); protected: + + int reconnectCount = 0; + virtual int32_t runOnce() override; private: From cab5fcf5ae3c2e9650f8747994ad0efa3df3e72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 3 Jan 2023 22:35:24 +0100 Subject: [PATCH 04/32] no excessive heap debugging on release builds --- arch/esp32/esp32.ini | 1 - arch/esp32/esp32s2.ini | 1 - arch/esp32/esp32s3.ini | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 0011cc39f..70654e8ec 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -26,7 +26,6 @@ build_flags = -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING - -DDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini index ca4f576d6..cd47c4ca1 100644 --- a/arch/esp32/esp32s2.ini +++ b/arch/esp32/esp32s2.ini @@ -27,7 +27,6 @@ build_flags = -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DHAS_BLUETOOTH=0 - -DDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini index b276ceff9..ce64fdbe2 100644 --- a/arch/esp32/esp32s3.ini +++ b/arch/esp32/esp32s3.ini @@ -26,7 +26,6 @@ build_flags = -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING - -DDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} From 6d989a29dd8975f862ea840c2b0a244fb1feebfb Mon Sep 17 00:00:00 2001 From: thebentern Date: Tue, 3 Jan 2023 22:34:34 +0000 Subject: [PATCH 05/32] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 5c253336e..816f7c2ac 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 0 -build = 11 +build = 12 From 78b6916b1b020810f7f131a2c6878f2a759ead3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 4 Jan 2023 14:45:28 +0100 Subject: [PATCH 06/32] External Notification Hotfix --- src/modules/ExternalNotificationModule.cpp | 79 ++++++++++------------ src/modules/ExternalNotificationModule.h | 14 ++++ 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index b24b0bbc0..e0014f98c 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -42,26 +42,22 @@ int32_t ExternalNotificationModule::runOnce() if (!moduleConfig.external_notification.enabled) { return INT32_MAX; // we don't need this thread here... } else { -#ifndef ARCH_PORTDUINO if ((nagCycleCutoff < millis()) && !rtttl::isPlaying()) { -#else - if (nagCycleCutoff < millis()) { -#endif + // let the song finish if we reach timeout nagCycleCutoff = UINT32_MAX; LOG_INFO("Turning off external notification: "); for (int i = 0; i < 2; i++) { - if (getExternal(i)) { - setExternalOff(i); - externalTurnedOn[i] = 0; - LOG_INFO("%d ", i); - } + setExternalOff(i); + externalTurnedOn[i] = 0; + LOG_INFO("%d ", i); } LOG_INFO("\n"); + isNagging = false; return INT32_MAX; // save cycles till we're needed again } // If the output is turned on, turn it back off after the given period of time. - if (nagCycleCutoff != UINT32_MAX) { + if (isNagging) { if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms : EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) { @@ -80,16 +76,14 @@ int32_t ExternalNotificationModule::runOnce() } // now let the PWM buzzer play -#ifndef ARCH_PORTDUINO if (moduleConfig.external_notification.use_pwm) { if (rtttl::isPlaying()) { rtttl::play(); - } else if (nagCycleCutoff >= millis()) { + } else if (isNagging && (nagCycleCutoff >= millis())) { // start the song again if we have time left rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); } } -#endif return 25; } } @@ -140,10 +134,9 @@ bool ExternalNotificationModule::getExternal(uint8_t index) } void ExternalNotificationModule::stopNow() { -#ifndef ARCH_PORTDUINO rtttl::stop(); -#endif nagCycleCutoff = 1; // small value + isNagging = false; setIntervalFromNow(0); } @@ -230,6 +223,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) if (moduleConfig.external_notification.alert_bell) { if (containsBell) { LOG_INFO("externalNotificationModule - Notification Bell\n"); + isNagging = true; setExternalOn(0); if (moduleConfig.external_notification.nag_timeout) { nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; @@ -242,6 +236,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) if (moduleConfig.external_notification.alert_bell_vibra) { if (containsBell) { LOG_INFO("externalNotificationModule - Notification Bell (Vibra)\n"); + isNagging = true; setExternalOn(1); if (moduleConfig.external_notification.nag_timeout) { nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; @@ -254,12 +249,11 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) if (moduleConfig.external_notification.alert_bell_buzzer) { if (containsBell) { LOG_INFO("externalNotificationModule - Notification Bell (Buzzer)\n"); + isNagging = true; if (!moduleConfig.external_notification.use_pwm) { setExternalOn(2); } else { -#ifndef ARCH_PORTDUINO rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); -#endif } if (moduleConfig.external_notification.nag_timeout) { nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; @@ -271,6 +265,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) if (moduleConfig.external_notification.alert_message) { LOG_INFO("externalNotificationModule - Notification Module\n"); + isNagging = true; setExternalOn(0); if (moduleConfig.external_notification.nag_timeout) { nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; @@ -279,33 +274,33 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) } } - if (!moduleConfig.external_notification.use_pwm) { - if (moduleConfig.external_notification.alert_message_vibra) { - LOG_INFO("externalNotificationModule - Notification Module (Vibra)\n"); - setExternalOn(1); - if (moduleConfig.external_notification.nag_timeout) { - nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; - } else { - nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; - } - } - - if (moduleConfig.external_notification.alert_message_buzzer) { - LOG_INFO("externalNotificationModule - Notification Module (Buzzer)\n"); - if (!moduleConfig.external_notification.use_pwm) { - setExternalOn(2); - } else { -#ifndef ARCH_PORTDUINO - rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); -#endif - } - if (moduleConfig.external_notification.nag_timeout) { - nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; - } else { - nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; - } + + if (moduleConfig.external_notification.alert_message_vibra) { + LOG_INFO("externalNotificationModule - Notification Module (Vibra)\n"); + isNagging = true; + setExternalOn(1); + if (moduleConfig.external_notification.nag_timeout) { + nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; + } else { + nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; } } + + if (moduleConfig.external_notification.alert_message_buzzer) { + LOG_INFO("externalNotificationModule - Notification Module (Buzzer)\n"); + isNagging = true; + if (!moduleConfig.external_notification.use_pwm) { + setExternalOn(2); + } else { + rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); + } + if (moduleConfig.external_notification.nag_timeout) { + nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; + } else { + nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; + } + } + setIntervalFromNow(0); // run once so we know if we should do something } diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h index 50af360c1..097ae96b3 100644 --- a/src/modules/ExternalNotificationModule.h +++ b/src/modules/ExternalNotificationModule.h @@ -5,6 +5,18 @@ #include "configuration.h" #ifndef ARCH_PORTDUINO #include +#else +// Noop class for portduino. +class rtttl +{ + public: + explicit rtttl() {} + static bool isPlaying() { return false; } + static void play() {} + static void begin(byte a, const char * b) {}; + static void stop() {} + static bool done() { return true; } +}; #endif #include #include @@ -39,6 +51,8 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency: virtual int32_t runOnce() override; + bool isNagging = false; + virtual AdminMessageHandleResult handleAdminMessageForModule(const MeshPacket &mp, AdminMessage *request, AdminMessage *response) override; }; From e5d9f1f946306c3d955c62f263f40d78677fa558 Mon Sep 17 00:00:00 2001 From: thebentern Date: Wed, 4 Jan 2023 16:13:43 +0000 Subject: [PATCH 07/32] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 816f7c2ac..40e7926a9 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 0 -build = 12 +build = 13 From bd51cbd721cd987265a501976d9134926aca96b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Jan 2023 09:15:54 +0000 Subject: [PATCH 08/32] Chance calculation for Nice TX. Still same value but dynamically based on duty cycle. --- src/airtime.cpp | 2 +- src/airtime.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/airtime.cpp b/src/airtime.cpp index ae3b30811..94ef6d5b2 100644 --- a/src/airtime.cpp +++ b/src/airtime.cpp @@ -132,7 +132,7 @@ bool AirTime::isTxAllowedChannelUtil(bool polite) bool AirTime::isTxAllowedAirUtil() { if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) { - if (utilizationTXPercent() < polite_tx_util_percent) { + if (utilizationTXPercent() < myRegion->dutyCycle * polite_tx_util_percent / 100) { return true; } else { LOG_WARN("Tx air utilization is >%d percent. Skipping this opportunity to send.\n", polite_tx_util_percent); diff --git a/src/airtime.h b/src/airtime.h index 2d1f1e2d9..5ba6f676a 100644 --- a/src/airtime.h +++ b/src/airtime.h @@ -70,7 +70,7 @@ class AirTime : private concurrency::OSThread uint32_t secSinceBoot = 0; uint8_t max_channel_util_percent = 40; uint8_t polite_channel_util_percent = 25; - uint8_t polite_tx_util_percent = 5; + uint8_t polite_tx_util_percent = 50; // half of Duty Cycle allowance struct airtimeStruct { uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted From bd2b766a369f5782da87f8c63fc134fa1cf9ca01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Jan 2023 14:03:06 +0100 Subject: [PATCH 09/32] Rename to make function clearer --- src/airtime.cpp | 4 ++-- src/airtime.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/airtime.cpp b/src/airtime.cpp index 94ef6d5b2..0c3fe81fc 100644 --- a/src/airtime.cpp +++ b/src/airtime.cpp @@ -132,10 +132,10 @@ bool AirTime::isTxAllowedChannelUtil(bool polite) bool AirTime::isTxAllowedAirUtil() { if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) { - if (utilizationTXPercent() < myRegion->dutyCycle * polite_tx_util_percent / 100) { + if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) { return true; } else { - LOG_WARN("Tx air utilization is >%d percent. Skipping this opportunity to send.\n", polite_tx_util_percent); + LOG_WARN("Tx air utilization is >%d percent. Skipping this opportunity to send.\n", myRegion->dutyCycle * polite_duty_cycle_percent / 100); return false; } } diff --git a/src/airtime.h b/src/airtime.h index 5ba6f676a..e454b35ad 100644 --- a/src/airtime.h +++ b/src/airtime.h @@ -70,7 +70,7 @@ class AirTime : private concurrency::OSThread uint32_t secSinceBoot = 0; uint8_t max_channel_util_percent = 40; uint8_t polite_channel_util_percent = 25; - uint8_t polite_tx_util_percent = 50; // half of Duty Cycle allowance + uint8_t polite_duty_cycle_percent = 50; // half of Duty Cycle allowance is ok for metadata struct airtimeStruct { uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted From 867e55b9e74776b6bcd2675ef7d433c50c8602da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Jan 2023 16:09:03 +0100 Subject: [PATCH 10/32] sync mqtt with develop --- src/mqtt/MQTT.cpp | 30 +++++++++++++++++++++++------- src/mqtt/MQTT.h | 3 ++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 3a5d3b364..cc091bcff 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -21,6 +21,10 @@ String statusTopic = "msh/2/stat/"; String cryptTopic = "msh/2/c/"; // msh/2/c/CHANNELID/NODEID String jsonTopic = "msh/2/json/"; // msh/2/json/CHANNELID/NODEID +static MemoryDynamic staticMqttPool; + +Allocator &mqttPool = staticMqttPool; + void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length) { mqtt->onPublish(topic, payload, length); @@ -142,7 +146,7 @@ void mqttInit() new MQTT(); } -MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient) +MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient), mqttQueue(MAX_MQTT_QUEUE) { if(moduleConfig.mqtt.enabled) { @@ -297,7 +301,7 @@ int32_t MQTT::runOnce() } mqttPool.release(env); } - return 20; + return 200; } else { return 30000; } @@ -322,17 +326,17 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex) if (ch.settings.uplink_enabled) { const char *channelId = channels.getGlobalId(chIndex); // FIXME, for now we just use the human name for the channel - ServiceEnvelope env = ServiceEnvelope_init_default; - env.channel_id = (char *)channelId; - env.gateway_id = owner.id; - env.packet = (MeshPacket *)∓ + ServiceEnvelope *env = mqttPool.allocZeroed(); + env->channel_id = (char *)channelId; + env->gateway_id = owner.id; + env->packet = (MeshPacket *)∓ // don't bother sending if not connected... if (pubSub.connected()) { // 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_msg, &env); + size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &ServiceEnvelope_msg, env); String topic = cryptTopic + channelId + "/" + owner.id; LOG_DEBUG("publish %s, %u bytes\n", topic.c_str(), numBytes); @@ -348,7 +352,19 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex) pubSub.publish(topicJson.c_str(), jsonString.c_str(), false); } } + } else { + LOG_INFO("MQTT not connected, queueing packet\n"); + if (mqttQueue.numFree() == 0) { + LOG_WARN("NOTE: MQTT queue is full, discarding oldest\n"); + ServiceEnvelope *d = mqttQueue.dequeuePtr(0); + if (d) + mqttPool.release(d); + } + // make a copy of serviceEnvelope and queue it + ServiceEnvelope *copied = mqttPool.allocCopy(*env); + assert(mqttQueue.enqueue(copied, 0)); } + mqttPool.release(env); } } diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index e3fb2b626..16ce4c37a 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -55,9 +55,10 @@ class MQTT : private concurrency::OSThread bool connected(); protected: + PointerQueue mqttQueue; int reconnectCount = 0; - + virtual int32_t runOnce() override; private: From c89ca50cc466b7c65f597f1b2cc7482bdb7a2be5 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 12 Jan 2023 09:33:55 -0600 Subject: [PATCH 11/32] Remove DEBUG_HEAP flag from esp32 pio config on release --- .github/workflows/build_esp32.yml | 7 +++++++ arch/esp32/esp32.ini | 1 + arch/esp32/esp32s2.ini | 1 + arch/esp32/esp32s3.ini | 1 + 4 files changed, 10 insertions(+) diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 6d5dd9863..74b71db50 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -29,6 +29,13 @@ jobs: tar -xf build.tar -C data/static rm build.tar + - name: Remove debug flags for release + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini + - name: Build ESP32 run: bin/build-esp32.sh ${{ inputs.board }} diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 70654e8ec..a84288d05 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -26,6 +26,7 @@ build_flags = -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + -DDDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini index cd47c4ca1..f1f2ceea5 100644 --- a/arch/esp32/esp32s2.ini +++ b/arch/esp32/esp32s2.ini @@ -27,6 +27,7 @@ build_flags = -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DHAS_BLUETOOTH=0 + -DDDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini index ce64fdbe2..fac12b4c1 100644 --- a/arch/esp32/esp32s3.ini +++ b/arch/esp32/esp32s3.ini @@ -26,6 +26,7 @@ build_flags = -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + -DDDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} From 7936c7c8ae97fef6de0435006a701d798598c249 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 12 Jan 2023 10:07:17 -0600 Subject: [PATCH 12/32] Remove the D! --- arch/esp32/esp32.ini | 2 +- arch/esp32/esp32s2.ini | 2 +- arch/esp32/esp32s3.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index a84288d05..0011cc39f 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -26,7 +26,7 @@ build_flags = -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING - -DDDEBUG_HEAP + -DDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini index f1f2ceea5..beba16f3e 100644 --- a/arch/esp32/esp32s2.ini +++ b/arch/esp32/esp32s2.ini @@ -27,7 +27,7 @@ build_flags = -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DHAS_BLUETOOTH=0 - -DDDEBUG_HEAP + -DDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini index fac12b4c1..023d1ca84 100644 --- a/arch/esp32/esp32s3.ini +++ b/arch/esp32/esp32s3.ini @@ -26,7 +26,7 @@ build_flags = -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING - -DDDEBUG_HEAP + -DDEBUG_HEAP lib_deps = ${arduino_base.lib_deps} From 8db3f317ab56841c6c8b57d1d22811f96833d801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Jan 2023 19:08:41 +0100 Subject: [PATCH 13/32] re-merge fixes by @lesykm --- src/modules/SerialModule.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index 5d02e3ba8..e4ec57a4b 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -61,7 +61,8 @@ SerialModuleRadio *serialModuleRadio; SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} -char serialStringChar[Constants_DATA_PAYLOAD_LEN]; +char serialBytes[Constants_DATA_PAYLOAD_LEN]; +size_t serialPayloadSize; SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") { @@ -203,15 +204,9 @@ int32_t SerialModule::runOnce() Serial2.printf("%s", outbuf); } } else { - String serialString; - while (Serial2.available()) { - serialString = Serial2.readString(); - serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN); - + serialPayloadSize = Serial2.readBytes(serialBytes, Constants_DATA_PAYLOAD_LEN); serialModuleRadio->sendPayload(); - - LOG_INFO("Received: %s\n", serialStringChar); } } } @@ -231,14 +226,18 @@ MeshPacket *SerialModuleRadio::allocReply() void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies) { + Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL; MeshPacket *p = allocReply(); p->to = dest; + if (ch != NULL) { + p->channel = ch->index; + } p->decoded.want_response = wantReplies; p->want_ack = ACK; - p->decoded.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, serialStringChar, p->decoded.payload.size); + p->decoded.payload.size = serialPayloadSize; // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, serialBytes, p->decoded.payload.size); service.sendToMesh(p); } From c33569f833c6947ea809023342b4a72369a72b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Jan 2023 19:08:41 +0100 Subject: [PATCH 14/32] re-merge fixes by @lesykm --- src/modules/SerialModule.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index 5d02e3ba8..e4ec57a4b 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -61,7 +61,8 @@ SerialModuleRadio *serialModuleRadio; SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} -char serialStringChar[Constants_DATA_PAYLOAD_LEN]; +char serialBytes[Constants_DATA_PAYLOAD_LEN]; +size_t serialPayloadSize; SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") { @@ -203,15 +204,9 @@ int32_t SerialModule::runOnce() Serial2.printf("%s", outbuf); } } else { - String serialString; - while (Serial2.available()) { - serialString = Serial2.readString(); - serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN); - + serialPayloadSize = Serial2.readBytes(serialBytes, Constants_DATA_PAYLOAD_LEN); serialModuleRadio->sendPayload(); - - LOG_INFO("Received: %s\n", serialStringChar); } } } @@ -231,14 +226,18 @@ MeshPacket *SerialModuleRadio::allocReply() void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies) { + Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL; MeshPacket *p = allocReply(); p->to = dest; + if (ch != NULL) { + p->channel = ch->index; + } p->decoded.want_response = wantReplies; p->want_ack = ACK; - p->decoded.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, serialStringChar, p->decoded.payload.size); + p->decoded.payload.size = serialPayloadSize; // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, serialBytes, p->decoded.payload.size); service.sendToMesh(p); } From 7e27729daed7887e8bb3547e998ed33cae1cbe0f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 15 Jan 2023 08:24:20 -0600 Subject: [PATCH 15/32] Remove HAS_GPS for WSLv3 --- variants/heltec_wsl_v3/variant.h | 1 - 1 file changed, 1 deletion(-) diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h index 60f611248..b8f911066 100644 --- a/variants/heltec_wsl_v3/variant.h +++ b/variants/heltec_wsl_v3/variant.h @@ -1,7 +1,6 @@ #define LED_PIN LED #define HAS_SCREEN 0 -#define HAS_GPS 0 #define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost #define BUTTON_PIN 0 From 85dd606423c17d858d0f2bdc002a008491b54f30 Mon Sep 17 00:00:00 2001 From: garthvh Date: Sun, 15 Jan 2023 16:52:29 +0000 Subject: [PATCH 16/32] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 40e7926a9..7cf773466 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 0 -build = 13 +build = 14 From aca1241a7f7483b5459c9ca1712aa3ebcbed0378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 16 Jan 2023 10:55:40 +0100 Subject: [PATCH 17/32] Having a first stab at flawfinder errors --- src/FSCommon.cpp | 12 +++++------ src/gps/GPS.cpp | 2 +- src/gps/NMEAWPL.cpp | 8 ++++---- src/graphics/Screen.cpp | 24 +++++++++++----------- src/main.cpp | 6 +++--- src/mesh/Channels.cpp | 2 +- src/mesh/NodeDB.cpp | 6 +++--- src/mesh/http/WiFiAPClient.cpp | 2 +- src/modules/AdminModule.cpp | 8 ++++---- src/modules/CannedMessageModule.cpp | 8 ++++---- src/modules/ExternalNotificationModule.cpp | 4 ++-- 11 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index 2541aa8b5..e072e54fb 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -80,7 +80,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false) listDir(file.path(), levels -1, del); if(del) { LOG_DEBUG("Removing %s\n", file.path()); - strcpy(buffer, file.path()); + strncpy(buffer, file.path(), sizeof(buffer)); file.close(); FSCom.rmdir(buffer); } else { @@ -90,7 +90,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false) listDir(file.name(), levels -1, del); if(del) { LOG_DEBUG("Removing %s\n", file.name()); - strcpy(buffer, file.name()); + strncpy(buffer, file.name(), sizeof(buffer)); file.close(); FSCom.rmdir(buffer); } else { @@ -105,7 +105,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false) #ifdef ARCH_ESP32 if(del) { LOG_DEBUG("Deleting %s\n", file.path()); - strcpy(buffer, file.path()); + strncpy(buffer, file.path(), sizeof(buffer)); file.close(); FSCom.remove(buffer); } else { @@ -115,7 +115,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false) #elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)) if(del) { LOG_DEBUG("Deleting %s\n", file.name()); - strcpy(buffer, file.name()); + strncpy(buffer, file.name(), sizeof(buffer)); file.close(); FSCom.remove(buffer); } else { @@ -132,7 +132,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false) #ifdef ARCH_ESP32 if(del) { LOG_DEBUG("Removing %s\n", root.path()); - strcpy(buffer, root.path()); + strncpy(buffer, root.path(), sizeof(buffer)); root.close(); FSCom.rmdir(buffer); } else { @@ -141,7 +141,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false) #elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)) if(del) { LOG_DEBUG("Removing %s\n", root.name()); - strcpy(buffer, root.name()); + strncpy(buffer, root.name(), sizeof(buffer)); root.close(); FSCom.rmdir(buffer); } else { diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index e5791223d..1814261a4 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -623,7 +623,7 @@ GnssModel_t GPS::probe() //tips: extensionNo field is 0 on some 6M GNSS modules for (int i = 0; i < info.extensionNo; ++i) { if (!strncmp(info.extension[i], "OD=", 3)) { - strcpy((char *)buffer, &(info.extension[i][3])); + strncpy((char *)buffer, &(info.extension[i][3]), sizeof(buffer)); LOG_DEBUG("GetModel:%s\n",(char *)buffer); } } diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 70812e87b..842fc0760 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -19,7 +19,7 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name) { GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude); - uint32_t len = sprintf(buf, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", + uint32_t len = snprintf(buf, sizeof(buf), "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), @@ -31,7 +31,7 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name) for (uint32_t i = 1; i < len; i++) { chk ^= buf[i]; } - len += sprintf(buf + len, "*%02X\r\n", chk); + len += snprintf(buf + len, sizeof(buf) + len, "*%02X\r\n", chk); return len; } @@ -62,7 +62,7 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name) uint32_t printGGA(char *buf, const Position &pos) { GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude); - uint32_t len = sprintf(buf, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", + uint32_t len = snprintf(buf, sizeof(buf), "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000, pos.time % 1000, geoCoord.getDMSLatDeg(), @@ -85,6 +85,6 @@ uint32_t printGGA(char *buf, const Position &pos) for (uint32_t i = 1; i < len; i++) { chk ^= buf[i]; } - len += sprintf(buf + len, "*%02X\r\n", chk); + len += snprintf(buf + len, sizeof(buf) + len, "*%02X\r\n", chk); return len; } \ No newline at end of file diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 53ca75a51..034ba3307 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -470,7 +470,7 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus) { char usersString[20]; - sprintf(usersString, "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal()); + snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal()); #if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) display->drawFastImage(x, y + 3, 8, 8, imgUser); #else @@ -521,7 +521,7 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus display->drawFastImage(x + 24, y, 8, 8, imgSatellite); // Draw the number of satellites - sprintf(satsString, "%u", gps->getNumSatellites()); + snprintf(satsString, sizeof(satsString), "%u", gps->getNumSatellites()); display->drawString(x + 34, y - 2, satsString); if(config.display.heading_bold) display->drawString(x + 35, y - 2, satsString); @@ -582,21 +582,21 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) { char coordinateLine[22]; if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees - sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7); + snprintf(coordinateLine, sizeof(coordinateLine), "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7); } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator - sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(), + snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(), geoCoord.getUTMEasting(), geoCoord.getUTMNorthing()); } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System - sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(), + snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing()); } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code geoCoord.getOLCCode(coordinateLine); } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region - sprintf(coordinateLine, "%s", "Out of Boundary"); + snprintf(coordinateLine, sizeof(coordinateLine), "%s", "Out of Boundary"); else - sprintf(coordinateLine, "%1c%1c %05u %05u", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(), + snprintf(coordinateLine, sizeof(coordinateLine), "%1c%1c %05u %05u", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(), geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing()); } @@ -614,9 +614,9 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const } else { char latLine[22]; char lonLine[22]; - sprintf(latLine, "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(), + snprintf(latLine, sizeof(latLine), "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(), geoCoord.getDMSLatCP()); - sprintf(lonLine, "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(), + snprintf(lonLine, sizeof(lonLine), "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(), geoCoord.getDMSLonCP()); display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(latLine))) / 2, y - FONT_HEIGHT_SMALL * 1, latLine); display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(lonLine))) / 2, y, lonLine); @@ -831,7 +831,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ } static char distStr[20]; - strcpy(distStr, "? km"); // might not have location data + strncpy(distStr, "? km", sizeof(distStr)); // might not have location data NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum()); const char *fields[] = {username, distStr, signalStr, lastStr, NULL}; int16_t compassX = 0, compassY = 0; @@ -1010,7 +1010,7 @@ void Screen::setup() // Get our hardware ID uint8_t dmac[6]; getMacAddr(dmac); - sprintf(ourId, "%02x%02x", dmac[4], dmac[5]); + snprintf(ourId, sizeof(ourId), "%02x%02x", dmac[4], dmac[5]); // Turn on the display. handleSetOn(true); @@ -1738,7 +1738,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat // Display Channel Utilization char chUtil[13]; - sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent()); + snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent()); display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil); if (config.position.gps_enabled) { // Line 3 diff --git a/src/main.cpp b/src/main.cpp index 2631e68df..76a6a6b6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -110,12 +110,12 @@ const char *getDeviceName() // Meshtastic_ab3c or Shortname_abcd static char name[20]; - sprintf(name, "%02x%02x", dmac[4], dmac[5]); + snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]); // if the shortname exists and is NOT the new default of ab3c, use it for BLE name. if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) { - sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]); + snprintf(name, sizeof(name), "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]); } else { - sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]); + snprintf(name, sizeof(name), "Meshtastic_%02x%02x", dmac[4], dmac[5]); } return name; } diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index 337fa66e0..f9b3eb9b8 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -84,7 +84,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex) uint8_t defaultpskIndex = 1; channelSettings.psk.bytes[0] = defaultpskIndex; channelSettings.psk.size = 1; - strcpy(channelSettings.name, ""); + strncpy(channelSettings.name, "", sizeof(channelSettings.name)); ch.has_settings = true; ch.role = Channel_Role_PRIMARY; diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index c19beadca..076f56af6 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -265,10 +265,10 @@ void NodeDB::installDefaultDeviceState() // Set default owner name pickNewNodeNum(); // based on macaddr now - sprintf(owner.long_name, "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]); - sprintf(owner.short_name, "%02x%02x", ourMacAddr[4], ourMacAddr[5]); + snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]); + snprintf(owner.short_name, sizeof(owner.short_name), "%02x%02x", ourMacAddr[4], ourMacAddr[5]); - sprintf(owner.id, "!%08x", getNodeNum()); // Default node ID now based on nodenum + snprintf(owner.id, sizeof(owner.id), "!%08x", getNodeNum()); // Default node ID now based on nodenum memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr)); } diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index 733e4c1f1..1139c305e 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -164,7 +164,7 @@ bool initWifi() if (*wifiName) { uint8_t dmac[6]; getMacAddr(dmac); - sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]); + snprintf(ourHost, sizeof(ourHost), "Meshtastic-%02x%02x", dmac[4], dmac[5]); WiFi.mode(WIFI_MODE_STA); WiFi.setHostname(ourHost); diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index b6ea8826a..f790eba71 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -27,7 +27,7 @@ static const char *secretReserved = "sekrit"; static void writeSecret(char *buf, const char *currentVal) { if (strcmp(buf, secretReserved) == 0) { - strcpy(buf, currentVal); + strncpy(buf, currentVal, sizeof(buf)); } } @@ -199,15 +199,15 @@ void AdminModule::handleSetOwner(const User &o) if (*o.long_name) { changed |= strcmp(owner.long_name, o.long_name); - strcpy(owner.long_name, o.long_name); + strncpy(owner.long_name, o.long_name, sizeof(owner.long_name)); } if (*o.short_name) { changed |= strcmp(owner.short_name, o.short_name); - strcpy(owner.short_name, o.short_name); + strncpy(owner.short_name, o.short_name, sizeof(owner.short_name)); } if (*o.id) { changed |= strcmp(owner.id, o.id); - strcpy(owner.id, o.id); + strncpy(owner.id, o.id, sizeof(owner.id)); } if (owner.is_licensed != o.is_licensed) { changed = 1; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index f1cbc576d..9e42f8467 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -75,7 +75,7 @@ int CannedMessageModule::splitConfiguredMessages() int i = 0; // collect all the message parts - strcpy(this->messageStore, cannedMessageModuleConfig.messages); + strncpy(this->messageStore, cannedMessageModuleConfig.messages, sizeof(this->messageStore)); // The first message points to the beginning of the store. this->messages[messageIndex++] = this->messageStore; @@ -454,7 +454,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st } display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest)); // used chars right aligned - sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length()); + snprintf(buffer, sizeof(buffer), "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length()); display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer); if (this->destSelect) { display->drawString(x + display->getWidth() - display->getStringWidth(buffer) - 1, y + 0, buffer); @@ -551,7 +551,7 @@ void CannedMessageModule::handleGetCannedMessageModuleMessages(const MeshPacket LOG_DEBUG("*** handleGetCannedMessageModuleMessages\n"); if(req.decoded.want_response) { response->which_payload_variant = AdminMessage_get_canned_message_module_messages_response_tag; - strcpy(response->get_canned_message_module_messages_response, cannedMessageModuleConfig.messages); + strncpy(response->get_canned_message_module_messages_response, cannedMessageModuleConfig.messages, sizeof(response->get_canned_message_module_messages_response)); } // Don't send anything if not instructed to. Better than asserting. } @@ -562,7 +562,7 @@ void CannedMessageModule::handleSetCannedMessageModuleMessages(const char *from_ if (*from_msg) { changed |= strcmp(cannedMessageModuleConfig.messages, from_msg); - strcpy(cannedMessageModuleConfig.messages, from_msg); + strncpy(cannedMessageModuleConfig.messages, from_msg, sizeof(cannedMessageModuleConfig.messages)); LOG_DEBUG("*** from_msg.text:%s\n", from_msg); } diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index a8f112c94..3f2137ec8 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -349,7 +349,7 @@ void ExternalNotificationModule::handleGetRingtone(const MeshPacket &req, AdminM LOG_INFO("*** handleGetRingtone\n"); if(req.decoded.want_response) { response->which_payload_variant = AdminMessage_get_ringtone_response_tag; - strcpy(response->get_ringtone_response, rtttlConfig.ringtone); + strncpy(response->get_ringtone_response, rtttlConfig.ringtone, sizeof(response->get_ringtone_response)); } // Don't send anything if not instructed to. Better than asserting. } @@ -360,7 +360,7 @@ void ExternalNotificationModule::handleSetRingtone(const char *from_msg) if (*from_msg) { changed |= strcmp(rtttlConfig.ringtone, from_msg); - strcpy(rtttlConfig.ringtone, from_msg); + strncpy(rtttlConfig.ringtone, from_msg, sizeof(rtttlConfig.ringtone)); LOG_INFO("*** from_msg.text:%s\n", from_msg); } From 2b9f01f0e4cfc3732d143bd1833bb3cff7b23133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 16 Jan 2023 11:08:48 +0100 Subject: [PATCH 18/32] fix cppcheck --- src/gps/NMEAWPL.cpp | 12 ++++++------ src/gps/NMEAWPL.h | 4 ++-- src/modules/AdminModule.cpp | 6 +++--- src/modules/SerialModule.cpp | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 842fc0760..8fafc6ba0 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -16,10 +16,10 @@ * ------------------------------------------- */ -uint32_t printWPL(char *buf, const Position &pos, const char *name) +uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name) { GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude); - uint32_t len = snprintf(buf, sizeof(buf), "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", + uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), @@ -31,7 +31,7 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name) for (uint32_t i = 1; i < len; i++) { chk ^= buf[i]; } - len += snprintf(buf + len, sizeof(buf) + len, "*%02X\r\n", chk); + len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk); return len; } @@ -59,10 +59,10 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name) * ------------------------------------------- */ -uint32_t printGGA(char *buf, const Position &pos) +uint32_t printGGA(char *buf, size_t bufsz, const Position &pos) { GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude); - uint32_t len = snprintf(buf, sizeof(buf), "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", + uint32_t len = snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000, pos.time % 1000, geoCoord.getDMSLatDeg(), @@ -85,6 +85,6 @@ uint32_t printGGA(char *buf, const Position &pos) for (uint32_t i = 1; i < len; i++) { chk ^= buf[i]; } - len += snprintf(buf + len, sizeof(buf) + len, "*%02X\r\n", chk); + len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk); return len; } \ No newline at end of file diff --git a/src/gps/NMEAWPL.h b/src/gps/NMEAWPL.h index aaa18933c..ee79ffd08 100644 --- a/src/gps/NMEAWPL.h +++ b/src/gps/NMEAWPL.h @@ -3,5 +3,5 @@ #include #include "main.h" -uint32_t printWPL(char *buf, const Position &pos, const char *name); -uint32_t printGGA(char *buf, const Position &pos); +uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name); +uint32_t printGGA(char *buf, size_t bufsz, const Position &pos); diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index f790eba71..0bef684f2 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -24,10 +24,10 @@ bool hasOpenEditTransaction; static const char *secretReserved = "sekrit"; /// If buf is the reserved secret word, replace the buffer with currentVal -static void writeSecret(char *buf, const char *currentVal) +static void writeSecret(char *buf, size_t bufsz, const char *currentVal) { if (strcmp(buf, secretReserved) == 0) { - strncpy(buf, currentVal, sizeof(buf)); + strncpy(buf, currentVal, bufsz); } } @@ -381,7 +381,7 @@ void AdminModule::handleGetConfig(const MeshPacket &req, const uint32_t configTy LOG_INFO("Getting config: Network\n"); res.get_config_response.which_payload_variant = Config_network_tag; res.get_config_response.payload_variant.network = config.network; - writeSecret(res.get_config_response.payload_variant.network.wifi_psk, config.network.wifi_psk); + writeSecret(res.get_config_response.payload_variant.network.wifi_psk, sizeof(res.get_config_response.payload_variant.network.wifi_psk), config.network.wifi_psk); break; case AdminMessage_ConfigType_DISPLAY_CONFIG: LOG_INFO("Getting config: Display\n"); diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index e4ec57a4b..4383ecaab 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -200,7 +200,7 @@ int32_t SerialModule::runOnce() // in NMEA mode send out GGA every 2 seconds, Don't read from Port if (millis() - lastNmeaTime > 2000) { lastNmeaTime = millis(); - printGGA(outbuf, nodeDB.getNode(myNodeInfo.my_node_num)->position); + printGGA(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position); Serial2.printf("%s", outbuf); } } else { @@ -293,7 +293,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp) decoded = &scratch; } // send position packet as WPL to the serial port - printWPL(outbuf, *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name); + printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name); Serial2.printf("%s", outbuf); } } From 5831124f1dd449eda3bb33e101b2ec98aced6a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 5 Jan 2023 17:25:43 +0100 Subject: [PATCH 19/32] Store and Forward: don't try to store a message if PSRAM is not initialized! --- src/modules/esp32/StoreForwardModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index b5e0b1e65..fba78478b 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -237,7 +237,7 @@ ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp) // The router node should not be sending messages as a client. Unless he is a ROUTER_CLIENT if ((getFrom(&mp) != nodeDB.getNodeNum()) || (config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT)) { - if (mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) { + if ((mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) && is_server) { storeForwardModule->historyAdd(mp); LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent); From 59ee0fb012e2154429bf8497f5a0aa82802ecd13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 5 Jan 2023 17:50:35 +0100 Subject: [PATCH 20/32] put legacy S&F call back in, till Apps support it. --- src/modules/esp32/StoreForwardModule.cpp | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index fba78478b..8082176e4 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -238,8 +238,30 @@ ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp) if ((getFrom(&mp) != nodeDB.getNodeNum()) || (config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT)) { if ((mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) && is_server) { - storeForwardModule->historyAdd(mp); - LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent); + auto &p = mp.decoded; + if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 0x00)) { + LOG_DEBUG("*** Legacy Request to send\n"); + + // Send the last 60 minutes of messages. + if (this->busy) { + storeForwardModule->sendMessage(getFrom(&mp), StoreAndForward_RequestResponse_ROUTER_BUSY); + LOG_INFO("*** S&F - Busy. Try again shortly.\n"); + MeshPacket *pr = allocReply(); + pr->to = getFrom(&mp); + pr->priority = MeshPacket_Priority_MIN; + pr->want_ack = false; + pr->decoded.want_response = false; + pr->decoded.portnum = PortNum_TEXT_MESSAGE_APP; + memcpy(pr->decoded.payload.bytes, "** S&F - Busy. Try again shortly.", Constants_DATA_PAYLOAD_LEN); + pr->decoded.payload.size = sizeof(pr->decoded.payload.bytes); + service.sendToMesh(pr); + } else { + storeForwardModule->historySend(historyReturnWindow * 60000, getFrom(&mp)); + } + } else { + storeForwardModule->historyAdd(mp); + LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent); + } } else if (mp.decoded.portnum == PortNum_STORE_FORWARD_APP) { auto &p = mp.decoded; From a4d3fa55dbb18660b034bfc1a2714166e77cb203 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 15 Jan 2023 08:24:20 -0600 Subject: [PATCH 21/32] Remove HAS_GPS for WSLv3 --- variants/heltec_wsl_v3/variant.h | 1 - 1 file changed, 1 deletion(-) diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h index 60f611248..b8f911066 100644 --- a/variants/heltec_wsl_v3/variant.h +++ b/variants/heltec_wsl_v3/variant.h @@ -1,7 +1,6 @@ #define LED_PIN LED #define HAS_SCREEN 0 -#define HAS_GPS 0 #define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost #define BUTTON_PIN 0 From e95db927acdfda4ce4a5a830817b523c3d72000c Mon Sep 17 00:00:00 2001 From: garthvh Date: Sun, 15 Jan 2023 16:52:29 +0000 Subject: [PATCH 22/32] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 40e7926a9..7cf773466 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 0 -build = 13 +build = 14 From f4779bd93f9cee9fc02ba480472d2deff4899f0f Mon Sep 17 00:00:00 2001 From: caveman99 Date: Mon, 16 Jan 2023 16:50:57 +0000 Subject: [PATCH 23/32] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/config.pb.h | 10 +++-- src/mesh/generated/mesh.pb.h | 25 +++++++---- src/mesh/generated/xmodem.pb.c | 13 ++++++ src/mesh/generated/xmodem.pb.h | 77 ++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 src/mesh/generated/xmodem.pb.c create mode 100644 src/mesh/generated/xmodem.pb.h diff --git a/protobufs b/protobufs index e00b5ba7d..1763fe4a3 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit e00b5ba7d06053d820f1123351881fc4fa9270d1 +Subproject commit 1763fe4a389f0864f153a9986699e1ea56e67fac diff --git a/src/mesh/generated/config.pb.h b/src/mesh/generated/config.pb.h index 38e53d0c8..a6c84306e 100644 --- a/src/mesh/generated/config.pb.h +++ b/src/mesh/generated/config.pb.h @@ -147,7 +147,11 @@ typedef enum _Config_LoRaConfig_RegionCode { /* Thailand */ Config_LoRaConfig_RegionCode_TH = 12, /* WLAN Band */ - Config_LoRaConfig_RegionCode_LORA_24 = 13 + Config_LoRaConfig_RegionCode_LORA_24 = 13, + /* Ukraine 433mhz */ + Config_LoRaConfig_RegionCode_UA_433 = 14, + /* Ukraine 868mhz */ + Config_LoRaConfig_RegionCode_UA_868 = 15 } Config_LoRaConfig_RegionCode; /* Standard predefined channel settings @@ -437,8 +441,8 @@ extern "C" { #define _Config_DisplayConfig_DisplayMode_ARRAYSIZE ((Config_DisplayConfig_DisplayMode)(Config_DisplayConfig_DisplayMode_COLOR+1)) #define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_UNSET -#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_LORA_24 -#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_LORA_24+1)) +#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_UA_868 +#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_UA_868+1)) #define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LONG_FAST #define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_SHORT_FAST diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index 984ae33ee..2e0b66629 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -9,6 +9,7 @@ #include "module_config.pb.h" #include "portnums.pb.h" #include "telemetry.pb.h" +#include "xmodem.pb.h" #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -437,8 +438,9 @@ typedef struct _Waypoint { int32_t longitude_i; /* Time the waypoint is to expire (epoch) */ uint32_t expire; - /* If true, only allow the original sender to update the waypoint. */ - bool locked; + /* If greater than zero, treat the value as a nodenum only allowing them to update the waypoint. + If zero, the waypoint is open to be edited by any member of the mesh. */ + uint32_t locked_to; /* Name of the waypoint - max 30 chars */ char name[30]; /* Description of the waypoint - max 100 chars */ @@ -673,6 +675,8 @@ typedef struct _FromRadio { Channel channel; /* Queue status info */ QueueStatus queueStatus; + /* File Transfer Chunk */ + XModem xmodemPacket; }; } FromRadio; @@ -696,6 +700,7 @@ typedef struct _ToRadio { This is useful for serial links where there is no hardware/protocol based notification that the client has dropped the link. (Sending this message is optional for clients) */ bool disconnect; + XModem xmodemPacket; }; } ToRadio; @@ -850,7 +855,7 @@ extern "C" { #define Waypoint_latitude_i_tag 2 #define Waypoint_longitude_i_tag 3 #define Waypoint_expire_tag 4 -#define Waypoint_locked_tag 5 +#define Waypoint_locked_to_tag 5 #define Waypoint_name_tag 6 #define Waypoint_description_tag 7 #define Waypoint_icon_tag 8 @@ -908,9 +913,11 @@ extern "C" { #define FromRadio_moduleConfig_tag 9 #define FromRadio_channel_tag 10 #define FromRadio_queueStatus_tag 11 +#define FromRadio_xmodemPacket_tag 12 #define ToRadio_packet_tag 1 #define ToRadio_want_config_id_tag 3 #define ToRadio_disconnect_tag 4 +#define ToRadio_xmodemPacket_tag 5 #define Compressed_portnum_tag 1 #define Compressed_data_tag 2 @@ -982,7 +989,7 @@ X(a, STATIC, SINGULAR, UINT32, id, 1) \ X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 2) \ X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 3) \ X(a, STATIC, SINGULAR, UINT32, expire, 4) \ -X(a, STATIC, SINGULAR, BOOL, locked, 5) \ +X(a, STATIC, SINGULAR, UINT32, locked_to, 5) \ X(a, STATIC, SINGULAR, STRING, name, 6) \ X(a, STATIC, SINGULAR, STRING, description, 7) \ X(a, STATIC, SINGULAR, FIXED32, icon, 8) @@ -1067,7 +1074,8 @@ X(a, STATIC, ONEOF, UINT32, (payload_variant,config_complete_id,config_co X(a, STATIC, ONEOF, BOOL, (payload_variant,rebooted,rebooted), 8) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,queueStatus,queueStatus), 11) +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,queueStatus,queueStatus), 11) \ +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 12) #define FromRadio_CALLBACK NULL #define FromRadio_DEFAULT NULL #define FromRadio_payload_variant_packet_MSGTYPE MeshPacket @@ -1078,14 +1086,17 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,queueStatus,queueStatus), 1 #define FromRadio_payload_variant_moduleConfig_MSGTYPE ModuleConfig #define FromRadio_payload_variant_channel_MSGTYPE Channel #define FromRadio_payload_variant_queueStatus_MSGTYPE QueueStatus +#define FromRadio_payload_variant_xmodemPacket_MSGTYPE XModem #define ToRadio_FIELDLIST(X, a) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \ X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) +X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) \ +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 5) #define ToRadio_CALLBACK NULL #define ToRadio_DEFAULT NULL #define ToRadio_payload_variant_packet_MSGTYPE MeshPacket +#define ToRadio_payload_variant_xmodemPacket_MSGTYPE XModem #define Compressed_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ @@ -1138,7 +1149,7 @@ extern const pb_msgdesc_t Compressed_msg; #define Routing_size 42 #define ToRadio_size 324 #define User_size 77 -#define Waypoint_size 161 +#define Waypoint_size 165 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/xmodem.pb.c b/src/mesh/generated/xmodem.pb.c new file mode 100644 index 000000000..f210380fe --- /dev/null +++ b/src/mesh/generated/xmodem.pb.c @@ -0,0 +1,13 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.7 */ + +#include "xmodem.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(XModem, XModem, AUTO) + + + + diff --git a/src/mesh/generated/xmodem.pb.h b/src/mesh/generated/xmodem.pb.h new file mode 100644 index 000000000..453c8ce7c --- /dev/null +++ b/src/mesh/generated/xmodem.pb.h @@ -0,0 +1,77 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.7 */ + +#ifndef PB_XMODEM_PB_H_INCLUDED +#define PB_XMODEM_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _XModem_Control { + XModem_Control_NUL = 0, + XModem_Control_SOH = 1, + XModem_Control_STX = 2, + XModem_Control_EOT = 4, + XModem_Control_ACK = 6, + XModem_Control_NAK = 21, + XModem_Control_CAN = 24, + XModem_Control_CTRLZ = 26 +} XModem_Control; + +/* Struct definitions */ +typedef PB_BYTES_ARRAY_T(128) XModem_buffer_t; +typedef struct _XModem { + XModem_Control control; + uint16_t seq; + uint16_t crc16; + XModem_buffer_t buffer; +} XModem; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _XModem_Control_MIN XModem_Control_NUL +#define _XModem_Control_MAX XModem_Control_CTRLZ +#define _XModem_Control_ARRAYSIZE ((XModem_Control)(XModem_Control_CTRLZ+1)) + +#define XModem_control_ENUMTYPE XModem_Control + + +/* Initializer values for message structs */ +#define XModem_init_default {_XModem_Control_MIN, 0, 0, {0, {0}}} +#define XModem_init_zero {_XModem_Control_MIN, 0, 0, {0, {0}}} + +/* Field tags (for use in manual encoding/decoding) */ +#define XModem_control_tag 1 +#define XModem_seq_tag 2 +#define XModem_crc16_tag 3 +#define XModem_buffer_tag 4 + +/* Struct field encoding specification for nanopb */ +#define XModem_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, control, 1) \ +X(a, STATIC, SINGULAR, UINT32, seq, 2) \ +X(a, STATIC, SINGULAR, UINT32, crc16, 3) \ +X(a, STATIC, SINGULAR, BYTES, buffer, 4) +#define XModem_CALLBACK NULL +#define XModem_DEFAULT NULL + +extern const pb_msgdesc_t XModem_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define XModem_fields &XModem_msg + +/* Maximum encoded size of messages (where known) */ +#define XModem_size 141 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif From 1cfda773569a883952b4e92336b2b45744803128 Mon Sep 17 00:00:00 2001 From: Krezalis Date: Thu, 12 Jan 2023 14:57:14 +0200 Subject: [PATCH 24/32] Add 868 MHz Ukrainian Band --- src/mesh/RadioInterface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 2e44b0ada..c6647e1fc 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -105,6 +105,12 @@ const RegionInfo regions[] = { This needs to be last. Same as US. */ RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false, false) + + /* + 868,0-868,6 Mhz 25 mW + https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf + */ + RDEF(UA868, 868.1f, 868.5f, 100, 0, 20, true, false, false) }; From 49279e56d05a81e0df81d0a21d6629e2a0aedffe Mon Sep 17 00:00:00 2001 From: Krezalis Date: Thu, 12 Jan 2023 15:25:05 +0200 Subject: [PATCH 25/32] Update RadioInterface.cpp --- src/mesh/RadioInterface.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index c6647e1fc..1d18d5ef4 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -100,18 +100,24 @@ const RegionInfo regions[] = { */ RDEF(LORA_24, 2400.0f, 2483.5f, 100, 0, 10, true, false, true), - + + /* + 433,05-434,7 Mhz 10 mW + https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf + */ + RDEF(UA_433, 433.0f, 434.0f, 100, 0, 12, true, false, false), + + /* + 868,0-868,6 Mhz 25 mW + https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf + */ + RDEF(UA_868, 868.1f, 868.5f, 100, 0, 14, true, false, false), + /* This needs to be last. Same as US. */ RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false, false) - /* - 868,0-868,6 Mhz 25 mW - https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf - */ - RDEF(UA868, 868.1f, 868.5f, 100, 0, 20, true, false, false) - }; const RegionInfo *myRegion; From 011013ab1a875d732174cf1dcc7c5e301e175cd1 Mon Sep 17 00:00:00 2001 From: Krezalis Date: Thu, 12 Jan 2023 15:27:20 +0200 Subject: [PATCH 26/32] Update RadioInterface.cpp --- src/mesh/RadioInterface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 1d18d5ef4..8b1261b51 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -100,24 +100,24 @@ const RegionInfo regions[] = { */ RDEF(LORA_24, 2400.0f, 2483.5f, 100, 0, 10, true, false, true), - + /* 433,05-434,7 Mhz 10 mW https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf */ RDEF(UA_433, 433.0f, 434.0f, 100, 0, 12, true, false, false), - + /* 868,0-868,6 Mhz 25 mW https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf */ RDEF(UA_868, 868.1f, 868.5f, 100, 0, 14, true, false, false), - + /* This needs to be last. Same as US. */ RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false, false) - + }; const RegionInfo *myRegion; From efbdb273c3f2e7e2a76cb8cd46e8e031c4cbdcf4 Mon Sep 17 00:00:00 2001 From: Krezalis Date: Thu, 12 Jan 2023 15:47:05 +0200 Subject: [PATCH 27/32] Update RadioInterface.cpp --- src/mesh/RadioInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 8b1261b51..b3f347def 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -105,13 +105,13 @@ const RegionInfo regions[] = { 433,05-434,7 Mhz 10 mW https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf */ - RDEF(UA_433, 433.0f, 434.0f, 100, 0, 12, true, false, false), + RDEF(UA_433, 433.0f, 434.7f, 10, 0, 10, true, false, false), /* 868,0-868,6 Mhz 25 mW https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf */ - RDEF(UA_868, 868.1f, 868.5f, 100, 0, 14, true, false, false), + RDEF(UA_868, 868.0f, 868.6f, 1, 0, 14, true, false, false), /* This needs to be last. Same as US. From d5a3acb83aad653f84f6d259f7d982e29c4de51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 16 Jan 2023 17:54:48 +0100 Subject: [PATCH 28/32] Trigger rebuild --- src/mesh/RadioInterface.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index b3f347def..37b929249 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -94,13 +94,7 @@ const RegionInfo regions[] = { https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf */ RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false, false), - - /* - 2.4 GHZ WLAN Band equivalent. Only for SX128x chips. - */ - - RDEF(LORA_24, 2400.0f, 2483.5f, 100, 0, 10, true, false, true), - + /* 433,05-434,7 Mhz 10 mW https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf @@ -113,6 +107,12 @@ const RegionInfo regions[] = { */ RDEF(UA_868, 868.0f, 868.6f, 1, 0, 14, true, false, false), + /* + 2.4 GHZ WLAN Band equivalent. Only for SX128x chips. + */ + + RDEF(LORA_24, 2400.0f, 2483.5f, 100, 0, 10, true, false, true), + /* This needs to be last. Same as US. */ From 0f4306158c09cc2787c8b576e5191db26f827787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 16 Jan 2023 17:56:48 +0100 Subject: [PATCH 29/32] fix S&F Problem --- src/modules/esp32/StoreForwardModule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index 8082176e4..ba0e7d6ee 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -252,8 +252,8 @@ ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp) pr->want_ack = false; pr->decoded.want_response = false; pr->decoded.portnum = PortNum_TEXT_MESSAGE_APP; - memcpy(pr->decoded.payload.bytes, "** S&F - Busy. Try again shortly.", Constants_DATA_PAYLOAD_LEN); - pr->decoded.payload.size = sizeof(pr->decoded.payload.bytes); + memcpy(pr->decoded.payload.bytes, "** S&F - Busy. Try again shortly.", 34); + pr->decoded.payload.size = 34; service.sendToMesh(pr); } else { storeForwardModule->historySend(historyReturnWindow * 60000, getFrom(&mp)); From 34b2d51113ff7ecfb73171f74ddece6ac84d2ff4 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 16 Jan 2023 11:05:36 -0600 Subject: [PATCH 30/32] Patch locked_to --- src/mqtt/MQTT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index cc091bcff..448b5c497 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -478,7 +478,7 @@ std::string MQTT::downstreamPacketToJson(MeshPacket *mp) msgPayload["name"] = new JSONValue(decoded->name); msgPayload["description"] = new JSONValue(decoded->description); msgPayload["expire"] = new JSONValue((int)decoded->expire); - msgPayload["locked"] = new JSONValue(decoded->locked); + msgPayload["locked_to"] = new JSONValue(decoded->locked_to); msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i); msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i); jsonObj["payload"] = new JSONValue(msgPayload); From 9f3c09cf40268f2fdc5a943045eb130d84c0cbf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 16 Jan 2023 18:09:17 +0100 Subject: [PATCH 31/32] adapt to new proto names --- src/mqtt/MQTT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index cc091bcff..8f4399370 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -478,7 +478,7 @@ std::string MQTT::downstreamPacketToJson(MeshPacket *mp) msgPayload["name"] = new JSONValue(decoded->name); msgPayload["description"] = new JSONValue(decoded->description); msgPayload["expire"] = new JSONValue((int)decoded->expire); - msgPayload["locked"] = new JSONValue(decoded->locked); + msgPayload["locked"] = new JSONValue((int)decoded->locked_to); msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i); msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i); jsonObj["payload"] = new JSONValue(msgPayload); From cc0cccbd1bc4d62cde2e9e633c03bee69d68c360 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 16 Jan 2023 12:26:10 -0600 Subject: [PATCH 32/32] Coerce int --- src/mqtt/MQTT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 448b5c497..34b75e5bb 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -478,7 +478,7 @@ std::string MQTT::downstreamPacketToJson(MeshPacket *mp) msgPayload["name"] = new JSONValue(decoded->name); msgPayload["description"] = new JSONValue(decoded->description); msgPayload["expire"] = new JSONValue((int)decoded->expire); - msgPayload["locked_to"] = new JSONValue(decoded->locked_to); + msgPayload["locked_to"] = new JSONValue((int)decoded->locked_to); msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i); msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i); jsonObj["payload"] = new JSONValue(msgPayload);