diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini
index ba98a6b1f..730b78942 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -31,7 +31,7 @@ lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
- https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
+ https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini
index f5338d9a9..0c2d7d8f1 100644
--- a/arch/esp32/esp32s3.ini
+++ b/arch/esp32/esp32s3.ini
@@ -31,7 +31,7 @@ lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
- https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
+ https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini
index b61071007..fb1e45af7 100644
--- a/arch/portduino/portduino.ini
+++ b/arch/portduino/portduino.ini
@@ -1,5 +1,7 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base]
+platform = https://github.com/meshtastic/platform-native.git#develop
+framework = arduino
build_src_filter =
${env.build_src_filter}
-
@@ -16,5 +18,6 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
- https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
+ ; jgromes/RadioLib@5.4.1
+ https://github.com/jgromes/RadioLib.git#63208f1e89d4dac6eedaafbe234bf90f1fd5402b ; 5.4.1 with some fixes, remove when 5.4.2 is released
build_flags = ${arduino_base.build_flags} -Isrc/platform/portduino
diff --git a/platformio.ini b/platformio.ini
index 618c7cddb..94e3e9f5b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -37,12 +37,24 @@ extra_scripts = bin/platformio-custom.py
; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile
; of code is a heap corruption bug!
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
+; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
build_flags = -Wno-missing-field-initializers
-Wno-format
-Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DUSE_THREAD_NAMES
- -DTINYGPS_OPTION_NO_CUSTOM_FIELDS
+; -DTINYGPS_OPTION_NO_CUSTOM_FIELDS // this should work now...
-DPB_ENABLE_MALLOC=1
+ -DRADIOLIB_EXCLUDE_CC1101
+ -DRADIOLIB_EXCLUDE_NRF24
+ -DRADIOLIB_EXCLUDE_RF69
+ -DRADIOLIB_EXCLUDE_SX1231
+ -DRADIOLIB_EXCLUDE_SI443X
+ -DRADIOLIB_EXCLUDE_RFM2X
+ -DRADIOLIB_EXCLUDE_AFSK
+ -DRADIOLIB_EXCLUDE_HELLSCHREIBER
+ -DRADIOLIB_EXCLUDE_MORSE
+ -DRADIOLIB_EXCLUDE_RTTY
+ -DRADIOLIB_EXCLUDE_SSTV
monitor_speed = 115200
diff --git a/protobufs b/protobufs
index da9bba9c5..24874086e 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit da9bba9c5dd43a98d431cb7a95159b145f0483c4
+Subproject commit 24874086e392b0ec504f9f89137e7b7f8b5bfcbd
diff --git a/src/GPSStatus.h b/src/GPSStatus.h
index cde351818..35a0b11f2 100644
--- a/src/GPSStatus.h
+++ b/src/GPSStatus.h
@@ -25,22 +25,6 @@ class GPSStatus : public Status
public:
GPSStatus() { statusType = STATUS_TYPE_GPS; }
- // // proposed for deprecation
- // GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
- // uint32_t heading, uint32_t numSatellites)
- // : Status()
- // {
- // this->hasLock = hasLock;
- // this->isConnected = isConnected;
-
- // this->p.latitude_i = latitude;
- // this->p.longitude_i = longitude;
- // this->p.altitude = altitude;
- // this->p.PDOP = dop;
- // this->p.ground_track = heading;
- // this->p.sats_in_view = numSatellites;
- // }
-
// preferred method
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
{
diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp
index 1b103f534..0ff302bab 100644
--- a/src/gps/NMEAGPS.cpp
+++ b/src/gps/NMEAGPS.cpp
@@ -109,7 +109,7 @@ bool NMEAGPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
fixType = atoi(gsafixtype.value()); // will set to zero if no data
- DEBUG_MSG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
+ // DEBUG_MSG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
@@ -168,7 +168,7 @@ bool NMEAGPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.HDOP = reader.hdop.value();
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
- DEBUG_MSG("PDOP=%d, HDOP=%d\n", dop, reader.hdop.value());
+ // DEBUG_MSG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
#else
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp
index ccef2df23..9602525b5 100644
--- a/src/mesh/InterfacesTemplates.cpp
+++ b/src/mesh/InterfacesTemplates.cpp
@@ -8,6 +8,6 @@ template class SX126xInterface;
template class SX126xInterface;
template class SX126xInterface;
-#if !defined(ARCH_PORTDUINO)
+#if defined(RADIOLIB_GODMODE)
template class SX128xInterface;
#endif
\ No newline at end of file
diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp
index d5c7c4a19..b4a4a171f 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -104,16 +104,17 @@ bool MeshService::reloadConfig(int saveWhat)
}
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
-void MeshService::reloadOwner()
+void MeshService::reloadOwner(bool shouldSave)
{
// DEBUG_MSG("reloadOwner()\n");
// update our local data directly
nodeDB.updateUser(nodeDB.getNodeNum(), owner);
assert(nodeInfoModule);
- // update everyone else
- if (nodeInfoModule)
+ // update everyone else and save to disk
+ if (nodeInfoModule && shouldSave) {
nodeInfoModule->sendOurNodeInfo();
- nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
+ nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
+ }
}
/**
diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h
index 24ec1c0bc..c3b3c95d9 100644
--- a/src/mesh/MeshService.h
+++ b/src/mesh/MeshService.h
@@ -69,7 +69,7 @@ class MeshService
bool reloadConfig(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
- void reloadOwner();
+ void reloadOwner(bool shouldSave = true);
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
/// sends our owner
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 8a7ee6086..c548b0acc 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -204,6 +204,7 @@ void NodeDB::installDefaultModuleConfig()
{
DEBUG_MSG("Installing default ModuleConfig\n");
memset(&moduleConfig, 0, sizeof(ModuleConfig));
+
moduleConfig.version = DEVICESTATE_CUR_VER;
moduleConfig.has_mqtt = true;
moduleConfig.has_range_test = true;
@@ -213,6 +214,10 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.has_external_notification = true;
moduleConfig.has_canned_message = true;
+ strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(default_mqtt_address));
+ strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(default_mqtt_username));
+ strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(default_mqtt_password));
+
initModuleConfigIntervals();
}
@@ -741,9 +746,9 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *f
String lcd = String("Critical error ") + code + "!\n";
screen->print(lcd.c_str());
if (filename)
- DEBUG_MSG("NOTE! Recording critical error %d at %s:%lx\n", code, filename, address);
+ DEBUG_MSG("NOTE! Recording critical error %d at %s:%lu\n", code, filename, address);
else
- DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);
+ DEBUG_MSG("NOTE! Recording critical error %d, address=0x%lx\n", code, address);
// Record error to DB
myNodeInfo.error_code = code;
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index dcd518191..1622a57ff 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -58,7 +58,7 @@ class NodeDB
void init();
/// write to flash
- void saveToDisk(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
+ void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
/** Reinit radio config if needed, because either:
* a) sometimes a buggy android app might send us bogus settings or
@@ -194,6 +194,10 @@ extern NodeDB nodeDB;
#define default_min_wake_secs 10
#define default_screen_on_secs 60 * 10
+#define default_mqtt_address "mqtt.meshtastic.org"
+#define default_mqtt_username "meshdev"
+#define default_mqtt_password "large4cats"
+
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
{
if (configuredInterval > 0) return configuredInterval * 1000;
diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp
index d56681412..5b88d45ed 100644
--- a/src/mesh/RF95Interface.cpp
+++ b/src/mesh/RF95Interface.cpp
@@ -129,6 +129,7 @@ bool RF95Interface::reconfigure()
if (power > MAX_POWER) // This chip has lower power limits than some
power = MAX_POWER;
+
err = lora->setOutputPower(power);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp
index c08220555..567215600 100644
--- a/src/mesh/RadioLibInterface.cpp
+++ b/src/mesh/RadioLibInterface.cpp
@@ -11,17 +11,6 @@
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
-#ifdef ARCH_PORTDUINO
-
-void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes)
-{
- concurrency::LockGuard g(spiLock);
-
- Module::SPItransfer(cmd, reg, dataOut, dataIn, numBytes);
-}
-
-#else
-
void LockingModule::SPIbeginTransaction()
{
spiLock->lock();
@@ -36,8 +25,6 @@ void LockingModule::SPIendTransaction()
Module::SPIendTransaction();
}
-#endif
-
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi, PhysicalLayer *_iface)
: NotifiedWorkerThread("RadioIf"), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h
index fbad830cd..f368cf83e 100644
--- a/src/mesh/RadioLibInterface.h
+++ b/src/mesh/RadioLibInterface.h
@@ -41,12 +41,8 @@ class LockingModule : public Module
{
}
-#ifdef ARCH_PORTDUINO
- void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
-#else
void SPIbeginTransaction() override;
void SPIendTransaction() override;
-#endif
};
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp
index e42f2cdef..2807178b8 100644
--- a/src/mesh/ReliableRouter.cpp
+++ b/src/mesh/ReliableRouter.cpp
@@ -96,7 +96,11 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
if (MeshModule::currentReply)
DEBUG_MSG("Some other module has replied to this message, no need for a 2nd ack\n");
else
- sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
+ if (p->which_payload_variant == MeshPacket_decoded_tag)
+ sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
+ else
+ // Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
+ sendAckNak(Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex());
}
// We consider an ack to be either a !routing packet with a request ID or a routing packet with !error
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
index cfb97e673..20c8056e2 100644
--- a/src/mesh/SX126xInterface.cpp
+++ b/src/mesh/SX126xInterface.cpp
@@ -144,8 +144,9 @@ bool SX126xInterface::reconfigure()
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
- if (power > 22) // This chip has lower power limits than some
- power = 22;
+ if (power > SX126X_MAX_POWER) // This chip has lower power limits than some
+ power = SX126X_MAX_POWER;
+
err = lora.setOutputPower(power);
assert(err == RADIOLIB_ERR_NONE);
diff --git a/src/mesh/SX1280Interface.cpp b/src/mesh/SX1280Interface.cpp
index 37aad1d40..97a3febe3 100644
--- a/src/mesh/SX1280Interface.cpp
+++ b/src/mesh/SX1280Interface.cpp
@@ -2,7 +2,7 @@
#include "SX1280Interface.h"
#include "error.h"
-#if !defined(ARCH_PORTDUINO)
+#if defined(RADIOLIB_GODMODE)
SX1280Interface::SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
diff --git a/src/mesh/SX1280Interface.h b/src/mesh/SX1280Interface.h
index 1c2e24900..a9661501a 100644
--- a/src/mesh/SX1280Interface.h
+++ b/src/mesh/SX1280Interface.h
@@ -6,7 +6,7 @@
* Our adapter for SX1280 radios
*/
-#if !defined(ARCH_PORTDUINO)
+#if defined(RADIOLIB_GODMODE)
class SX1280Interface : public SX128xInterface
{
diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp
index 0044ae7e5..36eb0bb94 100644
--- a/src/mesh/SX128xInterface.cpp
+++ b/src/mesh/SX128xInterface.cpp
@@ -2,7 +2,7 @@
#include "SX128xInterface.h"
#include "error.h"
-#if !defined(ARCH_PORTDUINO)
+#if defined(RADIOLIB_GODMODE)
// Particular boards might define a different max power based on what their hardware can do
#ifndef SX128X_MAX_POWER
@@ -105,8 +105,9 @@ bool SX128xInterface::reconfigure()
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
- if (power > 22) // This chip has lower power limits than some
- power = 22;
+ if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
+ power = SX128X_MAX_POWER;
+
err = lora.setOutputPower(power);
assert(err == RADIOLIB_ERR_NONE);
@@ -218,7 +219,11 @@ bool SX128xInterface::isChannelActive()
template
bool SX128xInterface::isActivelyReceiving()
{
- return isChannelActive();
+ // return isChannelActive();
+
+ uint16_t irq = lora.getIrqStatus();
+ bool hasPreamble = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
+ return hasPreamble;
}
template
diff --git a/src/mesh/SX128xInterface.h b/src/mesh/SX128xInterface.h
index f712b8bc4..9994ce850 100644
--- a/src/mesh/SX128xInterface.h
+++ b/src/mesh/SX128xInterface.h
@@ -1,6 +1,6 @@
#pragma once
-#if !defined(ARCH_PORTDUINO)
+#if defined(RADIOLIB_GODMODE)
#include "RadioLibInterface.h"
diff --git a/src/mesh/generated/admin.pb.h b/src/mesh/generated/admin.pb.h
index b5dc769ca..4257405fa 100644
--- a/src/mesh/generated/admin.pb.h
+++ b/src/mesh/generated/admin.pb.h
@@ -82,10 +82,11 @@ typedef struct _AdminMessage {
ModuleConfig set_module_config;
/* Set the Canned Message Module messages text. */
char set_canned_message_module_messages[201];
- /* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
- bool confirm_set_config;
- /* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
- bool confirm_set_module_config;
+ /* Begins an edit transaction for config, module config, owner, and channel settings changes
+ This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */
+ bool begin_edit_settings;
+ /* Commits an open transaction for any edits made to config, module config, owner, and channel settings */
+ bool commit_edit_settings;
/* Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again.
Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes.
If you fail to do so, the radio will assume loss of comms and revert your changes.
@@ -147,8 +148,8 @@ extern "C" {
#define AdminMessage_set_config_tag 34
#define AdminMessage_set_module_config_tag 35
#define AdminMessage_set_canned_message_module_messages_tag 36
-#define AdminMessage_confirm_set_config_tag 64
-#define AdminMessage_confirm_set_module_config_tag 65
+#define AdminMessage_begin_edit_settings_tag 64
+#define AdminMessage_commit_edit_settings_tag 65
#define AdminMessage_confirm_set_channel_tag 66
#define AdminMessage_confirm_set_radio_tag 67
#define AdminMessage_reboot_ota_seconds_tag 95
@@ -177,8 +178,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 3
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_module_config,set_module_config), 35) \
X(a, STATIC, ONEOF, STRING, (payload_variant,set_canned_message_module_messages,set_canned_message_module_messages), 36) \
-X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_config,confirm_set_config), 64) \
-X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_module_config,confirm_set_module_config), 65) \
+X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \
+X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_channel,confirm_set_channel), 66) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_radio,confirm_set_radio), 67) \
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp
index 09f5acf48..c00738d1a 100644
--- a/src/mesh/http/WiFiAPClient.cpp
+++ b/src/mesh/http/WiFiAPClient.cpp
@@ -35,32 +35,34 @@ char ourHost[16];
bool APStartupComplete = 0;
+unsigned long lastrun_ntp = 0;
+
static bool needReconnect = true; // If we create our reconnector, run it once at the beginning
+static Periodic *wifiReconnect;
+
static int32_t reconnectWiFi()
{
const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk;
- if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) {
+ if (config.network.wifi_enabled && needReconnect) {
if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL;
- if (*wifiName) {
- needReconnect = false;
+ needReconnect = false;
- // Make sure we clear old connection credentials
- WiFi.disconnect(false, true);
+ // Make sure we clear old connection credentials
+ WiFi.disconnect(false, true);
- DEBUG_MSG("... Reconnecting to WiFi access point\n");
- WiFi.mode(WIFI_MODE_STA);
- WiFi.begin(wifiName, wifiPsw);
- }
+ DEBUG_MSG("... Reconnecting to WiFi access point\n");
+ WiFi.mode(WIFI_MODE_STA);
+ WiFi.begin(wifiName, wifiPsw);
}
#ifndef DISABLE_NTP
- if (WiFi.isConnected()) {
+ if (WiFi.isConnected() && ((millis() - lastrun_ntp) > 43200000)) { // every 12 hours
DEBUG_MSG("Updating NTP time\n");
if (timeClient.update()) {
DEBUG_MSG("NTP Request Success - Setting RTCQualityNTP if needed\n");
@@ -70,6 +72,7 @@ static int32_t reconnectWiFi()
tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv);
+ lastrun_ntp = millis();
} else {
DEBUG_MSG("NTP Update failed\n");
@@ -77,11 +80,13 @@ static int32_t reconnectWiFi()
}
#endif
- return 43200 * 1000; // every 12 hours
+ if (config.network.wifi_enabled && !WiFi.isConnected()) {
+ return 1000; // check once per second
+ } else {
+ return 300000; // every 5 minutes
+ }
}
-static Periodic *wifiReconnect;
-
bool isWifiAvailable()
{
@@ -95,20 +100,10 @@ bool isWifiAvailable()
// Disable WiFi
void deinitWifi()
{
- /*
- Note from Jm (jm@casler.org - Sept 16, 2020):
-
- A bug in the ESP32 SDK was introduced in Oct 2019 that keeps the WiFi radio from
- turning back on after it's shut off. See:
- https://github.com/espressif/arduino-esp32/issues/3522
-
- Until then, WiFi should only be allowed when there's no power
- saving on the 2.4g transceiver.
- */
-
DEBUG_MSG("WiFi deinit\n");
if (isWifiAvailable()) {
+ WiFi.disconnect(true);
WiFi.mode(WIFI_MODE_NULL);
DEBUG_MSG("WiFi Turned Off\n");
// WiFi.printDiag(Serial);
@@ -169,7 +164,7 @@ bool initWifi()
WiFi.mode(WIFI_MODE_STA);
WiFi.setHostname(ourHost);
WiFi.onEvent(WiFiEvent);
- WiFi.setAutoReconnect(true);
+ WiFi.setAutoReconnect(false);
WiFi.setSleep(false);
if (config.network.eth_mode == Config_NetworkConfig_EthMode_STATIC && config.network.ipv4_config.ip != 0) {
WiFi.config(config.network.ipv4_config.ip,
@@ -231,7 +226,9 @@ static void WiFiEvent(WiFiEvent_t event)
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
DEBUG_MSG("Disconnected from WiFi access point\n");
+ WiFi.disconnect(false, true);
needReconnect = true;
+ wifiReconnect->setIntervalFromNow(1000);
break;
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
DEBUG_MSG("Authentication mode of access point has changed\n");
@@ -243,7 +240,9 @@ static void WiFiEvent(WiFiEvent_t event)
break;
case SYSTEM_EVENT_STA_LOST_IP:
DEBUG_MSG("Lost IP address and IP address is reset to 0\n");
+ WiFi.disconnect(false, true);
needReconnect = true;
+ wifiReconnect->setIntervalFromNow(1000);
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
DEBUG_MSG("WiFi Protected Setup (WPS): succeeded in enrollee mode\n");
@@ -259,7 +258,6 @@ static void WiFiEvent(WiFiEvent_t event)
break;
case SYSTEM_EVENT_AP_START:
DEBUG_MSG("WiFi access point started\n");
- onNetworkConnected();
break;
case SYSTEM_EVENT_AP_STOP:
DEBUG_MSG("WiFi access point stopped\n");
diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp
index 4a76faf6f..7226abd0b 100644
--- a/src/modules/AdminModule.cpp
+++ b/src/modules/AdminModule.cpp
@@ -13,7 +13,10 @@
#include "unistd.h"
#endif
+#define DEFAULT_REBOOT_SECONDS 5
+
AdminModule *adminModule;
+bool hasOpenEditTransaction;
/// A special reserved string to indicate strings we can not share with external nodes. We will use this 'reserved' word instead.
/// Also, to make setting work correctly, if someone tries to set a string to this reserved value we assume they don't really want
@@ -133,13 +136,23 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
case AdminMessage_factory_reset_tag: {
DEBUG_MSG("Initiating factory reset\n");
nodeDB.factoryReset();
- reboot(5);
+ reboot(DEFAULT_REBOOT_SECONDS);
break;
- }
- case AdminMessage_nodedb_reset_tag: {
+ } case AdminMessage_nodedb_reset_tag: {
DEBUG_MSG("Initiating node-db reset\n");
nodeDB.resetNodes();
- reboot(5);
+ reboot(DEFAULT_REBOOT_SECONDS);
+ break;
+ }
+ case AdminMessage_begin_edit_settings_tag: {
+ DEBUG_MSG("Beginning transaction for editing settings\n");
+ hasOpenEditTransaction = true;
+ break;
+ }
+ case AdminMessage_commit_edit_settings_tag: {
+ DEBUG_MSG("Committing transaction for edited settings\n");
+ hasOpenEditTransaction = false;
+ saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
break;
}
#ifdef ARCH_PORTDUINO
@@ -192,9 +205,8 @@ void AdminModule::handleSetOwner(const User &o)
}
if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
- service.reloadOwner();
- DEBUG_MSG("Rebooting due to owner changes\n");
- reboot(5);
+ service.reloadOwner(!hasOpenEditTransaction);
+ saveChanges(SEGMENT_DEVICESTATE);
}
}
@@ -220,7 +232,7 @@ void AdminModule::handleSetConfig(const Config &c)
config.has_position = true;
config.position = c.payload_variant.position;
// Save nodedb as well in case we got a fixed position packet
- nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
+ saveChanges(SEGMENT_DEVICESTATE, false);
break;
case Config_power_tag:
DEBUG_MSG("Setting config: Power\n");
@@ -252,9 +264,8 @@ void AdminModule::handleSetConfig(const Config &c)
config.bluetooth = c.payload_variant.bluetooth;
break;
}
-
- service.reloadConfig(SEGMENT_CONFIG);
- reboot(5);
+
+ saveChanges(SEGMENT_CONFIG);
}
void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
@@ -302,15 +313,14 @@ void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
break;
}
- service.reloadConfig(SEGMENT_MODULECONFIG);
- reboot(5);
+ saveChanges(SEGMENT_MODULECONFIG);
}
void AdminModule::handleSetChannel(const Channel &cc)
{
channels.setChannel(cc);
channels.onConfigChanged(); // tell the radios about this change
- nodeDB.saveChannelsToDisk();
+ saveChanges(SEGMENT_CHANNELS, false);
}
/**
@@ -479,6 +489,20 @@ void AdminModule::reboot(int32_t seconds)
rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000);
}
+void AdminModule::saveChanges(int saveWhat, bool shouldReboot)
+{
+ if (!hasOpenEditTransaction) {
+ DEBUG_MSG("Saving changes to disk\n");
+ service.reloadConfig(saveWhat); // Calls saveToDisk among other things
+ } else {
+ DEBUG_MSG("Delaying save of changes to disk until the open transaction is committed\n");
+ }
+ if (shouldReboot)
+ {
+ reboot(DEFAULT_REBOOT_SECONDS);
+ }
+}
+
AdminModule::AdminModule() : ProtobufModule("Admin", PortNum_ADMIN_APP, AdminMessage_fields)
{
// restrict to the admin channel for rx
diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h
index dd81c3218..3afbfa133 100644
--- a/src/modules/AdminModule.h
+++ b/src/modules/AdminModule.h
@@ -20,6 +20,9 @@ class AdminModule : public ProtobufModule
virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p) override;
private:
+ bool hasOpenEditTransaction = false;
+
+ void saveChanges(int saveWhat, bool shouldReboot = true);
/**
* Getters
*/
diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp
index b00dfb796..e7b34b9a7 100644
--- a/src/modules/CannedMessageModule.cpp
+++ b/src/modules/CannedMessageModule.cpp
@@ -176,7 +176,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
DEBUG_MSG("Canned message event Matrix key pressed\n");
// this will send the text immediately on matrix press
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
- this->payload = event->kbchar;
+ this->payload = MATRIXKEY;
this->currentMessageIndex = event->kbchar -1;
this->lastTouchMillis = millis();
validEvent = true;
@@ -246,7 +246,12 @@ int32_t CannedMessageModule::runOnce()
}
} else {
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
- sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
+ if(strcmp (this->messages[this->currentMessageIndex], "~") == 0) {
+ powerFSM.trigger(EVENT_PRESS);
+ return INT32_MAX;
+ } else {
+ sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
+ }
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
} else {
DEBUG_MSG("Reset message is empty.\n");
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index 194683939..fa1a66593 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -118,24 +118,16 @@ bool MQTT::connected()
void MQTT::reconnect()
{
if (wantsLink()) {
- const char *serverAddr = "mqtt.meshtastic.org"; // default hostname
- int serverPort = 1883; // default server port
- const char *mqttUsername = "meshdev";
- const char *mqttPassword = "large4cats";
+ // Defaults
+ int serverPort = 1883;
+ const char *serverAddr = default_mqtt_address;
+ const char *mqttUsername = default_mqtt_username;
+ const char *mqttPassword = default_mqtt_password;
if (*moduleConfig.mqtt.address) {
- serverAddr = moduleConfig.mqtt.address; // Override the default
- mqttUsername =
- moduleConfig.mqtt.username; // do not use the hardcoded credentials for a custom mqtt server
+ serverAddr = moduleConfig.mqtt.address;
+ mqttUsername = moduleConfig.mqtt.username;
mqttPassword = moduleConfig.mqtt.password;
- } else {
- // we are using the default server. Use the hardcoded credentials by default, but allow overriding
- if (*moduleConfig.mqtt.username && moduleConfig.mqtt.username[0] != '\0') {
- mqttUsername = moduleConfig.mqtt.username;
- }
- if (*moduleConfig.mqtt.password && moduleConfig.mqtt.password[0] != '\0') {
- mqttPassword = moduleConfig.mqtt.password;
- }
}
String server = String(serverAddr);
@@ -148,8 +140,7 @@ void MQTT::reconnect()
}
pubSub.setServer(serverAddr, serverPort);
- DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password: %s\n", serverAddr, serverPort, mqttUsername,
- mqttPassword);
+ DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password: %s\n", serverAddr, serverPort, mqttUsername, mqttPassword);
auto myStatus = (statusTopic + owner.id);
bool connected = pubSub.connect(owner.id, mqttUsername, mqttPassword, myStatus.c_str(), 1, true, "offline");
if (connected) {
@@ -176,9 +167,11 @@ void MQTT::sendSubscriptions()
String topic = cryptTopic + channels.getGlobalId(i) + "/#";
DEBUG_MSG("Subscribing to %s\n", topic.c_str());
pubSub.subscribe(topic.c_str(), 1); // FIXME, is QOS 1 right?
- String topicDecoded = jsonTopic + channels.getGlobalId(i) + "/#";
- DEBUG_MSG("Subscribing to %s\n", topicDecoded.c_str());
- pubSub.subscribe(topicDecoded.c_str(), 1); // FIXME, is QOS 1 right?
+ if (moduleConfig.mqtt.json_enabled == true) {
+ String topicDecoded = jsonTopic + channels.getGlobalId(i) + "/#";
+ DEBUG_MSG("Subscribing to %s\n", topicDecoded.c_str());
+ pubSub.subscribe(topicDecoded.c_str(), 1); // FIXME, is QOS 1 right?
+ }
}
}
}
diff --git a/variants/m5stack_coreink/Speaker.cpp b/variants/m5stack_coreink/Speaker.cpp
new file mode 100644
index 000000000..0aaff1238
--- /dev/null
+++ b/variants/m5stack_coreink/Speaker.cpp
@@ -0,0 +1,33 @@
+#include "Speaker.h"
+
+TONE::TONE(void) {
+ _volume = 5;
+ _begun = false;
+}
+
+void TONE::begin() {
+ _begun = true;
+ ledcSetup(TONE_PIN_CHANNEL, 0, 13);
+ ledcAttachPin(PIN_BUZZER, TONE_PIN_CHANNEL);
+}
+
+void TONE::end() {
+ mute();
+ ledcDetachPin(PIN_BUZZER);
+ _begun = false;
+}
+
+void TONE::tone(uint16_t frequency) {
+ if(!_begun) begin();
+ ledcWriteTone(TONE_PIN_CHANNEL, frequency);
+ ledcWrite(TONE_PIN_CHANNEL, 0x400 >> _volume);
+}
+
+void TONE::setVolume(uint8_t volume) {
+ _volume = 11 - volume;
+}
+
+void TONE::mute() {
+ ledcWriteTone(TONE_PIN_CHANNEL, 0);
+ digitalWrite(PIN_BUZZER, 0);
+}
\ No newline at end of file
diff --git a/variants/m5stack_coreink/Speaker.h b/variants/m5stack_coreink/Speaker.h
new file mode 100644
index 000000000..2ab877d9b
--- /dev/null
+++ b/variants/m5stack_coreink/Speaker.h
@@ -0,0 +1,30 @@
+#ifndef _SPEAKER_H_
+ #define _SPEAKER_H_
+
+ #include "configuration.h"
+
+ #ifdef __cplusplus
+ extern "C"
+ {
+ #endif /* __cplusplus */
+ #include "esp32-hal-dac.h"
+ #ifdef __cplusplus
+ }
+ #endif /* __cplusplus */
+
+ class TONE {
+ public:
+ TONE(void);
+
+ void begin();
+ void end();
+ void mute();
+ void tone(uint16_t frequency);
+ void setVolume(uint8_t volume);
+
+ private:
+ uint8_t _volume;
+ bool _begun;
+ bool speaker_on;
+ };
+#endif
diff --git a/variants/m5stack_coreink/platformio.ini b/variants/m5stack_coreink/platformio.ini
index c33187da0..796b58e67 100644
--- a/variants/m5stack_coreink/platformio.ini
+++ b/variants/m5stack_coreink/platformio.ini
@@ -1,18 +1,26 @@
[env:m5stack-coreink]
extends = esp32_base
board = m5stack-coreink
+build_src_filter =
+ ${esp32_base.build_src_filter}
+ +<../variants/m5stack_coreink>
build_flags =
- ${esp32_base.build_flags} -D M5_COREINK -I variants/m5stack_coreink
+ ${esp32_base.build_flags} -I variants/m5stack_coreink
;-D RADIOLIB_VERBOSE
-Ofast
-D__MCUXPRESSO
-DEPD_HEIGHT=200
-DEPD_WIDTH=200
+ -DUSER_SETUP_LOADED
+ -DM5_COREINK
-DM5STACK
lib_deps =
${esp32_base.lib_deps}
zinggjm/GxEPD2@^1.4.9
lewisxhe/PCF8563_Library@^1.0.1
+lib_ignore =
+ m5stack-coreink
+monitor_filters = esp32_exception_decoder
board_build.f_cpu = 240000000L
upload_protocol = esptool
-upload_port = /dev/ttyACM*
+upload_port = /dev/ttyACM0
diff --git a/variants/m5stack_coreink/variant.h b/variants/m5stack_coreink/variant.h
index ef490415c..0676fda1c 100644
--- a/variants/m5stack_coreink/variant.h
+++ b/variants/m5stack_coreink/variant.h
@@ -1,34 +1,40 @@
-#define I2C_SDA 21 //-1
-#define I2C_SCL 22 //-1
+#define I2C_SDA 21
+#define I2C_SCL 22
-//#define LED_PIN 10
+// LED?
+#define LED_INVERTED 0
+#define LED_PIN 10
#include "pcf8563.h"
// PCF8563 RTC Module
#define PCF8563_RTC 0x51
-
-#define BUTTON_NEED_PULLUP
-#define BUTTON_PIN 5
+#define HAS_RTC 1
//Wheel
// Down 37
// Push 38
// Up 39
-
// Top Physical Button 5
+#define BUTTON_NEED_PULLUP
+#define BUTTON_PIN 5
+
+//BUZZER
+#define PIN_BUZZER 2
+#define TONE_PIN_CHANNEL 0
+
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
#define USE_RF95
-#define RF95_SCK 18 //13
-#define RF95_MISO 34 //26
-#define RF95_MOSI 23 //25
+#define RF95_SCK 18
+#define RF95_MISO 34
+#define RF95_MOSI 23
#define RF95_NSS 14
-#define LORA_DIO0 25 //32 now moved from ext port
-#define LORA_RESET 26 //33 now moved from ext port
+#define LORA_DIO0 25
+#define LORA_RESET 26
#define LORA_DIO1 RADIOLIB_NC
#define LORA_DIO2 RADIOLIB_NC
@@ -39,12 +45,10 @@
#define USE_EINK
//https://docs.m5stack.com/en/core/coreink
//https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/schematic/Core/coreink/coreink_sch.pdf
-#define PIN_EINK_EN -1
-#define PIN_EINK_CS 9 // EPD_CS
-#define PIN_EINK_BUSY 4 // EPD_BUSY
+#define PIN_EINK_EN -1 // N/C
+#define PIN_EINK_CS 9 // EPD_CS
+#define PIN_EINK_BUSY 4 // EPD_BUSY
#define PIN_EINK_DC 15 // EPD_D/C
-#define PIN_EINK_RES -1 // Connected to GPIO0 but no needed !!!! maybe causing issue ?
-#define PIN_EINK_SCLK 18 // EPD_SCLK
+#define PIN_EINK_RES -1 // Connected but not needed
+#define PIN_EINK_SCLK 18 // EPD_SCLK
#define PIN_EINK_MOSI 23 // EPD_MOSI
-
-#define HAS_RTC 1
diff --git a/variants/portduino/platformio.ini b/variants/portduino/platformio.ini
index c95ae37fe..5bbde2adf 100644
--- a/variants/portduino/platformio.ini
+++ b/variants/portduino/platformio.ini
@@ -1,16 +1,22 @@
[env:native]
-platform = https://github.com/meshtastic/platform-native.git
+extends = portduino_base
build_flags = ${portduino_base.build_flags} -O0 -I variants/portduino
-framework = arduino
board = cross_platform
lib_deps = ${portduino_base.lib_deps}
build_src_filter = ${portduino_base.build_src_filter}
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
[env:linux]
-platform = https://github.com/meshtastic/platform-native.git
+extends = portduino_base
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino
-framework = arduino
board = linux_hardware
lib_deps = ${portduino_base.lib_deps}
build_src_filter = ${portduino_base.build_src_filter}
+
+; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
+[env:linux-arm]
+extends = portduino_base
+build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino
+board = linux_arm
+lib_deps = ${portduino_base.lib_deps}
+build_src_filter = ${portduino_base.build_src_filter}
diff --git a/variants/portduino/variant.h b/variants/portduino/variant.h
index 328afaf19..76696b7af 100644
--- a/variants/portduino/variant.h
+++ b/variants/portduino/variant.h
@@ -23,16 +23,3 @@
// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
#endif
-// Temporary shim for radio lib macros until we upgrade to upstream for portduino
-#define RADIOLIB_PREAMBLE_DETECTED PREAMBLE_DETECTED
-
-#define RADIOLIB_ERR_NONE ERR_NONE
-#define RADIOLIB_ERR_WRONG_MODEM ERR_WRONG_MODEM
-
-#define RADIOLIB_SX126X_IRQ_HEADER_VALID SX126X_IRQ_HEADER_VALID
-#define RADIOLIB_SX126X_LORA_CRC_ON SX126X_LORA_CRC_ON
-
-#define RADIOLIB_SX127X_REG_TCXO SX127X_REG_TCXO
-#define RADIOLIB_SX127X_REG_MODEM_STAT SX127X_REG_MODEM_STAT
-#define RADIOLIB_SX127X_SYNC_WORD SX127X_SYNC_WORD
-#define RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER SX127X_MASK_IRQ_FLAG_VALID_HEADER
diff --git a/variants/tlora_v1/variant.h b/variants/tlora_v1/variant.h
index 3a1d61db5..6ab8bad4c 100644
--- a/variants/tlora_v1/variant.h
+++ b/variants/tlora_v1/variant.h
@@ -6,7 +6,7 @@
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
-// #define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
+#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
#define LED_PIN 2 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define BUTTON_NEED_PULLUP
diff --git a/variants/tlora_v2_1_18/platformio.ini b/variants/tlora_v2_1_18/platformio.ini
index 4160be5de..f5af98904 100644
--- a/variants/tlora_v2_1_18/platformio.ini
+++ b/variants/tlora_v2_1_18/platformio.ini
@@ -5,4 +5,4 @@ lib_deps =
${esp32_base.lib_deps}
caveman99/ESP32 Codec2@^1.0.1
build_flags =
- ${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18
\ No newline at end of file
+ ${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18 -D RADIOLIB_GODMODE
\ No newline at end of file
diff --git a/version.properties b/version.properties
index 6172336cc..d560f5ba6 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 0
-build = 4
+build = 6