Merge branch 'delivery-report' of https://github.com/meshtastic/firmware into delivery-report

This commit is contained in:
Thomas Göttgens 2023-12-11 12:38:22 +01:00
commit 512399c8f5
51 changed files with 380 additions and 172 deletions

View File

@ -66,6 +66,7 @@ jobs:
- board: tlora-v2-1-1_6 - board: tlora-v2-1-1_6
- board: tlora-v2-1-1_8 - board: tlora-v2-1-1_8
- board: tbeam - board: tbeam
- board: heltec-ht62-esp32c3-sx1262
- board: heltec-v1 - board: heltec-v1
- board: heltec-v2_0 - board: heltec-v2_0
- board: heltec-v2_1 - board: heltec-v2_1
@ -123,7 +124,9 @@ jobs:
matrix: matrix:
include: include:
- board: pico - board: pico
- board: picow
- board: rak11310 - board: rak11310
- board: senselora_rp2040
uses: ./.github/workflows/build_rpi2040.yml uses: ./.github/workflows/build_rpi2040.yml
with: with:
board: ${{ matrix.board }} board: ${{ matrix.board }}
@ -210,6 +213,9 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
gather-artifacts: gather-artifacts:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
[ [
@ -283,14 +289,13 @@ jobs:
- name: Create request artifacts - name: Create request artifacts
continue-on-error: true # FIXME: Why are we getting 502, but things still work? continue-on-error: true # FIXME: Why are we getting 502, but things still work?
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v1.1.0 uses: gavv/pull-request-artifacts@v2.1.0
with: with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }} commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }} artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }}
artifacts-repo: meshtastic/artifacts artifacts-repo: meshtastic/artifacts
artifacts-branch: device artifacts-branch: device
artifacts-dir: pr
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
release-artifacts: release-artifacts:

View File

@ -1,25 +1,24 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.17.1 version: 1.17.2
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.2.6 ref: v1.3.0
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- bandit@1.7.5 - bandit@1.7.5
- checkov@3.0.16 - checkov@3.1.9
- terrascan@1.18.3 - terrascan@1.18.5
- trivy@0.46.1 - trivy@0.47.0
- trufflehog@3.62.1 #- trufflehog@3.63.2-rc0
- taplo@0.8.1 - taplo@0.8.1
- ruff@0.1.3 - ruff@0.1.6
- yamllint@1.32.0
- isort@5.12.0 - isort@5.12.0
- markdownlint@0.37.0 - markdownlint@0.37.0
- oxipng@9.0.0 - oxipng@9.0.0
- svgo@3.0.2 - svgo@3.0.5
- actionlint@1.6.26 - actionlint@1.6.26
- flake8@6.1.0 - flake8@6.1.0
- hadolint@2.12.0 - hadolint@2.12.0
@ -27,9 +26,9 @@ lint:
- shellcheck@0.9.0 - shellcheck@0.9.0
- black@23.9.1 - black@23.9.1
- git-diff-check - git-diff-check
- gitleaks@8.18.0 - gitleaks@8.18.1
- clang-format@16.0.3 - clang-format@16.0.3
- prettier@3.0.3 - prettier@3.1.0
runtimes: runtimes:
enabled: enabled:
- python@3.10.8 - python@3.10.8

View File

@ -39,7 +39,6 @@ lib_deps =
${environmental_base.lib_deps} ${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.1 h2zero/NimBLE-Arduino@^1.4.1
jgromes/RadioLib@^6.2.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f

View File

@ -11,11 +11,10 @@ build_flags =
-Isrc/platform/nrf52 -Isrc/platform/nrf52
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<mesh/eth/> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<mesh/eth/>
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}
jgromes/RadioLib@^6.2.0
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA

View File

@ -10,6 +10,7 @@ build_src_filter =
-<platform/nrf52/> -<platform/nrf52/>
-<platform/stm32wl/> -<platform/stm32wl/>
-<platform/rp2040> -<platform/rp2040>
-<mesh/wifi/>
-<mesh/http/> -<mesh/http/>
-<mesh/eth/> -<mesh/eth/>
-<modules/esp32> -<modules/esp32>
@ -22,7 +23,6 @@ lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
jgromes/RadioLib@^6.1.0
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}

View File

@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2040_base] [rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#612de5399d68b359053f1307ed223d400aea975c
extends = arduino_base extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.2 platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.6.2
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@ -12,7 +12,7 @@ build_flags =
-D__PLAT_RP2040__ -D__PLAT_RP2040__
# -D _POSIX_THREADS # -D _POSIX_THREADS
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/>
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
@ -20,5 +20,4 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
jgromes/RadioLib@^6.2.0
rweather/Crypto rweather/Crypto

View File

@ -13,17 +13,16 @@ build_flags =
-DVECT_TAB_OFFSET=0x08000000 -DVECT_TAB_OFFSET=0x08000000
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
board_upload.offset_address = 0x08000000 board_upload.offset_address = 0x08000000
upload_protocol = stlink upload_protocol = stlink
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
jgromes/RadioLib@^6.2.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
https://github.com/littlefs-project/littlefs.git#v2.5.1 https://github.com/littlefs-project/littlefs.git#v2.5.1
https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1 https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
lib_ignore = lib_ignore =
https://github.com/mathertel/OneButton#2.1.0 mathertel/OneButton

View File

@ -68,8 +68,9 @@ build_flags = -Wno-missing-field-initializers
monitor_speed = 115200 monitor_speed = 115200
lib_deps = lib_deps =
jgromes/RadioLib@^6.3.0
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61 https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3 https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3

@ -1 +1 @@
Subproject commit 9148427a3be535c9e3f17e846ecbb64ce04b6521 Subproject commit a34b2c680e2c1c240643c515e57c5532b29c91a7

View File

@ -435,7 +435,7 @@ void Power::shutdown()
ledOff(PIN_LED2); ledOff(PIN_LED2);
#endif #endif
#ifdef PIN_LED3 #ifdef PIN_LED3
ledOff(PIN_LED2); ledOff(PIN_LED3);
#endif #endif
doDeepSleep(DELAY_FOREVER, false); doDeepSleep(DELAY_FOREVER, false);
#endif #endif

View File

@ -33,7 +33,7 @@ class PowerFSMThread : public OSThread
powerFSM.trigger(EVENT_SHUTDOWN); powerFSM.trigger(EVENT_SHUTDOWN);
} }
return 10; return 100;
} }
}; };

