Merge branch 'master' of github.com:meshtastic/firmware

This commit is contained in:
Thomas Göttgens 2022-11-24 00:03:45 +01:00
commit 605fadabcf
36 changed files with 265 additions and 170 deletions

View File

@ -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

View File

@ -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

View File

@ -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}
-<platform/esp32/>
@ -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

View File

@ -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

@ -1 +1 @@
Subproject commit da9bba9c5dd43a98d431cb7a95159b145f0483c4
Subproject commit 24874086e392b0ec504f9f89137e7b7f8b5bfcbd

View File

@ -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()
{

View File

@ -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)

View File

@ -8,6 +8,6 @@ template class SX126xInterface<SX1262>;
template class SX126xInterface<SX1268>;
template class SX126xInterface<LLCC68>;
#if !defined(ARCH_PORTDUINO)
#if defined(RADIOLIB_GODMODE)
template class SX128xInterface<SX1280>;
#endif

View File

@ -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);
}
}
/**

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -144,8 +144,9 @@ bool SX126xInterface<T>::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);

View File

@ -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)

View File

@ -6,7 +6,7 @@
* Our adapter for SX1280 radios
*/
#if !defined(ARCH_PORTDUINO)
#if defined(RADIOLIB_GODMODE)
class SX1280Interface : public SX128xInterface<SX1280>
{

View File

@ -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<T>::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<T>::isChannelActive()
template<typename T>
bool SX128xInterface<T>::isActivelyReceiving()
{
return isChannelActive();
// return isChannelActive();
uint16_t irq = lora.getIrqStatus();
bool hasPreamble = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
return hasPreamble;
}
template<typename T>

View File

@ -1,6 +1,6 @@
#pragma once
#if !defined(ARCH_PORTDUINO)
#if defined(RADIOLIB_GODMODE)
#include "RadioLibInterface.h"

View File

@ -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) \

View File

@ -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");

View File

@ -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

View File

@ -20,6 +20,9 @@ class AdminModule : public ProtobufModule<AdminMessage>
virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p) override;
private:
bool hasOpenEditTransaction = false;
void saveChanges(int saveWhat, bool shouldReboot = true);
/**
* Getters
*/

View File

@ -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");

View File

@ -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?
}
}
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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
${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18 -D RADIOLIB_GODMODE

View File

@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 0
build = 4
build = 6