diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index fd4acbdba..66bf7539c 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -33,6 +33,7 @@ jobs:
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
+ - board: meshtastic-dr-dev
- board: rak4631
- board: rak4631_eink
- board: t-echo
@@ -41,8 +42,9 @@ jobs:
- board: m5stack-core
- board: m5stack-coreink
- board: tbeam-s3-core
+ - board: feather_diy
# - board: pico
-
+
runs-on: ubuntu-latest
steps:
- name: Checkout code
@@ -96,6 +98,7 @@ jobs:
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
+ - board: meshtastic-dr-dev
- board: nano-g1
- board: station-g1
- board: m5stack-core
@@ -131,11 +134,11 @@ jobs:
- name: Upgrade platformio
run: |
pio upgrade
-
+
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
- repo: "meshtastic/meshtastic-web"
+ repo: "meshtastic/web"
file: "build.tar"
target: "build.tar"
token: ${{ secrets.GITHUB_TOKEN }}
@@ -147,15 +150,15 @@ jobs:
- name: Build ESP32
run: bin/build-esp32.sh ${{ matrix.board }}
-
+
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
with:
- repo: "meshtastic/Meshtastic-OTA"
+ repo: "meshtastic/firmware-ota"
file: "firmware.bin"
target: "release/bleota.bin"
token: ${{ secrets.GITHUB_TOKEN }}
-
+
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
@@ -179,6 +182,7 @@ jobs:
- board: rak4631_eink
- board: t-echo
- board: pca10059_diy_eink
+ - board: feather_diy
runs-on: ubuntu-latest
steps:
@@ -369,7 +373,7 @@ jobs:
id: version
- name: Move files up
- run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
+ run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v3
@@ -392,7 +396,7 @@ jobs:
# For diagnostics
- name: Show artifacts
run: ls -lR
-
+
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
@@ -427,7 +431,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
-
+
- name: Setup Python
uses: actions/setup-python@v4
with:
@@ -441,7 +445,7 @@ jobs:
with:
name: firmware-${{ steps.version.outputs.version }}
path: ./output
-
+
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
@@ -454,7 +458,7 @@ jobs:
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./elfs
-
+
- name: Zip Elfs
run: zip -j -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs
@@ -468,7 +472,7 @@ jobs:
with:
draft: true
prerelease: true
- release_name: Meshtastic Device ${{ steps.version.outputs.version }} Alpha
+ release_name: Meshtastic Firmware ${{ steps.version.outputs.version }}
tag_name: v${{ steps.version.outputs.version }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
@@ -498,10 +502,9 @@ jobs:
- name: Bump version.properties
run: >-
bin/bump_version.py
-
+
- name: Create version.properties pull request
uses: peter-evans/create-pull-request@v3
with:
add-paths: |
version.properties
-
diff --git a/.gitmodules b/.gitmodules
index 489f01bea..e6f376a0b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "protobufs"]
path = protobufs
- url = https://github.com/meshtastic/Meshtastic-protobufs.git
+ url = https://github.com/meshtastic/protobufs.git
diff --git a/README.md b/README.md
index 39aebf9d7..6432803e4 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# Meshtastic Firmware
-
-[](https://github.com/meshtastic/repo/actions/workflows/main_matrix.yml)
-[](https://cla-assistant.io/meshtastic/Meshtastic-device)
+
+[](https://github.com/meshtastic/firmware/actions/workflows/main_matrix.yml)
+[](https://cla-assistant.io/meshtastic/firmware)
[](https://opencollective.com/meshtastic/)
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
@@ -10,10 +10,9 @@
This repository contains the device firmware for the Meshtastic project.
-
**[Building Instructions](https://meshtastic.org/docs/developers/Firmware/build)**
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
## Stats
-
+
diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini
index 798fb3d5a..ba98a6b1f 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -3,7 +3,7 @@
extends = arduino_base
platform = platformio/espressif32@^5.2.0
build_src_filter =
- ${arduino_base.build_src_filter} - - -
+ ${arduino_base.build_src_filter} - - - -
upload_speed = 921600
debug_init_break = tbreak setup
monitor_filters = esp32_exception_decoder
@@ -33,8 +33,7 @@ lib_deps =
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
h2zero/NimBLE-Arduino@^1.4.0
- arduino-libraries/NTPClient@^3.1.0
- https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
+ https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lib_ignore =
segger_rtt
diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini
index 8dc6d0b62..f5338d9a9 100644
--- a/arch/esp32/esp32s3.ini
+++ b/arch/esp32/esp32s3.ini
@@ -2,7 +2,7 @@
extends = arduino_base
platform = platformio/espressif32@^5.2.0
build_src_filter =
- ${arduino_base.build_src_filter} - - -
+ ${arduino_base.build_src_filter} - - - -
upload_speed = 961200
monitor_speed = 115200
debug_init_break = tbreak setup
@@ -33,7 +33,6 @@ lib_deps =
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
h2zero/NimBLE-Arduino@^1.4.0
- arduino-libraries/NTPClient@^3.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lib_ignore =
diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index f4e2af236..46f946530 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -8,7 +8,7 @@ build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52
build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - -
+ ${arduino_base.build_src_filter} - - - - - - - - -
lib_ignore =
BluetoothOTA
diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini
index eb65322d4..b61071007 100644
--- a/arch/portduino/portduino.ini
+++ b/arch/portduino/portduino.ini
@@ -7,7 +7,8 @@ build_src_filter =
-
-
-
- -
+ -
+ -
-
-
+<../variants/portduino>
diff --git a/arch/rp2040/rp2040.ini b/arch/rp2040/rp2040.ini
index 9eea340bf..8b7bdbff9 100644
--- a/arch/rp2040/rp2040.ini
+++ b/arch/rp2040/rp2040.ini
@@ -10,7 +10,7 @@ build_flags =
-D__PLAT_RP2040__
# -D _POSIX_THREADS
build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - -
+ ${arduino_base.build_src_filter} - - - - - - - - -
lib_ignore =
BluetoothOTA
lib_deps =
diff --git a/arch/stm32/stm32wl5e.ini b/arch/stm32/stm32wl5e.ini
index d13750fdb..3fc7583ad 100644
--- a/arch/stm32/stm32wl5e.ini
+++ b/arch/stm32/stm32wl5e.ini
@@ -10,7 +10,7 @@ build_flags =
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - - - - - - -
+ ${arduino_base.build_src_filter} - - - - - - - - - - - - - -
lib_deps =
${env.lib_deps}
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
diff --git a/bin/promote-release.sh b/bin/promote-release.sh
index b9380b02b..f96d2a568 100755
--- a/bin/promote-release.sh
+++ b/bin/promote-release.sh
@@ -9,9 +9,6 @@ VERSION=`bin/buildinfo.py long`
# Must have a V prefix to trigger github
git tag "v${VERSION}"
-# Commented out per https://github.com/meshtastic/Meshtastic-device/issues/947
-#git push root "v${VERSION}" # push the tag
-
git push origin "v${VERSION}" # push the tag
echo "Tag ${VERSION} pushed to github, github actions should now be building the draft release. If it seems good, click to publish it"
diff --git a/bin/regen-protos.sh b/bin/regen-protos.sh
index 9c16591e3..2734c213b 100755
--- a/bin/regen-protos.sh
+++ b/bin/regen-protos.sh
@@ -3,7 +3,7 @@
set -e
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.6 to be located in the"
-echo "meshtastic-device root directory if the following step fails, you should download the correct"
+echo "firmware root directory if the following step fails, you should download the correct"
echo "prebuilt binaries for your computer into nanopb-0.4.6"
# the nanopb tool seems to require that the .options file be in the current directory!
diff --git a/platformio.ini b/platformio.ini
index 1f97cfb19..7c1ba6851 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -22,6 +22,7 @@
;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1
+;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
@@ -68,7 +69,7 @@ lib_deps =
${env.lib_deps}
; Portduino is using meshtastic fork for now
jgromes/RadioLib@5.4.1
- https://github.com/caveman99/SparkFun_ATECCX08a_Arduino_Library.git#008e7f9d40bad66b2f7a0074aaac05b7c424339d
+ https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#52b5282639d08a8cbd4b748363089eed6102dc76
build_flags = ${env.build_flags} -Os
-DRADIOLIB_SPI_PARANOID=0
@@ -79,6 +80,7 @@ build_src_filter = ${env.build_src_filter} -
[networking_base]
lib_deps =
knolleary/PubSubClient@^2.8
+ arduino-libraries/NTPClient@^3.1.0
meshtastic/json11@^1.0.2
; Common libs for environmental measurements in telemetry module
diff --git a/protobufs b/protobufs
index 863a1d799..ed9f2499d 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 863a1d7997ae54471cbeea9baeb877924cc850cf
+Subproject commit ed9f2499d692925461facd64c6af2d2a7672245a
diff --git a/src/ButtonThread.h b/src/ButtonThread.h
index c1fd770bc..088642099 100644
--- a/src/ButtonThread.h
+++ b/src/ButtonThread.h
@@ -159,7 +159,7 @@ class ButtonThread : public concurrency::OSThread
static void userButtonDoublePressed()
{
-#if defined(USE_EINK)
+#if defined(USE_EINK) && defined(PIN_EINK_EN)
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif
}
diff --git a/src/Power.cpp b/src/Power.cpp
index d3782a2a4..af10acb5e 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -233,11 +233,14 @@ bool Power::setup()
void Power::shutdown()
{
-
+ screen->setOn(false);
+#if defined(USE_EINK) && defined(PIN_EINK_EN)
+ digitalWrite(PIN_EINK_EN, LOW); //power off backlight first
+#endif
#ifdef HAS_PMU
DEBUG_MSG("Shutting down\n");
- if(PMU){
+ if(PMU) {
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
PMU->shutdown();
}
@@ -312,7 +315,7 @@ int32_t Power::runOnce()
#ifdef HAS_PMU
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
// the IRQ status by reading the registers over I2C
- if(PMU){
+ if(PMU) {
PMU->getIrqStatus();
@@ -341,10 +344,11 @@ int32_t Power::runOnce()
if (PMU->isBatRemoveIrq()) {
DEBUG_MSG("Battery removed\n");
}
- if (PMU->isPekeyShortPressIrq()) {
- DEBUG_MSG("PEK short button press\n");
- }
*/
+ if (PMU->isPekeyLongPressIrq()) {
+ DEBUG_MSG("PEK long button press\n");
+ screen->setOn(false);
+ }
PMU->clearIrqStatus();
}
@@ -451,7 +455,6 @@ bool Power::axpChipInit()
// Set constant current charging current
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA);
-
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
// t-beam s3 core
diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp
index c16f52592..dd3992a14 100644
--- a/src/PowerFSM.cpp
+++ b/src/PowerFSM.cpp
@@ -337,7 +337,7 @@ void PowerFSM_setup()
#ifdef ARCH_ESP32
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
- // See: https://github.com/meshtastic/Meshtastic-device/issues/1071
+ // See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");
diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp
index de9b95027..66c83171a 100644
--- a/src/RedirectablePrint.cpp
+++ b/src/RedirectablePrint.cpp
@@ -44,11 +44,9 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
static char printBuf[160];
va_copy(copy, arg);
- int len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
+ size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
va_end(copy);
- if (len < 0) return 0;
-
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value
if (len > sizeof(printBuf) - 1) {
diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp
index 059630bfe..f8314fe51 100644
--- a/src/buzz/buzz.cpp
+++ b/src/buzz/buzz.cpp
@@ -1,5 +1,6 @@
#include "buzz.h"
#include "configuration.h"
+#include "NodeDB.h"
#ifndef PIN_BUZZER
@@ -42,17 +43,19 @@ const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note
void playTones(const ToneDuration *tone_durations, int size) {
- for (int i = 0; i < size; i++) {
- const auto &tone_duration = tone_durations[i];
+ if (config.network.eth_enabled != true) {
+ for (int i = 0; i < size; i++) {
+ const auto &tone_duration = tone_durations[i];
#ifdef M5STACK
- Tone.tone(tone_duration.frequency_khz);
- delay(tone_duration.duration_ms);
- Tone.mute();
+ Tone.tone(tone_duration.frequency_khz);
+ delay(tone_duration.duration_ms);
+ Tone.mute();
#else
- tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
+ tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
#endif
- // to distinguish the notes, set a minimum time between them.
- delay(1.3 * tone_duration.duration_ms);
+ // to distinguish the notes, set a minimum time between them.
+ delay(1.3 * tone_duration.duration_ms);
+ }
}
}
diff --git a/src/configuration.h b/src/configuration.h
index 9374c29d4..4b157611d 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -142,6 +142,9 @@ along with this program. If not, see .
#ifndef HAS_WIFI
#define HAS_WIFI 0
#endif
+#ifndef HAS_ETHERNET
+ #define HAS_ETHERNET 0
+#endif
#ifndef HAS_SCREEN
#define HAS_SCREEN 0
#endif
@@ -163,6 +166,12 @@ along with this program. If not, see .
#ifndef HAS_RTC
#define HAS_RTC 0
#endif
+#ifndef HAS_CPU_SHUTDOWN
+ #define HAS_CPU_SHUTDOWN 0
+#endif
+#ifndef HAS_BLUETOOTH
+ #define HAS_BLUETOOTH 0
+#endif
#include "RF95Configuration.h"
#include "DebugConfiguration.h"
diff --git a/src/graphics/EInkDisplay2.cpp b/src/graphics/EInkDisplay2.cpp
index 9062fc018..9e0834954 100644
--- a/src/graphics/EInkDisplay2.cpp
+++ b/src/graphics/EInkDisplay2.cpp
@@ -14,8 +14,8 @@
#define TECHO_DISPLAY_MODEL GxEPD2_154_D67
#elif defined(RAK4630)
-//GxEPD2_213_B74 - RAK14000 2.13 inch b/w 250x128
-#define TECHO_DISPLAY_MODEL GxEPD2_213_B74
+//GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122 - changed from GxEPD2_213_B74 - which was not going to give partial update support
+#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
//4.2 inch 300x400 - GxEPD2_420_M01
//#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
@@ -46,9 +46,9 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
#elif defined(RAK4630)
- //GxEPD2_213_B74 - RAK14000 2.13 inch b/w 250x128
+ //GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
setGeometry(GEOMETRY_RAWMODE, 250, 122);
-
+
//GxEPD2_420_M01
//setGeometry(GEOMETRY_RAWMODE, 300, 400);
@@ -110,14 +110,17 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
adafruitDisplay->display(false); // FIXME, use partial update mode
#elif defined(RAK4630)
- //RAK14000 2.13 inch b/w 250x122 does not support partial updates
- adafruitDisplay->display(false); // FIXME, use partial update mode
+ //RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
+
+ //Full update mode (slow)
+ //adafruitDisplay->display(false); // FIXME, use partial update mode
//Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
// 1.54 inch 200x200 - GxEPD2_154_M09
+ // 2.13 inch 250x122 - GxEPD2_213_BN
// 2.9 inch 296x128 - GxEPD2_290_T5D
// 4.2 inch 300x400 - GxEPD2_420_M01
- //adafruitDisplay->nextPage();
+ adafruitDisplay->nextPage();
#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
@@ -190,11 +193,11 @@ bool EInkDisplay::connect()
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
- //RAK14000 2.13 inch b/w 250x122 does not support partial updates
+ //RAK14000 2.13 inch b/w 250x122 does actually now support partial updates
adafruitDisplay->setRotation(3);
- //For 1.54, 2.9 and 4.2
+ //Partial update support for 1.54, 2.13 RAK14000 b/w , 2.9 and 4.2
//adafruitDisplay->setRotation(1);
- //adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
+ adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else {
(void)adafruitDisplay;
}
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 0f6c96f0f..4ddbe10d4 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -1390,7 +1390,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
{
#if HAS_WIFI
const char *wifiName = config.network.wifi_ssid;
- const char *wifiPsw = config.network.wifi_psk;
displayedNodeNum = 0; // Not currently showing a node pane
@@ -1399,11 +1398,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
- if (isSoftAPForced()) {
- display->drawString(x, y, String("WiFi: Software AP (Admin)"));
- } else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
- display->drawString(x, y, String("WiFi: Software AP"));
- } else if (WiFi.status() != WL_CONNECTED) {
+ if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected"));
} else {
display->drawString(x, y, String("WiFi: Connected"));
@@ -1424,25 +1419,14 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
- WL_NO_SHIELD: assigned when no WiFi shield is present;
*/
- if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
- if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
-
- // Number of connections to the AP. Default max for the esp32 is 4
- display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"),
- y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)");
- } else {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
- }
-
+ if (WiFi.status() == WL_CONNECTED) {
+ display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
} else if (WiFi.status() == WL_NO_SSID_AVAIL) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
} else if (WiFi.status() == WL_CONNECTION_LOST) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Lost");
} else if (WiFi.status() == WL_CONNECT_FAILED) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
- //} else if (WiFi.status() == WL_DISCONNECTED) {
- // display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disconnected");
} else if (WiFi.status() == WL_IDLE_STATUS) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
} else {
@@ -1509,24 +1493,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
}
}
- if (isSoftAPForced()) {
- if ((millis() / 10000) % 2) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: meshtasticAdmin");
- } else {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "PWD: 12345678");
- }
+ display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
- } else {
- if (config.network.wifi_mode== Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
- if ((millis() / 10000) % 2) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
- } else {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "PWD: " + String(wifiPsw));
- }
- } else {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
- }
- }
display->drawString(x, y + FONT_HEIGHT_SMALL * 3, "http://meshtastic.local");
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h
index ab8d44430..23828b3ee 100644
--- a/src/graphics/Screen.h
+++ b/src/graphics/Screen.h
@@ -10,7 +10,7 @@ namespace graphics
class Screen
{
public:
- Screen(char){}
+ explicit Screen(char){}
void onPress() {}
void setup() {}
void setOn(bool) {}
@@ -131,8 +131,7 @@ class Screen : public concurrency::OSThread
void setOn(bool on)
{
if (!on)
- handleSetOn(
- false); // We handle off commands immediately, because they might be called because the CPU is shutting down
+ handleSetOn(false); // We handle off commands immediately, because they might be called because the CPU is shutting down
else
enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF});
}
diff --git a/src/main.cpp b/src/main.cpp
index d40a1bdf0..8836b6460 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,6 +30,7 @@
// #include
#include "mesh/http/WiFiAPClient.h"
+#include "mesh/eth/ethClient.h"
#ifdef ARCH_ESP32
#include "mesh/http/WebServer.h"
@@ -41,11 +42,16 @@
#include "mqtt/MQTT.h"
#endif
+#if HAS_ETHERNET
+#include "mesh/eth/ethServerAPI.h"
+#include "mqtt/MQTT.h"
+#endif
+
#include "LLCC68Interface.h"
#include "RF95Interface.h"
#include "SX1262Interface.h"
#include "SX1268Interface.h"
-#include "SX1281Interface.h"
+#include "SX1280Interface.h"
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h"
#endif
@@ -191,8 +197,6 @@ void setup()
digitalWrite(RESET_OLED, 1);
#endif
- bool forceSoftAP = 0;
-
#ifdef BUTTON_PIN
#ifdef ARCH_ESP32
@@ -205,12 +209,6 @@ void setup()
delay(10);
#endif
- // BUTTON_PIN is pulled high by a 12k resistor.
- if (!digitalRead(BUTTON_PIN)) {
- forceSoftAP = 1;
- DEBUG_MSG("Setting forceSoftAP = 1\n");
- }
-
#endif
#endif
@@ -278,11 +276,12 @@ void setup()
#ifdef ARCH_NRF52
nrf52Setup();
#endif
- playStartMelody();
// We do this as early as possible because this loads preferences from flash
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
nodeDB.init();
+ playStartMelody();
+
// Currently only the tbeam has a PMU
power = new Power();
power->setStatusHandler(powerStatus);
@@ -373,15 +372,15 @@ void setup()
}
#endif
-#if defined(USE_SX1281) && !defined(ARCH_PORTDUINO)
+#if defined(USE_SX1280) && !defined(ARCH_PORTDUINO)
if (!rIf) {
- rIf = new SX1281Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
+ rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI);
if (!rIf->init()) {
- DEBUG_MSG("Warning: Failed to find SX1281 radio\n");
+ DEBUG_MSG("Warning: Failed to find SX1280 radio\n");
delete rIf;
rIf = NULL;
} else {
- DEBUG_MSG("SX1281 Radio init succeeded, using SX1281 radio\n");
+ DEBUG_MSG("SX1280 Radio init succeeded, using SX1280 radio\n");
rIf_wide_lora = true;
}
}
@@ -439,12 +438,17 @@ void setup()
}
#endif
-#if HAS_WIFI
+#if HAS_WIFI || HAS_ETHERNET
mqttInit();
#endif
+#ifndef ARCH_PORTDUINO
// Initialize Wifi
- initWifi(forceSoftAP);
+ initWifi();
+
+ // Initialize Ethernet
+ initEthernet();
+#endif
#ifdef ARCH_ESP32
// Start web server thread.
diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp
index f7fc35929..9ae211e6e 100644
--- a/src/mesh/Channels.cpp
+++ b/src/mesh/Channels.cpp
@@ -218,9 +218,7 @@ const char *Channels::getName(size_t chIndex)
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
// the app fucked up and forgot to set channelSettings.name
- if (config.lora.bandwidth != 0)
- channelName = "Custom";
- else
+ if (config.lora.use_preset) {
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
channelName = "ShortSlow";
@@ -247,6 +245,10 @@ const char *Channels::getName(size_t chIndex)
channelName = "Invalid";
break;
}
+ }
+ else {
+ channelName = "Custom";
+ }
}
return channelName;
@@ -265,7 +267,7 @@ their nodes
*
* This function will also need to be implemented in GUI apps that talk to the radio.
*
-* https://github.com/meshtastic/Meshtastic-device/issues/269
+* https://github.com/meshtastic/firmware/issues/269
*/
const char *Channels::getPrimaryName()
{
diff --git a/src/mesh/Channels.h b/src/mesh/Channels.h
index 5c5af0ec2..ebf08d32c 100644
--- a/src/mesh/Channels.h
+++ b/src/mesh/Channels.h
@@ -74,7 +74,7 @@ class Channels
*
* This function will also need to be implemented in GUI apps that talk to the radio.
*
- * https://github.com/meshtastic/Meshtastic-device/issues/269
+ * https://github.com/meshtastic/firmware/issues/269
*/
const char *getPrimaryName();
diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp
index b6519abdb..818bacf45 100644
--- a/src/mesh/FloodingRouter.cpp
+++ b/src/mesh/FloodingRouter.cpp
@@ -29,8 +29,8 @@ bool FloodingRouter::shouldFilterReceived(MeshPacket *p)
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
{
- PacketId ackId = ((c && c->error_reason == Routing_Error_NONE) || !c) ? p->decoded.request_id : 0;
- if (ackId && p->to != getNodeNum()) {
+ bool isAck = ((c && c->error_reason == Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
+ if (isAck && p->to != getNodeNum()) {
// do not flood direct message that is ACKed
DEBUG_MSG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp
index 6707813db..ccef2df23 100644
--- a/src/mesh/InterfacesTemplates.cpp
+++ b/src/mesh/InterfacesTemplates.cpp
@@ -9,5 +9,5 @@ template class SX126xInterface;
template class SX126xInterface;
#if !defined(ARCH_PORTDUINO)
-template class SX128xInterface;
+template class SX128xInterface;
#endif
\ No newline at end of file
diff --git a/src/mesh/MeshModule.cpp b/src/mesh/MeshModule.cpp
index 7b204ae49..ca1fb5b50 100644
--- a/src/mesh/MeshModule.cpp
+++ b/src/mesh/MeshModule.cpp
@@ -109,10 +109,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
/// to be able to fetch the initial admin packets without yet knowing any channels.
- bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
- !ch ||
- strlen(ch->settings.name) > 0 ||
- (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
+ bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
if (!rxChannelOk) {
// no one should have already replied!
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index 6b9744565..dcd518191 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -18,7 +18,7 @@ DeviceState versions used to be defined in the .proto file but really only this
#define SEGMENT_DEVICESTATE 4
#define SEGMENT_CHANNELS 8
-#define DEVICESTATE_CUR_VER 19
+#define DEVICESTATE_CUR_VER 20
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
extern DeviceState devicestate;
diff --git a/src/mesh/SX1281Interface.cpp b/src/mesh/SX1280Interface.cpp
similarity index 72%
rename from src/mesh/SX1281Interface.cpp
rename to src/mesh/SX1280Interface.cpp
index 50805cfe0..37aad1d40 100644
--- a/src/mesh/SX1281Interface.cpp
+++ b/src/mesh/SX1280Interface.cpp
@@ -1,10 +1,10 @@
#include "configuration.h"
-#include "SX1281Interface.h"
+#include "SX1280Interface.h"
#include "error.h"
#if !defined(ARCH_PORTDUINO)
-SX1281Interface::SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
+SX1280Interface::SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
: SX128xInterface(cs, irq, rst, busy, spi)
{
diff --git a/src/mesh/SX1281Interface.h b/src/mesh/SX1280Interface.h
similarity index 52%
rename from src/mesh/SX1281Interface.h
rename to src/mesh/SX1280Interface.h
index 3bd65309a..1c2e24900 100644
--- a/src/mesh/SX1281Interface.h
+++ b/src/mesh/SX1280Interface.h
@@ -3,15 +3,15 @@
#include "SX128xInterface.h"
/**
- * Our adapter for SX1281 radios
+ * Our adapter for SX1280 radios
*/
#if !defined(ARCH_PORTDUINO)
-class SX1281Interface : public SX128xInterface
+class SX1280Interface : public SX128xInterface
{
public:
- SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
+ SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
};
#endif
\ No newline at end of file
diff --git a/src/mesh/SX128xInterface.h b/src/mesh/SX128xInterface.h
index d01dfc510..f712b8bc4 100644
--- a/src/mesh/SX128xInterface.h
+++ b/src/mesh/SX128xInterface.h
@@ -6,7 +6,7 @@
/**
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
- * \tparam T RadioLib module type for SX128x: SX1281.
+ * \tparam T RadioLib module type for SX128x: SX1280.
*/
template
class SX128xInterface : public RadioLibInterface
diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp
new file mode 100644
index 000000000..793a86125
--- /dev/null
+++ b/src/mesh/eth/ethClient.cpp
@@ -0,0 +1,148 @@
+#include "mesh/eth/ethClient.h"
+#include "NodeDB.h"
+#include "RTC.h"
+#include "concurrency/Periodic.h"
+#include
+#include
+#include "target_specific.h"
+#include "mesh/eth/ethServerAPI.h"
+#include "mqtt/MQTT.h"
+
+#ifndef DISABLE_NTP
+#include
+
+// NTP
+EthernetUDP ntpUDP;
+NTPClient timeClient(ntpUDP, config.network.ntp_server);
+uint32_t ntp_renew = 0;
+#endif
+
+bool ethStartupComplete = 0;
+
+using namespace concurrency;
+
+static Periodic *ethEvent;
+
+static int32_t reconnectETH()
+{
+ if (config.network.eth_enabled) {
+ Ethernet.maintain();
+ if (!ethStartupComplete) {
+ // Start web server
+ DEBUG_MSG("... Starting network services\n");
+
+#ifndef DISABLE_NTP
+ DEBUG_MSG("Starting NTP time client\n");
+ timeClient.begin();
+ timeClient.setUpdateInterval(60 * 60); // Update once an hour
+#endif
+ // initWebServer();
+ initApiServer();
+
+ ethStartupComplete = true;
+ }
+
+ // FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
+ if (mqtt && !mqtt->connected()) {
+ mqtt->reconnect();
+ }
+ }
+
+#ifndef DISABLE_NTP
+ if (isEthernetAvailable() && (ntp_renew < millis())) {
+
+ DEBUG_MSG("Updating NTP time from %s\n", config.network.ntp_server);
+ if (timeClient.update()) {
+ DEBUG_MSG("NTP Request Success - Setting RTCQualityNTP if needed\n");
+
+ struct timeval tv;
+ tv.tv_sec = timeClient.getEpochTime();
+ tv.tv_usec = 0;
+
+ perhapsSetRTC(RTCQualityNTP, &tv);
+
+ ntp_renew = millis() + 43200 * 1000; // success, refresh every 12 hours
+
+ } else {
+ DEBUG_MSG("NTP Update failed\n");
+ ntp_renew = millis() + 300 * 1000; // failure, retry every 5 minutes
+ }
+ }
+#endif
+
+ return 5000; // every 5 seconds
+}
+
+// Startup Ethernet
+bool initEthernet()
+{
+ if (config.network.eth_enabled) {
+
+#ifdef PIN_ETHERNET_RESET
+ pinMode(PIN_ETHERNET_RESET, OUTPUT);
+ digitalWrite(PIN_ETHERNET_RESET, LOW); // Reset Time.
+ delay(100);
+ digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
+#endif
+
+ Ethernet.init( ETH_SPI_PORT, PIN_ETHERNET_SS );
+
+ uint8_t mac[6];
+
+ int status = 0;
+
+ // createSSLCert();
+
+ getMacAddr(mac); // FIXME use the BLE MAC for now...
+
+ if (config.network.eth_mode == Config_NetworkConfig_EthMode_DHCP) {
+ DEBUG_MSG("starting Ethernet DHCP\n");
+ status = Ethernet.begin(mac);
+ } else if (config.network.eth_mode == Config_NetworkConfig_EthMode_STATIC) {
+ DEBUG_MSG("starting Ethernet Static\n");
+ Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
+ } else {
+ DEBUG_MSG("Ethernet Disabled\n");
+ return false;
+ }
+
+ if (status == 0) {
+ if (Ethernet.hardwareStatus() == EthernetNoHardware) {
+ DEBUG_MSG("Ethernet shield was not found.\n");
+ return false;
+ } else if (Ethernet.linkStatus() == LinkOFF) {
+ DEBUG_MSG("Ethernet cable is not connected.\n");
+ return false;
+ } else{
+ DEBUG_MSG("Unknown Ethernet error.\n");
+ return false;
+ }
+ } else {
+ DEBUG_MSG("Local IP %u.%u.%u.%u\n",Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
+ DEBUG_MSG("Subnet Mask %u.%u.%u.%u\n",Ethernet.subnetMask()[0], Ethernet.subnetMask()[1], Ethernet.subnetMask()[2], Ethernet.subnetMask()[3]);
+ DEBUG_MSG("Gateway IP %u.%u.%u.%u\n",Ethernet.gatewayIP()[0], Ethernet.gatewayIP()[1], Ethernet.gatewayIP()[2], Ethernet.gatewayIP()[3]);
+ DEBUG_MSG("DNS Server IP %u.%u.%u.%u\n",Ethernet.dnsServerIP()[0], Ethernet.dnsServerIP()[1], Ethernet.dnsServerIP()[2], Ethernet.dnsServerIP()[3]);
+ }
+
+ ethEvent = new Periodic("ethConnect", reconnectETH);
+
+ return true;
+
+ } else {
+ DEBUG_MSG("Not using Ethernet\n");
+ return false;
+ }
+}
+
+bool isEthernetAvailable() {
+
+ if (!config.network.eth_enabled) {
+ return false;
+ } else if (Ethernet.hardwareStatus() == EthernetNoHardware) {
+ return false;
+ } else if (Ethernet.linkStatus() == LinkOFF) {
+ return false;
+ } else {
+ return true;
+ }
+}
diff --git a/src/mesh/eth/ethClient.h b/src/mesh/eth/ethClient.h
new file mode 100644
index 000000000..9e1745b9f
--- /dev/null
+++ b/src/mesh/eth/ethClient.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "configuration.h"
+#include
+#include
+
+bool initEthernet();
+bool isEthernetAvailable();
diff --git a/src/mesh/eth/ethServerAPI.cpp b/src/mesh/eth/ethServerAPI.cpp
new file mode 100644
index 000000000..bb7dd927d
--- /dev/null
+++ b/src/mesh/eth/ethServerAPI.cpp
@@ -0,0 +1,82 @@
+#include "ethServerAPI.h"
+#include "configuration.h"
+#include
+
+static ethServerPort *apiPort;
+
+void initApiServer(int port)
+{
+ // Start API server on port 4403
+ if (!apiPort) {
+ apiPort = new ethServerPort(port);
+ DEBUG_MSG("API server listening on TCP port %d\n", port);
+ apiPort->init();
+ }
+}
+
+ethServerAPI::ethServerAPI(EthernetClient &_client) : StreamAPI(&client), client(_client)
+{
+ DEBUG_MSG("Incoming ethernet connection\n");
+}
+
+ethServerAPI::~ethServerAPI()
+{
+ client.stop();
+
+ // FIXME - delete this if the client dropps the connection!
+}
+
+/// override close to also shutdown the TCP link
+void ethServerAPI::close()
+{
+ client.stop(); // drop tcp connection
+ StreamAPI::close();
+}
+
+/// Check the current underlying physical link to see if the client is currently connected
+bool ethServerAPI::checkIsConnected()
+{
+ return client.connected();
+}
+
+int32_t ethServerAPI::runOnce()
+{
+ if (client.connected()) {
+ return StreamAPI::runOnce();
+ } else {
+ DEBUG_MSG("Client dropped connection, suspending API service\n");
+ enabled = false; // we no longer need to run
+ return 0;
+ }
+}
+
+/// If an api server is running, we try to spit out debug 'serial' characters there
+void ethServerPort::debugOut(char c)
+{
+ if (apiPort && apiPort->openAPI)
+ apiPort->openAPI->debugOut(c);
+}
+
+
+ethServerPort::ethServerPort(int port) : EthernetServer(port), concurrency::OSThread("ApiServer") {}
+
+void ethServerPort::init()
+{
+ begin();
+}
+
+int32_t ethServerPort::runOnce()
+{
+ auto client = available();
+ if (client) {
+ // Close any previous connection (see FIXME in header file)
+ if (openAPI) {
+ DEBUG_MSG("Force closing previous TCP connection\n");
+ delete openAPI;
+ }
+
+ openAPI = new ethServerAPI(client);
+ }
+
+ return 100; // only check occasionally for incoming connections
+}
diff --git a/src/mesh/eth/ethServerAPI.h b/src/mesh/eth/ethServerAPI.h
new file mode 100644
index 000000000..c92ab2f17
--- /dev/null
+++ b/src/mesh/eth/ethServerAPI.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "StreamAPI.h"
+#include
+
+/**
+ * Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
+ * (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
+ */
+class ethServerAPI : public StreamAPI
+{
+ private:
+ EthernetClient client;
+
+ public:
+ explicit ethServerAPI(EthernetClient &_client);
+
+ virtual ~ethServerAPI();
+
+ /// override close to also shutdown the TCP link
+ virtual void close();
+
+ protected:
+ /// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to
+ /// stay in the POWERED state to prevent disabling wifi)
+ virtual void onConnectionChanged(bool connected) override {}
+
+ virtual int32_t runOnce() override; // Check for dropped client connections
+
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected() override;
+};
+
+/**
+ * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
+ */
+class ethServerPort : public EthernetServer, private concurrency::OSThread
+{
+ /** The currently open port
+ *
+ * FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
+ * delegate to the worker. Once coroutines are implemented we can relax this restriction.
+ */
+ ethServerAPI *openAPI = NULL;
+
+ public:
+ explicit ethServerPort(int port);
+
+ void init();
+
+ /// If an api server is running, we try to spit out debug 'serial' characters there
+ static void debugOut(char c);
+
+ protected:
+ int32_t runOnce() override;
+};
+
+void initApiServer(int port=4403);
diff --git a/src/mesh/generated/config.pb.c b/src/mesh/generated/config.pb.c
index f29dd7012..c5bc69552 100644
--- a/src/mesh/generated/config.pb.c
+++ b/src/mesh/generated/config.pb.c
@@ -21,7 +21,7 @@ PB_BIND(Config_PowerConfig, Config_PowerConfig, AUTO)
PB_BIND(Config_NetworkConfig, Config_NetworkConfig, AUTO)
-PB_BIND(Config_NetworkConfig_NetworkConfig, Config_NetworkConfig_NetworkConfig, AUTO)
+PB_BIND(Config_NetworkConfig_IpV4Config, Config_NetworkConfig_IpV4Config, AUTO)
PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO)
diff --git a/src/mesh/generated/config.pb.h b/src/mesh/generated/config.pb.h
index e98aff60a..6a8e56ad0 100644
--- a/src/mesh/generated/config.pb.h
+++ b/src/mesh/generated/config.pb.h
@@ -127,12 +127,12 @@ typedef struct _Config_LoRaConfig {
uint32_t ignore_incoming[3];
} Config_LoRaConfig;
-typedef struct _Config_NetworkConfig_NetworkConfig {
+typedef struct _Config_NetworkConfig_IpV4Config {
uint32_t ip;
uint32_t gateway;
uint32_t subnet;
uint32_t dns;
-} Config_NetworkConfig_NetworkConfig;
+} Config_NetworkConfig_IpV4Config;
typedef struct _Config_PositionConfig {
uint32_t position_broadcast_secs;
@@ -157,14 +157,13 @@ typedef struct _Config_PowerConfig {
typedef struct _Config_NetworkConfig {
bool wifi_enabled;
- Config_NetworkConfig_WiFiMode wifi_mode;
char wifi_ssid[33];
char wifi_psk[64];
char ntp_server[33];
bool eth_enabled;
Config_NetworkConfig_EthMode eth_mode;
- bool has_eth_config;
- Config_NetworkConfig_NetworkConfig eth_config;
+ bool has_ipv4_config;
+ Config_NetworkConfig_IpV4Config ipv4_config;
} Config_NetworkConfig;
typedef struct _Config {
@@ -228,8 +227,8 @@ extern "C" {
#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0}
#define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
-#define Config_NetworkConfig_init_default {0, _Config_NetworkConfig_WiFiMode_MIN, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_NetworkConfig_init_default}
-#define Config_NetworkConfig_NetworkConfig_init_default {0, 0, 0, 0}
+#define Config_NetworkConfig_init_default {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_default}
+#define Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
#define Config_BluetoothConfig_init_default {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
@@ -237,8 +236,8 @@ extern "C" {
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0}
#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
-#define Config_NetworkConfig_init_zero {0, _Config_NetworkConfig_WiFiMode_MIN, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_NetworkConfig_init_zero}
-#define Config_NetworkConfig_NetworkConfig_init_zero {0, 0, 0, 0}
+#define Config_NetworkConfig_init_zero {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_zero}
+#define Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
#define Config_BluetoothConfig_init_zero {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
@@ -268,10 +267,10 @@ extern "C" {
#define Config_LoRaConfig_tx_power_tag 10
#define Config_LoRaConfig_channel_num_tag 11
#define Config_LoRaConfig_ignore_incoming_tag 103
-#define Config_NetworkConfig_NetworkConfig_ip_tag 1
-#define Config_NetworkConfig_NetworkConfig_gateway_tag 2
-#define Config_NetworkConfig_NetworkConfig_subnet_tag 3
-#define Config_NetworkConfig_NetworkConfig_dns_tag 4
+#define Config_NetworkConfig_IpV4Config_ip_tag 1
+#define Config_NetworkConfig_IpV4Config_gateway_tag 2
+#define Config_NetworkConfig_IpV4Config_subnet_tag 3
+#define Config_NetworkConfig_IpV4Config_dns_tag 4
#define Config_PositionConfig_position_broadcast_secs_tag 1
#define Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define Config_PositionConfig_fixed_position_tag 3
@@ -288,13 +287,12 @@ extern "C" {
#define Config_PowerConfig_ls_secs_tag 7
#define Config_PowerConfig_min_wake_secs_tag 8
#define Config_NetworkConfig_wifi_enabled_tag 1
-#define Config_NetworkConfig_wifi_mode_tag 2
#define Config_NetworkConfig_wifi_ssid_tag 3
#define Config_NetworkConfig_wifi_psk_tag 4
#define Config_NetworkConfig_ntp_server_tag 5
#define Config_NetworkConfig_eth_enabled_tag 6
#define Config_NetworkConfig_eth_mode_tag 7
-#define Config_NetworkConfig_eth_config_tag 8
+#define Config_NetworkConfig_ipv4_config_tag 8
#define Config_device_tag 1
#define Config_position_tag 2
#define Config_power_tag 3
@@ -354,24 +352,23 @@ X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8)
#define Config_NetworkConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, wifi_enabled, 1) \
-X(a, STATIC, SINGULAR, UENUM, wifi_mode, 2) \
X(a, STATIC, SINGULAR, STRING, wifi_ssid, 3) \
X(a, STATIC, SINGULAR, STRING, wifi_psk, 4) \
X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \
X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \
X(a, STATIC, SINGULAR, UENUM, eth_mode, 7) \
-X(a, STATIC, OPTIONAL, MESSAGE, eth_config, 8)
+X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8)
#define Config_NetworkConfig_CALLBACK NULL
#define Config_NetworkConfig_DEFAULT NULL
-#define Config_NetworkConfig_eth_config_MSGTYPE Config_NetworkConfig_NetworkConfig
+#define Config_NetworkConfig_ipv4_config_MSGTYPE Config_NetworkConfig_IpV4Config
-#define Config_NetworkConfig_NetworkConfig_FIELDLIST(X, a) \
+#define Config_NetworkConfig_IpV4Config_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, FIXED32, ip, 1) \
X(a, STATIC, SINGULAR, FIXED32, gateway, 2) \
X(a, STATIC, SINGULAR, FIXED32, subnet, 3) \
X(a, STATIC, SINGULAR, FIXED32, dns, 4)
-#define Config_NetworkConfig_NetworkConfig_CALLBACK NULL
-#define Config_NetworkConfig_NetworkConfig_DEFAULT NULL
+#define Config_NetworkConfig_IpV4Config_CALLBACK NULL
+#define Config_NetworkConfig_IpV4Config_DEFAULT NULL
#define Config_DisplayConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \
@@ -411,7 +408,7 @@ extern const pb_msgdesc_t Config_DeviceConfig_msg;
extern const pb_msgdesc_t Config_PositionConfig_msg;
extern const pb_msgdesc_t Config_PowerConfig_msg;
extern const pb_msgdesc_t Config_NetworkConfig_msg;
-extern const pb_msgdesc_t Config_NetworkConfig_NetworkConfig_msg;
+extern const pb_msgdesc_t Config_NetworkConfig_IpV4Config_msg;
extern const pb_msgdesc_t Config_DisplayConfig_msg;
extern const pb_msgdesc_t Config_LoRaConfig_msg;
extern const pb_msgdesc_t Config_BluetoothConfig_msg;
@@ -422,7 +419,7 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
#define Config_PositionConfig_fields &Config_PositionConfig_msg
#define Config_PowerConfig_fields &Config_PowerConfig_msg
#define Config_NetworkConfig_fields &Config_NetworkConfig_msg
-#define Config_NetworkConfig_NetworkConfig_fields &Config_NetworkConfig_NetworkConfig_msg
+#define Config_NetworkConfig_IpV4Config_fields &Config_NetworkConfig_IpV4Config_msg
#define Config_DisplayConfig_fields &Config_DisplayConfig_msg
#define Config_LoRaConfig_fields &Config_LoRaConfig_msg
#define Config_BluetoothConfig_fields &Config_BluetoothConfig_msg
@@ -432,11 +429,11 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
#define Config_DeviceConfig_size 6
#define Config_DisplayConfig_size 20
#define Config_LoRaConfig_size 68
-#define Config_NetworkConfig_NetworkConfig_size 20
-#define Config_NetworkConfig_size 163
+#define Config_NetworkConfig_IpV4Config_size 20
+#define Config_NetworkConfig_size 161
#define Config_PositionConfig_size 30
#define Config_PowerConfig_size 43
-#define Config_size 166
+#define Config_size 164
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/device_metadata.pb.h b/src/mesh/generated/device_metadata.pb.h
index 7bd32979e..1f4c81c5b 100644
--- a/src/mesh/generated/device_metadata.pb.h
+++ b/src/mesh/generated/device_metadata.pb.h
@@ -16,6 +16,14 @@ typedef struct _DeviceMetadata {
char firmware_version[18];
/* Device state version */
uint32_t device_state_version;
+ /* Indicates whether the device can shutdown CPU natively or via power management chip */
+ bool canShutdown;
+ /* Indicates that the device has native wifi capability */
+ bool hasWifi;
+ /* Indicates that the device has native bluetooth capability */
+ bool hasBluetooth;
+ /* Indicates that the device has an ethernet peripheral */
+ bool hasEthernet;
} DeviceMetadata;
@@ -24,17 +32,25 @@ extern "C" {
#endif
/* Initializer values for message structs */
-#define DeviceMetadata_init_default {"", 0}
-#define DeviceMetadata_init_zero {"", 0}
+#define DeviceMetadata_init_default {"", 0, 0, 0, 0, 0}
+#define DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0}
/* Field tags (for use in manual encoding/decoding) */
#define DeviceMetadata_firmware_version_tag 1
#define DeviceMetadata_device_state_version_tag 2
+#define DeviceMetadata_canShutdown_tag 3
+#define DeviceMetadata_hasWifi_tag 4
+#define DeviceMetadata_hasBluetooth_tag 5
+#define DeviceMetadata_hasEthernet_tag 6
/* Struct field encoding specification for nanopb */
#define DeviceMetadata_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 1) \
-X(a, STATIC, SINGULAR, UINT32, device_state_version, 2)
+X(a, STATIC, SINGULAR, UINT32, device_state_version, 2) \
+X(a, STATIC, SINGULAR, BOOL, canShutdown, 3) \
+X(a, STATIC, SINGULAR, BOOL, hasWifi, 4) \
+X(a, STATIC, SINGULAR, BOOL, hasBluetooth, 5) \
+X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6)
#define DeviceMetadata_CALLBACK NULL
#define DeviceMetadata_DEFAULT NULL
@@ -44,7 +60,7 @@ extern const pb_msgdesc_t DeviceMetadata_msg;
#define DeviceMetadata_fields &DeviceMetadata_msg
/* Maximum encoded size of messages (where known) */
-#define DeviceMetadata_size 25
+#define DeviceMetadata_size 33
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/localonly.pb.h b/src/mesh/generated/localonly.pb.h
index 8e4199d48..b691ee408 100644
--- a/src/mesh/generated/localonly.pb.h
+++ b/src/mesh/generated/localonly.pb.h
@@ -144,7 +144,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
#define LocalModuleConfig_fields &LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
-#define LocalConfig_size 361
+#define LocalConfig_size 359
#define LocalModuleConfig_size 270
#ifdef __cplusplus
diff --git a/src/mesh/generated/mesh.pb.c b/src/mesh/generated/mesh.pb.c
index 2d46c960c..f98316a5d 100644
--- a/src/mesh/generated/mesh.pb.c
+++ b/src/mesh/generated/mesh.pb.c
@@ -42,9 +42,6 @@ PB_BIND(FromRadio, FromRadio, 2)
PB_BIND(ToRadio, ToRadio, 2)
-PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO)
-
-
PB_BIND(Compressed, Compressed, AUTO)
diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h
index d4407a2f1..3f2a8839c 100644
--- a/src/mesh/generated/mesh.pb.h
+++ b/src/mesh/generated/mesh.pb.h
@@ -243,8 +243,11 @@ typedef enum _LogRecord_Level {
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
+/* Compressed message payload */
typedef struct _Compressed {
+ /* PortNum to determine the how to handle the compressed payload. */
PortNum portnum;
+ /* Compressed data. */
Compressed_data_t data;
} Compressed;
@@ -425,14 +428,6 @@ typedef struct _RouteDiscovery {
uint32_t route[8];
} RouteDiscovery;
-/* Compressed message payload */
-typedef struct _ToRadio_PeerInfo {
- /* PortNum to determine the how to handle the compressed payload. */
- uint32_t app_version;
- /* Compressed data. */
- bool mqtt_gateway;
-} ToRadio_PeerInfo;
-
/* Broadcast when a newly powered mesh node wants to find a node num it can use
Sent from the phone over bluetooth to set the user id for the owner of this node.
Also sent from nodes to each other when a new node signs on (so all clients can have this info)
@@ -665,9 +660,6 @@ typedef struct _ToRadio {
union {
/* Send this packet on the mesh */
MeshPacket packet;
- /* Information about the peer, sent after the phone sneds want_config_id.
- Old clients do not send this, which is fine. */
- ToRadio_PeerInfo peer_info;
/* Phone wants radio to send full node db to the phone, This is
typically the first packet sent to the radio when the phone gets a
bluetooth connection. The radio will respond by sending back a
@@ -740,7 +732,6 @@ extern "C" {
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}}
-#define ToRadio_PeerInfo_init_default {0, 0}
#define Compressed_init_default {_PortNum_MIN, {0, {0}}}
#define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0}
@@ -754,7 +745,6 @@ extern "C" {
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
-#define ToRadio_PeerInfo_init_zero {0, 0}
#define Compressed_init_zero {_PortNum_MIN, {0, {0}}}
/* Field tags (for use in manual encoding/decoding) */
@@ -811,8 +801,6 @@ extern "C" {
#define Position_next_update_tag 21
#define Position_seq_number_tag 22
#define RouteDiscovery_route_tag 1
-#define ToRadio_PeerInfo_app_version_tag 1
-#define ToRadio_PeerInfo_mqtt_gateway_tag 2
#define User_id_tag 1
#define User_long_name_tag 2
#define User_short_name_tag 3
@@ -859,7 +847,6 @@ extern "C" {
#define FromRadio_moduleConfig_tag 9
#define FromRadio_channel_tag 10
#define ToRadio_packet_tag 1
-#define ToRadio_peer_info_tag 2
#define ToRadio_want_config_id_tag 3
#define ToRadio_disconnect_tag 4
@@ -1019,19 +1006,11 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
#define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \
-X(a, STATIC, ONEOF, MESSAGE, (payload_variant,peer_info,peer_info), 2) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4)
#define ToRadio_CALLBACK NULL
#define ToRadio_DEFAULT NULL
#define ToRadio_payload_variant_packet_MSGTYPE MeshPacket
-#define ToRadio_payload_variant_peer_info_MSGTYPE ToRadio_PeerInfo
-
-#define ToRadio_PeerInfo_FIELDLIST(X, a) \
-X(a, STATIC, SINGULAR, UINT32, app_version, 1) \
-X(a, STATIC, SINGULAR, BOOL, mqtt_gateway, 2)
-#define ToRadio_PeerInfo_CALLBACK NULL
-#define ToRadio_PeerInfo_DEFAULT NULL
#define Compressed_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
@@ -1051,7 +1030,6 @@ extern const pb_msgdesc_t MyNodeInfo_msg;
extern const pb_msgdesc_t LogRecord_msg;
extern const pb_msgdesc_t FromRadio_msg;
extern const pb_msgdesc_t ToRadio_msg;
-extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
extern const pb_msgdesc_t Compressed_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
@@ -1067,7 +1045,6 @@ extern const pb_msgdesc_t Compressed_msg;
#define LogRecord_fields &LogRecord_msg
#define FromRadio_fields &FromRadio_msg
#define ToRadio_fields &ToRadio_msg
-#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
#define Compressed_fields &Compressed_msg
/* Maximum encoded size of messages (where known) */
@@ -1081,7 +1058,6 @@ extern const pb_msgdesc_t Compressed_msg;
#define Position_size 137
#define RouteDiscovery_size 40
#define Routing_size 42
-#define ToRadio_PeerInfo_size 8
#define ToRadio_size 324
#define User_size 77
#define Waypoint_size 156
diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h
index 3c68e9bb0..d272fe2b9 100644
--- a/src/mesh/generated/portnums.pb.h
+++ b/src/mesh/generated/portnums.pb.h
@@ -81,7 +81,7 @@ typedef enum _PortNum {
PortNum_SIMULATOR_APP = 69,
/* Private applications should use portnums >= 256.
To simplify initial development and testing you can use "PRIVATE_APP"
- in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/Meshtastic-device/blob/master/bin/regen-protos.sh)) */
+ in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) */
PortNum_PRIVATE_APP = 256,
/* ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder */
PortNum_ATAK_FORWARDER = 257,
diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp
index 50e82f58f..82ac8feef 100644
--- a/src/mesh/http/ContentHandler.cpp
+++ b/src/mesh/http/ContentHandler.cpp
@@ -58,8 +58,6 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"}
{".css", "text/css"}, {".ico", "image/vnd.microsoft.icon"},
{".svg", "image/svg+xml"}, {"", ""}};
-// const char *tarURL = "https://www.casler.org/temp/meshtastic-web.tar";
-// const char *tarURL = "https://api-production-871d.up.railway.app/mirror/webui";
// const char *certificate = NULL; // change this as needed, leave as is for no TLS check (yolo security)
// Our API to handle messages to and from the radio.
@@ -75,8 +73,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio);
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
- ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
- ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
+ // ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
+ // ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
// ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
@@ -100,8 +98,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
secureServer->registerNode(nodeAPIv1ToRadioOptions);
secureServer->registerNode(nodeAPIv1ToRadio);
secureServer->registerNode(nodeAPIv1FromRadio);
- secureServer->registerNode(nodeHotspotApple);
- secureServer->registerNode(nodeHotspotAndroid);
+ // secureServer->registerNode(nodeHotspotApple);
+ // secureServer->registerNode(nodeHotspotAndroid);
secureServer->registerNode(nodeRestart);
secureServer->registerNode(nodeFormUpload);
secureServer->registerNode(nodeJsonScanNetworks);
@@ -121,8 +119,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
insecureServer->registerNode(nodeAPIv1ToRadioOptions);
insecureServer->registerNode(nodeAPIv1ToRadio);
insecureServer->registerNode(nodeAPIv1FromRadio);
- insecureServer->registerNode(nodeHotspotApple);
- insecureServer->registerNode(nodeHotspotAndroid);
+ // insecureServer->registerNode(nodeHotspotApple);
+ // insecureServer->registerNode(nodeHotspotAndroid);
insecureServer->registerNode(nodeRestart);
insecureServer->registerNode(nodeFormUpload);
insecureServer->registerNode(nodeJsonScanNetworks);
@@ -160,7 +158,7 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Content-Type", "application/x-protobuf");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
- res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/Meshtastic-protobufs/master/mesh.proto");
+ res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/mesh.proto");
uint8_t txBuf[MAX_STREAM_BUF_SIZE];
uint32_t len = 1;
@@ -204,7 +202,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Access-Control-Allow-Headers", "Content-Type");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "PUT, OPTIONS");
- res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/Meshtastic-protobufs/master/mesh.proto");
+ res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/mesh.proto");
if (req->getMethod() == "OPTIONS") {
res->setStatusCode(204); // Success with no content
@@ -266,7 +264,7 @@ std::vector> *htmlListDir(std::vector> *htmlListDir(std::vector thisFileMap;
thisFileMap[strdup("size")] = strdup(String(file.size()).c_str());
-#ifdef ARCH_ESP32
+#ifdef ARCH_ESP32
thisFileMap[strdup("name")] = strdup(String(file.path()).substring(1).c_str());
#else
thisFileMap[strdup("name")] = strdup(String(file.name()).substring(1).c_str());
@@ -620,12 +618,8 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
};
// data->wifi
- String ipStr;
- if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
- ipStr = String(WiFi.softAPIP().toString());
- } else {
- ipStr = String(WiFi.localIP().toString());
- }
+ String ipStr = String(WiFi.localIP().toString());
+
Json jsonObjWifi = Json::object{{"rssi", String(WiFi.RSSI())}, {"ip", ipStr.c_str()}};
// data->memory
diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp
index 48e084ed2..c1844b0cb 100644
--- a/src/mesh/http/WebServer.cpp
+++ b/src/mesh/http/WebServer.cpp
@@ -55,10 +55,6 @@ static void handleWebResponse()
if (isWifiAvailable()) {
if (isWebServerReady) {
- // We're going to handle the DNS responder here so it
- // will be ignored by the NRF boards.
- handleDNSResponse();
-
if (secureServer)
secureServer->loop();
insecureServer->loop();
diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp
index 4a4ac05a9..a031414e3 100644
--- a/src/mesh/http/WiFiAPClient.cpp
+++ b/src/mesh/http/WiFiAPClient.cpp
@@ -8,7 +8,6 @@
#include "mesh/wifi/WiFiServerAPI.h"
#include "mqtt/MQTT.h"
#include "target_specific.h"
-#include
#include
#include
#include
@@ -22,9 +21,6 @@ using namespace concurrency;
static void WiFiEvent(WiFiEvent_t event);
-// DNS Server for the Captive Portal
-DNSServer dnsServer;
-
// NTP
WiFiUDP ntpUDP;
@@ -37,8 +33,6 @@ uint8_t wifiDisconnectReason = 0;
// Stores our hostname
char ourHost[16];
-bool forcedSoftAP = 0;
-
bool APStartupComplete = 0;
static bool needReconnect = true; // If we create our reconnector, run it once at the beginning
@@ -88,16 +82,10 @@ static int32_t reconnectWiFi()
static Periodic *wifiReconnect;
-bool isSoftAPForced()
-{
- return forcedSoftAP;
-}
-
bool isWifiAvailable()
{
- if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forcedSoftAP)) {
-
+ if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
return true;
} else {
return false;
@@ -161,100 +149,48 @@ static void onNetworkConnected()
}
// Startup WiFi
-bool initWifi(bool forceSoftAP)
+bool initWifi()
{
- forcedSoftAP = forceSoftAP;
+ if (config.network.wifi_enabled && config.network.wifi_ssid[0]) {
- if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forceSoftAP)) {
- // if ((radioConfig.has_preferences && config.wifi.ssid[0]) || forceSoftAP) {
const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk;
- if (forceSoftAP) {
- DEBUG_MSG("WiFi ... Forced AP Mode\n");
- } else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT) {
- DEBUG_MSG("WiFi ... AP Mode\n");
- } else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
- DEBUG_MSG("WiFi ... Hidden AP Mode\n");
- } else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_CLIENT) {
- DEBUG_MSG("WiFi ... Client Mode\n");
- } else {
- DEBUG_MSG("WiFi ... WiFi Disabled\n");
- }
-
createSSLCert();
if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL;
- if (*wifiName || forceSoftAP) {
- if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || forceSoftAP) {
+ if (*wifiName) {
+ uint8_t dmac[6];
+ getMacAddr(dmac);
+ sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
- IPAddress apIP(192, 168, 42, 1);
- WiFi.onEvent(WiFiEvent);
- WiFi.mode(WIFI_AP);
+ WiFi.mode(WIFI_MODE_STA);
+ WiFi.setHostname(ourHost);
+ WiFi.onEvent(WiFiEvent);
- if (forcedSoftAP) {
- const char *softAPssid = "meshtasticAdmin";
- const char *softAPpasswd = "12345678";
- int ok = WiFi.softAP(softAPssid, softAPpasswd);
- DEBUG_MSG("Starting (Forced) WIFI AP: ssid=%s, ok=%d\n", softAPssid, ok);
+ // This is needed to improve performance.
+ esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
- } else {
+ WiFi.onEvent(
+ [](WiFiEvent_t event, WiFiEventInfo_t info) {
+ Serial.print("\nWiFi lost connection. Reason: ");
+ Serial.println(info.wifi_sta_disconnected.reason);
- // If AP is configured to be hidden hidden
- if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
+ /*
+ If we are disconnected from the AP for some reason,
+ save the error code.
- // The configurations on softAP are from the espresif library
- int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4);
- DEBUG_MSG("Starting hidden WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
- } else {
- int ok = WiFi.softAP(wifiName, wifiPsw);
- DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
- }
- int ok = WiFi.softAP(wifiName, wifiPsw);
- DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
- }
+ For a reference to the codes:
+ https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
+ */
+ wifiDisconnectReason = info.wifi_sta_disconnected.reason;
+ },
+ WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
- WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
- DEBUG_MSG("MY IP AP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str());
-
- // This is needed to improve performance.
- esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
-
- dnsServer.start(53, "*", apIP);
-
- } else {
- uint8_t dmac[6];
- getMacAddr(dmac);
- sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
-
- WiFi.mode(WIFI_MODE_STA);
- WiFi.setHostname(ourHost);
- WiFi.onEvent(WiFiEvent);
-
- // This is needed to improve performance.
- esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
-
- WiFi.onEvent(
- [](WiFiEvent_t event, WiFiEventInfo_t info) {
- Serial.print("\nWiFi lost connection. Reason: ");
- Serial.println(info.wifi_sta_disconnected.reason);
-
- /*
- If we are disconnected from the AP for some reason,
- save the error code.
-
- For a reference to the codes:
- https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
- */
- wifiDisconnectReason = info.wifi_sta_disconnected.reason;
- },
- WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
-
- DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
- wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
- }
+ DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
+ wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
}
return true;
} else {
@@ -356,13 +292,6 @@ static void WiFiEvent(WiFiEvent_t event)
}
}
-void handleDNSResponse()
-{
- if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
- dnsServer.processNextRequest();
- }
-}
-
uint8_t getWifiDisconnectReason()
{
return wifiDisconnectReason;
diff --git a/src/mesh/http/WiFiAPClient.h b/src/mesh/http/WiFiAPClient.h
index 2c6bc912c..9729c24b5 100644
--- a/src/mesh/http/WiFiAPClient.h
+++ b/src/mesh/http/WiFiAPClient.h
@@ -5,19 +5,14 @@
#include
#ifdef ARCH_ESP32
-#include
#include
#endif
/// @return true if wifi is now in use
-bool initWifi(bool forceSoftAP);
+bool initWifi();
void deinitWifi();
bool isWifiAvailable();
-void handleDNSResponse();
-
-bool isSoftAPForced();
-
uint8_t getWifiDisconnectReason();
diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp
index 6a10c618a..16ce47cec 100644
--- a/src/modules/AdminModule.cpp
+++ b/src/modules/AdminModule.cpp
@@ -441,6 +441,10 @@ void AdminModule::handleGetDeviceMetadata(const MeshPacket &req) {
DeviceMetadata deviceMetadata;
strncpy(deviceMetadata.firmware_version, myNodeInfo.firmware_version, 18);
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
+ deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
+ deviceMetadata.hasBluetooth = HAS_BLUETOOTH;
+ deviceMetadata.hasWifi = HAS_WIFI;
+ deviceMetadata.hasEthernet = HAS_ETHERNET;
r.get_device_metadata_response = deviceMetadata;
r.which_payload_variant = AdminMessage_get_device_metadata_response_tag;
diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp
index 4951d635e..e5d371c1b 100644
--- a/src/modules/ExternalNotificationModule.cpp
+++ b/src/modules/ExternalNotificationModule.cpp
@@ -16,10 +16,10 @@
/*
Documentation:
- https://github.com/meshtastic/Meshtastic-device/blob/master/docs/software/modules/ExternalNotificationModule.md
+ https://github.com/meshtastic/firmware/blob/master/docs/software/modules/ExternalNotificationModule.md
This module supports:
- https://github.com/meshtastic/Meshtastic-device/issues/654
+ https://github.com/meshtastic/firmware/issues/654
Quick reference:
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index 7deba4668..e77e82e54 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -8,7 +8,9 @@
#include "mesh/generated/mqtt.pb.h"
#include "mesh/generated/telemetry.pb.h"
#include "sleep.h"
+#if HAS_WIFI
#include
+#endif
#include
#include
@@ -105,6 +107,11 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient)
// preflightSleepObserver.observe(&preflightSleep);
}
+bool MQTT::connected()
+{
+ return pubSub.connected();
+}
+
void MQTT::reconnect()
{
if (wantsLink()) {
@@ -189,7 +196,13 @@ bool MQTT::wantsLink() const
}
}
+#if HAS_WIFI
return hasChannel && WiFi.isConnected();
+#endif
+#if HAS_ETHERNET
+ return hasChannel && (Ethernet.linkStatus() == LinkON);
+#endif
+ return false;
}
int32_t MQTT::runOnce()
@@ -346,9 +359,9 @@ std::string MQTT::downstreamPacketToJson(MeshPacket *mp)
msgPayload = Json::object{
{"time", (int)decoded->time},
{"pos_timestamp", (int)decoded->timestamp},
- {"latitude_i", decoded->latitude_i},
- {"longitude_i", decoded->longitude_i},
- {"altitude", decoded->altitude}
+ {"latitude_i", (int)decoded->latitude_i},
+ {"longitude_i", (int)decoded->longitude_i},
+ {"altitude", (int)decoded->altitude}
};
} else {
DEBUG_MSG("Error decoding protobuf for position message!\n");
@@ -371,8 +384,8 @@ std::string MQTT::downstreamPacketToJson(MeshPacket *mp)
{"description", decoded->description},
{"expire", (int)decoded->expire},
{"locked", decoded->locked},
- {"latitude_i", decoded->latitude_i},
- {"longitude_i", decoded->longitude_i},
+ {"latitude_i", (int)decoded->latitude_i},
+ {"longitude_i", (int)decoded->longitude_i},
};
} else {
DEBUG_MSG("Error decoding protobuf for position message!\n");
diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h
index 9d80c7d91..c8381574c 100644
--- a/src/mqtt/MQTT.h
+++ b/src/mqtt/MQTT.h
@@ -5,7 +5,12 @@
#include "concurrency/OSThread.h"
#include "mesh/Channels.h"
#include
+#if HAS_WIFI
#include
+#endif
+#if HAS_ETHERNET
+#include
+#endif
/**
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
@@ -16,7 +21,12 @@ class MQTT : private concurrency::OSThread
// supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
// WiFiClientSecure wifiClient;
+#if HAS_WIFI
WiFiClient mqttClient;
+#endif
+#if HAS_ETHERNET
+ EthernetClient mqttClient;
+#endif
PubSubClient pubSub;
// instead we supress sleep from our runOnce() callback
@@ -38,6 +48,8 @@ class MQTT : private concurrency::OSThread
/** Attempt to connect to server if necessary
*/
void reconnect();
+
+ bool connected();
protected:
virtual int32_t runOnce() override;
diff --git a/src/network-stubs.cpp b/src/network-stubs.cpp
new file mode 100644
index 000000000..0119fa1be
--- /dev/null
+++ b/src/network-stubs.cpp
@@ -0,0 +1,27 @@
+#include "configuration.h"
+
+#if (HAS_WIFI == 0)
+
+bool initWifi() {
+ return false;
+}
+
+void deinitWifi() {}
+
+bool isWifiAvailable() {
+ return false;
+}
+
+#endif
+
+#if (HAS_ETHERNET == 0)
+
+bool initEthernet() {
+ return false;
+}
+
+bool isEthernetAvailable() {
+ return false;
+}
+
+#endif
diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h
index 527f2947e..00d221691 100644
--- a/src/platform/esp32/architecture.h
+++ b/src/platform/esp32/architecture.h
@@ -70,6 +70,8 @@
#define HW_VENDOR HardwareModel_TLORA_V1_1P3
#elif defined(TLORA_V2_1_16)
#define HW_VENDOR HardwareModel_TLORA_V2_1_1P6
+#elif defined(TLORA_V2_1_18)
+ #define HW_VENDOR HardwareModel_TLORA_V2_1_1P8
#elif defined(GENIEBLOCKS)
#define HW_VENDOR HardwareModel_GENIEBLOCKS
#elif defined(PRIVATE_HW)
@@ -80,6 +82,8 @@
#define HW_VENDOR HardwareModel_M5STACK
#elif defined(STATION_G1)
#define HW_VENDOR HardwareModel_STATION_G1
+#elif defined(DR_DEV)
+ #define HW_VENDOR HardwareModel_DR_DEV
#endif
//
diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h
index 63e173434..986a864c9 100644
--- a/src/platform/nrf52/architecture.h
+++ b/src/platform/nrf52/architecture.h
@@ -26,6 +26,9 @@
#ifndef HAS_RADIO
#define HAS_RADIO 1
#endif
+#ifdef HAS_CPU_SHUTDOWN
+ #define HAS_CPU_SHUTDOWN 1
+#endif
//
// set HW_VENDOR
@@ -42,7 +45,7 @@
#define HW_VENDOR HardwareModel_T_ECHO
#elif defined(NORDIC_PCA10059)
#define HW_VENDOR HardwareModel_NRF52840_PCA10059
-#elif defined(PRIVATE_HW)
+#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
#define HW_VENDOR HardwareModel_PRIVATE_HW
#else
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
diff --git a/src/shutdown.h b/src/shutdown.h
index f37339641..3927825fb 100644
--- a/src/shutdown.h
+++ b/src/shutdown.h
@@ -13,11 +13,12 @@ void powerCommandsCheck()
#elif defined(ARCH_NRF52)
NVIC_SystemReset();
#else
- DEBUG_MSG("FIXME implement reboot for this platform");
+ rebootAtMsec = -1;
+ DEBUG_MSG("FIXME implement reboot for this platform. Skipping for now.\n");
#endif
}
-#if defined(ARCH_NRF52)
+#if defined(ARCH_NRF52) || defined(HAS_PMU)
if (shutdownAtMsec) {
screen->startShutdownScreen();
playBeep();
diff --git a/src/wifi-stubs.cpp b/src/wifi-stubs.cpp
deleted file mode 100644
index faf58b620..000000000
--- a/src/wifi-stubs.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//#include "mesh/wifi/WebServer.h"
-#include "configuration.h"
-
-#ifndef ARCH_ESP32
-
-//#include "mesh/wifi/WiFiAPClient.h"
-
-bool initWifi(bool forceSoftAP) {
- return false;
-}
-
-void deinitWifi() {}
-
-bool isWifiAvailable()
-{
- return false;
-}
-
-#endif
diff --git a/variants/diy/dr-dev/variant.h b/variants/diy/dr-dev/variant.h
new file mode 100644
index 000000000..7d0625907
--- /dev/null
+++ b/variants/diy/dr-dev/variant.h
@@ -0,0 +1,71 @@
+// Initialize i2c bus on sd_dat and esp_led pins, respectively. We need a bus to not hang on boot
+#define HAS_SCREEN 0
+#define I2C_SDA 4
+#define I2C_SCL 5
+
+// GPS
+#undef GPS_RX_PIN
+#define GPS_RX_PIN NOT_A_PIN
+#define HAS_GPS 0
+
+#define BUTTON_PIN 13 // The middle button GPIO on the T-Beam
+#define BUTTON_NEED_PULLUP
+#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
+
+#define LORA_DIO0 NOT_A_PIN // a No connect on the SX1262/SX1268 module
+#define LORA_RESET NOT_A_PIN // RST for SX1276, and for SX1262/SX1268
+#define LORA_DIO3 NOT_A_PIN // Not connected on PCB, but internally on the SX1262/SX1268, if DIO3 is high the TXCO is enabled
+
+// In transmitting, set TXEN as high communication level,RXEN pin is low level;
+// In receiving, set RXEN as high communication level, TXEN is lowlevel;
+// Before powering off, set TXEN、RXEN as low level.
+
+#undef RF95_SCK
+#define RF95_SCK 18
+#undef RF95_MISO
+#define RF95_MISO 19
+#undef RF95_MOSI
+#define RF95_MOSI 23
+
+// PINS FOR THE 900M22S
+
+#define LORA_DIO1 26 // IRQ for SX1262/SX1268
+#define LORA_DIO2 22 // BUSY for SX1262/SX1268
+#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
+#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
+#undef RF95_NSS
+#define RF95_NSS 16
+#define SX126X_BUSY 22
+#define SX126X_CS 16
+
+
+// PINS FOR THE 900M30S
+/*
+#define LORA_DIO1 27 // IRQ for SX1262/SX1268
+#define LORA_DIO2 35 // BUSY for SX1262/SX1268
+#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
+#define LORA_RXEN 21 // Input - RF switch RX control, connecting external MCU IO, valid in high level
+#undef RF95_NSS
+#define RF95_NSS 33
+#define SX126X_BUSY 35
+#define SX126X_CS 33
+*/
+
+// RX/TX for RFM95/SX127x
+#define RF95_RXEN LORA_RXEN
+#define RF95_TXEN LORA_TXEN
+// #define RF95_TCXO
+
+// common pinouts for SX126X modules
+
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_RESET LORA_RESET
+#define SX126X_RXEN LORA_RXEN
+#define SX126X_TXEN LORA_TXEN
+
+// supported modules list
+//#define USE_RF95 // RFM95/SX127x
+#define USE_SX1262
+//#define USE_SX1268
+//#define USE_LLCC68
+#define SX126X_E22
diff --git a/variants/feather_diy/platformio.ini b/variants/feather_diy/platformio.ini
new file mode 100644
index 000000000..84c582ab0
--- /dev/null
+++ b/variants/feather_diy/platformio.ini
@@ -0,0 +1,11 @@
+; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
+[env:feather_diy]
+extends = nrf52840_base
+board = adafruit_feather_nrf52840
+build_flags = ${nrf52840_base.build_flags} -Ivariants/feather_diy -Dfeather_diy
+build_src_filter = ${nrf52_base.build_src_filter} +<../variants/feather_diy>
+lib_deps =
+ ${nrf52840_base.lib_deps}
+debug_tool = jlink
+; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
+;upload_protocol = jlink
\ No newline at end of file
diff --git a/variants/feather_diy/variant.cpp b/variants/feather_diy/variant.cpp
new file mode 100644
index 000000000..7311c9019
--- /dev/null
+++ b/variants/feather_diy/variant.cpp
@@ -0,0 +1,24 @@
+/*
+ Copyright (c) 2014-2015 Arduino LLC. All right reserved.
+ Copyright (c) 2016 Sandeep Mistry All right reserved.
+ Copyright (c) 2018, Adafruit Industries (adafruit.com)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "variant.h"
+#include "nrf.h"
+#include "wiring_constants.h"
+#include "wiring_digital.h"
diff --git a/variants/feather_diy/variant.h b/variants/feather_diy/variant.h
new file mode 100644
index 000000000..703d32202
--- /dev/null
+++ b/variants/feather_diy/variant.h
@@ -0,0 +1,119 @@
+/*
+ Copyright (c) 2014-2015 Arduino LLC. All right reserved.
+ Copyright (c) 2016 Sandeep Mistry All right reserved.
+ Copyright (c) 2018, Adafruit Industries (adafruit.com)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef _VARIANT_FEATHER_DIY_
+#define _VARIANT_FEATHER_DIY_
+
+/** Master clock frequency */
+#define VARIANT_MCK (64000000ul)
+
+#define USE_LFXO // Board uses 32khz crystal for LF
+// define USE_LFRC // Board uses RC for LF
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "WVariant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+// Number of pins defined in PinDescription array
+#define PINS_COUNT (48)
+#define NUM_DIGITAL_PINS (48)
+#define NUM_ANALOG_INPUTS (6)
+#define NUM_ANALOG_OUTPUTS (0)
+
+#define WIRE_INTERFACES_COUNT 1
+
+#define PIN_WIRE_SDA 22
+#define PIN_WIRE_SCL 23
+
+#define PIN_LED1 3
+#define PIN_LED2 4
+
+#define LED_BUILTIN PIN_LED1
+
+#define LED_GREEN PIN_LED2 // Actually red
+#define LED_BLUE PIN_LED1
+
+#define LED_STATE_ON 1 // State when LED is litted
+
+#define BUTTON_PIN 7
+
+/*
+ * Serial interfaces
+ */
+#define PIN_SERIAL1_RX 1
+#define PIN_SERIAL1_TX 0
+
+#define PIN_SERIAL2_RX (-1)
+#define PIN_SERIAL2_TX (-1)
+
+#define SPI_INTERFACES_COUNT 1
+
+#define PIN_SPI_MISO 24
+#define PIN_SPI_MOSI 25
+#define PIN_SPI_SCK 26
+
+#define SS 2
+
+#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
+#define LORA_RESET 13 // RST for SX1276, and for SX1262/SX1268
+#define LORA_DIO1 11 // IRQ for SX1262/SX1268
+#define LORA_DIO2 12 // BUSY for SX1262/SX1268
+#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
+
+#define RF95_SCK SCK
+#define RF95_MISO MI
+#define RF95_MOSI MO
+#define RF95_NSS SS
+
+// enables 3.3V periphery like GPS or IO Module
+#define PIN_3V3_EN (34)
+
+#undef USE_EINK
+
+// supported modules list
+#define USE_SX1262
+
+// common pinouts for SX126X modules
+#define SX126X_CS RF95_NSS // NSS for SX126X
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_BUSY LORA_DIO2
+#define SX126X_RESET LORA_RESET
+#define SX126X_RXEN 10
+#define SX126X_TXEN 9
+
+#ifdef EBYTE_E22
+// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
+// (which is the default for the sx1262interface code)
+#define SX126X_E22
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * Arduino objects - C++ only
+ *----------------------------------------------------------------------------*/
+
+#endif
diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini
index d8e2ba3e9..3521a43ff 100644
--- a/variants/rak4631/platformio.ini
+++ b/variants/rak4631/platformio.ini
@@ -3,10 +3,12 @@
extends = nrf52840_base
board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
-build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631>
+build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> + +
lib_deps =
${nrf52840_base.lib_deps}
+ ${networking_base.lib_deps}
melopero/Melopero RV3028@^1.1.0
+ https://github.com/meshtastic/RAK13800-W5100S.git#b680706eb8006cd62c919ac74c8af1950eb82c81
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink
\ No newline at end of file
diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h
index b42163fbb..904491b6a 100644
--- a/variants/rak4631/variant.h
+++ b/variants/rak4631/variant.h
@@ -229,6 +229,12 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define HAS_RTC 1
+#define HAS_ETHERNET 1
+
+#define PIN_ETHERNET_RESET 21
+#define PIN_ETHERNET_SS PIN_EINK_CS
+#define ETH_SPI_PORT SPI1
+
#ifdef __cplusplus
}
#endif
diff --git a/variants/tlora_v2_1_18/platformio.ini b/variants/tlora_v2_1_18/platformio.ini
new file mode 100644
index 000000000..2cb1c3d2f
--- /dev/null
+++ b/variants/tlora_v2_1_18/platformio.ini
@@ -0,0 +1,7 @@
+[env:tlora-v2-1-1.8]
+extends = esp32_base
+board = ttgo-lora32-v21
+lib_deps =
+ ${esp32_base.lib_deps}
+build_flags =
+ ${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18
\ No newline at end of file
diff --git a/variants/tlora_v2_1_18/variant.h b/variants/tlora_v2_1_18/variant.h
new file mode 100644
index 000000000..cd693a3d2
--- /dev/null
+++ b/variants/tlora_v2_1_18/variant.h
@@ -0,0 +1,33 @@
+#undef GPS_RX_PIN
+#undef GPS_TX_PIN
+#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick
+#define GPS_TX_PIN 13
+
+#define EXT_NOTIFY_OUT 2 // Default pin to use for Ext Notify Module.
+
+#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+// ratio of voltage divider = 2.0 (R42=100k, R43=100k)
+#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
+
+#define I2C_SDA 21 // I2C pins for this board
+#define I2C_SCL 22
+
+// #define RESET_OLED 16 // If defined, this pin will be used to reset the display controller. Crashes on newer ESP-IDF and not needed per schematic
+
+#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
+#define LED_PIN 25 // If defined we will blink this LED
+#define BUTTON_PIN 12 // If defined, this will be used for user button presses,
+
+#define BUTTON_NEED_PULLUP
+
+#define USE_SX1280
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 23
+
+#define SX128X_CS 18 // FIXME - we really should define LORA_CS instead
+#define SX128X_DIO1 33
+#define SX128X_BUSY 32
+#define SX128X_RESET LORA_RESET
+#define SX128X_E22 // Not really an E22 but TTGO seems to be trying to clone that
+// Internally the TTGO module hooks the SX1280-DIO2 in to control the TX/RX switch (which is the default for the sx1280interface
+// code)
diff --git a/version.properties b/version.properties
index 3d2355d7b..7d6851090 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
-major = 1
-minor = 3
-build = 48
+major = 2
+minor = 0
+build = 0