View File

@ -293,7 +293,7 @@ bool GPS::setup()
gnssModel = GNSS_MODEL_UNKNOWN; gnssModel = GNSS_MODEL_UNKNOWN;
} }
#else #else
gnssModel = GNSS_MODEL_UC6850; gnssModel = GNSS_MODEL_UC6580;
#endif #endif
if (gnssModel == GNSS_MODEL_MTK) { if (gnssModel == GNSS_MODEL_MTK) {
@ -311,11 +311,23 @@ bool GPS::setup()
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n"); _serial_gps->write("$PCAS11,3*1E\r\n");
delay(250); delay(250);
} else if (gnssModel == GNSS_MODEL_UC6850) { } else if (gnssModel == GNSS_MODEL_UC6580) {
// The Unicore UC6580 can use a lot of sat systems, enable it to
// use GPS + GLONASS // use GPS L1 & L5 + BDS B1I & B2a + GLONASS L1 + GALILEO E1 & E5a + SBAS
_serial_gps->write("$CFGSYS,h15\r\n"); // This will reset the receiver, so wait a bit afterwards
// The paranoid will wait for the OK*04 confirmation response after each command.
_serial_gps->write("$CFGSYS,h25155\r\n");
delay(750);
// Must be done after the CFGSYS command
// Turn off GSV messages, we don't really care about which and where the sats are, maybe someday.
_serial_gps->write("$CFGMSG,0,3,0\r\n");
delay(250); delay(250);
// Turn off NOTICE __TXT messages, these may provide Unicore some info but we don't care.
_serial_gps->write("$CFGMSG,6,0,0\r\n");
delay(250);
_serial_gps->write("$CFGMSG,6,1,0\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_UBLOX) { } else if (gnssModel == GNSS_MODEL_UBLOX) {
// Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command) // Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command)
// We need set it because by default it is GPS only, and we want to use GLONASS too // We need set it because by default it is GPS only, and we want to use GLONASS too
@ -495,14 +507,14 @@ void GPS::setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime)
#ifdef PIN_GPS_STANDBY // Specifically the standby pin for L76K and clones #ifdef PIN_GPS_STANDBY // Specifically the standby pin for L76K and clones
if (on) { if (on) {
LOG_INFO("Waking GPS"); LOG_INFO("Waking GPS");
digitalWrite(PIN_GPS_STANDBY, 1);
pinMode(PIN_GPS_STANDBY, OUTPUT); pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, 1);
return; return;
} else { } else {
LOG_INFO("GPS entering sleep"); LOG_INFO("GPS entering sleep");
// notifyGPSSleep.notifyObservers(NULL); // notifyGPSSleep.notifyObservers(NULL);
digitalWrite(PIN_GPS_STANDBY, 0);
pinMode(PIN_GPS_STANDBY, OUTPUT); pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, 0);
return; return;
} }
#endif #endif
@ -920,8 +932,8 @@ GPS *GPS::createGps()
if (_en_gpio != 0) { if (_en_gpio != 0) {
LOG_DEBUG("Setting %d to output.\n", _en_gpio); LOG_DEBUG("Setting %d to output.\n", _en_gpio);
digitalWrite(_en_gpio, !GPS_EN_ACTIVE);
pinMode(_en_gpio, OUTPUT); pinMode(_en_gpio, OUTPUT);
digitalWrite(_en_gpio, !GPS_EN_ACTIVE);
} }
#ifdef PIN_GPS_PPS #ifdef PIN_GPS_PPS
@ -941,8 +953,8 @@ GPS *GPS::createGps()
new_gps->setGPSPower(true, false, 0); new_gps->setGPSPower(true, false, 0);
#ifdef PIN_GPS_RESET #ifdef PIN_GPS_RESET
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
pinMode(PIN_GPS_RESET, OUTPUT); pinMode(PIN_GPS_RESET, OUTPUT);
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
delay(10); delay(10);
digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE); digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE);
#endif #endif
@ -987,8 +999,8 @@ bool GPS::factoryReset()
{ {
#ifdef PIN_GPS_REINIT #ifdef PIN_GPS_REINIT
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW // The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
digitalWrite(PIN_GPS_REINIT, 0);
pinMode(PIN_GPS_REINIT, OUTPUT); pinMode(PIN_GPS_REINIT, OUTPUT);
digitalWrite(PIN_GPS_REINIT, 0);
delay(150); // The L76K datasheet calls for at least 100MS delay delay(150); // The L76K datasheet calls for at least 100MS delay
digitalWrite(PIN_GPS_REINIT, 1); digitalWrite(PIN_GPS_REINIT, 1);
#endif #endif

View File

@ -23,7 +23,7 @@ struct uBloxGnssModelInfo {
typedef enum { typedef enum {
GNSS_MODEL_MTK, GNSS_MODEL_MTK,
GNSS_MODEL_UBLOX, GNSS_MODEL_UBLOX,
GNSS_MODEL_UC6850, GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN, GNSS_MODEL_UNKNOWN,
} GnssModel_t; } GnssModel_t;

View File

@ -152,7 +152,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
#endif #endif
// nrf52 doesn't have a readable RTC (yet - software not written) // nrf52 doesn't have a readable RTC (yet - software not written)
#ifdef HAS_RTC #if HAS_RTC
readFromRTC(); readFromRTC();
#endif #endif

View File

@ -46,7 +46,7 @@
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09 #define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#elif defined(HELTEC_WIRELESS_PAPER) #elif defined(HELTEC_WIRELESS_PAPER)
//#define TECHO_DISPLAY_MODEL GxEPD2_213_T5D // #define TECHO_DISPLAY_MODEL GxEPD2_213_T5D
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN #define TECHO_DISPLAY_MODEL GxEPD2_213_BN
#endif #endif
@ -193,14 +193,14 @@ bool EInkDisplay::connect()
LOG_INFO("Doing EInk init\n"); LOG_INFO("Doing EInk init\n");
#ifdef PIN_EINK_PWR_ON #ifdef PIN_EINK_PWR_ON
digitalWrite(PIN_EINK_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
pinMode(PIN_EINK_PWR_ON, OUTPUT); pinMode(PIN_EINK_PWR_ON, OUTPUT);
digitalWrite(PIN_EINK_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
#endif #endif
#ifdef PIN_EINK_EN #ifdef PIN_EINK_EN
// backlight power, HIGH is backlight on, LOW is off // backlight power, HIGH is backlight on, LOW is off
digitalWrite(PIN_EINK_EN, LOW);
pinMode(PIN_EINK_EN, OUTPUT); pinMode(PIN_EINK_EN, OUTPUT);
digitalWrite(PIN_EINK_EN, LOW);
#endif #endif
#if defined(TTGO_T_ECHO) #if defined(TTGO_T_ECHO)

View File

@ -43,9 +43,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "sleep.h" #include "sleep.h"
#include "target_specific.h" #include "target_specific.h"
#if HAS_WIFI && !defined(ARCH_RASPBERRY_PI)
#include "mesh/wifi/WiFiAPClient.h"
#endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#include "mesh/http/WiFiAPClient.h"
#include "modules/esp32/StoreForwardModule.h" #include "modules/esp32/StoreForwardModule.h"
#endif #endif
@ -1294,7 +1297,7 @@ void Screen::setFrames()
// call a method on debugInfoScreen object (for more details) // call a method on debugInfoScreen object (for more details)
normalFrames[numframes++] = &Screen::drawDebugInfoSettingsTrampoline; normalFrames[numframes++] = &Screen::drawDebugInfoSettingsTrampoline;
#ifdef ARCH_ESP32 #if HAS_WIFI && !defined(ARCH_RASPBERRY_PI)
if (isWifiAvailable()) { if (isWifiAvailable()) {
// call a method on debugInfoScreen object (for more details) // call a method on debugInfoScreen object (for more details)
normalFrames[numframes++] = &Screen::drawDebugInfoWiFiTrampoline; normalFrames[numframes++] = &Screen::drawDebugInfoWiFiTrampoline;
@ -1618,12 +1621,19 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed"); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
} else if (WiFi.status() == WL_IDLE_STATUS) { } else if (WiFi.status() == WL_IDLE_STATUS) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting"); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
} else { }
#ifdef ARCH_ESP32
else {
// Codes: // Codes:
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason()))); WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
} }
#else
else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unkown status: " + String(WiFi.status()));
}
#endif
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName)); display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));

