Compare commits

...

26 Commits

Author SHA1 Message Date
vidplace7
e8e6b39bc9 Add libuv to GitHub Actions 2025-03-18 15:12:29 -04:00
Jorropo
bf7afd657a replace symlink to point to my fork
Allows anyone to test the PR
2025-03-18 20:03:38 +01:00
vidplace7
ca951caa38 Add libuv to Linux packaging 2025-03-18 20:03:38 +01:00
Jorropo
16a1c9f148 Add UDP multicast support on linux.
We tested it an it works.

This is really hacky to say the least.
2025-03-18 20:03:38 +01:00
Jorropo
af8b64e84e pass pointer to UDP multicast packet to protobuf decoder (#6333)
The packet.readBytes API is not available on all targets:
- RP2040 & RP2340
- yet to be written portduino API

Instead pass the data buffer as-is.
It also removes a memcpy which do not need to exists.

I've tested it successfully on a tbeam.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-03-16 19:36:33 -05:00
Jorropo
96ba94843b Send UDP packets to multicast address rather than broadcast address (#6331)
A smart router or switch is able to snoop the multicast address to
only send the packets to nodes listening on the multicast address.

Before all machines reachable on the L2 layer would receive the packet.
2025-03-16 19:36:02 -05:00
Thomas Göttgens
2d565c2921 trunk'd 2025-03-16 16:18:12 +01:00
HarukiToreda
2525111c39 E-ink partial refresh limitation removed for free text screen (#6201) 2025-03-16 16:15:33 +01:00
dylanli
64b9cfe199 update seeed-xiao-nrf52840-kit board defination (#6318)
- Due to the lack of pins, we have temporarily removed the button. There are some technical solutions that can solve this problem, and we are currently exploring and researching them
2025-03-16 16:04:24 +01:00
Ben Meadors
dc100e4d3e Cleanup 2025-03-16 08:19:46 -05:00
Thomas Göttgens
1640fb105d new device: Lilygo T-Eth-Elite (#6321) 2025-03-15 14:15:35 +01:00
github-actions[bot]
99e42b4d22 [create-pull-request] automated change (#6323)
Co-authored-by: caveman99 <25002+caveman99@users.noreply.github.com>
2025-03-15 07:03:53 -05:00
Thomas Göttgens
79233fe99d mainline tlora v3 (#6322) 2025-03-15 11:30:58 +01:00
Chris Danis
f66784ed2a Don't allow is_managed without any valid admin_keys (#6310) 2025-03-14 10:10:38 -05:00
github-actions[bot]
f198d5d49f Upgrade trunk to 1.22.11 (#6316)
Co-authored-by: sachaw <11172820+sachaw@users.noreply.github.com>
2025-03-14 06:58:08 -05:00
dependabot[bot]
4d34b3d73c Bump dorny/test-reporter from 1.9.1 to 2.0.0 in /.github/workflows (#6309)
Bumps [dorny/test-reporter](https://github.com/dorny/test-reporter) from 1.9.1 to 2.0.0.
- [Release notes](https://github.com/dorny/test-reporter/releases)
- [Changelog](https://github.com/dorny/test-reporter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dorny/test-reporter/compare/v1.9.1...v2.0.0)

---
updated-dependencies:
- dependency-name: dorny/test-reporter
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-13 08:32:49 -05:00
paragonnov
8efe8a2ea3 Fix KR920's Tx power limitation (#6307) 2025-03-13 18:14:41 +08:00
Kalle Lilja
499ea56e3b update devcontainer (#6299) 2025-03-12 15:32:34 -05:00
Ben Meadors
2473af6995 45 days stale 2025-03-12 12:43:55 -05:00
github-actions[bot]
508ab171d6 Upgrade trunk (#6295)
Co-authored-by: sachaw <11172820+sachaw@users.noreply.github.com>
2025-03-12 06:22:24 -05:00
Manuel
ec59f7d7dd fix packet queue full (#6292) 2025-03-11 18:59:44 -05:00
Kalle Lilja
f4c79530ec update gitattributes for windows (#6289) 2025-03-11 13:05:51 -05:00
Mark Trevor Birss
e9effb9fff Update platformio.ini (#6286) 2025-03-11 15:45:20 +02:00
Mark Trevor Birss
cb6dfb66d2 Update ME25LS01/MS24SF1 comment out upload port (#6285)
* Update platformio.ini

* Update platformio.ini

* Update platformio.ini
2025-03-11 14:56:12 +02:00
github-actions[bot]
8795a63427 Upgrade trunk (#6283)
Co-authored-by: sachaw <11172820+sachaw@users.noreply.github.com>
2025-03-11 06:26:45 -05:00
Mark Trevor Birss
186e509607 Update esp32-s3-pico.json (#6284)
* Update esp32-s3-pico.json

* Update esp32-s3-pico.json
2025-03-11 13:11:11 +02:00
59 changed files with 439 additions and 142 deletions

View File

@@ -29,7 +29,11 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
gpg \
gnupg2 \
libusb-1.0-0-dev \
libuv1-dev \
libi2c-dev \
libxcb-xkb-dev \
libxkbcommon-dev \
libinput-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN pipx install platformio

6
.gitattributes vendored
View File

@@ -1,5 +1,5 @@
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.{ps1,[pP][sS]} text eol=crlf
*.cmd text eol=crlf
*.bat text eol=crlf
*.ps1 text eol=crlf
*.{sh,[sS][hH]} text eol=lf

View File

@@ -20,7 +20,7 @@ runs:
shell: bash
run: |
sudo apt-get -y update --fix-missing
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev libuv1-dev lsb-release
- name: Setup Python
uses: actions/setup-python@v5

View File

@@ -11,4 +11,4 @@ runs:
- name: Install libs needed for native build
shell: bash
run: |
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev libuv1-dev

View File

@@ -18,5 +18,6 @@ jobs:
- name: Stale PR+Issues
uses: actions/stale@v9.1.0
with:
days-before-stale: 45
exempt-issue-labels: pinned,3.0
exempt-pr-labels: pinned,3.0

View File

@@ -143,7 +143,7 @@ jobs:
merge-multiple: true
- name: Test Report
uses: dorny/test-reporter@v1.9.1
uses: dorny/test-reporter@v2.0.0
with:
name: PlatformIO Tests
path: testreport.xml

View File

@@ -1,6 +1,6 @@
version: 0.1
cli:
version: 1.22.10
version: 1.22.11
plugins:
sources:
- id: trunk
@@ -9,14 +9,14 @@ plugins:
lint:
enabled:
- prettier@3.5.3
- trufflehog@3.88.15
- yamllint@1.35.1
- trufflehog@3.88.17
- yamllint@1.36.0
- bandit@1.8.3
- checkov@3.2.382
- checkov@3.2.386
- terrascan@1.19.9
- trivy@0.60.0
- taplo@0.9.3
- ruff@0.9.9
- ruff@0.10.0
- isort@6.0.1
- markdownlint@0.44.0
- oxipng@9.1.4

View File

@@ -13,7 +13,7 @@ ENV TZ=Etc/UTC
ENV PIP_ROOT_USER_ACTION=ignore
RUN apt-get update && apt-get install --no-install-recommends -y \
wget g++ zip git ca-certificates \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir -U platformio \
@@ -38,7 +38,7 @@ ENV TZ=Etc/UTC
USER root
RUN apt-get update && apt-get --no-install-recommends -y install \
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 \
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev liborcania2.3 libulfius2.7 libssl3 \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \

View File

@@ -9,7 +9,7 @@ FROM python:3.13-alpine3.21 AS builder
ENV PIP_ROOT_USER_ACTION=ignore
RUN apk --no-cache add \
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone \
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
&& rm -rf /var/cache/apk/* \
&& pip install --no-cache-dir -U platformio \
&& mkdir /tmp/firmware
@@ -32,7 +32,7 @@ FROM alpine:3.21
USER root
RUN apk --no-cache add \
libstdc++ libgpiod yaml-cpp libusb i2c-tools \
libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
&& rm -rf /var/cache/apk/* \
&& mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \

View File

@@ -1,6 +1,6 @@
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated).
[portduino_base]
platform = https://github.com/meshtastic/platform-native.git#562d189828f09fbf4c4093b3c0104bae9d8e9ff9
platform = https://github.com/Jorropo/platform-native.git#17fa89daec4402af491512f75278a7fec8a5818c
framework = arduino
build_src_filter =
@@ -34,10 +34,12 @@ build_flags =
-Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED
-DPORTDUINO_LINUX_HARDWARE
-DHAS_UDP_MULTICAST
-lpthread
-lstdc++fs
-lbluetooth
-lgpiod
-lyaml-cpp
-li2c
-luv
-std=c++17

View File

@@ -7,13 +7,15 @@
"core": "esp32",
"extra_flags": [
"-DARDUINO_ESP32S3_DEV",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
"-DARDUINO_EVENT_RUNNING_CORE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DBOARD_HAS_PSRAM"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "esp32s3"

1
debian/control vendored
View File

@@ -17,6 +17,7 @@ Build-Depends: debhelper-compat (= 13),
libbluetooth-dev,
libusb-1.0-0-dev,
libi2c-dev,
libuv1-dev,
openssl,
libssl-dev,
libulfius-dev,

View File

@@ -36,6 +36,7 @@ BuildRequires: pkgconfig(libgpiod)
BuildRequires: pkgconfig(bluez)
BuildRequires: pkgconfig(libusb-1.0)
BuildRequires: libi2c-devel
BuildRequires: pkgconfig(libuv)
# Web components:
BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(liborcania)

View File

@@ -121,10 +121,15 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...);
// Default Bluetooth PIN
#define defaultBLEPin 123456
#if HAS_ETHERNET
#if HAS_ETHERNET && !defined(USE_WS5500)
#include <RAK13800_W5100S.h>
#endif // HAS_ETHERNET
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
#if HAS_WIFI
#include <WiFi.h>
#endif // HAS_WIFI
@@ -164,4 +169,4 @@ class Syslog
bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0)));
};
#endif // HAS_ETHERNET || HAS_WIFI
#endif // HAS_NETWORKING

View File

@@ -32,6 +32,11 @@
#include <WiFi.h>
#endif
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
#endif
#ifndef DELAY_FOREVER

View File

@@ -11,12 +11,18 @@ static File openFile(const char *filename, bool fullAtomic)
FSCom.remove(filename);
return FSCom.open(filename, FILE_O_WRITE);
#endif
if (!fullAtomic)
if (!fullAtomic) {
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
}
String filenameTmp = filename;
filenameTmp += ".tmp";
// FIXME: If we are doing a full atomic write, we may need to remove the old tmp file now
// if (fullAtomic) {
// FSCom.remove(filename);
// }
// clear any previous LFS errors
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
}

View File

@@ -1104,12 +1104,16 @@ int32_t GPS::runOnce()
return (powerState == GPS_ACTIVE) ? GPS_THREAD_INTERVAL : 5000;
}
// clear the GPS rx buffer as quickly as possible
// clear the GPS rx/tx buffer as quickly as possible
void GPS::clearBuffer()
{
#ifdef ARCH_ESP32
_serial_gps->flush(false);
#else
int x = _serial_gps->available();
while (x--)
_serial_gps->read();
#endif
}
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs

View File

@@ -324,6 +324,14 @@ void EInkDynamicDisplay::checkConsecutiveFastRefreshes()
if (refresh != UNSPECIFIED)
return;
// Bypass limit if UNLIMITED_FAST mode is active
if (frameFlags & UNLIMITED_FAST) {
refresh = FAST;
reason = NO_OBJECTIONS;
LOG_DEBUG("refresh=FAST, reason=UNLIMITED_FAST_MODE_ACTIVE, frameFlags=0x%x", frameFlags);
return;
}
// If too many FAST refreshes consecutively - force a FULL refresh
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
refresh = FULL;

View File

@@ -23,6 +23,10 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
EInkDynamicDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus);
~EInkDynamicDisplay();
// Methods to enable or disable unlimited fast refresh mode
void enableUnlimitedFastMode() { addFrameFlag(UNLIMITED_FAST); }
void disableUnlimitedFastMode() { frameFlags = (frameFlagTypes)(frameFlags & ~UNLIMITED_FAST); }
// What kind of frame is this
enum frameFlagTypes : uint8_t {
BACKGROUND = (1 << 0), // For frames via display()
@@ -30,6 +34,7 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
COSMETIC = (1 << 2), // For splashes
DEMAND_FAST = (1 << 3), // Special case only
BLOCKING = (1 << 4), // Modifier - block while refresh runs
UNLIMITED_FAST = (1 << 5)
};
void addFrameFlag(frameFlagTypes flag);

View File

@@ -55,12 +55,12 @@ NimbleBluetooth *nimbleBluetooth = nullptr;
NRF52Bluetooth *nrf52Bluetooth = nullptr;
#endif
#if HAS_WIFI
#if HAS_WIFI || defined(USE_WS5500)
#include "mesh/api/WiFiServerAPI.h"
#include "mesh/wifi/WiFiAPClient.h"
#endif
#if HAS_ETHERNET
#if HAS_ETHERNET && !defined(USE_WS5500)
#include "mesh/api/ethServerAPI.h"
#include "mesh/eth/ethClient.h"
#endif
@@ -822,6 +822,10 @@ void setup()
#ifdef HAS_UDP_MULTICAST
LOG_DEBUG("Start multicast thread");
udpThread = new UdpMulticastThread();
#ifdef ARCH_PORTDUINO
// FIXME: portduino does not ever call onNetworkConnected so call it here because I don't know what happen if I call onNetworkConnected there
udpThread->start();
#endif
#endif
service = new MeshService();
service->init();

View File

@@ -25,7 +25,7 @@ template class LR11x0Interface<LR1121>;
template class SX126xInterface<STM32WLx>;
#endif
#if HAS_ETHERNET
#if HAS_ETHERNET && !defined(USE_WS5500)
#include "api/ethServerAPI.h"
template class ServerAPI<EthernetClient>;
template class APIServerPort<ethServerAPI, EthernetServer>;

View File

@@ -125,17 +125,15 @@ void MeshService::loop()
}
/// The radioConfig object just changed, call this to force the hw to change to the new settings
bool MeshService::reloadConfig(int saveWhat)
void MeshService::reloadConfig(int saveWhat)
{
// If we can successfully set this radio to these settings, save them to disk
// This will also update the region as needed
bool didReset = nodeDB->resetRadioConfig(); // Don't let the phone send us fatally bad settings
nodeDB->resetRadioConfig(); // Don't let the phone send us fatally bad settings
configChanged.notifyObservers(NULL); // This will cause radio hardware to change freqs etc
nodeDB->saveToDisk(saveWhat);
return didReset;
}
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh

View File

@@ -118,7 +118,7 @@ class MeshService
/** The radioConfig object just changed, call this to force the hw to change to the new settings
* @return true if client devices should be sent a new set of radio configs
*/
bool reloadConfig(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
void reloadConfig(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
void reloadOwner(bool shouldSave = true);

View File

@@ -400,18 +400,12 @@ bool isBroadcast(uint32_t dest)
return dest == NODENUM_BROADCAST || dest == NODENUM_BROADCAST_NO_LORA;
}
bool NodeDB::resetRadioConfig(bool factory_reset, bool is_fresh_install)
void NodeDB::resetRadioConfig(bool is_fresh_install)
{
bool didFactoryReset = false;
if (is_fresh_install) {
radioGeneration++;
}
if (factory_reset) {
didFactoryReset = factoryReset();
}
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
LOG_INFO("Set default channel and radio preferences!");
@@ -422,14 +416,6 @@ bool NodeDB::resetRadioConfig(bool factory_reset, bool is_fresh_install)
// Update the global myRegion
initRegion();
if (didFactoryReset) {
LOG_INFO("Reboot due to factory reset");
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + (5 * 1000);
}
return didFactoryReset;
}
bool NodeDB::factoryReset(bool eraseBleBonds)
@@ -591,7 +577,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
config.device.node_info_broadcast_secs = default_node_info_broadcast_secs;
config.security.serial_enabled = true;
config.security.admin_channel_enabled = false;
resetRadioConfig(false, true); // This also triggers NodeInfo/Position requests since we're fresh
resetRadioConfig(true); // This also triggers NodeInfo/Position requests since we're fresh
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3) || defined(SENSECAP_INDICATOR)) && \

View File

@@ -103,7 +103,7 @@ class NodeDB
* @param is_fresh_install set to true after a fresh install, to trigger NodeInfo/Position requests
* @return true if the config was completely reset, in that case, we should send it back to the client
*/
bool resetRadioConfig(bool factory_reset = false, bool is_fresh_install = false);
void resetRadioConfig(bool is_fresh_install = false);
/// given a subpacket sniffed from the network, update our DB state
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw

View File

@@ -73,9 +73,10 @@ const RegionInfo regions[] = {
RDEF(RU, 868.7f, 869.2f, 100, 0, 20, true, false, false),
/*
???
https://www.law.go.kr/LSW/admRulLsInfoP.do?admRulId=53943&efYd=0
https://resources.lora-alliance.org/technical-specifications/rp002-1-0-4-regional-parameters
*/
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false, false),
RDEF(KR, 920.0f, 923.0f, 100, 0, 23, true, false, false),
/*
Taiwan, 920-925Mhz, limited to 0.5W indoor or coastal, 1.0W outdoor.
@@ -655,7 +656,7 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
// if the sender nodenum is zero, that means uninitialized
assert(radioBuffer.header.from);
assert(p->encrypted.size <= sizeof(radioBuffer.payload));
memcpy(radioBuffer.payload, p->encrypted.bytes, p->encrypted.size);
sendingPacket = p;

View File

@@ -198,6 +198,14 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
return send(p);
}
}
/**
* Send a packet on a suitable interface.
*/
ErrorCode Router::rawSend(meshtastic_MeshPacket *p)
{
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
return iface->send(p);
}
/**
* Send a packet on a suitable interface. This routine will
@@ -319,27 +327,27 @@ void Router::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Rout
// FIXME, update nodedb here for any packet that passes through us
}
bool perhapsDecode(meshtastic_MeshPacket *p)
DecodeState perhapsDecode(meshtastic_MeshPacket *p)
{
concurrency::LockGuard g(cryptLock);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING)
return false;
return DecodeState::DECODE_FAILURE;
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
(nodeDB->getMeshNode(p->from) == NULL || !nodeDB->getMeshNode(p->from)->has_user)) {
LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet", p->from);
return false;
return DecodeState::DECODE_FAILURE;
}
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)
return true; // If packet was already decoded just return
return DecodeState::DECODE_SUCCESS; // If packet was already decoded just return
size_t rawSize = p->encrypted.size;
if (rawSize > sizeof(bytes)) {
LOG_ERROR("Packet too large to attempt decryption! (rawSize=%d > 256)", rawSize);
return false;
return DecodeState::DECODE_FATAL;
}
bool decrypted = false;
ChannelIndex chIndex = 0;
@@ -353,18 +361,22 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
if (crypto->decryptCurve25519(p->from, nodeDB->getMeshNode(p->from)->user.public_key, p->id, rawSize, p->encrypted.bytes,
bytes)) {
LOG_INFO("PKI Decryption worked!");
memset(&p->decoded, 0, sizeof(p->decoded));
meshtastic_Data decodedtmp;
memset(&decodedtmp, 0, sizeof(decodedtmp));
rawSize -= MESHTASTIC_PKC_OVERHEAD;
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded) &&
p->decoded.portnum != meshtastic_PortNum_UNKNOWN_APP) {
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp) &&
decodedtmp.portnum != meshtastic_PortNum_UNKNOWN_APP) {
decrypted = true;
LOG_INFO("Packet decrypted using PKI!");
p->pki_encrypted = true;
memcpy(&p->public_key.bytes, nodeDB->getMeshNode(p->from)->user.public_key.bytes, 32);
p->public_key.size = 32;
memcpy(&p->decoded, &decodedtmp, sizeof(meshtastic_Data_msg));
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
} else {
LOG_ERROR("PKC Decrypted, but pb_decode failed!");
return false;
return DecodeState::DECODE_FAILURE;
}
} else {
LOG_WARN("PKC decrypt attempted but failed!");
@@ -387,12 +399,15 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
// printBytes("plaintext", bytes, p->encrypted.size);
// Take those raw bytes and convert them back into a well structured protobuf we can understand
memset(&p->decoded, 0, sizeof(p->decoded));
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded)) {
meshtastic_Data decodedtmp;
memset(&decodedtmp, 0, sizeof(decodedtmp));
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp)) {
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
} else if (p->decoded.portnum == meshtastic_PortNum_UNKNOWN_APP) {
} else if (decodedtmp.portnum == meshtastic_PortNum_UNKNOWN_APP) {
LOG_ERROR("Invalid portnum (bad psk?)!");
} else {
p->decoded = decodedtmp;
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
decrypted = true;
break;
}
@@ -401,8 +416,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
}
if (decrypted) {
// parsing was successful
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
p->channel = chIndex; // change to store the index instead of the hash
p->channel = chIndex; // change to store the index instead of the hash
if (p->decoded.has_bitfield)
p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK;
@@ -434,10 +448,10 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
}
#endif
return true;
return DecodeState::DECODE_SUCCESS;
} else {
LOG_WARN("No suitable channel found for decoding, hash was 0x%x!", p->channel);
return false;
return DecodeState::DECODE_FAILURE;
}
}
@@ -592,8 +606,13 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
// Take those raw bytes and convert them back into a well structured protobuf we can understand
bool decoded = perhapsDecode(p);
if (decoded) {
auto decodedState = perhapsDecode(p);
if (decodedState == DecodeState::DECODE_FATAL) {
// Fatal decoding error, we can't do anything with this packet
LOG_WARN("Fatal decode error, dropping packet");
cancelSending(p->from, p->id);
skipHandle = true;
} else if (decodedState == DecodeState::DECODE_SUCCESS) {
// parsing was successful, queue for our recipient
if (src == RX_SRC_LOCAL)
printPacket("handleReceived(LOCAL)", p);
@@ -636,10 +655,12 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
#if !MESHTASTIC_EXCLUDE_MQTT
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
// us (because we would be able to decrypt it)
if (!decoded && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 && !isBroadcast(p->to) && !isToUs(p))
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
!isBroadcast(p->to) && !isToUs(p))
p_encrypted->pki_encrypted = true;
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
if ((decoded || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled && !isFromUs(p) && mqtt)
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
!isFromUs(p) && mqtt)
mqtt->onSend(*p_encrypted, *p, p->channel);
#endif
}

View File

@@ -85,6 +85,7 @@ class Router : protected concurrency::OSThread, protected PacketHistory
* NOTE: This method will free the provided packet (even if we return an error code)
*/
virtual ErrorCode send(meshtastic_MeshPacket *p);
virtual ErrorCode rawSend(meshtastic_MeshPacket *p);
/* Statistics for the amount of duplicate received packets and the amount of times we cancel a relay because someone did it
before us */
@@ -139,12 +140,14 @@ class Router : protected concurrency::OSThread, protected PacketHistory
void abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket *p);
};
enum DecodeState { DECODE_SUCCESS, DECODE_FAILURE, DECODE_FATAL };
/** FIXME - move this into a mesh packet class
* Remove any encryption and decode the protobufs inside this packet (if necessary).
*
* @return true for success, false for corrupt packet.
*/
bool perhapsDecode(meshtastic_MeshPacket *p);
DecodeState perhapsDecode(meshtastic_MeshPacket *p);
/** Return 0 for success or a Routing_Error code for failure
*/

View File

@@ -89,18 +89,20 @@ bool PacketAPI::receivePacket(void)
bool PacketAPI::sendPacket(void)
{
// fill dummy buffer; we don't use it, we directly send the fromRadio structure
uint32_t len = getFromRadio(txBuf);
if (len != 0) {
static uint32_t id = 0;
fromRadioScratch.id = ++id;
bool result = server->sendPacket(DataPacket<meshtastic_FromRadio>(id, fromRadioScratch));
if (!result) {
LOG_ERROR("send queue full");
if (server->available()) {
// fill dummy buffer; we don't use it, we directly send the fromRadio structure
uint32_t len = getFromRadio(txBuf);
if (len != 0) {
static uint32_t id = 0;
fromRadioScratch.id = ++id;
bool result = server->sendPacket(DataPacket<meshtastic_FromRadio>(id, fromRadioScratch));
if (!result) {
LOG_ERROR("send queue full");
}
return result;
}
return result;
} else
return false;
}
return false;
}
bool PacketAPI::notifyProgrammingMode(void)

View File

@@ -3,6 +3,11 @@
#include "ServerAPI.h"
#include <WiFi.h>
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
/**
* 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).

View File

@@ -1,7 +1,7 @@
#include "configuration.h"
#include <Arduino.h>
#if HAS_ETHERNET
#if HAS_ETHERNET && !defined(USE_WS5500)
#include "ethServerAPI.h"

View File

@@ -1,6 +1,7 @@
#pragma once
#include "ServerAPI.h"
#ifndef USE_WS5500
#include <RAK13800_W5100S.h>
/**
@@ -23,3 +24,4 @@ class ethServerPort : public APIServerPort<ethServerAPI, EthernetServer>
};
void initApiServer(int port = SERVER_API_DEFAULT_PORT);
#endif

View File

@@ -34,7 +34,7 @@ typedef enum _meshtastic_AdminMessage_ConfigType {
meshtastic_AdminMessage_ConfigType_BLUETOOTH_CONFIG = 6,
/* TODO: REPLACE */
meshtastic_AdminMessage_ConfigType_SECURITY_CONFIG = 7,
/* */
/* Session key config */
meshtastic_AdminMessage_ConfigType_SESSIONKEY_CONFIG = 8,
/* device-ui config */
meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG = 9

View File

@@ -374,7 +374,7 @@ typedef struct _meshtastic_Config_PositionConfig {
/* Power Config\
See [Power Config](/docs/settings/config/power) for additional power config details. */
typedef struct _meshtastic_Config_PowerConfig {
/* Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
/* Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.
Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles */
bool is_power_saving;
@@ -426,7 +426,7 @@ typedef struct _meshtastic_Config_NetworkConfig {
char wifi_ssid[33];
/* If set, will be use to authenticate to the named wifi */
char wifi_psk[65];
/* NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` */
/* NTP server to use if WiFi is conneced, defaults to `meshtastic.pool.ntp.org` */
char ntp_server[33];
/* Enable Ethernet */
bool eth_enabled;

View File

@@ -53,6 +53,8 @@ typedef enum _meshtastic_Language {
meshtastic_Language_NORWEGIAN = 14,
/* Slovenian */
meshtastic_Language_SLOVENIAN = 15,
/* Ukrainian */
meshtastic_Language_UKRAINIAN = 16,
/* Simplified Chinese (experimental) */
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
/* Traditional Chinese (experimental) */

View File

@@ -159,7 +159,7 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_TD_LORAC = 60,
/* CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 */
meshtastic_HardwareModel_CDEBYTE_EORA_S3 = 61,
/* TWC_MESH_V4
/* TWC_MESH_V4
Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS */
meshtastic_HardwareModel_TWC_MESH_V4 = 62,
/* NRF52_PROMICRO_DIY
@@ -228,6 +228,13 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_MESHLINK = 87,
/* Seeed XIAO nRF52840 + Wio SX1262 kit */
meshtastic_HardwareModel_XIAO_NRF52_KIT = 88,
/* Elecrow ThinkNode M1 & M2
https://www.elecrow.com/wiki/ThinkNode-M1_Transceiver_Device(Meshtastic)_Power_By_nRF52840.html
https://www.elecrow.com/wiki/ThinkNode-M2_Transceiver_Device(Meshtastic)_Power_By_NRF52840.html (this actually uses ESP32-S3) */
meshtastic_HardwareModel_THINKNODE_M1 = 89,
meshtastic_HardwareModel_THINKNODE_M2 = 90,
/* Lilygo T-ETH-Elite */
meshtastic_HardwareModel_T_ETH_ELITE = 91,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -769,7 +776,7 @@ typedef struct _meshtastic_MeshPacket {
meshtastic_MeshPacket_public_key_t public_key;
/* Indicates whether the packet was en/decrypted using PKI */
bool pki_encrypted;
/* Last byte of the node number of the node that should be used as the next hop in routing.
/* Last byte of the node number of the node that should be used as the next hop in routing.
Set by the firmware internally, clients are not supposed to set this. */
uint8_t next_hop;
/* Last byte of the node number of the node that will relay/relayed this packet.

View File

@@ -12,6 +12,11 @@
#include <WebServer.h>
#include <WiFi.h>
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
#ifdef ARCH_ESP32
#include "esp_task_wdt.h"
#endif
@@ -166,14 +171,14 @@ WebServerThread *webServerThread;
WebServerThread::WebServerThread() : concurrency::OSThread("WebServer")
{
if (!config.network.wifi_enabled) {
if (!config.network.wifi_enabled && !config.network.eth_enabled) {
disable();
}
}
int32_t WebServerThread::runOnce()
{
if (!config.network.wifi_enabled) {
if (!config.network.wifi_enabled && !config.network.eth_enabled) {
disable();
}

View File

@@ -7,6 +7,11 @@
#include <AsyncUDP.h>
#include <WiFi.h>
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
#define UDP_MULTICAST_DEFAUL_PORT 4403 // Default port for UDP multicast is same as TCP api server
#define UDP_MULTICAST_THREAD_INTERVAL_MS 15000
@@ -18,7 +23,12 @@ class UdpMulticastThread : public concurrency::OSThread
void start()
{
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT)) {
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
#if !defined(ARCH_PORTDUINO)
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
#else
LOG_DEBUG("UDP Listening");
#endif
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
} else {
LOG_DEBUG("Failed to listen on UDP");
@@ -28,12 +38,13 @@ class UdpMulticastThread : public concurrency::OSThread
void onReceive(AsyncUDPPacket packet)
{
size_t packetLength = packet.length();
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
#ifndef ARCH_PORTDUINO
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
#endif
meshtastic_MeshPacket mp;
uint8_t bytes[meshtastic_MeshPacket_size]; // Allocate buffer for the data
size_t packetSize = packet.readBytes(bytes, packet.length());
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetSize);
bool isPacketDecoded = pb_decode_from_bytes(bytes, packetLength, &meshtastic_MeshPacket_msg, &mp);
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength);
bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp);
if (isPacketDecoded && router) {
UniquePacketPoolPacket p = packetPool.allocUniqueCopy(mp);
// Unset received SNR/RSSI
@@ -45,13 +56,18 @@ class UdpMulticastThread : public concurrency::OSThread
bool onSend(const meshtastic_MeshPacket *mp)
{
if (!mp || WiFi.status() != WL_CONNECTED) {
if (!mp || !udp) {
return false;
}
#if !defined(ARCH_PORTDUINO)
if (WiFi.status() != WL_CONNECTED) {
return false;
}
#endif
LOG_DEBUG("Broadcasting packet over UDP (id=%u)", mp->id);
uint8_t buffer[meshtastic_MeshPacket_size];
size_t encodedLength = pb_encode_to_bytes(buffer, sizeof(buffer), &meshtastic_MeshPacket_msg, mp);
udp.broadcastTo(buffer, encodedLength, UDP_MULTICAST_DEFAUL_PORT);
udp.writeTo(buffer, encodedLength, udpIpAddress, UDP_MULTICAST_DEFAUL_PORT);
return true;
}

View File

@@ -9,6 +9,12 @@
#include "mesh/api/WiFiServerAPI.h"
#include "target_specific.h"
#include <WiFi.h>
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
#include <WiFiUdp.h>
#ifdef ARCH_ESP32
#if !MESHTASTIC_EXCLUDE_WEBSERVER
@@ -52,11 +58,28 @@ Syslog syslog(syslogClient);
Periodic *wifiReconnect;
#ifdef USE_WS5500
// Startup Ethernet
bool initEthernet()
{
if ((config.network.eth_enabled) && (ETH.begin(ETH_PHY_W5500, 1, ETH_CS_PIN, ETH_INT_PIN, ETH_RST_PIN, SPI3_HOST,
ETH_SCLK_PIN, ETH_MISO_PIN, ETH_MOSI_PIN))) {
WiFi.onEvent(WiFiEvent);
#if !MESHTASTIC_EXCLUDE_WEBSERVER
createSSLCert(); // For WebServer
#endif
return true;
}
return false;
}
#endif
static void onNetworkConnected()
{
if (!APStartupComplete) {
// Start web server
LOG_INFO("Start WiFi network services");
LOG_INFO("Start network services");
// start mdns
if (!MDNS.begin("Meshtastic")) {
@@ -188,6 +211,10 @@ bool isWifiAvailable()
if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
return true;
#ifdef USE_WS5500
} else if (config.network.eth_enabled) {
return true;
#endif
} else {
return false;
}
@@ -282,7 +309,7 @@ bool initWifi()
// Called by the Espressif SDK to
static void WiFiEvent(WiFiEvent_t event)
{
LOG_DEBUG("WiFi-Event %d: ", event);
LOG_DEBUG("Network-Event %d: ", event);
switch (event) {
case ARDUINO_EVENT_WIFI_READY:
@@ -377,19 +404,32 @@ static void WiFiEvent(WiFiEvent_t event)
LOG_INFO("Ethernet started");
break;
case ARDUINO_EVENT_ETH_STOP:
syslog.disable();
LOG_INFO("Ethernet stopped");
break;
case ARDUINO_EVENT_ETH_CONNECTED:
LOG_INFO("Ethernet connected");
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
syslog.disable();
LOG_INFO("Ethernet disconnected");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
LOG_INFO("Obtained IP address (ARDUINO_EVENT_ETH_GOT_IP)");
#ifdef USE_WS5500
LOG_INFO("Obtained IP address: %s, %u Mbps, %s", ETH.localIP().toString().c_str(), ETH.linkSpeed(),
ETH.fullDuplex() ? "FULL_DUPLEX" : "HALF_DUPLEX");
onNetworkConnected();
#endif
break;
case ARDUINO_EVENT_ETH_GOT_IP6:
LOG_INFO("Obtained IP6 address (ARDUINO_EVENT_ETH_GOT_IP6)");
#ifdef USE_WS5500
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
LOG_INFO("Obtained Local IP6 address: %s", ETH.linkLocalIPv6().toString().c_str());
LOG_INFO("Obtained GlobalIP6 address: %s", ETH.globalIPv6().toString().c_str());
#else
LOG_INFO("Obtained IP6 address: %s", ETH.localIPv6().toString().c_str());
#endif
#endif
break;
case ARDUINO_EVENT_SC_SCAN_DONE:
LOG_INFO("SmartConfig: Scan done");

View File

@@ -9,6 +9,11 @@
#include <WiFi.h>
#endif
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
extern bool needReconnect;
extern concurrency::Periodic *wifiReconnect;
@@ -19,4 +24,9 @@ void deinitWifi();
bool isWifiAvailable();
uint8_t getWifiDisconnectReason();
uint8_t getWifiDisconnectReason();
#ifdef USE_WS5500
// Startup Ethernet
bool initEthernet();
#endif

View File

@@ -637,6 +637,14 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
#if !MESHTASTIC_EXCLUDE_PKI
crypto->setDHPrivateKey(config.security.private_key.bytes);
#endif
if (config.security.is_managed && !(config.security.admin_key[0].size == 32 || config.security.admin_key[1].size == 32 ||
config.security.admin_key[2].size == 32)) {
config.security.is_managed = false;
const char *warning = "You must provide at least one admin public key to enable managed mode";
LOG_WARN(warning);
sendWarning(warning);
}
if (config.security.debug_log_api_enabled == c.payload_variant.security.debug_log_api_enabled &&
config.security.serial_enabled == c.payload_variant.security.serial_enabled)
requiresReboot = false;
@@ -980,7 +988,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
}
#endif
#if HAS_ETHERNET
#if HAS_ETHERNET && !defined(USE_WS5500)
conn.has_ethernet = true;
conn.ethernet.has_status = true;
if (Ethernet.linkStatus() == LinkON) {

View File

@@ -1057,6 +1057,11 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
requestFocus(); // Tell Screen::setFrames to move to our module's frame
#if defined(USE_EINK) && defined(USE_EINK_DYNAMICDISPLAY)
EInkDynamicDisplay *einkDisplay = static_cast<EInkDynamicDisplay *>(display);
einkDisplay->enableUnlimitedFastMode(); // Enable unlimited fast refresh while typing
#endif
#if defined(USE_VIRTUAL_KEYBOARD)
drawKeyboard(display, state, 0, 0);
#else

View File

@@ -46,11 +46,6 @@ meshtastic_MeshPacket *RoutingModule::allocReply()
return NULL;
assert(currentRequest);
// We only consider making replies if the request was a legit routing packet (not just something we were sniffing)
if (currentRequest->decoded.portnum == meshtastic_PortNum_ROUTING_APP) {
assert(0); // 1.2 refactoring fixme, Not sure if anything needs this yet?
// return allocDataProtobuf(u);
}
return NULL;
}

View File

@@ -19,6 +19,10 @@
#include "mesh/wifi/WiFiAPClient.h"
#include <WiFi.h>
#endif
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#endif // HAS_ETHERNET
#include "Default.h"
#if !defined(ARCH_NRF52) || NRF52_USE_JSON
#include "serialization/JSON.h"
@@ -113,7 +117,8 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
// likely they discovered each other via a channel we have downlink enabled for
if (isToUs(p.get()) || (tx && tx->has_user && rx && rx->has_user))
router->enqueueReceivedMessage(p.release());
} else if (router && perhapsDecode(p.get())) // ignore messages if we don't have the channel key
} else if (router &&
perhapsDecode(p.get()) == DecodeState::DECODE_SUCCESS) // ignore messages if we don't have the channel key
router->enqueueReceivedMessage(p.release());
}
@@ -295,6 +300,11 @@ bool connectPubSub(const PubSubConfig &config, PubSubClient &pubSub, Client &cli
inline bool isConnectedToNetwork()
{
#ifdef USE_WS5500
if (ETH.connected())
return true;
#endif
#if HAS_WIFI
return WiFi.isConnected();
#elif HAS_ETHERNET

View File

@@ -14,7 +14,7 @@
#include <WiFiClientSecure.h>
#endif
#endif
#if HAS_ETHERNET
#if HAS_ETHERNET && !defined(USE_WS5500)
#include <EthernetClient.h>
#endif

View File

@@ -176,6 +176,8 @@
#define HW_VENDOR meshtastic_HardwareModel_SEEED_XIAO_S3
#elif defined(MESH_TAB)
#define HW_VENDOR meshtastic_HardwareModel_MESH_TAB
#elif defined(T_ETH_ELITE)
#define HW_VENDOR meshtastic_HardwareModel_T_ETH_ELITE
#endif
// -----------------------------------------------------------------------------

View File

@@ -26,7 +26,9 @@
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_BLUETOOTH
void setBluetoothEnable(bool enable)
{
#if HAS_WIFI
#ifdef USE_WS5500
if ((config.bluetooth.enabled == true) && (config.network.wifi_enabled == false))
#elif HAS_WIFI
if (!isWifiAvailable() && config.bluetooth.enabled == true)
#else
if (config.bluetooth.enabled == true)

View File

@@ -12,4 +12,4 @@ lib_deps =
${nrf52840_base.lib_deps}
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
upload_protocol = nrfutil
upload_port = /dev/ttyACM1
;upload_port = /dev/ttyACM1

View File

@@ -16,4 +16,4 @@ lib_deps =
zinggjm/GxEPD2@^1.6.2
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
upload_protocol = nrfutil
upload_port = /dev/ttyACM1
;upload_port = /dev/ttyACM1

View File

@@ -12,4 +12,4 @@ lib_deps =
${nrf52840_base.lib_deps}
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
upload_protocol = nrfutil
upload_port = /dev/ttyACM1
;upload_port = /dev/ttyACM1

View File

@@ -6,7 +6,7 @@ board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board = esp32-s3-devkitc-1
upload_port = /dev/ttyUSB0
;upload_port = /dev/ttyUSB0
board_level = extra
upload_protocol = esptool
build_flags =
@@ -33,7 +33,7 @@ board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board = esp32-s3-devkitc-1
upload_port = /dev/ttyUSB0
;upload_port = /dev/ttyUSB0
board_level = extra
upload_protocol = esptool
build_flags =
@@ -60,7 +60,7 @@ board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board = esp32-s3-devkitc-1
upload_port = /dev/ttyUSB0
;upload_port = /dev/ttyUSB0
board_level = extra
upload_protocol = esptool
build_flags =

View File

@@ -1,8 +1,8 @@
#include "variant.h"
#include "configuration.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
#include "configuration.h"
#include <map>
#include <memory>
#include <stddef.h>
@@ -58,8 +58,6 @@ const uint32_t g_ADigitalPinMap[] = {
31, // D32 is P0.10 (VBAT)
};
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
@@ -80,7 +78,6 @@ const uint32_t g_ADigitalPinMap[] = {
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
void initVariant()
{
// LED1 & LED2

View File

@@ -43,7 +43,6 @@ extern "C" {
* Buttons
*/
// Digital PINs
#define D0 (0ul)
#define D1 (1ul)
@@ -57,11 +56,15 @@ extern "C" {
#define D9 (9ul)
#define D10 (10ul)
/*Due to the lack of pins,and have to make sure gps standby work well we have temporarily removed the button.
There are some technical solutions that can solve this problem,
and we are currently exploring and researching them*/
// #define BUTTON_PIN D0 // This is the Program Button
// // #define BUTTON_NEED_PULLUP 1
// #define BUTTON_ACTIVE_LOW true
// #define BUTTON_ACTIVE_PULLUP false
#define BUTTON_PIN D0 // This is the Program Button
// #define BUTTON_NEED_PULLUP 1
#define BUTTON_ACTIVE_LOW true
#define BUTTON_ACTIVE_PULLUP false
/*
* Analog pins
*/
@@ -82,7 +85,6 @@ static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;
#define ADC_RESOLUTION 12
#define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1)
@@ -95,7 +97,6 @@ static const uint8_t A5 = PIN_A5;
#define PIN_SPI_MOSI (10)
#define PIN_SPI_SCK (8)
static const uint8_t SS = D4;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
@@ -113,40 +114,36 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_TXEN RADIOLIB_NC
#define SX126X_RXEN D4
#define SX126X_DIO2_AS_RF_SWITCH // DIO2 is used to control the RF switch really necessary!!!
#define SX126X_DIO2_AS_RF_SWITCH // DIO2 is used to control the RF switch really necessary!!!
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
/*
* Wire Interfaces
*/
#define I2C_NO_RESCAN // I2C is a bit finicky, don't scan too much
#define I2C_NO_RESCAN // I2C is a bit finicky, don't scan too much
#define WIRE_INTERFACES_COUNT 1 // 2
#define PIN_WIRE_SDA (24) //change to use the correct pins if needed
#define PIN_WIRE_SCL (25) //change to use the correct pins if needed
#define PIN_WIRE_SDA (24) // change to use the correct pins if needed
#define PIN_WIRE_SCL (25) // change to use the correct pins if needed
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// GPS L76KB
#define GPS_L76K
#ifdef GPS_L76K
#define PIN_GPS_RX 32+12 // 44
#define PIN_GPS_TX 32+11 // 43
#define PIN_GPS_RX D6
#define PIN_GPS_TX D7
#define HAS_GPS 1
#define GPS_BAUDRATE 9600
#define GPS_THREAD_INTERVAL 50
#define PIN_SERIAL1_RX PIN_GPS_TX
#define PIN_SERIAL1_TX PIN_GPS_RX
#define PIN_GPS_STANDBY 2
#define PIN_GPS_STANDBY D0
#endif
// Battery
#define BAT_READ \

View File

@@ -0,0 +1,26 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x303a
#define USB_PID 0x1001
// The default Wire will be mapped to PMU and RTC
static const uint8_t SDA = 17;
static const uint8_t SCL = 18;
// Default SPI will be mapped to Radio
static const uint8_t SS = 40;
static const uint8_t MOSI = 11;
static const uint8_t MISO = 9;
static const uint8_t SCK = 10;
#define SPI_MOSI (11)
#define SPI_SCK (10)
#define SPI_MISO (9)
#define SPI_CS (12)
#define SDCARD_CS SPI_CS
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,16 @@
[env:t-eth-elite]
extends = esp32s3_base
board = esp32s3box
board_check = true
build_flags =
${esp32s3_base.build_flags}
-D T_ETH_ELITE
-I variants/t-eth-elite
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
lib_ignore =
Ethernet
lib_deps =
${esp32s3_base.lib_deps}
https://github.com/meshtastic/ETHClass2#v1.0.0

View File

@@ -0,0 +1,11 @@
#include "RadioLib.h"
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[] = {
// mode DIO5 DIO6
{LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}},
{LR11x0::MODE_TX, {LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}},
{LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}},
{LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE,
};

View File

@@ -0,0 +1,83 @@
#define HAS_SDCARD
#define SDCARD_USE_SPI1
#define HAS_GPS 1
#define GPS_RX_PIN 39
#define GPS_TX_PIN 42
#define GPS_BAUDRATE_FIXED 1
#define GPS_BAUDRATE 9600
#define I2C_SDA 17 // I2C pins for this board
#define I2C_SCL 18
#define HAS_SCREEN 1 // Allow for OLED Screens on I2C Header of shield
#define LED_PIN 38 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses,
#define BUTTON_NEED_PULLUP
// TTGO uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
// not found then probe for SX1262
#define USE_RF95 // RFM95/SX127x
#define USE_SX1262
#define USE_SX1280
#define USE_LR1121
#define LORA_SCK 10
#define LORA_MISO 9
#define LORA_MOSI 11
#define LORA_CS 40
#define LORA_RESET 46
// per SX1276_Receive_Interrupt/utilities.h
#define LORA_DIO0 8
#define LORA_DIO1 16
#define LORA_DIO2 RADIOLIB_NC
// per SX1262_Receive_Interrupt/utilities.h
#ifdef USE_SX1262
#define SX126X_CS LORA_CS
#define SX126X_DIO1 8
#define SX126X_BUSY 16
#define SX126X_RESET LORA_RESET
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif
// per SX128x_Receive_Interrupt/utilities.h
#ifdef USE_SX1280
#define SX128X_CS LORA_CS
#define SX128X_DIO1 8
#define SX128X_DIO2 33
#define SX128X_DIO3 34
#define SX128X_BUSY 16
#define SX128X_RESET LORA_RESET
#define SX128X_RXEN 13
#define SX128X_TXEN 38
#define SX128X_MAX_POWER 3
#endif
// LR1121
#ifdef USE_LR1121
#define LR1121_IRQ_PIN 8
#define LR1121_NRESET_PIN LORA_RESET
#define LR1121_BUSY_PIN 16
#define LR1121_SPI_NSS_PIN LORA_CS
#define LR1121_SPI_SCK_PIN LORA_SCK
#define LR1121_SPI_MOSI_PIN LORA_MOSI
#define LR1121_SPI_MISO_PIN LORA_MISO
#define LR11X0_DIO3_TCXO_VOLTAGE 3.0
#define LR11X0_DIO_AS_RF_SWITCH
#endif
#define HAS_ETHERNET 1
#define USE_WS5500 1 // this driver uses the same stack as the ESP32 Wifi driver
#define ETH_MISO_PIN 47
#define ETH_MOSI_PIN 21
#define ETH_SCLK_PIN 48
#define ETH_CS_PIN 45
#define ETH_INT_PIN 14
#define ETH_RST_PIN -1
#define ETH_ADDR 1

View File

@@ -1,7 +1,6 @@
[env:tlora-v3-3-0-tcxo]
extends = esp32_base
board = ttgo-lora32-v21
board_level = extra
build_flags =
${esp32_base.build_flags}
-D TLORA_V2_1_16