diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml
index 795c1b1a0..d4e00b4ed 100644
--- a/.github/ISSUE_TEMPLATE/Bug Report.yml
+++ b/.github/ISSUE_TEMPLATE/Bug Report.yml
@@ -40,10 +40,12 @@ body:
- T-Echo
- Rak4631
- Rak11200
+ - Rak11310
- Heltec v1
- Heltec v2
- Heltec v2.1
- Heltec V3
+ - Raspberry Pi Pico (W)
- Relay v1
- Relay v2
- DIY
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 9ef8f77c6..32f280a04 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -7,7 +7,8 @@
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on
-- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor and the 'clang-format' extension,
- because automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines.
+- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows),
+ because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed.
+- Please also enable "Allow edits by maintainers".
diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index caf04fff6..1cac7479b 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -150,12 +150,14 @@ jobs:
release/device-*.bat
- name: Docker login
+ if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/login-action@v2
with:
username: meshtastic
password: ${{ secrets.DOCKER_TOKEN }}
- name: Docker setup
+ if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/setup-buildx-action@v2
- name: Docker build and push tagged versions
@@ -168,7 +170,7 @@ jobs:
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
- name: Docker build and push
- if: github.ref == 'refs/heads/master'
+ if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/build-push-action@v3
with:
context: .
diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini
index 961b41852..62a943ece 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -37,7 +37,7 @@ lib_deps =
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0
- jgromes/RadioLib@^6.0.0
+ jgromes/RadioLib@^6.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
@@ -55,4 +55,4 @@ lib_ignore =
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
-board_build.partitions = partition-table.csv
+board_build.partitions = partition-table.csv
\ No newline at end of file
diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index d471e24c5..f44054f24 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -13,8 +13,7 @@ build_src_filter =
lib_deps=
${arduino_base.lib_deps}
- jgromes/RadioLib@^6.0.0
+ jgromes/RadioLib@^6.1.0
lib_ignore =
- BluetoothOTA
-
+ BluetoothOTA
\ No newline at end of file
diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini
index 7e3557475..b39974853 100644
--- a/arch/portduino/portduino.ini
+++ b/arch/portduino/portduino.ini
@@ -1,6 +1,6 @@
; 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#096b3c3e9c5c8e19d4c3b6cd803fffef2a9be4c5
+platform = https://github.com/meshtastic/platform-native.git#489ff929dca0bb768256ba2de45f95815111490f
framework = arduino
build_src_filter =
@@ -22,9 +22,9 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
- jgromes/RadioLib@^6.0.0
+ jgromes/RadioLib@6.1.0
build_flags =
${arduino_base.build_flags}
-fPIC
- -Isrc/platform/portduino
+ -Isrc/platform/portduino
\ No newline at end of file
diff --git a/arch/rp2040/rp2040.ini b/arch/rp2040/rp2040.ini
index 1ed83f3b0..52fba9cba 100644
--- a/arch/rp2040/rp2040.ini
+++ b/arch/rp2040/rp2040.ini
@@ -2,7 +2,7 @@
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
extends = arduino_base
-platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.1
+platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.2
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@@ -20,5 +20,5 @@ lib_ignore =
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
- jgromes/RadioLib@^6.0.0
+ jgromes/RadioLib@^6.1.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
\ No newline at end of file
diff --git a/arch/stm32/stm32wl5e.ini b/arch/stm32/stm32wl5e.ini
index b610bf40b..819ecc31c 100644
--- a/arch/stm32/stm32wl5e.ini
+++ b/arch/stm32/stm32wl5e.ini
@@ -1,20 +1,29 @@
[stm32wl5e_base]
-platform = platformio/ststm32@^15.4.1
+platform_packages = platformio/framework-arduinoststm32 @ https://github.com/stm32duino/Arduino_Core_STM32.git#6e3f9910d0122e82a6c3438507dfac3d2fd80a39
+platform = ststm32
board = generic_wl5e
framework = arduino
build_type = debug
-build_flags =
+
+build_flags =
${arduino_base.build_flags}
-Isrc/platform/stm32wl -g
+ -DconfigUSE_CMSIS_RTOS_V2=1
+ -DVECT_TAB_OFFSET=0x08000000
+
+build_src_filter =
+ ${arduino_base.build_src_filter} - - - - - - - - - - - - -
-build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - - - - - - - -
+board_upload.offset_address = 0x08000000
+upload_protocol = stlink
lib_deps =
${env.lib_deps}
- jgromes/RadioLib@^6.0.0
+ jgromes/RadioLib@^6.1.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
+ https://github.com/littlefs-project/littlefs.git#v2.5.1
+ https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
lib_ignore =
- https://github.com/mathertel/OneButton#2.1.0
+ https://github.com/mathertel/OneButton#2.1.0
\ No newline at end of file
diff --git a/boards/generic_wl5e.json b/boards/generic_wl5e.json
index 433c55b59..5c4bc24a7 100644
--- a/boards/generic_wl5e.json
+++ b/boards/generic_wl5e.json
@@ -20,7 +20,7 @@
"maximum_ram_size": 65536,
"maximum_size": 262144,
"protocol": "cmsis-dap",
- "protocols": ["cmsis-dap"]
+ "protocols": ["cmsis-dap", "stlink"]
},
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST"
diff --git a/platformio.ini b/platformio.ini
index 156eb0076..b580d7160 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -2,7 +2,7 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
-default_envs = tbeam
+;default_envs = tbeam
;default_envs = pico
;default_envs = tbeam-s3-core
;default_envs = tbeam0.7
@@ -25,6 +25,7 @@ default_envs = tbeam
;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
+default_envs = wio-e5
extra_configs =
arch/*/*.ini
@@ -55,6 +56,12 @@ build_flags = -Wno-missing-field-initializers
-DRADIOLIB_EXCLUDE_MORSE
-DRADIOLIB_EXCLUDE_RTTY
-DRADIOLIB_EXCLUDE_SSTV
+ -DRADIOLIB_EXCLUDE_AX25
+ -DRADIOLIB_EXCLUDE_DIRECT_RECEIVE
+ -DRADIOLIB_EXCLUDE_BELL
+ -DRADIOLIB_EXCLUDE_PAGER
+ -DRADIOLIB_EXCLUDE_FSK4
+ -DRADIOLIB_EXCLUDE_APRS
monitor_speed = 115200
diff --git a/protobufs b/protobufs
index 1a8f80d7f..5f3daac5f 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 1a8f80d7fe2b8e4c0dd9d204d5a6c07151dc10a5
+Subproject commit 5f3daac5fabdfe2a0561395fed0ba11a38ba3e7e
diff --git a/src/ButtonThread.h b/src/ButtonThread.h
index d8e781a6c..135d727c2 100644
--- a/src/ButtonThread.h
+++ b/src/ButtonThread.h
@@ -157,7 +157,7 @@ class ButtonThread : public concurrency::OSThread
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif
screen->print("Sent ad-hoc ping\n");
- service.refreshMyNodeInfo();
+ service.refreshLocalMeshNode();
service.sendNetworkPing(NODENUM_BROADCAST, true);
}
@@ -196,4 +196,4 @@ class ButtonThread : public concurrency::OSThread
}
};
-} // namespace concurrency
+} // namespace concurrency
\ No newline at end of file
diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp
index cc99caed8..150391237 100644
--- a/src/FSCommon.cpp
+++ b/src/FSCommon.cpp
@@ -57,7 +57,7 @@ bool renameFile(const char *pathFrom, const char *pathTo)
#endif
}
-void listDir(const char *dirname, uint8_t levels, boolean del = false)
+void listDir(const char *dirname, uint8_t levels, bool del = false)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
diff --git a/src/FSCommon.h b/src/FSCommon.h
index 98d3911d7..ef1d3e4c1 100644
--- a/src/FSCommon.h
+++ b/src/FSCommon.h
@@ -13,6 +13,13 @@
#define FILE_O_READ "r"
#endif
+#if defined(ARCH_STM32WL)
+#include "platform/stm32wl/InternalFileSystem.h" // STM32WL version
+#define FSCom InternalFS
+#define FSBegin() FSCom.begin()
+using namespace LittleFS_Namespace;
+#endif
+
#if defined(ARCH_RP2040)
// RP2040
#include "LittleFS.h"
@@ -42,6 +49,6 @@ using namespace Adafruit_LittleFS_Namespace;
void fsInit();
bool copyFile(const char *from, const char *to);
bool renameFile(const char *pathFrom, const char *pathTo);
-void listDir(const char *dirname, uint8_t levels, boolean del);
+void listDir(const char *dirname, uint8_t levels, bool del);
void rmDir(const char *dirname);
void setupSDCard();
\ No newline at end of file
diff --git a/src/GPSStatus.h b/src/GPSStatus.h
index 6b760385f..ed3b3fc14 100644
--- a/src/GPSStatus.h
+++ b/src/GPSStatus.h
@@ -55,7 +55,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude\n");
#endif
- meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
return node->position.latitude_i;
} else {
return p.latitude_i;
@@ -68,7 +68,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude\n");
#endif
- meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
return node->position.longitude_i;
} else {
return p.longitude_i;
@@ -81,7 +81,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude\n");
#endif
- meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
return node->position.altitude;
} else {
return p.altitude;
@@ -149,4 +149,4 @@ class GPSStatus : public Status
} // namespace meshtastic
-extern meshtastic::GPSStatus *gpsStatus;
+extern meshtastic::GPSStatus *gpsStatus;
\ No newline at end of file
diff --git a/src/Power.cpp b/src/Power.cpp
index 1f4c3535a..37d80a31f 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -37,12 +37,18 @@ static const adc_atten_t atten = ADC_ATTENUATION;
#endif
#endif // BATTERY_PIN && ARCH_ESP32
+#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
+INA260Sensor ina260Sensor;
+INA219Sensor ina219Sensor;
+#endif
+
#ifdef HAS_PMU
#include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp"
#include "XPowersLibInterface.hpp"
XPowersLibInterface *PMU = NULL;
#else
+
// Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency.
class HasBatteryLevel
@@ -128,6 +134,13 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override
{
+#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
+ if (hasINA()) {
+ LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
+ return getINAVoltage();
+ }
+#endif
+
#ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 2.0
#endif
@@ -246,6 +259,35 @@ class AnalogBatteryLevel : public HasBatteryLevel
const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT;
float last_read_value = 0.0;
uint32_t last_read_time_ms = 0;
+
+#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
+ uint16_t getINAVoltage()
+ {
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
+ return ina219Sensor.getBusVoltageMv();
+ } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
+ return ina260Sensor.getBusVoltageMv();
+ }
+ return 0;
+ }
+
+ bool hasINA()
+ {
+ if (!config.power.device_battery_ina_address) {
+ return false;
+ }
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
+ if (!ina219Sensor.isInitialized())
+ return ina219Sensor.runOnce() > 0;
+ return ina219Sensor.isRunning();
+ } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
+ if (!ina260Sensor.isInitialized())
+ return ina260Sensor.runOnce() > 0;
+ return ina260Sensor.isRunning();
+ }
+ return false;
+ }
+#endif
};
AnalogBatteryLevel analogLevel;
@@ -639,7 +681,6 @@ bool Power::axpChipInit()
// GNSS VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
-
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
// t-beam s3 core
/**
diff --git a/src/airtime.cpp b/src/airtime.cpp
index 7be4c5b0d..2702ee2bf 100644
--- a/src/airtime.cpp
+++ b/src/airtime.cpp
@@ -6,20 +6,22 @@ AirTime *airTime = NULL;
// Don't read out of this directly. Use the helper functions.
+uint32_t air_period_tx[PERIODS_TO_LOG];
+uint32_t air_period_rx[PERIODS_TO_LOG];
+
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
if (reportType == TX_LOG) {
LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
- myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
+ air_period_tx[0] = air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
-
} else if (reportType == RX_LOG) {
LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
- myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
+ air_period_rx[0] = air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
@@ -55,16 +57,16 @@ void AirTime::airtimeRotatePeriod()
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
- myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
- myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
+ air_period_tx[i + 1] = this->airtimes.periodTX[i];
+ air_period_rx[i + 1] = this->airtimes.periodRX[i];
}
this->airtimes.periodTX[0] = 0;
this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0;
- myNodeInfo.air_period_tx[0] = 0;
- myNodeInfo.air_period_rx[0] = 0;
+ air_period_tx[0] = 0;
+ air_period_rx[0] = 0;
this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
}
@@ -179,18 +181,17 @@ int32_t AirTime::runOnce()
}
// Init airtime windows to all 0
- for (int i = 0; i < myNodeInfo.air_period_rx_count; i++) {
+ for (int i = 0; i < PERIODS_TO_LOG; i++) {
this->airtimes.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0;
- // myNodeInfo.air_period_tx[i] = 0;
- // myNodeInfo.air_period_rx[i] = 0;
+ // air_period_tx[i] = 0;
+ // air_period_rx[i] = 0;
}
firstTime = false;
lastUtilPeriod = utilPeriod;
-
} else {
this->airtimeRotatePeriod();
@@ -206,12 +207,6 @@ int32_t AirTime::runOnce()
this->utilizationTX[utilPeriodTX] = 0;
}
-
- // Update channel_utilization every second.
- myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
-
- // Update channel_utilization every second.
- myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
/*
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
@@ -223,4 +218,4 @@ int32_t AirTime::runOnce()
LOG_DEBUG("\n");
*/
return (1000 * 1);
-}
+}
\ No newline at end of file
diff --git a/src/error.h b/src/error.h
index fc0707cd6..d16ee6595 100644
--- a/src/error.h
+++ b/src/error.h
@@ -9,4 +9,4 @@
/// Record an error that should be reported via analytics
void recordCriticalError(meshtastic_CriticalErrorCode code = meshtastic_CriticalErrorCode_UNSPECIFIED, uint32_t address = 0,
- const char *filename = NULL);
+ const char *filename = NULL);
\ No newline at end of file
diff --git a/src/freertosinc.h b/src/freertosinc.h
index c5dfddc8e..166054241 100644
--- a/src/freertosinc.h
+++ b/src/freertosinc.h
@@ -12,7 +12,7 @@
#include
#endif
-#if defined(ARDUINO_NRF52_ADAFRUIT)
+#if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_RP2040)
#define HAS_FREE_RTOS
#include
@@ -44,4 +44,4 @@ typedef uint32_t BaseType_t;
enum eNotifyAction { eNoAction, eSetValueWithoutOverwrite, eSetValueWithOverwrite };
-#endif
+#endif
\ No newline at end of file
diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp
index 784ecac5d..9eff4d00e 100644
--- a/src/gps/NMEAWPL.cpp
+++ b/src/gps/NMEAWPL.cpp
@@ -18,7 +18,7 @@
* -------------------------------------------
*/
-uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode)
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, const char *name, bool isCaltopoMode)
{
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
char type = isCaltopoMode ? 'P' : 'N';
@@ -34,6 +34,21 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const
return len;
}
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode)
+{
+ GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
+ char type = isCaltopoMode ? 'P' : 'N';
+ uint32_t len = snprintf(buf, bufsz, "$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(),
+ (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
+ geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
+ geoCoord.getDMSLonCP(), name);
+ uint32_t chk = 0;
+ for (uint32_t i = 1; i < len; i++) {
+ chk ^= buf[i];
+ }
+ len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
+ return len;
+}
/* -------------------------------------------
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
* | | | | | | | | | | | | | | |
diff --git a/src/gps/NMEAWPL.h b/src/gps/NMEAWPL.h
index d597b7ea6..5821624c6 100644
--- a/src/gps/NMEAWPL.h
+++ b/src/gps/NMEAWPL.h
@@ -4,4 +4,5 @@
#include
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode = false);
-uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, const char *name, bool isCaltopoMode = false);
+uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
\ No newline at end of file
diff --git a/src/graphics/RAKled.h b/src/graphics/RAKled.h
new file mode 100644
index 000000000..06e2a717f
--- /dev/null
+++ b/src/graphics/RAKled.h
@@ -0,0 +1,7 @@
+#include "main.h"
+
+#ifdef RAK4630
+#include
+extern NCP5623 rgb;
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 91db473d0..434ca2f97 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -27,6 +27,7 @@ along with this program. If not, see .
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
+#include "error.h"
#include "gps/GeoCoord.h"
#include "gps/RTC.h"
#include "graphics/images.h"
@@ -352,7 +353,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
display->setFont(FONT_MEDIUM);
char tempBuf[24];
- snprintf(tempBuf, sizeof(tempBuf), "Critical fault #%d", myNodeInfo.error_code);
+ snprintf(tempBuf, sizeof(tempBuf), "Critical fault #%d", error_code);
display->drawString(0 + x, 0 + y, tempBuf);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
@@ -372,7 +373,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_text_message;
- meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// mp.decoded.variant.data.decoded.bytes);
@@ -410,7 +411,7 @@ static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, i
static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
- meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
@@ -792,16 +793,16 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
if (state->currentFrame != prevFrame) {
prevFrame = state->currentFrame;
- nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
- meshtastic_NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
+ nodeIndex = (nodeIndex + 1) % nodeDB.getNumMeshNodes();
+ meshtastic_NodeInfoLite *n = nodeDB.getMeshNodeByIndex(nodeIndex);
if (n->num == nodeDB.getNodeNum()) {
// Don't show our node, just skip to next
- nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
- n = nodeDB.getNodeByIndex(nodeIndex);
+ nodeIndex = (nodeIndex + 1) % nodeDB.getNumMeshNodes();
+ n = nodeDB.getMeshNodeByIndex(nodeIndex);
}
}
- meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNodeByIndex(nodeIndex);
display->setFont(FONT_SMALL);
@@ -835,7 +836,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
static char distStr[20];
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
- meshtastic_NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *ourNode = nodeDB.getMeshNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
int16_t compassX = 0, compassY = 0;
@@ -850,14 +851,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
bool hasNodeHeading = false;
if (ourNode && hasValidPosition(ourNode)) {
- meshtastic_Position &op = ourNode->position;
+ meshtastic_PositionLite &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading);
if (hasValidPosition(node)) {
// display direction toward node
hasNodeHeading = true;
- meshtastic_Position &p = node->position;
+ meshtastic_PositionLite &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
@@ -1239,9 +1240,9 @@ void Screen::setFrames()
#endif
// We don't show the node info our our node (if we have it yet - we should)
- size_t numnodes = nodeDB.getNumNodes();
- if (numnodes > 0)
- numnodes--;
+ size_t numMeshNodes = nodeDB.getNumMeshNodes();
+ if (numMeshNodes > 0)
+ numMeshNodes--;
size_t numframes = 0;
@@ -1258,7 +1259,7 @@ void Screen::setFrames()
LOG_DEBUG("Added modules. numframes: %d\n", numframes);
// If we have a critical fault, show it first
- if (myNodeInfo.error_code)
+ if (error_code)
normalFrames[numframes++] = drawCriticalFaultFrame;
// If we have a text message - show it next, unless it's a phone message and we aren't using any special modules
@@ -1272,7 +1273,7 @@ void Screen::setFrames()
// then all the nodes
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
- size_t numToShow = min(numnodes, 4U);
+ size_t numToShow = min(numMeshNodes, 4U);
for (size_t i = 0; i < numToShow; i++)
normalFrames[numframes++] = drawNodeInfo;
@@ -1849,4 +1850,4 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
} // namespace graphics
#else
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
-#endif // HAS_SCREEN
+#endif // HAS_SCREEN
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 5120cb269..c867930d0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,6 +19,7 @@
#include "detect/ScanI2CTwoWire.h"
#include "detect/axpDebug.h"
#include "detect/einkScan.h"
+#include "graphics/RAKled.h"
#include "graphics/Screen.h"
#include "main.h"
#include "mesh/generated/meshtastic/config.pb.h"
@@ -59,6 +60,9 @@ NRF52Bluetooth *nrf52Bluetooth;
#include "SX1262Interface.h"
#include "SX1268Interface.h"
#include "SX1280Interface.h"
+#ifdef ARCH_STM32WL
+#include "STM32WLE5JCInterface.h"
+#endif
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h"
#endif
@@ -68,7 +72,7 @@ NRF52Bluetooth *nrf52Bluetooth;
#endif
#include "PowerFSMThread.h"
-#if !defined(ARCH_PORTDUINO)
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "AccelerometerThread.h"
#endif
@@ -260,6 +264,12 @@ void setup()
// We need to enable 3.3V periphery in order to scan it
pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, HIGH);
+
+#ifndef USE_EINK
+ // RAK-12039 set pin for Air quality sensor
+ pinMode(AQ_SET_PIN, OUTPUT);
+ digitalWrite(AQ_SET_PIN, HIGH);
+#endif
#endif
// Currently only the tbeam has a PMU
@@ -347,10 +357,20 @@ void setup()
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
* "found".
*/
+
// Only one supported RGB LED currently
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
-#if !defined(ARCH_PORTDUINO)
+// Start the RGB LED at 50%
+#ifdef RAK4630
+ if (rgb_found.type == ScanI2C::NCP5623) {
+ rgb.begin();
+ rgb.setCurrent(10);
+ rgb.setColor(128, 128, 128);
+ }
+#endif
+
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type);
@@ -439,7 +459,7 @@ void setup()
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
#endif
-#if !defined(ARCH_PORTDUINO)
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (acc_info.type != ScanI2C::DeviceType::NONE) {
accelerometerThread = new AccelerometerThread(acc_info.type);
}
@@ -530,6 +550,18 @@ void setup()
#endif
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
+#if defined(USE_STM32WLx)
+ if (!rIf) {
+ rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
+ if (!rIf->init()) {
+ LOG_WARN("Failed to find STM32WL radio\n");
+ delete rIf;
+ rIf = NULL;
+ } else {
+ LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n");
+ }
+ }
+#endif
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
if (!rIf) {
@@ -651,12 +683,10 @@ void setup()
else {
router->addInterface(rIf);
- // Calculate and save the bit rate to myNodeInfo
- // TODO: This needs to be added what ever method changes the channel from the phone.
- myNodeInfo.bitrate =
- (float(meshtastic_Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
- 1000;
- LOG_DEBUG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
+ // Log bit rate to debug output
+ LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
+ (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
+ 1000);
}
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
@@ -677,7 +707,7 @@ bool runASAP;
extern meshtastic_DeviceMetadata getDeviceMetadata()
{
meshtastic_DeviceMetadata deviceMetadata;
- strncpy(deviceMetadata.firmware_version, myNodeInfo.firmware_version, 18);
+ strncpy(deviceMetadata.firmware_version, optstr(APP_VERSION), sizeof(deviceMetadata.firmware_version));
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
deviceMetadata.hasBluetooth = HAS_BLUETOOTH;
diff --git a/src/main.h b/src/main.h
index 0d23dd10c..93baec590 100644
--- a/src/main.h
+++ b/src/main.h
@@ -38,8 +38,6 @@ extern bool isUSBPowered;
extern ATECCX08A atecc;
#endif
-extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
-
extern int TCPPort; // set by Portduino
// Global Screen singleton.
@@ -69,4 +67,4 @@ void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), clearBonds();
meshtastic_DeviceMetadata getDeviceMetadata();
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
-extern SPISettings spiSettings;
+extern SPISettings spiSettings;
\ No newline at end of file
diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp
index d8861943e..171199277 100644
--- a/src/mesh/FloodingRouter.cpp
+++ b/src/mesh/FloodingRouter.cpp
@@ -21,6 +21,7 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
{
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg, because we've already seen it", p);
+ Router::cancelSending(p->from, p->id); // cancel rebroadcast of this message *if* there was already one
return true;
}
@@ -62,4 +63,4 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
}
// handle the packet as normal
Router::sniffReceived(p, c);
-}
+}
\ No newline at end of file
diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp
index 73b0bdfbc..c732829e9 100644
--- a/src/mesh/InterfacesTemplates.cpp
+++ b/src/mesh/InterfacesTemplates.cpp
@@ -10,6 +10,9 @@ template class SX126xInterface;
template class SX126xInterface;
template class SX126xInterface;
template class SX128xInterface;
+#ifdef ARCH_STM32WL
+template class SX126xInterface;
+#endif
#if HAS_ETHERNET
#include "api/ethServerAPI.h"
diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp
index 4408f408e..2ad46a6b7 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -9,6 +9,7 @@
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RTC.h"
+#include "TypeConversions.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "modules/NodeInfoModule.h"
@@ -76,7 +77,8 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
- if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getNode(mp->from)->has_user && nodeInfoModule) {
+ if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getMeshNode(mp->from)->has_user &&
+ nodeInfoModule) {
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
}
@@ -236,7 +238,8 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
{
- meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
+
assert(node);
if (hasValidPosition(node)) {
@@ -266,9 +269,9 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
fromNum++;
}
-meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
+meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
{
- meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
assert(node);
// We might not have a position yet for our local node, in that case, at least try to send the time
@@ -277,7 +280,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
node->has_position = true;
}
- meshtastic_Position &position = node->position;
+ meshtastic_PositionLite &position = node->position;
// Update our local node info with our time (even if we don't decide to update anyone else)
node->last_heard =
@@ -293,7 +296,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
{
// Update our local node info with our position (even if we don't decide to update anyone else)
- meshtastic_NodeInfo *node = refreshMyNodeInfo();
+ meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
meshtastic_Position pos = meshtastic_Position_init_default;
if (newStatus->getHasLock()) {
@@ -307,12 +310,12 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
#endif
if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n");
- pos = node->position;
+ pos = ConvertToPosition(node->position);
}
}
// Finally add a fresh timestamp and battery level reading
- // I KNOW this is redundant with refreshMyNodeInfo() above, but these are
+ // I KNOW this is redundant with refreshLocalMeshNode() above, but these are
// inexpensive nonblocking calls and can be refactored in due course
pos.time = getValidTime(RTCQualityGPS);
@@ -329,4 +332,4 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
bool MeshService::isToPhoneQueueEmpty()
{
return toPhoneQueue.isEmpty();
-}
+}
\ No newline at end of file
diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h
index 4314ea362..d14db7139 100644
--- a/src/mesh/MeshService.h
+++ b/src/mesh/MeshService.h
@@ -98,7 +98,7 @@ class MeshService
bool cancelSending(PacketId id);
/// Pull the latest power and time info into my nodeinfo
- meshtastic_NodeInfo *refreshMyNodeInfo();
+ meshtastic_NodeInfoLite *refreshLocalMeshNode();
/// Send a packet to the phone
void sendToPhone(meshtastic_MeshPacket *p);
@@ -118,4 +118,4 @@ class MeshService
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
};
-extern MeshService service;
+extern MeshService service;
\ No newline at end of file
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index b1dd3d06d..565a08ff9 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -11,6 +11,7 @@
#include "PowerFSM.h"
#include "RTC.h"
#include "Router.h"
+#include "TypeConversions.h"
#include "error.h"
#include "main.h"
#include "mesh-pb-constants.h"
@@ -55,10 +56,18 @@ extern void getMacAddr(uint8_t *dmac);
* we use !macaddr (no colons).
*/
meshtastic_User &owner = devicestate.owner;
+meshtastic_Position localPosition = meshtastic_Position_init_default;
+meshtastic_CriticalErrorCode error_code =
+ meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
+uint32_t error_address = 0;
static uint8_t ourMacAddr[6];
-NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
+NodeDB::NodeDB()
+ : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count), meshNodes(devicestate.node_db_lite),
+ numMeshNodes(&devicestate.node_db_lite_count)
+{
+}
/**
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
@@ -216,6 +225,15 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
moduleConfig.has_external_notification = true;
+#if defined(RAK4630) || defined(RAK11310)
+ // Default to RAK led pin 2 (blue)
+ moduleConfig.external_notification.enabled = true;
+ moduleConfig.external_notification.output = PIN_LED2;
+ moduleConfig.external_notification.active = true;
+ moduleConfig.external_notification.alert_message = true;
+ moduleConfig.external_notification.output_ms = 1000;
+ moduleConfig.external_notification.nag_timeout = 60;
+#endif
moduleConfig.has_canned_message = true;
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
@@ -258,6 +276,9 @@ void NodeDB::resetNodes()
{
devicestate.node_db_count = 0;
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
+
+ devicestate.node_db_lite_count = 0;
+ memset(devicestate.node_db_lite, 0, sizeof(devicestate.node_db_lite));
saveDeviceStateToDisk();
}
@@ -272,17 +293,12 @@ void NodeDB::installDefaultDeviceState()
devicestate.has_my_node = true;
devicestate.has_owner = true;
devicestate.node_db_count = 0;
+ devicestate.node_db_lite_count = 0;
devicestate.version = DEVICESTATE_CUR_VER;
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
- // default to no GPS, until one has been found by probing
- myNodeInfo.has_gps = false;
- myNodeInfo.message_timeout_msec = FLOOD_EXPIRE_TIME;
generatePacketId(); // FIXME - ugly way to init current_packet_id;
- // Init our blank owner info to reasonable defaults
- getMacAddr(ourMacAddr);
-
// Set default owner name
pickNewNodeNum(); // based on macaddr now
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
@@ -303,28 +319,34 @@ void NodeDB::init()
int saveWhat = 0;
- myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
-
- myNodeInfo.error_code =
- meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
- myNodeInfo.error_address = 0;
-
// likewise - we always want the app requirements to come from the running appload
- myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
-
+ myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
+ myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
// Note! We do this after loading saved settings, so that if somehow an invalid nodenum was stored in preferences we won't
// keep using that nodenum forever. Crummy guess at our nodenum (but we will check against the nodedb to avoid conflicts)
+ strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
pickNewNodeNum();
// Set our board type so we can share it with others
owner.hw_model = HW_VENDOR;
// Include our owner in the node db under our nodenum
- meshtastic_NodeInfo *info = getOrCreateNode(getNodeNum());
+ meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum());
info->user = owner;
info->has_user = true;
- strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
+ if (*numNodes > 0) {
+ LOG_DEBUG("Legacy NodeDB detected... Migrating to NodeDBLite\n");
+ uint32_t readIndex = 0;
+ const meshtastic_NodeInfo *oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
+ while (oldNodeInfo != NULL) {
+ migrateToNodeInfoLite(oldNodeInfo);
+ oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
+ }
+ LOG_DEBUG("Migration complete! Clearing out legacy NodeDB...\n");
+ devicestate.node_db_count = 0;
+ memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
+ }
#ifdef ARCH_ESP32
Preferences preferences;
@@ -332,11 +354,6 @@ void NodeDB::init()
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
preferences.end();
LOG_DEBUG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
-
- /* The ESP32 has a wifi radio. This will need to be modified at some point so
- * the test isn't so simplistic.
- */
- myNodeInfo.has_wifi = true;
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
@@ -367,17 +384,19 @@ void NodeDB::pickNewNodeNum()
{
NodeNum r = myNodeInfo.my_node_num;
- // If we don't have a nodenum at app - pick an initial nodenum based on the macaddr
- if (r == 0)
- r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
+ getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
+
+ // Pick an initial nodenum based on the macaddr
+ r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
r = NUM_RESERVED; // don't pick a reserved node number
- meshtastic_NodeInfo *found;
- while ((found = getNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
+ meshtastic_NodeInfoLite *found;
+ while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
+ // FIXME: input for random() is int, so NODENUM_BROADCAST becomes -1
NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice
- LOG_DEBUG("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
+ LOG_WARN("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
r = n;
}
@@ -584,7 +603,7 @@ void NodeDB::saveToDisk(int saveWhat)
}
}
-const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
+const meshtastic_NodeInfo *NodeDB::readNextNodeInfo(uint32_t &readIndex)
{
if (readIndex < *numNodes)
return &nodes[readIndex++];
@@ -592,8 +611,16 @@ const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
return NULL;
}
+const meshtastic_NodeInfoLite *NodeDB::readNextMeshNode(uint32_t &readIndex)
+{
+ if (readIndex < *numMeshNodes)
+ return &meshNodes[readIndex++];
+ else
+ return NULL;
+}
+
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
-uint32_t sinceLastSeen(const meshtastic_NodeInfo *n)
+uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n)
{
uint32_t now = getTime();
@@ -617,13 +644,13 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
-size_t NodeDB::getNumOnlineNodes()
+size_t NodeDB::getNumOnlineMeshNodes()
{
size_t numseen = 0;
// FIXME this implementation is kinda expensive
- for (int i = 0; i < *numNodes; i++)
- if (sinceLastSeen(&nodes[i]) < NUM_ONLINE_SECS)
+ for (int i = 0; i < *numMeshNodes; i++)
+ if (sinceLastSeen(&meshNodes[i]) < NUM_ONLINE_SECS)
numseen++;
return numseen;
@@ -635,7 +662,7 @@ size_t NodeDB::getNumOnlineNodes()
*/
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
{
- meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
+ meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
if (!info) {
return;
}
@@ -644,7 +671,9 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
// Local packet, fully authoritative
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
p.longitude_i, p.altitude);
- info->position = p;
+
+ info->position = ConvertToPositionLite(p);
+ localPosition = p;
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
@@ -662,7 +691,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
uint32_t tmp_time = info->position.time;
// Next, update atomically
- info->position = p;
+ info->position = ConvertToPositionLite(p);
// Last, restore any fields that may have been overwritten
if (!info->position.time)
@@ -678,7 +707,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
*/
void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src)
{
- meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
+ meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
// Environment metrics should never go to NodeDb but we'll safegaurd anyway
if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) {
return;
@@ -700,7 +729,7 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
*/
bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
{
- meshtastic_NodeInfo *info = getOrCreateNode(nodeId);
+ meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
if (!info) {
return false;
}
@@ -733,7 +762,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
LOG_DEBUG("Update DB node 0x%x, rx_time=%u, channel=%d\n", mp.from, mp.rx_time, mp.channel);
- meshtastic_NodeInfo *info = getOrCreateNode(getFrom(&mp));
+ meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
if (!info) {
return;
}
@@ -750,9 +779,9 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
}
}
-uint8_t NodeDB::getNodeChannel(NodeNum n)
+uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
{
- meshtastic_NodeInfo *info = getNode(n);
+ meshtastic_NodeInfoLite *info = getMeshNode(n);
if (!info) {
return 0; // defaults to PRIMARY
}
@@ -761,7 +790,7 @@ uint8_t NodeDB::getNodeChannel(NodeNum n)
/// Find a node in our DB, return null for missing
/// NOTE: This function might be called from an ISR
-meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
+meshtastic_NodeInfo *NodeDB::getNodeInfo(NodeNum n)
{
for (int i = 0; i < *numNodes; i++)
if (nodes[i].num == n)
@@ -770,38 +799,100 @@ meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
return NULL;
}
-/// Find a node in our DB, create an empty NodeInfo if missing
-meshtastic_NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
+/// Find a node in our DB, return null for missing
+/// NOTE: This function might be called from an ISR
+meshtastic_NodeInfoLite *NodeDB::getMeshNode(NodeNum n)
{
- meshtastic_NodeInfo *info = getNode(n);
+ for (int i = 0; i < *numMeshNodes; i++)
+ if (meshNodes[i].num == n)
+ return &meshNodes[i];
- if (!info) {
- if ((*numNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfo_size * 3)) {
- screen->print("warning: node_db full! erasing oldest entry\n");
+ return NULL;
+}
+
+/// Find a node in our DB, create an empty NodeInfo if missing
+meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
+{
+ meshtastic_NodeInfoLite *lite = getMeshNode(n);
+
+ if (!lite) {
+ if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
+ screen->print("warning: node_db_lite full! erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
int oldestIndex = -1;
- for (int i = 0; i < *numNodes; i++) {
- if (nodes[i].last_heard < oldest) {
- oldest = nodes[i].last_heard;
+ for (int i = 0; i < *numMeshNodes; i++) {
+ if (meshNodes[i].last_heard < oldest) {
+ oldest = meshNodes[i].last_heard;
oldestIndex = i;
}
}
// Shove the remaining nodes down the chain
- for (int i = oldestIndex; i < *numNodes - 1; i++) {
- nodes[i] = nodes[i + 1];
+ for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
+ meshNodes[i] = meshNodes[i + 1];
}
- (*numNodes)--;
+ (*numMeshNodes)--;
}
// add the node at the end
- info = &nodes[(*numNodes)++];
+ lite = &meshNodes[(*numMeshNodes)++];
// everything is missing except the nodenum
- memset(info, 0, sizeof(*info));
- info->num = n;
+ memset(lite, 0, sizeof(*lite));
+ lite->num = n;
}
- return info;
+ return lite;
+}
+
+void NodeDB::migrateToNodeInfoLite(const meshtastic_NodeInfo *node)
+{
+ meshtastic_NodeInfoLite *lite = getMeshNode(node->num);
+
+ if (!lite) {
+ if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
+ screen->print("warning: node_db_lite full! erasing oldest entry\n");
+ // look for oldest node and erase it
+ uint32_t oldest = UINT32_MAX;
+ int oldestIndex = -1;
+ for (int i = 0; i < *numMeshNodes; i++) {
+ if (meshNodes[i].last_heard < oldest) {
+ oldest = meshNodes[i].last_heard;
+ oldestIndex = i;
+ }
+ }
+ // Shove the remaining nodes down the chain
+ for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
+ meshNodes[i] = meshNodes[i + 1];
+ }
+ (*numMeshNodes)--;
+ }
+ // add the node at the end
+ lite = &meshNodes[(*numMeshNodes)++];
+
+ // everything is missing except the nodenum
+ memset(lite, 0, sizeof(*lite));
+ lite->num = node->num;
+ lite->snr = node->snr;
+ lite->last_heard = node->last_heard;
+ lite->channel = node->channel;
+
+ if (node->has_position) {
+ lite->has_position = true;
+ lite->position.latitude_i = node->position.latitude_i;
+ lite->position.longitude_i = node->position.longitude_i;
+ lite->position.altitude = node->position.altitude;
+ lite->position.location_source = node->position.location_source;
+ lite->position.time = node->position.time;
+ }
+ if (node->has_user) {
+ lite->has_user = true;
+ lite->user = node->user;
+ }
+ if (node->has_device_metrics) {
+ lite->has_device_metrics = true;
+ lite->device_metrics = node->device_metrics;
+ }
+ }
}
/// Record an error that should be reported via analytics
@@ -817,9 +908,8 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
}
// Record error to DB
- myNodeInfo.error_code = code;
- myNodeInfo.error_address = address;
- myNodeInfo.error_count++;
+ error_code = code;
+ error_address = address;
// Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
#ifdef ARCH_PORTDUINO
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index 65ab72c8c..83d9e252f 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -7,6 +7,7 @@
#include "MeshTypes.h"
#include "NodeStatus.h"
#include "mesh-pb-constants.h"
+#include "mesh/generated/meshtastic/mesh.pb.h" // For CriticalErrorCode
/*
DeviceState versions used to be defined in the .proto file but really only this function cares. So changed to a
@@ -28,9 +29,10 @@ extern meshtastic_LocalConfig config;
extern meshtastic_LocalModuleConfig moduleConfig;
extern meshtastic_OEMStore oemStore;
extern meshtastic_User &owner;
+extern meshtastic_Position localPosition;
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
-uint32_t sinceLastSeen(const meshtastic_NodeInfo *n);
+uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
/// Given a packet, return how many seconds in the past (vs now) it was received
uint32_t sinceReceived(const meshtastic_MeshPacket *p);
@@ -46,9 +48,12 @@ class NodeDB
meshtastic_NodeInfo *nodes;
pb_size_t *numNodes;
+ meshtastic_NodeInfoLite *meshNodes;
+ pb_size_t *numMeshNodes;
+
public:
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled
- meshtastic_NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
+ meshtastic_NodeInfoLite *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
Observable newStatus;
/// don't do mesh based algoritm for node id assignment (initially)
@@ -89,8 +94,6 @@ class NodeDB
/// @return our node number
NodeNum getNodeNum() { return myNodeInfo.my_node_num; }
- size_t getNumNodes() { return *numNodes; }
-
/// if returns false, that means our node should send a DenyNodeNum response. If true, we think the number is okay for use
// bool handleWantNodeNum(NodeNum n);
@@ -102,26 +105,14 @@ class NodeDB
their denial?)
*/
- /// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
- const meshtastic_NodeInfo *readNextInfo(uint32_t &readIndex);
-
/// pick a provisional nodenum we hope no one is using
void pickNewNodeNum();
// get channel channel index we heard a nodeNum on, defaults to 0 if not found
- uint8_t getNodeChannel(NodeNum n);
-
- /// Find a node in our DB, return null for missing
- meshtastic_NodeInfo *getNode(NodeNum n);
-
- meshtastic_NodeInfo *getNodeByIndex(size_t x)
- {
- assert(x < *numNodes);
- return &nodes[x];
- }
+ uint8_t getMeshNodeChannel(NodeNum n);
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
- size_t getNumOnlineNodes();
+ size_t getNumOnlineMeshNodes();
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
@@ -132,15 +123,38 @@ class NodeDB
void installRoleDefaults(meshtastic_Config_DeviceConfig_Role role);
+ const meshtastic_NodeInfoLite *readNextMeshNode(uint32_t &readIndex);
+
+ meshtastic_NodeInfoLite *getMeshNodeByIndex(size_t x)
+ {
+ assert(x < *numMeshNodes);
+ return &meshNodes[x];
+ }
+
+ meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
+ size_t getNumMeshNodes() { return *numMeshNodes; }
+
private:
- /// Find a node in our DB, create an empty NodeInfo if missing
- meshtastic_NodeInfo *getOrCreateNode(NodeNum n);
+ /// Find a node in our DB, create an empty NodeInfoLite if missing
+ meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
+ void migrateToNodeInfoLite(const meshtastic_NodeInfo *node);
+ /// Find a node in our DB, return null for missing
+ meshtastic_NodeInfo *getNodeInfo(NodeNum n);
+ /// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
+ const meshtastic_NodeInfo *readNextNodeInfo(uint32_t &readIndex);
+ size_t getNumNodes() { return *numNodes; }
+
+ meshtastic_NodeInfo *getNodeByIndex(size_t x)
+ {
+ assert(x < *numNodes);
+ return &nodes[x];
+ }
/// Notify observers of changes to the DB
void notifyObservers(bool forceUpdate = false)
{
// Notify observers of the current node state
- const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineNodes(), getNumNodes(), forceUpdate);
+ const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineMeshNodes(), getNumMeshNodes(), forceUpdate);
newStatus.notifyObservers(&status);
}
@@ -218,13 +232,24 @@ static inline bool hasValidPosition(const meshtastic_NodeInfo *n)
{
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
}
+static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n)
+{
+ return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
+}
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel.
*/
extern uint32_t radioGeneration;
+extern meshtastic_CriticalErrorCode error_code;
+
+/*
+ * A numeric error address (nonzero if available)
+ */
+extern uint32_t error_address;
+
#define Module_Config_size \
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
- ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
+ ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
\ No newline at end of file
diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp
index 76c2ba3db..ebc886301 100644
--- a/src/mesh/PhoneAPI.cpp
+++ b/src/mesh/PhoneAPI.cpp
@@ -5,6 +5,7 @@
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RadioInterface.h"
+#include "TypeConversions.h"
#include "configuration.h"
#include "main.h"
#include "xmodem.h"
@@ -40,7 +41,7 @@ void PhoneAPI::handleStartConfig()
state = STATE_SEND_MY_INFO;
LOG_INFO("Starting API client config\n");
- nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos
+ nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
resetReadIndex();
}
@@ -143,25 +144,23 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO\n");
// If the user has specified they don't want our node to share its location, make sure to tell the phone
// app not to send locations on our behalf.
- myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO;
- service.refreshMyNodeInfo(); // Update my NodeInfo because the client will be asking for it soon.
+ service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon.
break;
case STATE_SEND_NODEINFO: {
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
- const meshtastic_NodeInfo *info = nodeInfoForPhone;
- nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
- if (info) {
- LOG_INFO("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->last_heard, info->user.id,
- info->user.long_name);
+ if (nodeInfoForPhone.num != 0) {
+ LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
+ nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
- fromRadioScratch.node_info = *info;
+ fromRadioScratch.node_info = nodeInfoForPhone;
// Stay in current state until done sending nodeinfos
+ nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
} else {
LOG_INFO("Done sending nodeinfos\n");
state = STATE_SEND_CHANNELS;
@@ -371,8 +370,12 @@ bool PhoneAPI::available()
return true;
case STATE_SEND_NODEINFO:
- if (!nodeInfoForPhone)
- nodeInfoForPhone = nodeDB.readNextInfo(readIndex);
+ if (nodeInfoForPhone.num == 0) {
+ auto nextNode = nodeDB.readNextMeshNode(readIndex);
+ if (nextNode) {
+ nodeInfoForPhone = ConvertToNodeInfo(nextNode);
+ }
+ }
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_PACKETS: {
@@ -427,4 +430,4 @@ int PhoneAPI::onNotify(uint32_t newValue)
}
return 0;
-}
+}
\ No newline at end of file
diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h
index 2ea4d3a0c..8097ad34b 100644
--- a/src/mesh/PhoneAPI.h
+++ b/src/mesh/PhoneAPI.h
@@ -51,7 +51,7 @@ class PhoneAPI
meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio
- const meshtastic_NodeInfo *nodeInfoForPhone = NULL;
+ meshtastic_NodeInfo nodeInfoForPhone = meshtastic_NodeInfo_init_default;
meshtastic_ToRadio toRadioScratch = {
0}; // this is a static scratch object, any data must be copied elsewhere before returning
diff --git a/src/mesh/ProtobufModule.h b/src/mesh/ProtobufModule.h
index bdfdea9ad..1771f4322 100644
--- a/src/mesh/ProtobufModule.h
+++ b/src/mesh/ProtobufModule.h
@@ -52,7 +52,7 @@ template class ProtobufModule : protected SinglePortModule
*/
const char *getSenderShortName(const meshtastic_MeshPacket &mp)
{
- auto node = nodeDB.getNode(getFrom(&mp));
+ auto node = nodeDB.getMeshNode(getFrom(&mp));
const char *sender = (node) ? node->user.short_name : "???";
return sender;
}
@@ -86,4 +86,4 @@ template class ProtobufModule : protected SinglePortModule
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;
}
-};
+};
\ No newline at end of file
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 1eee86c8e..00af93e15 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -232,7 +232,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
delay = random(0, 2 * CWsize) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
} else {
- delay = random(0, pow(2, CWsize)) * slotTimeMsec;
+ // offset the maximum delay for routers: (2 * CWmax * slotTimeMsec)
+ delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d\n", delay);
}
diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h
index 6635089e5..4634ca7ee 100644
--- a/src/mesh/RadioLibInterface.h
+++ b/src/mesh/RadioLibInterface.h
@@ -27,6 +27,19 @@ class LockingArduinoHal : public ArduinoHal
void spiEndTransaction() override;
};
+#if defined(USE_STM32WLx)
+/**
+ * A wrapper for the RadioLib STM32WLx_Module class, that doesn't connect any pins as they are virtual
+ */
+class STM32WLx_ModuleWrapper : public STM32WLx_Module
+{
+ public:
+ STM32WLx_ModuleWrapper(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
+ RADIOLIB_PIN_TYPE busy)
+ : STM32WLx_Module(){};
+};
+#endif
+
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
{
/// Used as our notification from the ISR
@@ -56,7 +69,11 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset.
+#if !defined(USE_STM32WLx)
Module module; // The HW interface to the radio
+#else
+ STM32WLx_ModuleWrapper module;
+#endif
/**
* provides lowest common denominator RadioLib API
diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp
index 156b48209..6f020d739 100644
--- a/src/mesh/Router.cpp
+++ b/src/mesh/Router.cpp
@@ -178,7 +178,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
}
if (!p->channel) { // don't override if a channel was requested
- p->channel = nodeDB.getNodeChannel(p->to);
+ p->channel = nodeDB.getMeshNodeChannel(p->to);
LOG_DEBUG("localSend to channel %d\n", p->channel);
}
@@ -493,4 +493,4 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
handleReceived(p);
packetPool.release(p);
-}
+}
\ No newline at end of file
diff --git a/src/mesh/STM32WLE5JCInterface.cpp b/src/mesh/STM32WLE5JCInterface.cpp
new file mode 100644
index 000000000..5b6fd0844
--- /dev/null
+++ b/src/mesh/STM32WLE5JCInterface.cpp
@@ -0,0 +1,45 @@
+#include "STM32WLE5JCInterface.h"
+#include "configuration.h"
+#include "error.h"
+
+#ifndef STM32WLx_MAX_POWER
+#define STM32WLx_MAX_POWER 22
+#endif
+
+#ifdef ARCH_STM32WL
+
+STM32WLE5JCInterface::STM32WLE5JCInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
+ RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy)
+ : SX126xInterface(hal, cs, irq, rst, busy)
+{
+}
+
+bool STM32WLE5JCInterface::init()
+{
+ RadioLibInterface::init();
+
+ lora.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ if (power == 0)
+ power = STM32WLx_MAX_POWER;
+
+ if (power > STM32WLx_MAX_POWER) // This chip has lower power limits than some
+ power = STM32WLx_MAX_POWER;
+
+ limitPower();
+
+ int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
+
+ LOG_INFO("STM32WLx init result %d\n", res);
+
+ LOG_INFO("Frequency set to %f\n", getFreq());
+ LOG_INFO("Bandwidth set to %f\n", bw);
+ LOG_INFO("Power output set to %d\n", power);
+
+ if (res == RADIOLIB_ERR_NONE)
+ startReceive(); // start receiving
+
+ return res == RADIOLIB_ERR_NONE;
+}
+
+#endif // ARCH_STM32WL
diff --git a/src/mesh/STM32WLE5JCInterface.h b/src/mesh/STM32WLE5JCInterface.h
new file mode 100644
index 000000000..73d53d92f
--- /dev/null
+++ b/src/mesh/STM32WLE5JCInterface.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "SX126xInterface.h"
+
+#ifdef ARCH_STM32WL
+
+/**
+ * Our adapter for STM32WLE5JC radios
+ */
+class STM32WLE5JCInterface : public SX126xInterface
+{
+ public:
+ STM32WLE5JCInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
+ RADIOLIB_PIN_TYPE busy);
+
+ virtual bool init() override;
+};
+
+// https://github.com/Seeed-Studio/LoRaWan-E5-Node/blob/main/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c
+static const float tcxoVoltage = 1.7;
+
+/* https://wiki.seeedstudio.com/LoRa-E5_STM32WLE5JC_Module/
+ * Wio-E5 module ONLY transmits through RFO_HP
+ * Receive: PA4=1, PA5=0
+ * Transmit(high output power, SMPS mode): PA4=0, PA5=1 */
+static const RADIOLIB_PIN_TYPE rfswitch_pins[3] = {PA4, PA5, RADIOLIB_NC};
+
+static const Module::RfSwitchMode_t rfswitch_table[4] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW}}, {STM32WLx::MODE_RX, {HIGH, LOW}}, {STM32WLx::MODE_TX_HP, {LOW, HIGH}}, END_OF_MODE_TABLE};
+
+#endif // ARCH_STM32WL
\ No newline at end of file
diff --git a/src/mesh/TypeConversions.h b/src/mesh/TypeConversions.h
new file mode 100644
index 000000000..bfc87102b
--- /dev/null
+++ b/src/mesh/TypeConversions.h
@@ -0,0 +1,54 @@
+#include "mesh/generated/meshtastic/deviceonly.pb.h"
+#include "mesh/generated/meshtastic/mesh.pb.h"
+
+inline static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
+{
+ meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
+
+ info.num = lite->num;
+ info.snr = lite->snr;
+ info.last_heard = lite->last_heard;
+ info.channel = lite->channel;
+
+ if (lite->has_position) {
+ info.has_position = true;
+ info.position.latitude_i = lite->position.latitude_i;
+ info.position.longitude_i = lite->position.longitude_i;
+ info.position.altitude = lite->position.altitude;
+ info.position.location_source = lite->position.location_source;
+ info.position.time = lite->position.time;
+ }
+ if (lite->has_user) {
+ info.has_user = true;
+ info.user = lite->user;
+ }
+ if (lite->has_device_metrics) {
+ info.has_device_metrics = true;
+ info.device_metrics = lite->device_metrics;
+ }
+ return info;
+}
+
+inline static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position)
+{
+ meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
+ lite.latitude_i = position.latitude_i;
+ lite.longitude_i = position.longitude_i;
+ lite.altitude = position.altitude;
+ lite.location_source = position.location_source;
+ lite.time = position.time;
+
+ return lite;
+}
+
+inline static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite)
+{
+ meshtastic_Position position = meshtastic_Position_init_default;
+ position.latitude_i = lite.latitude_i;
+ position.longitude_i = lite.longitude_i;
+ position.altitude = lite.altitude;
+ position.location_source = lite.location_source;
+ position.time = lite.time;
+
+ return position;
+}
\ No newline at end of file
diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp
index 659de05f8..c60e35394 100644
--- a/src/mesh/eth/ethClient.cpp
+++ b/src/mesh/eth/ethClient.cpp
@@ -98,6 +98,11 @@ static int32_t reconnectETH()
return 5000; // every 5 seconds
}
+static uint32_t bigToLittleEndian(uint32_t value)
+{
+ return ((value >> 24) & 0xFF) | ((value >> 8) & 0xFF00) | ((value << 8) & 0xFF0000) | ((value << 24) & 0xFF000000);
+}
+
// Startup Ethernet
bool initEthernet()
{
@@ -126,7 +131,15 @@ bool initEthernet()
status = Ethernet.begin(mac);
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
LOG_INFO("starting Ethernet Static\n");
- Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
+
+ IPAddress ip = IPAddress(bigToLittleEndian(config.network.ipv4_config.ip));
+ IPAddress dns = IPAddress(bigToLittleEndian(config.network.ipv4_config.dns));
+ IPAddress gateway = IPAddress(bigToLittleEndian(config.network.ipv4_config.gateway));
+ IPAddress subnet = IPAddress(bigToLittleEndian(config.network.ipv4_config.subnet));
+
+ Ethernet.begin(mac, ip, dns, gateway, subnet);
+
+ status = 1;
} else {
LOG_INFO("Ethernet Disabled\n");
return false;
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.c b/src/mesh/generated/meshtastic/deviceonly.pb.c
index e741d25de..82c3fc44c 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.c
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.c
@@ -9,6 +9,12 @@
PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 4)
+PB_BIND(meshtastic_NodeInfoLite, meshtastic_NodeInfoLite, AUTO)
+
+
+PB_BIND(meshtastic_PositionLite, meshtastic_PositionLite, AUTO)
+
+
PB_BIND(meshtastic_ChannelFile, meshtastic_ChannelFile, 2)
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h
index ffce0cdd4..48f93da5e 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.h
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.h
@@ -7,6 +7,7 @@
#include "meshtastic/channel.pb.h"
#include "meshtastic/localonly.pb.h"
#include "meshtastic/mesh.pb.h"
+#include "meshtastic/telemetry.pb.h"
#include "meshtastic/module_config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
@@ -25,6 +26,47 @@ typedef enum _meshtastic_ScreenFonts {
} meshtastic_ScreenFonts;
/* Struct definitions */
+/* Position with static location information only for NodeDBLite */
+typedef struct _meshtastic_PositionLite {
+ /* The new preferred location encoding, multiply by 1e-7 to get degrees
+ in floating point */
+ int32_t latitude_i;
+ /* TODO: REPLACE */
+ int32_t longitude_i;
+ /* In meters above MSL (but see issue #359) */
+ int32_t altitude;
+ /* This is usually not sent over the mesh (to save space), but it is sent
+ from the phone so that the local device can set its RTC If it is sent over
+ the mesh (because there are devices on the mesh without GPS), it will only
+ be sent by devices which has a hardware GPS clock.
+ seconds since 1970 */
+ uint32_t time;
+ /* TODO: REPLACE */
+ meshtastic_Position_LocSource location_source;
+} meshtastic_PositionLite;
+
+typedef struct _meshtastic_NodeInfoLite {
+ /* The node number */
+ uint32_t num;
+ /* The user info for this node */
+ bool has_user;
+ meshtastic_User user;
+ /* This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
+ Position.time now indicates the last time we received a POSITION from that node. */
+ bool has_position;
+ meshtastic_PositionLite position;
+ /* Returns the Signal-to-noise ratio (SNR) of the last received message,
+ as measured by the receiver. Return SNR of the last received message in dB */
+ float snr;
+ /* Set to indicate the last time we received a packet from this node */
+ uint32_t last_heard;
+ /* The latest device metrics for the node. */
+ bool has_device_metrics;
+ meshtastic_DeviceMetrics device_metrics;
+ /* local channel index we heard that node on. Only populated if its not the default channel. */
+ uint8_t channel;
+} meshtastic_NodeInfoLite;
+
/* The on-disk saved channels */
typedef struct _meshtastic_ChannelFile {
/* The channels our node knows about */
@@ -82,7 +124,8 @@ typedef struct _meshtastic_DeviceState {
/* My owner info */
bool has_owner;
meshtastic_User owner;
- /* TODO: REPLACE */
+ /* Deprecated in 2.1.x
+ Old node_db. See NodeInfoLite node_db_lite */
pb_size_t node_db_count;
meshtastic_NodeInfo node_db[80];
/* Received packets saved for delivery to the phone */
@@ -110,6 +153,9 @@ typedef struct _meshtastic_DeviceState {
/* The mesh's nodes with their available gpio pins for RemoteHardware module */
pb_size_t node_remote_hardware_pins_count;
meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12];
+ /* New lite version of NodeDB to decrease */
+ pb_size_t node_db_lite_count;
+ meshtastic_NodeInfoLite node_db_lite[80];
} meshtastic_DeviceState;
@@ -124,21 +170,40 @@ extern "C" {
+#define meshtastic_PositionLite_location_source_ENUMTYPE meshtastic_Position_LocSource
+
+
#define meshtastic_OEMStore_oem_font_ENUMTYPE meshtastic_ScreenFonts
/* Initializer values for message structs */
-#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
+#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, 0, {meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default}}
+#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
+#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
#define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default}
-#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
+#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, 0, {meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero}}
+#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
+#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
#define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
#define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero}
/* Field tags (for use in manual encoding/decoding) */
+#define meshtastic_PositionLite_latitude_i_tag 1
+#define meshtastic_PositionLite_longitude_i_tag 2
+#define meshtastic_PositionLite_altitude_tag 3
+#define meshtastic_PositionLite_time_tag 4
+#define meshtastic_PositionLite_location_source_tag 5
+#define meshtastic_NodeInfoLite_num_tag 1
+#define meshtastic_NodeInfoLite_user_tag 2
+#define meshtastic_NodeInfoLite_position_tag 3
+#define meshtastic_NodeInfoLite_snr_tag 4
+#define meshtastic_NodeInfoLite_last_heard_tag 5
+#define meshtastic_NodeInfoLite_device_metrics_tag 6
+#define meshtastic_NodeInfoLite_channel_tag 7
#define meshtastic_ChannelFile_channels_tag 1
#define meshtastic_ChannelFile_version_tag 2
#define meshtastic_OEMStore_oem_icon_width_tag 1
@@ -161,6 +226,7 @@ extern "C" {
#define meshtastic_DeviceState_did_gps_reset_tag 11
#define meshtastic_DeviceState_rx_waypoint_tag 12
#define meshtastic_DeviceState_node_remote_hardware_pins_tag 13
+#define meshtastic_DeviceState_node_db_lite_tag 14
/* Struct field encoding specification for nanopb */
#define meshtastic_DeviceState_FIELDLIST(X, a) \
@@ -173,7 +239,8 @@ X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12) \
-X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13)
+X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13) \
+X(a, STATIC, REPEATED, MESSAGE, node_db_lite, 14)
#define meshtastic_DeviceState_CALLBACK NULL
#define meshtastic_DeviceState_DEFAULT NULL
#define meshtastic_DeviceState_my_node_MSGTYPE meshtastic_MyNodeInfo
@@ -183,6 +250,30 @@ X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13)
#define meshtastic_DeviceState_rx_text_message_MSGTYPE meshtastic_MeshPacket
#define meshtastic_DeviceState_rx_waypoint_MSGTYPE meshtastic_MeshPacket
#define meshtastic_DeviceState_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin
+#define meshtastic_DeviceState_node_db_lite_MSGTYPE meshtastic_NodeInfoLite
+
+#define meshtastic_NodeInfoLite_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, UINT32, num, 1) \
+X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
+X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
+X(a, STATIC, SINGULAR, FLOAT, snr, 4) \
+X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \
+X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
+X(a, STATIC, SINGULAR, UINT32, channel, 7)
+#define meshtastic_NodeInfoLite_CALLBACK NULL
+#define meshtastic_NodeInfoLite_DEFAULT NULL
+#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_User
+#define meshtastic_NodeInfoLite_position_MSGTYPE meshtastic_PositionLite
+#define meshtastic_NodeInfoLite_device_metrics_MSGTYPE meshtastic_DeviceMetrics
+
+#define meshtastic_PositionLite_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
+X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
+X(a, STATIC, SINGULAR, INT32, altitude, 3) \
+X(a, STATIC, SINGULAR, FIXED32, time, 4) \
+X(a, STATIC, SINGULAR, UENUM, location_source, 5)
+#define meshtastic_PositionLite_CALLBACK NULL
+#define meshtastic_PositionLite_DEFAULT NULL
#define meshtastic_ChannelFile_FIELDLIST(X, a) \
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
@@ -213,21 +304,27 @@ X(a, STATIC, OPTIONAL, MESSAGE, pin, 2)
#define meshtastic_NodeRemoteHardwarePin_pin_MSGTYPE meshtastic_RemoteHardwarePin
extern const pb_msgdesc_t meshtastic_DeviceState_msg;
+extern const pb_msgdesc_t meshtastic_NodeInfoLite_msg;
+extern const pb_msgdesc_t meshtastic_PositionLite_msg;
extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
extern const pb_msgdesc_t meshtastic_OEMStore_msg;
extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define meshtastic_DeviceState_fields &meshtastic_DeviceState_msg
+#define meshtastic_NodeInfoLite_fields &meshtastic_NodeInfoLite_msg
+#define meshtastic_PositionLite_fields &meshtastic_PositionLite_msg
#define meshtastic_ChannelFile_fields &meshtastic_ChannelFile_msg
#define meshtastic_OEMStore_fields &meshtastic_OEMStore_msg
#define meshtastic_NodeRemoteHardwarePin_fields &meshtastic_NodeRemoteHardwarePin_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_ChannelFile_size 638
-#define meshtastic_DeviceState_size 22736
+#define meshtastic_DeviceState_size 35056
+#define meshtastic_NodeInfoLite_size 151
#define meshtastic_NodeRemoteHardwarePin_size 29
-#define meshtastic_OEMStore_size 3142
+#define meshtastic_OEMStore_size 3152
+#define meshtastic_PositionLite_size 28
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h
index fd1c8a5c1..d70acc7fc 100644
--- a/src/mesh/generated/meshtastic/localonly.pb.h
+++ b/src/mesh/generated/meshtastic/localonly.pb.h
@@ -72,6 +72,9 @@ typedef struct _meshtastic_LocalModuleConfig {
/* The part of the config that is specific to the Remote Hardware module */
bool has_remote_hardware;
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
+ /* The part of the config that is specific to the Neighbor Info module */
+ bool has_neighbor_info;
+ meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
} meshtastic_LocalModuleConfig;
@@ -81,9 +84,9 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0}
-#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default}
+#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default}
#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0}
-#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero}
+#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_LocalConfig_device_tag 1
@@ -104,6 +107,7 @@ extern "C" {
#define meshtastic_LocalModuleConfig_version_tag 8
#define meshtastic_LocalModuleConfig_audio_tag 9
#define meshtastic_LocalModuleConfig_remote_hardware_tag 10
+#define meshtastic_LocalModuleConfig_neighbor_info_tag 11
/* Struct field encoding specification for nanopb */
#define meshtastic_LocalConfig_FIELDLIST(X, a) \
@@ -135,7 +139,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \
-X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10)
+X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \
+X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11)
#define meshtastic_LocalModuleConfig_CALLBACK NULL
#define meshtastic_LocalModuleConfig_DEFAULT NULL
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -147,6 +152,7 @@ X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10)
#define meshtastic_LocalModuleConfig_canned_message_MSGTYPE meshtastic_ModuleConfig_CannedMessageConfig
#define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
#define meshtastic_LocalModuleConfig_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
+#define meshtastic_LocalModuleConfig_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
extern const pb_msgdesc_t meshtastic_LocalConfig_msg;
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
@@ -157,7 +163,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_LocalConfig_size 461
-#define meshtastic_LocalModuleConfig_size 535
+#define meshtastic_LocalModuleConfig_size 545
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index 62388e94e..0ed2f8e68 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -372,7 +372,8 @@ typedef struct _meshtastic_User {
/* A VERY short name, ideally two characters.
Suitable for a tiny OLED screen */
char short_name[5];
- /* This is the addr of the radio.
+ /* Deprecated in Meshtastic 2.1.x
+ This is the addr of the radio.
Not populated by the phone, but added by the esp32 when broadcasting */
pb_byte_t macaddr[6];
/* TBEAM, HELTEC, etc...
@@ -578,12 +579,15 @@ typedef struct _meshtastic_MyNodeInfo {
/* Tells the phone what our node number is, default starting value is
lowbyte of macaddr, but it will be fixed if that is already in use */
uint32_t my_node_num;
- /* Note: This flag merely means we detected a hardware GPS in our node.
+ /* Deprecated in 2.1.x (Source from device_metadata)
+ Note: This flag merely means we detected a hardware GPS in our node.
Not the same as UserPreferences.location_sharing */
bool has_gps;
- /* The maximum number of 'software' channels that can be set on this node. */
+ /* Deprecated in 2.1.x
+ The maximum number of 'software' channels that can be set on this node. */
uint32_t max_channels;
- /* 0.0.5 etc... */
+ /* Deprecated in 2.1.x (Source from device_metadata)
+ 0.0.5 etc... */
char firmware_version[18];
/* An error message we'd like to report back to the mothership through analytics.
It indicates a serious bug occurred on the device, the device coped with it,
@@ -600,9 +604,11 @@ typedef struct _meshtastic_MyNodeInfo {
/* The total number of reboots this node has ever encountered
(well - since the last time we discarded preferences) */
uint32_t reboot_count;
- /* Calculated bitrate of the current channel (in Bytes Per Second) */
+ /* Deprecated in 2.1.x
+ Calculated bitrate of the current channel (in Bytes Per Second) */
float bitrate;
- /* How long before we consider a message abandoned and we can clear our
+ /* Deprecated in 2.1.x
+ How long before we consider a message abandoned and we can clear our
caches of any messages in flight Normally quite large to handle the worst case
message delivery time, 5 minutes.
Formerly called FLOOD_EXPIRE_TIME in the device code */
@@ -610,17 +616,22 @@ typedef struct _meshtastic_MyNodeInfo {
/* The minimum app version that can talk to this device.
Phone/PC apps should compare this to their build number and if too low tell the user they must update their app */
uint32_t min_app_version;
- /* 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
+ /* Deprecated in 2.1.x (Only used on device to keep track of utilization)
+ 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
pb_size_t air_period_tx_count;
uint32_t air_period_tx[8];
- /* 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
+ /* Deprecated in 2.1.x (Only used on device to keep track of utilization)
+ 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
pb_size_t air_period_rx_count;
uint32_t air_period_rx[8];
- /* Is the device wifi capable? */
+ /* Deprecated in 2.1.x (Source from DeviceMetadata instead)
+ Is the device wifi capable? */
bool has_wifi;
- /* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
+ /* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
+ Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
float channel_utilization;
- /* Percent of airtime for transmission used within the last hour. */
+ /* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
+ Percent of airtime for transmission used within the last hour. */
float air_util_tx;
} meshtastic_MyNodeInfo;
diff --git a/src/mesh/generated/meshtastic/module_config.pb.c b/src/mesh/generated/meshtastic/module_config.pb.c
index 123a4fedf..9352feb17 100644
--- a/src/mesh/generated/meshtastic/module_config.pb.c
+++ b/src/mesh/generated/meshtastic/module_config.pb.c
@@ -15,6 +15,9 @@ PB_BIND(meshtastic_ModuleConfig_MQTTConfig, meshtastic_ModuleConfig_MQTTConfig,
PB_BIND(meshtastic_ModuleConfig_RemoteHardwareConfig, meshtastic_ModuleConfig_RemoteHardwareConfig, AUTO)
+PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO)
+
+
PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO)
diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h
index 53a55073f..6273a89ae 100644
--- a/src/mesh/generated/meshtastic/module_config.pb.h
+++ b/src/mesh/generated/meshtastic/module_config.pb.h
@@ -114,6 +114,15 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig {
char root[16];
} meshtastic_ModuleConfig_MQTTConfig;
+/* NeighborInfoModule Config */
+typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig {
+ /* Whether the Module is enabled */
+ bool enabled;
+ /* Interval in seconds of how often we should try to send our
+ Neighbor Info to the mesh */
+ uint32_t update_interval;
+} meshtastic_ModuleConfig_NeighborInfoConfig;
+
/* Audio Config for codec2 voice */
typedef struct _meshtastic_ModuleConfig_AudioConfig {
/* Whether Audio is enabled */
@@ -313,6 +322,8 @@ typedef struct _meshtastic_ModuleConfig {
meshtastic_ModuleConfig_AudioConfig audio;
/* TODO: REPLACE */
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
+ /* TODO: REPLACE */
+ meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
} payload_variant;
} meshtastic_ModuleConfig;
@@ -345,6 +356,7 @@ extern "C" {
+
#define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud
#define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud
@@ -365,6 +377,7 @@ extern "C" {
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, ""}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
+#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -376,6 +389,7 @@ extern "C" {
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, ""}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
+#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -394,6 +408,8 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6
#define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7
#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8
+#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
+#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
#define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3
@@ -464,6 +480,7 @@ extern "C" {
#define meshtastic_ModuleConfig_canned_message_tag 7
#define meshtastic_ModuleConfig_audio_tag 8
#define meshtastic_ModuleConfig_remote_hardware_tag 9
+#define meshtastic_ModuleConfig_neighbor_info_tag 10
/* Struct field encoding specification for nanopb */
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
@@ -475,7 +492,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,range_test,payload_variant.r
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.telemetry), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
-X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9)
+X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
+X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10)
#define meshtastic_ModuleConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -487,6 +505,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_vari
#define meshtastic_ModuleConfig_payload_variant_canned_message_MSGTYPE meshtastic_ModuleConfig_CannedMessageConfig
#define meshtastic_ModuleConfig_payload_variant_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
+#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
@@ -508,6 +527,12 @@ X(a, STATIC, REPEATED, MESSAGE, available_pins, 3)
#define meshtastic_ModuleConfig_RemoteHardwareConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_RemoteHardwareConfig_available_pins_MSGTYPE meshtastic_RemoteHardwarePin
+#define meshtastic_ModuleConfig_NeighborInfoConfig_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
+X(a, STATIC, SINGULAR, UINT32, update_interval, 2)
+#define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL
+#define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL
+
#define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \
@@ -601,6 +626,7 @@ X(a, STATIC, SINGULAR, UENUM, type, 3)
extern const pb_msgdesc_t meshtastic_ModuleConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg;
+extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg;
@@ -614,6 +640,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_fields &meshtastic_ModuleConfig_msg
#define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg
#define meshtastic_ModuleConfig_RemoteHardwareConfig_fields &meshtastic_ModuleConfig_RemoteHardwareConfig_msg
+#define meshtastic_ModuleConfig_NeighborInfoConfig_fields &meshtastic_ModuleConfig_NeighborInfoConfig_msg
#define meshtastic_ModuleConfig_AudioConfig_fields &meshtastic_ModuleConfig_AudioConfig_msg
#define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg
#define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg
@@ -628,6 +655,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
#define meshtastic_ModuleConfig_MQTTConfig_size 220
+#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
#define meshtastic_ModuleConfig_SerialConfig_size 28
diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp
index 5fba2b5de..bbd39f696 100644
--- a/src/modules/CannedMessageModule.cpp
+++ b/src/modules/CannedMessageModule.cpp
@@ -305,13 +305,14 @@ int32_t CannedMessageModule::runOnce()
switch (this->payload) {
case 0xb4: // left
if (this->destSelect) {
- size_t numNodes = nodeDB.getNumNodes();
+ size_t numMeshNodes = nodeDB.getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
- for (unsigned int i = 0; i < numNodes; i++) {
- if (nodeDB.getNodeByIndex(i)->num == this->dest) {
- this->dest = (i > 0) ? nodeDB.getNodeByIndex(i - 1)->num : nodeDB.getNodeByIndex(numNodes - 1)->num;
+ for (unsigned int i = 0; i < numMeshNodes; i++) {
+ if (nodeDB.getMeshNodeByIndex(i)->num == this->dest) {
+ this->dest =
+ (i > 0) ? nodeDB.getMeshNodeByIndex(i - 1)->num : nodeDB.getMeshNodeByIndex(numMeshNodes - 1)->num;
break;
}
}
@@ -326,13 +327,14 @@ int32_t CannedMessageModule::runOnce()
break;
case 0xb7: // right
if (this->destSelect) {
- size_t numNodes = nodeDB.getNumNodes();
+ size_t numMeshNodes = nodeDB.getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum();
}
- for (unsigned int i = 0; i < numNodes; i++) {
- if (nodeDB.getNodeByIndex(i)->num == this->dest) {
- this->dest = (i < numNodes - 1) ? nodeDB.getNodeByIndex(i + 1)->num : nodeDB.getNodeByIndex(0)->num;
+ for (unsigned int i = 0; i < numMeshNodes; i++) {
+ if (nodeDB.getMeshNodeByIndex(i)->num == this->dest) {
+ this->dest =
+ (i < numMeshNodes - 1) ? nodeDB.getMeshNodeByIndex(i + 1)->num : nodeDB.getMeshNodeByIndex(0)->num;
break;
}
}
@@ -409,7 +411,7 @@ const char *CannedMessageModule::getNodeName(NodeNum node)
if (node == NODENUM_BROADCAST) {
return "Broadcast";
} else {
- meshtastic_NodeInfo *info = nodeDB.getNode(node);
+ meshtastic_NodeInfoLite *info = nodeDB.getMeshNode(node);
if (info != NULL) {
return info->user.long_name;
} else {
diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp
index 7dbf78a08..82701cdc0 100644
--- a/src/modules/ExternalNotificationModule.cpp
+++ b/src/modules/ExternalNotificationModule.cpp
@@ -11,7 +11,7 @@
#include "main.h"
#ifdef RAK4630
-#include
+#include
NCP5623 rgb;
uint8_t red = 0;
diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h
index 7d4f54c2f..f8ec053dd 100644
--- a/src/modules/ExternalNotificationModule.h
+++ b/src/modules/ExternalNotificationModule.h
@@ -3,7 +3,7 @@
#include "SinglePortModule.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
-#ifndef ARCH_PORTDUINO
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include
#else
// Noop class for portduino.
diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp
index 5d49a213e..61de2c265 100644
--- a/src/modules/Modules.cpp
+++ b/src/modules/Modules.cpp
@@ -22,12 +22,12 @@
#endif
#ifdef ARCH_ESP32
#include "modules/esp32/AudioModule.h"
-#include "modules/esp32/RangeTestModule.h"
#include "modules/esp32/StoreForwardModule.h"
#endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
#include "modules/ExternalNotificationModule.h"
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
+#include "modules/RangeTestModule.h"
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#include "modules/SerialModule.h"
#endif
#endif
@@ -72,20 +72,18 @@ void setupModules()
new AirQualityTelemetryModule();
}
#endif
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
- !defined(CONFIG_IDF_TARGET_ESP32C3)
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
new SerialModule();
#endif
#ifdef ARCH_ESP32
// Only run on an esp32 based device.
audioModule = new AudioModule();
- externalNotificationModule = new ExternalNotificationModule();
storeForwardModule = new StoreForwardModule();
-
- new RangeTestModule();
-#elif defined(ARCH_NRF52)
+#endif
+#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
externalNotificationModule = new ExternalNotificationModule();
+ new RangeTestModule();
#endif
} else {
adminModule = new AdminModule();
diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp
index 12f2fedc3..35457a23e 100644
--- a/src/modules/PositionModule.cpp
+++ b/src/modules/PositionModule.cpp
@@ -3,6 +3,7 @@
#include "NodeDB.h"
#include "RTC.h"
#include "Router.h"
+#include "TypeConversions.h"
#include "airtime.h"
#include "configuration.h"
#include "gps/GeoCoord.h"
@@ -56,55 +57,57 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
meshtastic_MeshPacket *PositionModule::allocReply()
{
- meshtastic_NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position
+ meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
assert(node->has_position);
- node->position.seq_number++;
-
// configuration of POSITION packet
// consider making this a function argument?
uint32_t pos_flags = config.position.position_flags;
// Populate a Position struct with ONLY the requested fields
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
+ if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
+ localPosition = ConvertToPosition(node->position);
+ }
+ localPosition.seq_number++;
// lat/lon are unconditionally included - IF AVAILABLE!
- p.latitude_i = node->position.latitude_i;
- p.longitude_i = node->position.longitude_i;
- p.time = node->position.time;
+ p.latitude_i = localPosition.latitude_i;
+ p.longitude_i = localPosition.longitude_i;
+ p.time = localPosition.time;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) {
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL)
- p.altitude = node->position.altitude;
+ p.altitude = localPosition.altitude;
else
- p.altitude_hae = node->position.altitude_hae;
+ p.altitude_hae = localPosition.altitude_hae;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_GEOIDAL_SEPARATION)
- p.altitude_geoidal_separation = node->position.altitude_geoidal_separation;
+ p.altitude_geoidal_separation = localPosition.altitude_geoidal_separation;
}
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_DOP) {
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HVDOP) {
- p.HDOP = node->position.HDOP;
- p.VDOP = node->position.VDOP;
+ p.HDOP = localPosition.HDOP;
+ p.VDOP = localPosition.VDOP;
} else
- p.PDOP = node->position.PDOP;
+ p.PDOP = localPosition.PDOP;
}
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SATINVIEW)
- p.sats_in_view = node->position.sats_in_view;
+ p.sats_in_view = localPosition.sats_in_view;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_TIMESTAMP)
- p.timestamp = node->position.timestamp;
+ p.timestamp = localPosition.timestamp;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SEQ_NO)
- p.seq_number = node->position.seq_number;
+ p.seq_number = localPosition.seq_number;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HEADING)
- p.ground_track = node->position.ground_track;
+ p.ground_track = localPosition.ground_track;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SPEED)
- p.ground_speed = node->position.ground_speed;
+ p.ground_speed = localPosition.ground_speed;
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other
// nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless
@@ -144,7 +147,7 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
int32_t PositionModule::runOnce()
{
- meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
// We limit our GPS broadcasts to a max rate
uint32_t now = millis();
@@ -164,14 +167,14 @@ int32_t PositionModule::runOnce()
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
- LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies);
+ LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
}
}
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized or we're a tracker.
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
- meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
+ meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
if (hasValidPosition(node2)) {
// The minimum distance to travel before we are able to send a new position packet.
@@ -193,7 +196,7 @@ int32_t PositionModule::runOnce()
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
- node2->position.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
+ localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
msSinceLastSend, minimumTimeThreshold);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
@@ -211,4 +214,4 @@ int32_t PositionModule::runOnce()
}
return 5000; // to save power only wake for our callback occasionally
-}
+}
\ No newline at end of file
diff --git a/src/modules/esp32/RangeTestModule.cpp b/src/modules/RangeTestModule.cpp
similarity index 97%
rename from src/modules/esp32/RangeTestModule.cpp
rename to src/modules/RangeTestModule.cpp
index b3f03c04b..783fbd758 100644
--- a/src/modules/esp32/RangeTestModule.cpp
+++ b/src/modules/RangeTestModule.cpp
@@ -1,4 +1,5 @@
#include "RangeTestModule.h"
+#include "FSCommon.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
@@ -8,7 +9,6 @@
#include "configuration.h"
#include "gps/GeoCoord.h"
#include
-#include
/*
As a sender, I can send packets every n seconds. These packets include an incremented PacketID.
@@ -28,7 +28,7 @@ uint32_t packetSequence = 0;
int32_t RangeTestModule::runOnce()
{
-#ifdef ARCH_ESP32
+#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
/*
Uncomment the preferences below if you want to use the module
@@ -60,7 +60,6 @@ int32_t RangeTestModule::runOnce()
return disable();
// This thread does not need to run as a receiver
}
-
} else {
if (moduleConfig.range_test.sender) {
@@ -122,7 +121,7 @@ void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket &mp)
{
-#ifdef ARCH_ESP32
+#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
if (moduleConfig.range_test.enabled) {
@@ -139,7 +138,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
}
/*
- NodeInfo *n = nodeDB.getNode(getFrom(&mp));
+ NodeInfoLite *n = nodeDB.getMeshNode(getFrom(&mp));
LOG_DEBUG("-----------------------------------------\n");
LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes);
@@ -153,7 +152,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n");
LOG_DEBUG("n->user.long_name %s\n", n->user.long_name);
LOG_DEBUG("n->user.short_name %s\n", n->user.short_name);
- LOG_DEBUG("n->user.macaddr %X\n", n->user.macaddr);
LOG_DEBUG("n->has_position %d\n", n->has_position);
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
@@ -165,7 +163,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_DEBUG("-----------------------------------------\n");
*/
}
-
} else {
LOG_INFO("Range Test Module Disabled\n");
}
@@ -177,9 +174,10 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
{
+#ifdef ARCH_ESP32
auto &p = mp.decoded;
- meshtastic_NodeInfo *n = nodeDB.getNode(getFrom(&mp));
+ meshtastic_NodeInfoLite *n = nodeDB.getMeshNode(getFrom(&mp));
/*
LOG_DEBUG("-----------------------------------------\n");
LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes);
@@ -193,7 +191,6 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n");
LOG_DEBUG("n->user.long_name %s\n", n->user.long_name);
LOG_DEBUG("n->user.short_name %s\n", n->user.short_name);
- LOG_DEBUG("n->user.macaddr %X\n", n->user.macaddr);
LOG_DEBUG("n->has_position %d\n", n->has_position);
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
@@ -284,6 +281,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
fileToAppend.printf("\"%s\"\n", p.payload.bytes);
fileToAppend.flush();
fileToAppend.close();
+#endif
return 1;
-}
+}
\ No newline at end of file
diff --git a/src/modules/esp32/RangeTestModule.h b/src/modules/RangeTestModule.h
similarity index 100%
rename from src/modules/esp32/RangeTestModule.h
rename to src/modules/RangeTestModule.h
diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp
index 1a7c081c6..af7ba1381 100644
--- a/src/modules/SerialModule.cpp
+++ b/src/modules/SerialModule.cpp
@@ -39,13 +39,12 @@
KNOWN PROBLEMS
* Until the module is initilized by the startup sequence, the TX pin is in a floating
state. Device connected to that pin may see this as "noise".
- * Will not work on T-Echo and the Linux device targets.
+ * Will not work on Linux device targets.
*/
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
- !defined(CONFIG_IDF_TARGET_ESP32C3)
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 128
#define TIMEOUT 250
@@ -58,11 +57,16 @@
SerialModule *serialModule;
SerialModuleRadio *serialModuleRadio;
+#ifdef TTGO_T_ECHO
+SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("SerialModule") {}
+static Print *serialPrint = &Serial;
+#else
SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {}
+static Print *serialPrint = &Serial2;
+#endif
char serialBytes[meshtastic_Constants_DATA_PAYLOAD_LEN];
size_t serialPayloadSize;
-static Print *serialPrint = &Serial2;
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
{
@@ -119,8 +123,6 @@ int32_t SerialModule::runOnce()
serialPrint = &Serial;
// Give it a chance to flush out 💩
delay(10);
- } else {
- serialPrint = &Serial2;
}
#ifdef ARCH_ESP32
@@ -131,7 +133,7 @@ int32_t SerialModule::runOnce()
Serial.begin(baud);
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
}
-#else
+#elif !defined(TTGO_T_ECHO)
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
Serial2.begin(baud, SERIAL_8N1);
@@ -140,6 +142,9 @@ int32_t SerialModule::runOnce()
Serial.begin(baud, SERIAL_8N1);
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
}
+#else
+ Serial.begin(baud, SERIAL_8N1);
+ Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
#endif
serialModuleRadio = new SerialModuleRadio();
@@ -156,26 +161,29 @@ 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, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position);
+ printGGA(outbuf, sizeof(outbuf), localPosition);
serialPrint->printf("%s", outbuf);
}
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) {
if (millis() - lastNmeaTime > 10000) {
lastNmeaTime = millis();
uint32_t readIndex = 0;
- const meshtastic_NodeInfo *tempNodeInfo = nodeDB.readNextInfo(readIndex);
+ const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB.readNextMeshNode(readIndex);
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
serialPrint->printf("%s", outbuf);
- tempNodeInfo = nodeDB.readNextInfo(readIndex);
+ tempNodeInfo = nodeDB.readNextMeshNode(readIndex);
}
}
- } else {
+ }
+#ifndef TTGO_T_ECHO
+ else {
while (Serial2.available()) {
serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
serialModuleRadio->sendPayload();
}
}
+#endif
}
return (10);
} else {
@@ -243,7 +251,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) {
serialPrint->printf("%s", p.payload.bytes);
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG) {
- meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
+ meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
String sender = (node && node->has_user) ? node->user.short_name : "???";
serialPrint->println();
serialPrint->printf("%s: %s", sender, p.payload.bytes);
@@ -259,7 +267,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
decoded = &scratch;
}
// send position packet as WPL to the serial port
- printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name,
+ printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getMeshNode(getFrom(&mp))->user.long_name,
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO);
serialPrint->printf("%s", outbuf);
}
@@ -304,4 +312,4 @@ uint32_t SerialModule::getBaudRate()
}
return BAUD;
}
-#endif
+#endif
\ No newline at end of file
diff --git a/src/modules/SerialModule.h b/src/modules/SerialModule.h
index 5782ab093..562ccd42b 100644
--- a/src/modules/SerialModule.h
+++ b/src/modules/SerialModule.h
@@ -8,8 +8,7 @@
#include
#include
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
- !defined(CONFIG_IDF_TARGET_ESP32C3)
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread
{
diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp
index 696429aeb..4ef5a9a13 100644
--- a/src/modules/Telemetry/DeviceTelemetry.cpp
+++ b/src/modules/Telemetry/DeviceTelemetry.cpp
@@ -50,14 +50,14 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
t.time = getTime();
t.which_variant = meshtastic_Telemetry_device_metrics_tag;
- t.variant.device_metrics.air_util_tx = myNodeInfo.air_util_tx;
+ t.variant.device_metrics.air_util_tx = airTime->utilizationTXPercent();
if (powerStatus->getIsCharging()) {
t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL;
} else {
t.variant.device_metrics.battery_level = powerStatus->getBatteryChargePercent();
}
- t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
+ t.variant.device_metrics.channel_utilization = airTime->channelUtilizationPercent();
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
@@ -78,4 +78,4 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
return true;
-}
+}
\ No newline at end of file
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index 76385197a..5cdc4bf4d 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -7,6 +7,7 @@
#include "Router.h"
#include "configuration.h"
#include "main.h"
+#include "power.h"
#include
#include
@@ -14,8 +15,6 @@
#include "Sensor/BME280Sensor.h"
#include "Sensor/BME680Sensor.h"
#include "Sensor/BMP280Sensor.h"
-#include "Sensor/INA219Sensor.h"
-#include "Sensor/INA260Sensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/SHT31Sensor.h"
@@ -25,8 +24,6 @@ BMP280Sensor bmp280Sensor;
BME280Sensor bme280Sensor;
BME680Sensor bme680Sensor;
MCP9808Sensor mcp9808Sensor;
-INA260Sensor ina260Sensor;
-INA219Sensor ina219Sensor;
SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor;
SHT31Sensor sht31Sensor;
@@ -83,15 +80,10 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = bme680Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce();
- if (ina260Sensor.hasSensor())
- result = ina260Sensor.runOnce();
- if (ina219Sensor.hasSensor())
- result = ina219Sensor.runOnce();
if (shtc3Sensor.hasSensor())
result = shtc3Sensor.runOnce();
- if (lps22hbSensor.hasSensor()) {
+ if (lps22hbSensor.hasSensor())
result = lps22hbSensor.runOnce();
- }
if (sht31Sensor.hasSensor())
result = sht31Sensor.runOnce();
}
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.cpp b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
index bffa1e367..1dd7f7f2c 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
@@ -12,8 +12,12 @@ int32_t INA219Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
- status = ina219.begin();
+ if (!ina219.success()) {
+ ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
+ status = ina219.begin();
+ } else {
+ status = ina219.success();
+ }
return initI2CSensor();
}
@@ -24,4 +28,9 @@ bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true;
+}
+
+uint16_t INA219Sensor::getBusVoltageMv()
+{
+ return lround(ina219.getBusVoltage_V() * 1000);
}
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.h b/src/modules/Telemetry/Sensor/INA219Sensor.h
index dc6c0a5af..f11a571cc 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.h
@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
+#include "VoltageSensor.h"
#include
-class INA219Sensor : virtual public TelemetrySensor
+class INA219Sensor : virtual public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA219 ina219;
@@ -14,4 +15,5 @@ class INA219Sensor : virtual public TelemetrySensor
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
+ virtual uint16_t getBusVoltageMv() override;
};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.cpp b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
index ee0256e62..034fecca0 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
@@ -12,7 +12,10 @@ int32_t INA260Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
+
+ if (!status) {
+ status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
+ }
return initI2CSensor();
}
@@ -24,4 +27,9 @@ bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
+}
+
+uint16_t INA260Sensor::getBusVoltageMv()
+{
+ return lround(ina260.readBusVoltage());
}
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.h b/src/modules/Telemetry/Sensor/INA260Sensor.h
index 1dcb596e6..8ea532697 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.h
@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
+#include "VoltageSensor.h"
#include
-class INA260Sensor : virtual public TelemetrySensor
+class INA260Sensor : virtual public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
@@ -14,4 +15,5 @@ class INA260Sensor : virtual public TelemetrySensor
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
+ virtual uint16_t getBusVoltageMv() override;
};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/TelemetrySensor.h b/src/modules/Telemetry/Sensor/TelemetrySensor.h
index 7a579ef5c..dec81e061 100644
--- a/src/modules/Telemetry/Sensor/TelemetrySensor.h
+++ b/src/modules/Telemetry/Sensor/TelemetrySensor.h
@@ -1,9 +1,9 @@
#pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
-#include "main.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
+extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor
{
@@ -18,6 +18,7 @@ class TelemetrySensor
const char *sensorName;
meshtastic_TelemetrySensorType sensorType;
unsigned status;
+ bool initialized = false;
int32_t initI2CSensor()
{
@@ -28,6 +29,7 @@ class TelemetrySensor
LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName);
setup();
}
+ initialized = true;
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
virtual void setup();
@@ -36,5 +38,8 @@ class TelemetrySensor
bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; }
virtual int32_t runOnce() = 0;
+ virtual bool isInitialized() { return initialized; }
+ virtual bool isRunning() { return status > 0; }
+
virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0;
-};
+};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/VoltageSensor.h b/src/modules/Telemetry/Sensor/VoltageSensor.h
new file mode 100644
index 000000000..f2f28fb06
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/VoltageSensor.h
@@ -0,0 +1,7 @@
+#pragma once
+
+class VoltageSensor
+{
+ public:
+ virtual uint16_t getBusVoltageMv() = 0;
+};
\ No newline at end of file
diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp
index 38e983669..767e1fb2b 100644
--- a/src/modules/esp32/StoreForwardModule.cpp
+++ b/src/modules/esp32/StoreForwardModule.cpp
@@ -36,8 +36,6 @@ int32_t StoreForwardModule::runOnce()
this->packetHistoryTXQueue_index++;
}
}
- LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
-
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
lastHeartbeat = millis();
LOG_INFO("*** Sending heartbeat\n");
@@ -266,7 +264,6 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
storeForwardModule->historyAdd(mp);
LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent);
}
-
} else if (mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) {
auto &p = mp.decoded;
meshtastic_StoreAndForward scratch;
diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp
index 36ddefeb4..c630aa13b 100644
--- a/src/platform/nrf52/main-nrf52.cpp
+++ b/src/platform/nrf52/main-nrf52.cpp
@@ -172,6 +172,10 @@ void cpuDeepSleep(uint32_t msecToWake)
setBluetoothEnable(false);
#ifdef RAK4630
digitalWrite(PIN_3V3_EN, LOW);
+#ifndef USE_EINK
+ // RAK-12039 set pin for Air quality sensor
+ digitalWrite(AQ_SET_PIN, LOW);
+#endif
#endif
// FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per
@@ -197,4 +201,4 @@ void clearBonds()
nrf52Bluetooth->setup();
}
nrf52Bluetooth->clearBonds();
-}
+}
\ No newline at end of file
diff --git a/src/platform/stm32wl/InternalFileSystem.cpp b/src/platform/stm32wl/InternalFileSystem.cpp
new file mode 100644
index 000000000..950ceb0cd
--- /dev/null
+++ b/src/platform/stm32wl/InternalFileSystem.cpp
@@ -0,0 +1,141 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "InternalFileSystem.h"
+#include
+
+//--------------------------------------------------------------------+
+// LFS Disk IO
+//--------------------------------------------------------------------+
+
+static inline uint32_t lba2addr(uint32_t block)
+{
+ return ((uint32_t)LFS_FLASH_ADDR) + block * LFS_BLOCK_SIZE;
+}
+
+static int _internal_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
+{
+ (void)c;
+
+ uint32_t addr = lba2addr(block) + off;
+ uint8_t prom;
+
+ for (int i = 0; i < size; i++) {
+ prom = EEPROM.read(addr + i);
+ memcpy((char *)buffer + i, &prom, 1);
+ }
+ return 0;
+}
+
+// Program a region in a block. The block must have previously
+// been erased. Negative error codes are propogated to the user.
+// May return LFS_ERR_CORRUPT if the block should be considered bad.
+static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
+{
+ (void)c;
+
+ uint32_t addr = lba2addr(block) + off;
+ uint8_t prom;
+
+ for (int i = 0; i < size; i++) {
+ memcpy(&prom, (char *)buffer + i, 1);
+ EEPROM.update(addr + i, prom);
+ }
+ return 0;
+}
+
+// Erase a block. A block must be erased before being programmed.
+// The state of an erased block is undefined. Negative error codes
+// are propogated to the user.
+// May return LFS_ERR_CORRUPT if the block should be considered bad.
+static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
+{
+ (void)c;
+
+ uint32_t addr = lba2addr(block);
+
+ // implement as write 0xff to whole block address
+ for (int i = 0; i < LFS_BLOCK_SIZE; i++) {
+ EEPROM.update(addr, 0xff);
+ }
+
+ return 0;
+}
+
+// Sync the state of the underlying block device. Negative error codes
+// are propogated to the user.
+static int _internal_flash_sync(const struct lfs_config *c)
+{
+ // we don't use a ram cache, this is a noop
+ return 0;
+}
+
+static struct lfs_config _InternalFSConfig = {.context = NULL,
+
+ .read = _internal_flash_read,
+ .prog = _internal_flash_prog,
+ .erase = _internal_flash_erase,
+ .sync = _internal_flash_sync,
+
+ .read_size = LFS_CACHE_SIZE,
+ .prog_size = LFS_CACHE_SIZE,
+ .block_size = LFS_BLOCK_SIZE,
+ .block_count = LFS_FLASH_TOTAL_SIZE / LFS_BLOCK_SIZE,
+ .block_cycles =
+ 500, // protection against wear leveling (suggested values between 100-1000)
+ .cache_size = LFS_CACHE_SIZE,
+ .lookahead_size = LFS_CACHE_SIZE,
+
+ .read_buffer = lfs_read_buffer,
+ .prog_buffer = lfs_prog_buffer,
+ .lookahead_buffer = lfs_lookahead_buffer};
+
+InternalFileSystem InternalFS;
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+InternalFileSystem::InternalFileSystem(void) : LittleFS(&_InternalFSConfig) {}
+
+bool InternalFileSystem::begin(void)
+{
+ // failed to mount, erase all sector then format and mount again
+ if (!LittleFS::begin()) {
+ // Erase all sectors of internal flash region for Filesystem.
+ // implement as write 0xff to whole block address
+ for (uint32_t addr = LFS_FLASH_ADDR; addr < (LFS_FLASH_ADDR + LFS_FLASH_TOTAL_SIZE); addr++) {
+ EEPROM.update(addr, 0xff);
+ }
+
+ // lfs format
+ this->format();
+
+ // mount again if still failed, give up
+ if (!LittleFS::begin())
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/platform/stm32wl/InternalFileSystem.h b/src/platform/stm32wl/InternalFileSystem.h
new file mode 100644
index 000000000..66344194e
--- /dev/null
+++ b/src/platform/stm32wl/InternalFileSystem.h
@@ -0,0 +1,54 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef INTERNALFILESYSTEM_H_
+#define INTERNALFILESYSTEM_H_
+
+#include "LittleFS.h"
+
+// The EEPROM Library assumes our usable flash area starts at logical 0
+#define LFS_FLASH_ADDR 0
+
+// use the built in EEPROM emulation. Total Size is 2Kbyte
+#define LFS_BLOCK_SIZE 128 // min. block size is 128 to fit CTZ pointers
+#define LFS_CACHE_SIZE 16
+
+#define LFS_FLASH_TOTAL_SIZE FLASH_PAGE_SIZE
+
+static uint8_t lfs_read_buffer[LFS_CACHE_SIZE] = {0};
+static uint8_t lfs_prog_buffer[LFS_CACHE_SIZE] = {0};
+static uint8_t lfs_lookahead_buffer[LFS_CACHE_SIZE] = {0};
+
+class InternalFileSystem : public LittleFS
+{
+ public:
+ InternalFileSystem(void);
+
+ // overwrite to also perform low level format (sector erase of whole flash region)
+ bool begin(void);
+};
+
+extern InternalFileSystem InternalFS;
+
+#endif /* INTERNALFILESYSTEM_H_ */
diff --git a/src/platform/stm32wl/LittleFS.cpp b/src/platform/stm32wl/LittleFS.cpp
new file mode 100644
index 000000000..b1267d88a
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS.cpp
@@ -0,0 +1,258 @@
+#include
+#include
+
+#include "LittleFS.h"
+
+using namespace LittleFS_Namespace;
+
+//--------------------------------------------------------------------+
+// Implementation
+//--------------------------------------------------------------------+
+
+LittleFS::LittleFS(void) : LittleFS(NULL) {}
+
+LittleFS::LittleFS(struct lfs_config *cfg)
+{
+ memset(&_lfs, 0, sizeof(_lfs));
+ _lfs_cfg = cfg;
+ _mounted = false;
+ _mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
+}
+
+LittleFS::~LittleFS() {}
+
+// Initialize and mount the file system
+// Return true if mounted successfully else probably corrupted.
+// User should format the disk and try again
+bool LittleFS::begin(struct lfs_config *cfg)
+{
+ _lockFS();
+
+ bool ret;
+ // not a loop, just an quick way to short-circuit on error
+ do {
+ if (_mounted) {
+ ret = true;
+ break;
+ }
+ if (cfg) {
+ _lfs_cfg = cfg;
+ }
+ if (nullptr == _lfs_cfg) {
+ ret = false;
+ break;
+ }
+ // actually attempt to mount, and log error if one occurs
+ int err = lfs_mount(&_lfs, _lfs_cfg);
+ PRINT_LFS_ERR(err);
+ _mounted = (err == LFS_ERR_OK);
+ ret = _mounted;
+ } while (0);
+
+ _unlockFS();
+ return ret;
+}
+
+// Tear down and unmount file system
+void LittleFS::end(void)
+{
+ _lockFS();
+
+ if (_mounted) {
+ _mounted = false;
+ int err = lfs_unmount(&_lfs);
+ PRINT_LFS_ERR(err);
+ (void)err;
+ }
+
+ _unlockFS();
+}
+
+bool LittleFS::format(void)
+{
+ _lockFS();
+
+ int err = LFS_ERR_OK;
+ bool attemptMount = _mounted;
+ // not a loop, just an quick way to short-circuit on error
+ do {
+ // if already mounted: umount first -> format -> remount
+ if (_mounted) {
+ _mounted = false;
+ err = lfs_unmount(&_lfs);
+ if (LFS_ERR_OK != err) {
+ PRINT_LFS_ERR(err);
+ break;
+ }
+ }
+ err = lfs_format(&_lfs, _lfs_cfg);
+ if (LFS_ERR_OK != err) {
+ PRINT_LFS_ERR(err);
+ break;
+ }
+
+ if (attemptMount) {
+ err = lfs_mount(&_lfs, _lfs_cfg);
+ if (LFS_ERR_OK != err) {
+ PRINT_LFS_ERR(err);
+ break;
+ }
+ _mounted = true;
+ }
+ // success!
+ } while (0);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Open a file or folder
+LittleFS_Namespace::File LittleFS::open(char const *filepath, uint8_t mode)
+{
+ // No lock is required here ... the File() object will synchronize with the mutex provided
+ return LittleFS_Namespace::File(filepath, mode, *this);
+}
+
+// Check if file or folder exists
+bool LittleFS::exists(char const *filepath)
+{
+ struct lfs_info info;
+ _lockFS();
+
+ bool ret = (0 == lfs_stat(&_lfs, filepath, &info));
+
+ _unlockFS();
+ return ret;
+}
+
+// Create a directory, create intermediate parent if needed
+bool LittleFS::mkdir(char const *filepath)
+{
+ bool ret = true;
+ const char *slash = filepath;
+ if (slash[0] == '/')
+ slash++; // skip root '/'
+
+ _lockFS();
+
+ // make intermediate parent directory(ies)
+ while (NULL != (slash = strchr(slash, '/'))) {
+ char parent[slash - filepath + 1] = {0};
+ memcpy(parent, filepath, slash - filepath);
+
+ int rc = lfs_mkdir(&_lfs, parent);
+ if (rc != LFS_ERR_OK && rc != LFS_ERR_EXIST) {
+ PRINT_LFS_ERR(rc);
+ ret = false;
+ break;
+ }
+ slash++;
+ }
+ // make the final requested directory
+ if (ret) {
+ int rc = lfs_mkdir(&_lfs, filepath);
+ if (rc != LFS_ERR_OK && rc != LFS_ERR_EXIST) {
+ PRINT_LFS_ERR(rc);
+ ret = false;
+ }
+ }
+
+ _unlockFS();
+ return ret;
+}
+
+// Remove a file
+bool LittleFS::remove(char const *filepath)
+{
+ _lockFS();
+
+ int err = lfs_remove(&_lfs, filepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Rename a file
+bool LittleFS::rename(char const *oldfilepath, char const *newfilepath)
+{
+ _lockFS();
+
+ int err = lfs_rename(&_lfs, oldfilepath, newfilepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Remove a folder
+bool LittleFS::rmdir(char const *filepath)
+{
+ _lockFS();
+
+ int err = lfs_remove(&_lfs, filepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Remove a folder recursively
+bool LittleFS::rmdir_r(char const *filepath)
+{
+ /* adafruit: lfs is modified to remove non-empty folder,
+ According to below issue, comment these 2 line won't corrupt filesystem
+ at least when using LFS v1. If moving to LFS v2, see tracked issue
+ to see if issues (such as the orphans in threaded linked list) are resolved.
+ https://github.com/ARMmbed/littlefs/issues/43
+ */
+ _lockFS();
+
+ int err = lfs_remove(&_lfs, filepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+//------------- Debug -------------//
+#if CFG_DEBUG
+
+const char *dbg_strerr_lfs(int32_t err)
+{
+ switch (err) {
+ case LFS_ERR_OK:
+ return "LFS_ERR_OK";
+ case LFS_ERR_IO:
+ return "LFS_ERR_IO";
+ case LFS_ERR_CORRUPT:
+ return "LFS_ERR_CORRUPT";
+ case LFS_ERR_NOENT:
+ return "LFS_ERR_NOENT";
+ case LFS_ERR_EXIST:
+ return "LFS_ERR_EXIST";
+ case LFS_ERR_NOTDIR:
+ return "LFS_ERR_NOTDIR";
+ case LFS_ERR_ISDIR:
+ return "LFS_ERR_ISDIR";
+ case LFS_ERR_NOTEMPTY:
+ return "LFS_ERR_NOTEMPTY";
+ case LFS_ERR_BADF:
+ return "LFS_ERR_BADF";
+ case LFS_ERR_INVAL:
+ return "LFS_ERR_INVAL";
+ case LFS_ERR_NOSPC:
+ return "LFS_ERR_NOSPC";
+ case LFS_ERR_NOMEM:
+ return "LFS_ERR_NOMEM";
+
+ default:
+ static char errcode[10];
+ sprintf(errcode, "%ld", err);
+ return errcode;
+ }
+
+ return NULL;
+}
+
+#endif
diff --git a/src/platform/stm32wl/LittleFS.h b/src/platform/stm32wl/LittleFS.h
new file mode 100644
index 000000000..4a0b01af2
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS.h
@@ -0,0 +1,85 @@
+
+#ifndef LITTLEFS_H_
+#define LITTLEFS_H_
+
+#include
+
+#include "lfs.h"
+
+#include "LittleFS_File.h"
+
+#include "FreeRTOS.h" // tied to FreeRTOS for serialization
+#include "semphr.h"
+
+class LittleFS
+{
+ public:
+ LittleFS(void);
+ explicit LittleFS(struct lfs_config *cfg);
+ virtual ~LittleFS();
+
+ bool begin(struct lfs_config *cfg = NULL);
+ void end(void);
+
+ // Open the specified file/directory with the supplied mode (e.g. read or
+ // write, etc). Returns a File object for interacting with the file.
+ // Note that currently only one file can be open at a time.
+ LittleFS_Namespace::File open(char const *filename, uint8_t mode = LittleFS_Namespace::FILE_O_READ);
+
+ // Methods to determine if the requested file path exists.
+ bool exists(char const *filepath);
+
+ // Create the requested directory hierarchy--if intermediate directories
+ // do not exist they will be created.
+ bool mkdir(char const *filepath);
+
+ // Delete the file.
+ bool remove(char const *filepath);
+
+ // Rename the file.
+ bool rename(char const *oldfilepath, char const *newfilepath);
+
+ // Delete a folder (must be empty)
+ bool rmdir(char const *filepath);
+
+ // Delete a folder (recursively)
+ bool rmdir_r(char const *filepath);
+
+ // format file system
+ bool format(void);
+
+ /*------------------------------------------------------------------*/
+ /* INTERNAL USAGE ONLY
+ * Although declare as public, it is meant to be invoked by internal
+ * code. User should not call these directly
+ *------------------------------------------------------------------*/
+ lfs_t *_getFS(void) { return &_lfs; }
+ void _lockFS(void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
+ void _unlockFS(void) { xSemaphoreGive(_mutex); }
+
+ protected:
+ bool _mounted;
+ struct lfs_config *_lfs_cfg;
+ lfs_t _lfs;
+ SemaphoreHandle_t _mutex;
+
+ private:
+ StaticSemaphore_t _MutexStorageSpace;
+};
+
+#if !CFG_DEBUG
+#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
+#define PRINT_LFS_ERR(_err)
+#else
+#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_strerr_lfs)
+#define PRINT_LFS_ERR(_err) \
+ do { \
+ if (_err) { \
+ VERIFY_MESS((long int)_err, dbg_strerr_lfs); \
+ } \
+ } while (0) // LFS_ERR are of type int, VERIFY_MESS expects long_int
+
+const char *dbg_strerr_lfs(int32_t err);
+#endif
+
+#endif /* LITTLEFS_H_ */
diff --git a/src/platform/stm32wl/LittleFS_File.cpp b/src/platform/stm32wl/LittleFS_File.cpp
new file mode 100644
index 000000000..cffb924e1
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS_File.cpp
@@ -0,0 +1,362 @@
+#include
+
+#include "LittleFS.h"
+
+#include
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+using namespace LittleFS_Namespace;
+
+File::File(LittleFS &fs)
+{
+ _fs = &fs;
+ _is_dir = false;
+ _name[0] = 0;
+ _dir_path = NULL;
+
+ _dir = NULL;
+ _file = NULL;
+}
+
+File::File(char const *filename, uint8_t mode, LittleFS &fs) : File(fs)
+{
+ // public constructor calls public API open(), which will obtain the mutex
+ this->open(filename, mode);
+}
+
+bool File::_open_file(char const *filepath, uint8_t mode)
+{
+ int flags = (mode == FILE_O_READ) ? LFS_O_RDONLY : (mode == FILE_O_WRITE) ? (LFS_O_RDWR | LFS_O_CREAT) : 0;
+
+ if (flags) {
+ _file = (lfs_file_t *)malloc(sizeof(lfs_file_t));
+ if (!_file)
+ return false;
+
+ int rc = lfs_file_open(_fs->_getFS(), _file, filepath, flags);
+
+ if (rc) {
+ // failed to open
+ PRINT_LFS_ERR(rc);
+ return false;
+ }
+
+ // move to end of file
+ if (mode == FILE_O_WRITE)
+ lfs_file_seek(_fs->_getFS(), _file, 0, LFS_SEEK_END);
+
+ _is_dir = false;
+ }
+
+ return true;
+}
+
+bool File::_open_dir(char const *filepath)
+{
+ _dir = (lfs_dir_t *)malloc(sizeof(lfs_dir_t));
+ if (!_dir)
+ return false;
+
+ int rc = lfs_dir_open(_fs->_getFS(), _dir, filepath);
+
+ if (rc) {
+ // failed to open
+ PRINT_LFS_ERR(rc);
+ return false;
+ }
+
+ _is_dir = true;
+
+ _dir_path = (char *)malloc(strlen(filepath) + 1);
+ strcpy(_dir_path, filepath);
+
+ return true;
+}
+
+bool File::open(char const *filepath, uint8_t mode)
+{
+ bool ret = false;
+ _fs->_lockFS();
+
+ ret = this->_open(filepath, mode);
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+bool File::_open(char const *filepath, uint8_t mode)
+{
+ bool ret = false;
+
+ // close if currently opened
+ if (this->isOpen())
+ _close();
+
+ struct lfs_info info;
+ int rc = lfs_stat(_fs->_getFS(), filepath, &info);
+
+ if (LFS_ERR_OK == rc) {
+ // file existed, open file or directory accordingly
+ ret = (info.type == LFS_TYPE_REG) ? _open_file(filepath, mode) : _open_dir(filepath);
+ } else if (LFS_ERR_NOENT == rc) {
+ // file not existed, only proceed with FILE_O_WRITE mode
+ if (mode == FILE_O_WRITE)
+ ret = _open_file(filepath, mode);
+ } else {
+ PRINT_LFS_ERR(rc);
+ }
+
+ // save bare file name
+ if (ret) {
+ char const *splash = strrchr(filepath, '/');
+ strncpy(_name, splash ? (splash + 1) : filepath, LFS_NAME_MAX);
+ }
+ return ret;
+}
+
+size_t File::write(uint8_t ch)
+{
+ return write(&ch, 1);
+}
+
+size_t File::write(uint8_t const *buf, size_t size)
+{
+ lfs_ssize_t wrcount = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ wrcount = lfs_file_write(_fs->_getFS(), _file, buf, size);
+ if (wrcount < 0) {
+ wrcount = 0;
+ }
+ }
+
+ _fs->_unlockFS();
+ return wrcount;
+}
+
+int File::read(void)
+{
+ // this thin wrapper relies on called function to synchronize
+ int ret = -1;
+ uint8_t ch;
+ if (read(&ch, 1) > 0) {
+ ret = static_cast(ch);
+ }
+ return ret;
+}
+
+int File::read(void *buf, uint16_t nbyte)
+{
+ int ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_read(_fs->_getFS(), _file, buf, nbyte);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+int File::peek(void)
+{
+ int ret = -1;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
+ uint8_t ch = 0;
+ if (lfs_file_read(_fs->_getFS(), _file, &ch, 1) > 0) {
+ ret = static_cast(ch);
+ }
+ (void)lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+int File::available(void)
+{
+ int ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ uint32_t size = lfs_file_size(_fs->_getFS(), _file);
+ uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
+ ret = size - pos;
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+bool File::seek(uint32_t pos)
+{
+ bool ret = false;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET) >= 0;
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+uint32_t File::position(void)
+{
+ uint32_t ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_tell(_fs->_getFS(), _file);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+uint32_t File::size(void)
+{
+ uint32_t ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_size(_fs->_getFS(), _file);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+bool File::truncate(uint32_t pos)
+{
+ int32_t ret = LFS_ERR_ISDIR;
+ _fs->_lockFS();
+ if (!this->_is_dir) {
+ ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
+ }
+ _fs->_unlockFS();
+ return (ret == 0);
+}
+
+bool File::truncate(void)
+{
+ int32_t ret = LFS_ERR_ISDIR;
+ _fs->_lockFS();
+ if (!this->_is_dir) {
+ uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
+ ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
+ }
+ _fs->_unlockFS();
+ return (ret == 0);
+}
+
+void File::flush(void)
+{
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ lfs_file_sync(_fs->_getFS(), _file);
+ }
+
+ _fs->_unlockFS();
+ return;
+}
+
+void File::close(void)
+{
+ _fs->_lockFS();
+ this->_close();
+ _fs->_unlockFS();
+}
+
+void File::_close(void)
+{
+ if (this->isOpen()) {
+ if (this->_is_dir) {
+ lfs_dir_close(_fs->_getFS(), _dir);
+ free(_dir);
+ _dir = NULL;
+
+ if (this->_dir_path)
+ free(_dir_path);
+ _dir_path = NULL;
+ } else {
+ lfs_file_close(this->_fs->_getFS(), _file);
+ free(_file);
+ _file = NULL;
+ }
+ }
+}
+
+File::operator bool(void)
+{
+ return isOpen();
+}
+
+bool File::isOpen(void)
+{
+ return (_file != NULL) || (_dir != NULL);
+}
+
+// WARNING -- although marked as `const`, the values pointed
+// to may change. For example, if the same File
+// object has `open()` called with a different
+// file or directory name, this same pointer will
+// suddenly (unexpectedly?) have different values.
+char const *File::name(void)
+{
+ return this->_name;
+}
+
+bool File::isDirectory(void)
+{
+ return this->_is_dir;
+}
+
+File File::openNextFile(uint8_t mode)
+{
+ _fs->_lockFS();
+
+ File ret(*_fs);
+ if (this->_is_dir) {
+ struct lfs_info info;
+ int rc;
+
+ // lfs_dir_read returns 0 when reaching end of directory, 1 if found an entry
+ // Skip the "." and ".." entries ...
+ do {
+ rc = lfs_dir_read(_fs->_getFS(), _dir, &info);
+ } while (rc == 1 && (!strcmp(".", info.name) || !strcmp("..", info.name)));
+
+ if (rc == 1) {
+ // string cat name with current folder
+ char filepath[strlen(_dir_path) + 1 + strlen(info.name) + 1]; // potential for significant stack usage
+ strcpy(filepath, _dir_path);
+ if (!(_dir_path[0] == '/' && _dir_path[1] == 0))
+ strcat(filepath, "/"); // only add '/' if cwd is not root
+ strcat(filepath, info.name);
+
+ (void)ret._open(filepath, mode); // return value is ignored ... caller is expected to check isOpened()
+ } else if (rc < 0) {
+ PRINT_LFS_ERR(rc);
+ }
+ }
+ _fs->_unlockFS();
+ return ret;
+}
+
+void File::rewindDirectory(void)
+{
+ _fs->_lockFS();
+ if (this->_is_dir) {
+ lfs_dir_rewind(_fs->_getFS(), _dir);
+ }
+ _fs->_unlockFS();
+}
diff --git a/src/platform/stm32wl/LittleFS_File.h b/src/platform/stm32wl/LittleFS_File.h
new file mode 100644
index 000000000..e88a2790d
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS_File.h
@@ -0,0 +1,82 @@
+#ifndef LITTLEFS_FILE_H_
+#define LITTLEFS_FILE_H_
+
+// Forward declaration
+class LittleFS;
+
+namespace LittleFS_Namespace
+{
+
+// avoid conflict with other FileSystem FILE_READ/FILE_WRITE
+enum {
+ FILE_O_READ = 0,
+ FILE_O_WRITE = 1,
+};
+
+class File : public Stream
+{
+ public:
+ explicit File(LittleFS &fs);
+ File(char const *filename, uint8_t mode, LittleFS &fs);
+
+ public:
+ bool open(char const *filename, uint8_t mode);
+
+ //------------- Stream API -------------//
+ virtual size_t write(uint8_t ch);
+ virtual size_t write(uint8_t const *buf, size_t size);
+ size_t write(const char *str)
+ {
+ if (str == NULL)
+ return 0;
+ return write((const uint8_t *)str, strlen(str));
+ }
+ size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, size); }
+
+ virtual int read(void);
+ int read(void *buf, uint16_t nbyte);
+
+ virtual int peek(void);
+ virtual int available(void);
+ virtual void flush(void);
+
+ bool seek(uint32_t pos);
+ uint32_t position(void);
+ uint32_t size(void);
+
+ bool truncate(uint32_t pos);
+ bool truncate(void);
+
+ void close(void);
+
+ operator bool(void);
+
+ bool isOpen(void);
+ char const *name(void);
+
+ bool isDirectory(void);
+ File openNextFile(uint8_t mode = FILE_O_READ);
+ void rewindDirectory(void);
+
+ private:
+ LittleFS *_fs;
+
+ bool _is_dir;
+
+ union {
+ lfs_file_t *_file;
+ lfs_dir_t *_dir;
+ };
+
+ char *_dir_path;
+ char _name[LFS_NAME_MAX + 1];
+
+ bool _open(char const *filepath, uint8_t mode);
+ bool _open_file(char const *filepath, uint8_t mode);
+ bool _open_dir(char const *filepath);
+ void _close(void);
+};
+
+} // namespace LittleFS_Namespace
+
+#endif /* LITTLEFS_FILE_H_ */
diff --git a/src/platform/stm32wl/architecture.h b/src/platform/stm32wl/architecture.h
index dc7adc5ff..1c021903a 100644
--- a/src/platform/stm32wl/architecture.h
+++ b/src/platform/stm32wl/architecture.h
@@ -6,24 +6,19 @@
// defaults for STM32WL architecture
//
+#ifndef HAS_RADIO
+#define HAS_RADIO 1
+#endif
+
//
// set HW_VENDOR
//
#ifndef HW_VENDOR
-#define HW_VENDOR HardwareModel_PRIVATE_HW
+#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-void stm32wl_emulate_digitalWrite(long unsigned int pin, long unsigned int value);
-int stm32wl_emulate_digitalRead(long unsigned int pin);
-#ifdef __cplusplus
-}
-#endif
-
-/* virtual pins for stm32wl_emulate_digitalWrite() / stm32wl_emulate_digitalRead() to recognize */
+/* virtual pins */
#define SX126X_CS 1000
#define SX126X_DIO1 1001
#define SX126X_RESET 1003
diff --git a/src/platform/stm32wl/layer.c b/src/platform/stm32wl/layer.c
deleted file mode 100644
index d6f073200..000000000
--- a/src/platform/stm32wl/layer.c
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "architecture.h"
-#include "stm32wlxx.h"
-#include "stm32wlxx_hal.h"
-#include
-
-void HardFault_Handler(void)
-{
- asm("bkpt");
-}
-
-void stm32wl_emulate_digitalWrite(long unsigned int pin, long unsigned int value)
-{
- switch (pin) {
- case SX126X_CS: /* active low */
- if (value)
- LL_PWR_UnselectSUBGHZSPI_NSS();
- else
- LL_PWR_SelectSUBGHZSPI_NSS();
- break;
- case SX126X_RESET: /* active low */
- if (value)
- LL_RCC_RF_DisableReset();
- else {
- LL_RCC_RF_EnableReset();
- LL_RCC_HSE_EnableTcxo();
- LL_RCC_HSE_Enable();
- while (!LL_RCC_HSE_IsReady())
- ;
- }
- break;
- default:
- asm("bkpt");
- break;
- }
-}
-
-static bool irq_happened;
-
-void SUBGHZ_Radio_IRQHandler(void)
-{
- NVIC_DisableIRQ(SUBGHZ_Radio_IRQn);
- irq_happened = true;
-}
-
-int stm32wl_emulate_digitalRead(long unsigned int pin)
-{
- int outcome = 0;
-
- switch (pin) {
- case SX126X_BUSY:
- // return ((LL_PWR_IsActiveFlag_RFBUSYMS() & LL_PWR_IsActiveFlag_RFBUSYS()) == 1UL);
- outcome = LL_PWR_IsActiveFlag_RFBUSYS();
- break;
- case SX126X_DIO1:
- default:
- NVIC_ClearPendingIRQ(SUBGHZ_Radio_IRQn);
- irq_happened = false;
- NVIC_EnableIRQ(SUBGHZ_Radio_IRQn);
- for (int i = 0; i < 64; i++)
- asm("nop");
- outcome = irq_happened;
- break;
- }
- return outcome;
-}
diff --git a/src/platform/stm32wl/main-stm32wl.cpp b/src/platform/stm32wl/main-stm32wl.cpp
index 8ebcb029e..f57928c60 100644
--- a/src/platform/stm32wl/main-stm32wl.cpp
+++ b/src/platform/stm32wl/main-stm32wl.cpp
@@ -11,8 +11,18 @@ void updateBatteryLevel(uint8_t level) {}
void getMacAddr(uint8_t *dmac)
{
- for (int i = 0; i < 6; i++)
- dmac[i] = i;
+ // https://flit.github.io/2020/06/06/mcu-unique-id-survey.html
+ const uint32_t uid0 = HAL_GetUIDw0(); // X/Y coordinate on wafer
+ const uint32_t uid1 = HAL_GetUIDw1(); // [31:8] Lot number (23:0), [7:0] Wafer number
+ const uint32_t uid2 = HAL_GetUIDw2(); // Lot number (55:24)
+
+ // Need to go from 96-bit to 48-bit unique ID
+ dmac[5] = (uint8_t)uid0;
+ dmac[4] = (uint8_t)(uid0 >> 16);
+ dmac[3] = (uint8_t)uid1;
+ dmac[2] = (uint8_t)(uid1 >> 8);
+ dmac[1] = (uint8_t)uid2;
+ dmac[0] = (uint8_t)(uid2 >> 8);
}
void cpuDeepSleep(uint32_t msecToWake) {}
diff --git a/src/power.h b/src/power.h
index c47e78466..e90e3f21b 100644
--- a/src/power.h
+++ b/src/power.h
@@ -22,6 +22,13 @@ extern RTC_NOINIT_ATTR uint64_t RTC_reg_b;
#include "soc/sens_reg.h" // needed for adc pin reset
#endif
+#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
+#include "modules/Telemetry/Sensor/INA219Sensor.h"
+#include "modules/Telemetry/Sensor/INA260Sensor.h"
+extern INA260Sensor ina260Sensor;
+extern INA219Sensor ina219Sensor;
+#endif
+
class Power : private concurrency::OSThread
{
@@ -41,7 +48,6 @@ class Power : private concurrency::OSThread
/// Setup a xpowers chip axp192/axp2101, return true if found
bool axpChipInit();
-
/// Setup a simple ADC input based battery sensor
bool analogInit();
diff --git a/src/shutdown.h b/src/shutdown.h
index b08478a1e..ee63422dd 100644
--- a/src/shutdown.h
+++ b/src/shutdown.h
@@ -26,8 +26,8 @@ void powerCommandsCheck()
if (shutdownAtMsec && millis() > shutdownAtMsec) {
LOG_INFO("Shutting down from admin command\n");
- playShutdownMelody();
#if defined(ARCH_NRF52) || defined(ARCH_ESP32)
+ playShutdownMelody();
power->shutdown();
#else
LOG_WARN("FIXME implement shutdown for this platform");
diff --git a/src/xmodem.h b/src/xmodem.h
index 848e926bd..2ba0bb39f 100644
--- a/src/xmodem.h
+++ b/src/xmodem.h
@@ -59,7 +59,7 @@ class XModemAdapter
uint16_t packetno = 0;
-#if defined(ARCH_NRF52)
+#if defined(ARCH_NRF52) || defined(ARCH_STM32WL)
File file = File(FSCom);
#else
File file;
diff --git a/variants/rak11310/variant.h b/variants/rak11310/variant.h
index a2bef0730..1d1577cfd 100644
--- a/variants/rak11310/variant.h
+++ b/variants/rak11310/variant.h
@@ -14,6 +14,7 @@
#undef GPS_SERIAL_NUM
#define LED_CONN PIN_LED2
+#define LED_PIN LED_BUILTIN
#define BUTTON_PIN 9
#define BUTTON_NEED_PULLUP
diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h
index 69a77a029..fe9f062c8 100644
--- a/variants/rak4631/variant.h
+++ b/variants/rak4631/variant.h
@@ -258,6 +258,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
#define PIN_ETHERNET_RESET 21
#define PIN_ETHERNET_SS PIN_EINK_CS
#define ETH_SPI_PORT SPI1
+#define AQ_SET_PIN 10
#ifdef __cplusplus
}
@@ -267,4 +268,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
-#endif
+#endif
\ No newline at end of file
diff --git a/variants/wio-e5/platformio.ini b/variants/wio-e5/platformio.ini
index 32436dae8..07f6efa6d 100644
--- a/variants/wio-e5/platformio.ini
+++ b/variants/wio-e5/platformio.ini
@@ -1,5 +1,11 @@
[env:wio-e5]
extends = stm32wl5e_base
board_level = extra
-build_flags = ${stm32wl5e_base.build_flags} -Ivariants/wio-e5 -DHAL_DAC_MODULE_ONLY
- -DSERIAL_UART_INSTANCE=1 -DPIN_SERIAL_RX=PB7 -DPIN_SERIAL_TX=PB6
+build_flags =
+ ${stm32wl5e_base.build_flags}
+ -Ivariants/wio-e5
+ -DHAL_DAC_MODULE_ONLY
+ -DSERIAL_UART_INSTANCE=1
+ -DPIN_SERIAL_RX=PB7
+ -DPIN_SERIAL_TX=PB6
+upload_port = stlink
\ No newline at end of file
diff --git a/variants/wio-e5/variant.h b/variants/wio-e5/variant.h
index b1f7556b4..86e58bcb2 100644
--- a/variants/wio-e5/variant.h
+++ b/variants/wio-e5/variant.h
@@ -12,18 +12,6 @@ Do not expect a working Meshtastic device with this target.
#ifndef _VARIANT_WIOE5_
#define _VARIANT_WIOE5_
-// Arduino/PlatformIO support for SUBGHZSPI is not currently available
-//#define USE_SX1262
-
-#ifdef USE_SX1262
-#define HAS_RADIO 1
-
-/* module only transmits through RFO_HP */
-#define SX126X_RXEN PA5
-#define SX126X_TXEN PA4
-
-/* TCXO fed by internal LDO option behind PB0 pin */
-#define SX126X_E22
-#endif
+#define USE_STM32WLx
#endif
\ No newline at end of file
diff --git a/version.properties b/version.properties
index d131e4cc8..1b9a7da4f 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 1
-build = 15
+build = 17