View File

@ -478,8 +478,8 @@ bool TFTDisplay::connect()
LOG_INFO("Doing TFT init\n"); LOG_INFO("Doing TFT init\n");
#ifdef TFT_BL #ifdef TFT_BL
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
pinMode(TFT_BL, OUTPUT); pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
// pinMode(PIN_3V3_EN, OUTPUT); // pinMode(PIN_3V3_EN, OUTPUT);
// digitalWrite(PIN_3V3_EN, HIGH); // digitalWrite(PIN_3V3_EN, HIGH);
LOG_INFO("Power to TFT Backlight\n"); LOG_INFO("Power to TFT Backlight\n");
@ -487,11 +487,11 @@ bool TFTDisplay::connect()
#ifdef ST7735_BACKLIGHT_EN_V03 #ifdef ST7735_BACKLIGHT_EN_V03
if (heltec_version == 3) { if (heltec_version == 3) {
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT); pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
} else { } else {
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT); pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
} }
#endif #endif

View File

@ -32,9 +32,6 @@
#include <utility> #include <utility>
// #include <driver/rtc_io.h> // #include <driver/rtc_io.h>
#include "mesh/eth/ethClient.h"
#include "mesh/http/WiFiAPClient.h"
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "mesh/http/WebServer.h" #include "mesh/http/WebServer.h"
#include "nimble/NimbleBluetooth.h" #include "nimble/NimbleBluetooth.h"
@ -48,10 +45,12 @@ NRF52Bluetooth *nrf52Bluetooth;
#if HAS_WIFI #if HAS_WIFI
#include "mesh/api/WiFiServerAPI.h" #include "mesh/api/WiFiServerAPI.h"
#include "mesh/wifi/WiFiAPClient.h"
#endif #endif
#if HAS_ETHERNET #if HAS_ETHERNET
#include "mesh/api/ethServerAPI.h" #include "mesh/api/ethServerAPI.h"
#include "mesh/eth/ethClient.h"
#endif #endif
#include "mqtt/MQTT.h" #include "mqtt/MQTT.h"
@ -433,6 +432,10 @@ void setup()
auto i2cCount = i2cScanner->countDevices(); auto i2cCount = i2cScanner->countDevices();
if (i2cCount == 0) { if (i2cCount == 0) {
LOG_INFO("No I2C devices found\n"); LOG_INFO("No I2C devices found\n");
Wire.end();
#ifdef I2C_SDA1
Wire1.end();
#endif
} else { } else {
LOG_INFO("%i I2C devices found\n", i2cCount); LOG_INFO("%i I2C devices found\n", i2cCount);
} }
@ -577,10 +580,13 @@ void setup()
// but we need to do this after main cpu init (esp32setup), because we need the random seed set // but we need to do this after main cpu init (esp32setup), because we need the random seed set
nodeDB.init(); nodeDB.init();
// If we're taking on the repeater role, use flood router // If we're taking on the repeater role, use flood router and turn off 3V3_S rail because peripherals are not needed
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
router = new FloodingRouter(); router = new FloodingRouter();
else #ifdef PIN_3V3_EN
digitalWrite(PIN_3V3_EN, LOW);
#endif
} else
router = new ReliableRouter(); router = new ReliableRouter();
#if HAS_BUTTON || defined(ARCH_RASPBERRY_PI) #if HAS_BUTTON || defined(ARCH_RASPBERRY_PI)
@ -654,7 +660,10 @@ void setup()
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
gps = GPS::createGps(); // If we're taking on the repeater role, ignore GPS
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
gps = GPS::createGps();
}
if (gps) { if (gps) {
gpsStatus->observe(&gps->newStatus); gpsStatus->observe(&gps->newStatus);
} else { } else {
@ -835,11 +844,15 @@ void setup()
#ifndef ARCH_PORTDUINO #ifndef ARCH_PORTDUINO
// Initialize Wifi // Initialize Wifi
#if HAS_WIFI
initWifi(); initWifi();
#endif
#if HAS_ETHERNET
// Initialize Ethernet // Initialize Ethernet
initEthernet(); initEthernet();
#endif #endif
#endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Start web server thread. // Start web server thread.

View File

@ -320,7 +320,9 @@ meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
position.time = getValidTime(RTCQualityFromNet); position.time = getValidTime(RTCQualityFromNet);
updateBatteryLevel(powerStatus->getBatteryChargePercent()); if (powerStatus->getHasBattery() == 1) {
updateBatteryLevel(powerStatus->getBatteryChargePercent());
}
return node; return node;
} }

View File

@ -21,7 +21,7 @@
#include <pb_encode.h> #include <pb_encode.h>
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include "modules/esp32/StoreForwardModule.h" #include "modules/esp32/StoreForwardModule.h"
#include <Preferences.h> #include <Preferences.h>
#include <nvs_flash.h> #include <nvs_flash.h>
@ -248,6 +248,12 @@ void NodeDB::installDefaultModuleConfig()
#ifdef T_WATCH_S3 #ifdef T_WATCH_S3
// Don't worry about the other settings, we'll use the DRV2056 behavior for notifications // Don't worry about the other settings, we'll use the DRV2056 behavior for notifications
moduleConfig.external_notification.enabled = true; moduleConfig.external_notification.enabled = true;
#endif
#ifdef NANO_G2_ULTRA
moduleConfig.external_notification.enabled = true;
moduleConfig.external_notification.alert_message = true;
moduleConfig.external_notification.output_ms = 100;
moduleConfig.external_notification.active = true;
#endif #endif
moduleConfig.has_canned_message = true; moduleConfig.has_canned_message = true;
@ -296,6 +302,15 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED | (meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP); meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
moduleConfig.telemetry.device_update_interval = ONE_DAY; moduleConfig.telemetry.device_update_interval = ONE_DAY;
} else if (role == meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN) {
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY;
config.device.node_info_broadcast_secs = UINT32_MAX;
config.position.position_broadcast_smart_enabled = false;
config.position.position_broadcast_secs = UINT32_MAX;
moduleConfig.neighbor_info.update_interval = UINT32_MAX;
moduleConfig.telemetry.device_update_interval = UINT32_MAX;
moduleConfig.telemetry.environment_update_interval = UINT32_MAX;
moduleConfig.telemetry.air_quality_interval = UINT32_MAX;
} }
} }

View File

@ -299,6 +299,12 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING) config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING)
return false; return false;
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
!nodeDB.getMeshNode(p->from)->has_user) {
LOG_DEBUG("Node 0x%x not in NodeDB. Rebroadcast mode KNOWN_ONLY will ignore packet\n", p->from);
return false;
}
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)
return true; // If packet was already decoded just return return true; // If packet was already decoded just return

View File

@ -26,8 +26,8 @@ SX126xInterface<T>::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
template <typename T> bool SX126xInterface<T>::init() template <typename T> bool SX126xInterface<T>::init()
{ {
#ifdef SX126X_POWER_EN #ifdef SX126X_POWER_EN
digitalWrite(SX126X_POWER_EN, HIGH);
pinMode(SX126X_POWER_EN, OUTPUT); pinMode(SX126X_POWER_EN, OUTPUT);
digitalWrite(SX126X_POWER_EN, HIGH);
#endif #endif
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE // FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE

View File

@ -22,8 +22,8 @@ SX128xInterface<T>::SX128xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
template <typename T> bool SX128xInterface<T>::init() template <typename T> bool SX128xInterface<T>::init()
{ {
#ifdef SX128X_POWER_EN #ifdef SX128X_POWER_EN
digitalWrite(SX128X_POWER_EN, HIGH);
pinMode(SX128X_POWER_EN, OUTPUT); pinMode(SX128X_POWER_EN, OUTPUT);
digitalWrite(SX128X_POWER_EN, HIGH);
#endif #endif
#ifdef RF95_FAN_EN #ifdef RF95_FAN_EN
@ -32,12 +32,12 @@ template <typename T> bool SX128xInterface<T>::init()
#endif #endif
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
pinMode(SX128X_RXEN, OUTPUT); pinMode(SX128X_RXEN, OUTPUT);
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
#endif #endif
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) #if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC)
digitalWrite(SX128X_TXEN, LOW);
pinMode(SX128X_TXEN, OUTPUT); pinMode(SX128X_TXEN, OUTPUT);
digitalWrite(SX128X_TXEN, LOW);
#endif #endif
RadioLibInterface::init(); RadioLibInterface::init();

View File

@ -43,7 +43,18 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
Used for nodes dedicated for connection to an ATAK EUD. Used for nodes dedicated for connection to an ATAK EUD.
Turns off many of the routine broadcasts to favor CoT packet stream Turns off many of the routine broadcasts to favor CoT packet stream
from the Meshtastic ATAK plugin -> IMeshService -> Node */ from the Meshtastic ATAK plugin -> IMeshService -> Node */
meshtastic_Config_DeviceConfig_Role_TAK = 7 meshtastic_Config_DeviceConfig_Role_TAK = 7,
/* Client Hidden device role
Used for nodes that "only speak when spoken to"
Turns all of the routine broadcasts but allows for ad-hoc communication
Still rebroadcasts, but with local only rebroadcast mode (known meshes only)
Can be used for clandestine operation or to dramatically reduce airtime / power consumption */
meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN = 8,
/* Lost and Found device role
Used to automatically send a text message to the mesh
with the current position of the device on a frequent interval:
"I'm lost! Position: lat / long" */
meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND = 9
} meshtastic_Config_DeviceConfig_Role; } meshtastic_Config_DeviceConfig_Role;
/* Defines the device's behavior for how messages are rebroadcast */ /* Defines the device's behavior for how messages are rebroadcast */
@ -56,7 +67,10 @@ typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode {
meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING = 1, meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING = 1,
/* Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. /* Ignores observed messages from foreign meshes that are open or those which it cannot decrypt.
Only rebroadcasts message on the nodes local primary / secondary channels. */ Only rebroadcasts message on the nodes local primary / secondary channels. */
meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY = 2 meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY = 2,
/* Ignores observed messages from foreign meshes like LOCAL_ONLY,
but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB) */
meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY = 3
} meshtastic_Config_DeviceConfig_RebroadcastMode; } meshtastic_Config_DeviceConfig_RebroadcastMode;
/* Bit field of boolean configuration options, indicating which optional /* Bit field of boolean configuration options, indicating which optional
@ -479,12 +493,12 @@ extern "C" {
/* Helper constants for enums */ /* Helper constants for enums */
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT #define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_TAK #define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND
#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_TAK+1)) #define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND+1))
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY+1)) #define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY+1))
#define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET #define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET
#define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED #define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED

View File

@ -67,6 +67,10 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_STATION_G1 = 25, meshtastic_HardwareModel_STATION_G1 = 25,
/* RAK11310 (RP2040 + SX1262) */ /* RAK11310 (RP2040 + SX1262) */
meshtastic_HardwareModel_RAK11310 = 26, meshtastic_HardwareModel_RAK11310 = 26,
/* Makerfabs SenseLoRA Receiver (RP2040 + RFM96) */
meshtastic_HardwareModel_SENSELORA_RP2040 = 27,
/* Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) */
meshtastic_HardwareModel_SENSELORA_S3 = 28,
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
Less common/prototype boards listed here (needs one more byte over the air) Less common/prototype boards listed here (needs one more byte over the air)
--------------------------------------------------------------------------- */ --------------------------------------------------------------------------- */

View File

@ -5,7 +5,7 @@
#include "main.h" #include "main.h"
#include "mesh/http/ContentHelper.h" #include "mesh/http/ContentHelper.h"
#include "mesh/http/WebServer.h" #include "mesh/http/WebServer.h"
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include "mqtt/JSON.h" #include "mqtt/JSON.h"
#include "power.h" #include "power.h"
#include "sleep.h" #include "sleep.h"

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer); void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
// Declare some handler functions for the various URLs on the server // Declare some handler functions for the various URLs on the server

View File

@ -1,6 +1,6 @@
#include "mesh/http/ContentHelper.h" #include "mesh/http/ContentHelper.h"
//#include <Arduino.h> // #include <Arduino.h>
//#include "main.h" // #include "main.h"
void replaceAll(std::string &str, const std::string &from, const std::string &to) void replaceAll(std::string &str, const std::string &from, const std::string &to)
{ {

View File

@ -2,7 +2,7 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "graphics/Screen.h" #include "graphics/Screen.h"
#include "main.h" #include "main.h"
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include "sleep.h" #include "sleep.h"
#include <HTTPBodyParser.hpp> #include <HTTPBodyParser.hpp>
#include <HTTPMultipartBodyParser.hpp> #include <HTTPMultipartBodyParser.hpp>

View File

@ -1,17 +1,20 @@
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h" #include "RTC.h"
#include "concurrency/Periodic.h" #include "concurrency/Periodic.h"
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#include "mesh/api/WiFiServerAPI.h" #include "mesh/api/WiFiServerAPI.h"
#include "mesh/http/WebServer.h"
#include "mqtt/MQTT.h" #include "mqtt/MQTT.h"
#include "target_specific.h" #include "target_specific.h"
#include <ESPmDNS.h>
#include <WiFi.h> #include <WiFi.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
#ifdef ARCH_ESP32
#include "mesh/http/WebServer.h"
#include <ESPmDNS.h>
#include <esp_wifi.h> #include <esp_wifi.h>
static void WiFiEvent(WiFiEvent_t event);
#endif
#ifndef DISABLE_NTP #ifndef DISABLE_NTP
#include <NTPClient.h> #include <NTPClient.h>
@ -19,8 +22,6 @@
using namespace concurrency; using namespace concurrency;
static void WiFiEvent(WiFiEvent_t event);
// NTP // NTP
WiFiUDP ntpUDP; WiFiUDP ntpUDP;
@ -44,6 +45,65 @@ Syslog syslog(syslogClient);
Periodic *wifiReconnect; Periodic *wifiReconnect;
static void onNetworkConnected()
{
if (!APStartupComplete) {
// Start web server
LOG_INFO("Starting network services\n");
#ifdef ARCH_ESP32
// start mdns
if (!MDNS.begin("Meshtastic")) {
LOG_ERROR("Error setting up MDNS responder!\n");
} else {
LOG_INFO("mDNS responder started\n");
LOG_INFO("mDNS Host: Meshtastic.local\n");
MDNS.addService("http", "tcp", 80);
MDNS.addService("https", "tcp", 443);
}
#else // ESP32 handles this in WiFiEvent
LOG_INFO("Obtained IP address: %s\n", WiFi.localIP().toString().c_str());
#endif
#ifndef DISABLE_NTP
LOG_INFO("Starting NTP time client\n");
timeClient.begin();
timeClient.setUpdateInterval(60 * 60); // Update once an hour
#endif
if (config.network.rsyslog_server[0]) {
LOG_INFO("Starting Syslog client\n");
// Defaults
int serverPort = 514;
const char *serverAddr = config.network.rsyslog_server;
String server = String(serverAddr);
int delimIndex = server.indexOf(':');
if (delimIndex > 0) {
String port = server.substring(delimIndex + 1, server.length());
server[delimIndex] = 0;
serverPort = port.toInt();
serverAddr = server.c_str();
}
syslog.server(serverAddr, serverPort);
syslog.deviceHostname(getDeviceName());
syslog.appName("Meshtastic");
syslog.defaultPriority(LOGLEVEL_USER);
syslog.enable();
}
#ifdef ARCH_ESP32
initWebServer();
#endif
initApiServer();
APStartupComplete = true;
}
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
if (mqtt)
mqtt->reconnect();
}
static int32_t reconnectWiFi() static int32_t reconnectWiFi()
{ {
const char *wifiName = config.network.wifi_ssid; const char *wifiName = config.network.wifi_ssid;
@ -57,7 +117,11 @@ static int32_t reconnectWiFi()
needReconnect = false; needReconnect = false;
// Make sure we clear old connection credentials // Make sure we clear old connection credentials
#ifdef ARCH_ESP32
WiFi.disconnect(false, true); WiFi.disconnect(false, true);
#else
WiFi.disconnect(false);
#endif
LOG_INFO("Reconnecting to WiFi access point %s\n", wifiName); LOG_INFO("Reconnecting to WiFi access point %s\n", wifiName);
delay(5000); delay(5000);
@ -87,8 +151,16 @@ static int32_t reconnectWiFi()
#endif #endif
if (config.network.wifi_enabled && !WiFi.isConnected()) { if (config.network.wifi_enabled && !WiFi.isConnected()) {
#ifdef ARCH_RP2040 // (ESP32 handles this in WiFiEvent)
/* If APStartupComplete, but we're not connected, try again.
Shouldn't try again before APStartupComplete. */
needReconnect = APStartupComplete;
#endif
return 1000; // check once per second return 1000; // check once per second
} else { } else {
#ifdef ARCH_RP2040
onNetworkConnected(); // will only do anything once
#endif
return 300000; // every 5 minutes return 300000; // every 5 minutes
} }
} }
@ -109,66 +181,17 @@ void deinitWifi()
LOG_INFO("WiFi deinit\n"); LOG_INFO("WiFi deinit\n");
if (isWifiAvailable()) { if (isWifiAvailable()) {
#ifdef ARCH_ESP32
WiFi.disconnect(true, false);
#else
WiFi.disconnect(true); WiFi.disconnect(true);
WiFi.mode(WIFI_MODE_NULL); #endif
WiFi.mode(WIFI_OFF);
LOG_INFO("WiFi Turned Off\n"); LOG_INFO("WiFi Turned Off\n");
// WiFi.printDiag(Serial); // WiFi.printDiag(Serial);
} }
} }
static void onNetworkConnected()
{
if (!APStartupComplete) {
// Start web server
LOG_INFO("Starting network services\n");
// start mdns
if (!MDNS.begin("Meshtastic")) {
LOG_ERROR("Error setting up MDNS responder!\n");
} else {
LOG_INFO("mDNS responder started\n");
LOG_INFO("mDNS Host: Meshtastic.local\n");
MDNS.addService("http", "tcp", 80);
MDNS.addService("https", "tcp", 443);
}
#ifndef DISABLE_NTP
LOG_INFO("Starting NTP time client\n");
timeClient.begin();
timeClient.setUpdateInterval(60 * 60); // Update once an hour
#endif
if (config.network.rsyslog_server[0]) {
LOG_INFO("Starting Syslog client\n");
// Defaults
int serverPort = 514;
const char *serverAddr = config.network.rsyslog_server;
String server = String(serverAddr);
int delimIndex = server.indexOf(':');
if (delimIndex > 0) {
String port = server.substring(delimIndex + 1, server.length());
server[delimIndex] = 0;
serverPort = port.toInt();
serverAddr = server.c_str();
}
syslog.server(serverAddr, serverPort);
syslog.deviceHostname(getDeviceName());
syslog.appName("Meshtastic");
syslog.defaultPriority(LOGLEVEL_USER);
syslog.enable();
}
initWebServer();
initApiServer();
APStartupComplete = true;
}
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
if (mqtt)
mqtt->reconnect();
}
// Startup WiFi // Startup WiFi
bool initWifi() bool initWifi()
{ {
@ -177,10 +200,10 @@ bool initWifi()
const char *wifiName = config.network.wifi_ssid; const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk; const char *wifiPsw = config.network.wifi_psk;
createSSLCert(); #ifndef ARCH_RP2040
createSSLCert(); // For WebServer
esp_wifi_set_storage(WIFI_STORAGE_RAM); // Disable flash storage for WiFi credentials esp_wifi_set_storage(WIFI_STORAGE_RAM); // Disable flash storage for WiFi credentials
#endif
if (!*wifiPsw) // Treat empty password as no password if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL; wifiPsw = NULL;
@ -189,17 +212,17 @@ bool initWifi()
getMacAddr(dmac); getMacAddr(dmac);
snprintf(ourHost, sizeof(ourHost), "Meshtastic-%02x%02x", dmac[4], dmac[5]); snprintf(ourHost, sizeof(ourHost), "Meshtastic-%02x%02x", dmac[4], dmac[5]);
WiFi.mode(WIFI_MODE_STA); WiFi.mode(WIFI_STA);
WiFi.setHostname(ourHost); WiFi.setHostname(ourHost);
WiFi.onEvent(WiFiEvent);
WiFi.setAutoReconnect(true);
WiFi.setSleep(false);
if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC && if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC &&
config.network.ipv4_config.ip != 0) { config.network.ipv4_config.ip != 0) {
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet, WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet,
config.network.ipv4_config.dns, config.network.ipv4_config.dns);
config.network.ipv4_config.dns); // Wifi wants two DNS servers... set both to the same value
} }
#ifndef ARCH_RP2040
WiFi.onEvent(WiFiEvent);
WiFi.setAutoReconnect(true);
WiFi.setSleep(false);
// This is needed to improve performance. // This is needed to improve performance.
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
@ -218,7 +241,7 @@ bool initWifi()
wifiDisconnectReason = info.wifi_sta_disconnected.reason; wifiDisconnectReason = info.wifi_sta_disconnected.reason;
}, },
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED); WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
#endif
LOG_DEBUG("JOINING WIFI soon: ssid=%s\n", wifiName); LOG_DEBUG("JOINING WIFI soon: ssid=%s\n", wifiName);
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi); wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
} }
@ -229,6 +252,7 @@ bool initWifi()
} }
} }
#ifdef ARCH_ESP32
// Called by the Espressif SDK to // Called by the Espressif SDK to
static void WiFiEvent(WiFiEvent_t event) static void WiFiEvent(WiFiEvent_t event)
{ {
@ -262,11 +286,11 @@ static void WiFiEvent(WiFiEvent_t event)
LOG_INFO("Authentication mode of access point has changed\n"); LOG_INFO("Authentication mode of access point has changed\n");
break; break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP:
LOG_INFO("Obtained IP address: ", WiFi.localIPv6()); LOG_INFO("Obtained IP address: %s\n", WiFi.localIP().toString().c_str());
onNetworkConnected(); onNetworkConnected();
break; break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
LOG_INFO("Obtained IP6 address: %s", WiFi.localIPv6()); LOG_INFO("Obtained IP6 address: %s\n", WiFi.localIPv6().toString().c_str());
break; break;
case ARDUINO_EVENT_WIFI_STA_LOST_IP: case ARDUINO_EVENT_WIFI_STA_LOST_IP:
LOG_INFO("Lost IP address and IP address is reset to 0\n"); LOG_INFO("Lost IP address and IP address is reset to 0\n");
@ -369,6 +393,7 @@ static void WiFiEvent(WiFiEvent_t event)
break; break;
} }
} }
#endif
uint8_t getWifiDisconnectReason() uint8_t getWifiDisconnectReason()
{ {

View File

@ -5,7 +5,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <functional> #include <functional>
#ifdef ARCH_ESP32 #if defined(HAS_WIFI) && !defined(ARCH_PORTDUINO)
#include <WiFi.h> #include <WiFi.h>
#endif #endif

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "ProtobufModule.h" #include "ProtobufModule.h"
#ifdef ARCH_ESP32 #if HAS_WIFI
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#endif #endif
/** /**

View File

@ -89,7 +89,7 @@ int32_t NodeInfoModule::runOnce()
bool requestReplies = currentGeneration != radioGeneration; bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration; currentGeneration = radioGeneration;
if (airTime->isTxAllowedAirUtil()) { if (airTime->isTxAllowedAirUtil() && config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN) {
LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies); LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies);
sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies) sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
} }

View File

@ -46,5 +46,6 @@ void RoutingModule::sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketI
RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg) RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg)
{ {
isPromiscuous = true; isPromiscuous = true;
encryptedOk = config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY; encryptedOk = config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY &&
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY;
} }

View File

@ -18,7 +18,8 @@ int32_t DeviceTelemetryModule::runOnce()
if (((lastSentToMesh == 0) || if (((lastSentToMesh == 0) ||
((now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval))) && ((now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval))) &&
airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil() && airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil() &&
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) { config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN) {
sendTelemetry(); sendTelemetry();
lastSentToMesh = now; lastSentToMesh = now;
} else if (service.isToPhoneQueueEmpty()) { } else if (service.isToPhoneQueueEmpty()) {

View File

@ -97,9 +97,9 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = lps22hbSensor.runOnce(); result = lps22hbSensor.runOnce();
if (sht31Sensor.hasSensor()) if (sht31Sensor.hasSensor())
result = sht31Sensor.runOnce(); result = sht31Sensor.runOnce();
if (ina219Sensor.hasSensor() && !ina219Sensor.isInitialized()) if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce(); result = ina219Sensor.runOnce();
if (ina260Sensor.hasSensor() && !ina260Sensor.isInitialized()) if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce(); result = ina260Sensor.runOnce();
} }
return result; return result;

View File

@ -7,9 +7,9 @@
#include "mesh/Router.h" #include "mesh/Router.h"
#include "mesh/generated/meshtastic/mqtt.pb.h" #include "mesh/generated/meshtastic/mqtt.pb.h"
#include "mesh/generated/meshtastic/telemetry.pb.h" #include "mesh/generated/meshtastic/telemetry.pb.h"
#include "mesh/http/WiFiAPClient.h"
#include "sleep.h" #include "sleep.h"
#if HAS_WIFI #if HAS_WIFI
#include "mesh/wifi/WiFiAPClient.h"
#include <WiFi.h> #include <WiFi.h>
#endif #endif
#include "mqtt/JSON.h" #include "mqtt/JSON.h"

View File

@ -186,7 +186,7 @@ void NimbleBluetooth::setupService()
// Setup the battery service // Setup the battery service
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic) BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); (uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY, 1);
NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904); NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904);
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8); batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
@ -208,8 +208,10 @@ void NimbleBluetooth::startAdvertising()
/// Given a level between 0-100, update the BLE attribute /// Given a level between 0-100, update the BLE attribute
void updateBatteryLevel(uint8_t level) void updateBatteryLevel(uint8_t level)
{ {
BatteryCharacteristic->setValue(&level, 1); if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) {
BatteryCharacteristic->notify(); BatteryCharacteristic->setValue(&level, 1);
BatteryCharacteristic->notify();
}
} }
void NimbleBluetooth::clearBonds() void NimbleBluetooth::clearBonds()

View File

@ -121,6 +121,10 @@
#define HW_VENDOR meshtastic_HardwareModel_PICOMPUTER_S3 #define HW_VENDOR meshtastic_HardwareModel_PICOMPUTER_S3
#elif defined(HELTEC_HT62) #elif defined(HELTEC_HT62)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62 #define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62
#elif defined(SENSELORA_S3)
#define HW_VENDOR meshtastic_HardwareModel_SENSELORA_S3
#elif defined(HELTEC_HT62)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -7,7 +7,7 @@
#include "nimble/NimbleBluetooth.h" #include "nimble/NimbleBluetooth.h"
#endif #endif
#include "BleOta.h" #include "BleOta.h"
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include "meshUtils.h" #include "meshUtils.h"
#include "sleep.h" #include "sleep.h"

View File

@ -211,6 +211,7 @@ void NRF52Bluetooth::shutdown()
// Shutdown bluetooth for minimum power draw // Shutdown bluetooth for minimum power draw
LOG_INFO("Disable NRF52 bluetooth\n"); LOG_INFO("Disable NRF52 bluetooth\n");
Bluefruit.Advertising.stop(); Bluefruit.Advertising.stop();
Bluefruit.setTxPower(0); // Minimum power
} }
bool NRF52Bluetooth::isConnected() bool NRF52Bluetooth::isConnected()

View File

@ -25,4 +25,6 @@
#define HW_VENDOR meshtastic_HardwareModel_RPI_PICO #define HW_VENDOR meshtastic_HardwareModel_RPI_PICO
#elif defined(RAK11310) #elif defined(RAK11310)
#define HW_VENDOR meshtastic_HardwareModel_RAK11310 #define HW_VENDOR meshtastic_HardwareModel_RAK11310
#elif defined(SENSELORA_RP2040)
#define HW_VENDOR meshtastic_HardwareModel_SENSELORA_RP2040
#endif #endif

View File

@ -11,7 +11,7 @@
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "esp32/pm.h" #include "esp32/pm.h"
#include "esp_pm.h" #include "esp_pm.h"
#include "mesh/http/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#include "rom/rtc.h" #include "rom/rtc.h"
#include <driver/rtc_io.h> #include <driver/rtc_io.h>
#include <driver/uart.h> #include <driver/uart.h>

View File

@ -18,6 +18,7 @@
// Radio // Radio
#define USE_SX1262 // E22-900M30S uses SX1262 #define USE_SX1262 // E22-900M30S uses SX1262
#define USE_SX1268 // E22-400M30S uses SX1268
#define SX126X_MAX_POWER \ #define SX126X_MAX_POWER \
22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA) 22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA)
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V #define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V

View File

@ -8,8 +8,10 @@ upload_protocol = picotool
build_flags = ${rp2040_base.build_flags} build_flags = ${rp2040_base.build_flags}
-DRPI_PICO -DRPI_PICO
-Ivariants/rpipicow -Ivariants/rpipicow
-DDEBUG_RP2040_PORT=Serial
-DHW_SPI1_DEVICE -DHW_SPI1_DEVICE
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus" -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
-fexceptions # for exception handling in MQTT
build_src_filter = ${rp2040_base.build_src_filter} +<mesh/wifi/>
lib_deps = lib_deps =
${rp2040_base.lib_deps} ${rp2040_base.lib_deps}
${networking_base.lib_deps}

View File

@ -4,6 +4,10 @@
#define ARDUINO_ARCH_AVR #define ARDUINO_ARCH_AVR
#ifndef HAS_WIFI
#define HAS_WIFI 1
#endif
#define USE_SH1106 1 #define USE_SH1106 1
// default I2C pins: // default I2C pins:

View File

@ -0,0 +1,50 @@
#pragma once
#define PIN_A0 (26u)
#define PIN_A1 (27u)
#define PIN_A2 (28u)
#define PIN_A3 (29u)
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
// LEDs
#define PIN_LED (23u)
#define PIN_LED1 PIN_LED
#define LED_BUILTIN PIN_LED
#define ADC_RESOLUTION 12
// Serial
#define PIN_SERIAL1_TX (0ul)
#define PIN_SERIAL1_RX (1ul)
#define PIN_SERIAL2_TX (4ul)
#define PIN_SERIAL2_RX (5ul)
// SPI
#define PIN_SPI0_MISO (16u)
#define PIN_SPI0_MOSI (19u)
#define PIN_SPI0_SCK (18u)
#define PIN_SPI0_SS (17u)
// Wire
#define PIN_WIRE0_SDA (6u)
#define PIN_WIRE0_SCL (7u)
#define PIN_WIRE1_SDA (-1)
#define PIN_WIRE1_SCL (-1)
#define SERIAL_HOWMANY (3u)
#define SPI_HOWMANY (2u)
#define WIRE_HOWMANY (1u)
static const uint8_t SS = PIN_SPI0_SS;
static const uint8_t MOSI = PIN_SPI0_MOSI;
static const uint8_t MISO = PIN_SPI0_MISO;
static const uint8_t SCK = PIN_SPI0_SCK;
static const uint8_t SDA = PIN_WIRE0_SDA;
static const uint8_t SCL = PIN_WIRE0_SCL;

View File

@ -0,0 +1,13 @@
[env:senselora_rp2040]
extends = rp2040_base
board = rpipico
upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
-DSENSELORA_RP2040
-Ivariants/senselora_rp2040
-DDEBUG_RP2040_PORT=Serial
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}

View File

@ -0,0 +1,26 @@
#define ARDUINO_ARCH_AVR
#define USE_SSD1306
#define BUTTON_PIN 2
#define BUTTON_NEED_PULLUP
#define LED_PIN PIN_LED
#undef BATTERY_PIN
#undef LORA_SCK
#undef LORA_MISO
#undef LORA_MOSI
#undef LORA_CS
#define USE_RF95
#define LORA_SCK PIN_SPI0_SCK
#define LORA_MISO PIN_SPI0_MISO
#define LORA_MOSI PIN_SPI0_MOSI
#define LORA_CS PIN_SPI0_SS
#define LORA_DIO0 21
#define LORA_DIO1 22
#define LORA_DIO2 RADIOLIB_NC
#define LORA_RESET 20

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 2 minor = 2
build = 14 build = 16