mirror of
https://github.com/meshtastic/firmware.git
synced 2025-07-31 02:45:41 +00:00
Merge branch 'master' into add-traceroute
This commit is contained in:
commit
d7a3dee1be
24
.github/workflows/pr_enforce_labels.yml
vendored
Normal file
24
.github/workflows/pr_enforce_labels.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
name: Check PR Labels
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, edited, labeled, unlabeled, synchronize, reopened]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: read
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-label:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Check for PR labels
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const labels = context.payload.pull_request.labels.map(label => label.name);
|
||||||
|
const requiredLabels = ['bugfix', 'enhancement', 'hardware-support', 'dependencies', 'submodules', 'github_actions', 'trunk'];
|
||||||
|
const hasRequiredLabel = labels.some(label => requiredLabels.includes(label));
|
||||||
|
if (!hasRequiredLabel) {
|
||||||
|
core.setFailed(`PR must have at least one of the following labels before it can be merged: ${requiredLabels.join(', ')}.`);
|
||||||
|
}
|
3
.github/workflows/release_channels.yml
vendored
3
.github/workflows/release_channels.yml
vendored
@ -103,8 +103,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
base: ${{ github.event.repository.default_branch }}
|
base: ${{ github.event.repository.default_branch }}
|
||||||
branch: create-pull-request/bump-version
|
branch: create-pull-request/bump-version
|
||||||
|
labels: github_actions
|
||||||
title: Bump release version
|
title: Bump release version
|
||||||
commit-message: automated bumps
|
commit-message: Automated version bumps
|
||||||
add-paths: |
|
add-paths: |
|
||||||
version.properties
|
version.properties
|
||||||
debian/changelog
|
debian/changelog
|
||||||
|
2
.github/workflows/update_protobufs.yml
vendored
2
.github/workflows/update_protobufs.yml
vendored
@ -34,7 +34,9 @@ jobs:
|
|||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v7
|
||||||
with:
|
with:
|
||||||
branch: create-pull-request/update-protobufs
|
branch: create-pull-request/update-protobufs
|
||||||
|
labels: submodules
|
||||||
title: Update protobufs and classes
|
title: Update protobufs and classes
|
||||||
|
commit-message: Update protobufs
|
||||||
add-paths: |
|
add-paths: |
|
||||||
protobufs
|
protobufs
|
||||||
src/mesh
|
src/mesh
|
||||||
|
@ -8,15 +8,15 @@ plugins:
|
|||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.450
|
- checkov@3.2.451
|
||||||
- renovate@41.30.5
|
- renovate@41.37.9
|
||||||
- prettier@3.6.2
|
- prettier@3.6.2
|
||||||
- trufflehog@3.89.2
|
- trufflehog@3.90.0
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.8.6
|
- bandit@1.8.6
|
||||||
- trivy@0.64.1
|
- trivy@0.64.1
|
||||||
- taplo@0.9.3
|
- taplo@0.9.3
|
||||||
- ruff@0.12.2
|
- ruff@0.12.3
|
||||||
- isort@6.0.1
|
- isort@6.0.1
|
||||||
- markdownlint@0.45.0
|
- markdownlint@0.45.0
|
||||||
- oxipng@9.1.5
|
- oxipng@9.1.5
|
||||||
|
@ -39,7 +39,7 @@ build_flags =
|
|||||||
-Isrc/platform/portduino
|
-Isrc/platform/portduino
|
||||||
-DRADIOLIB_EEPROM_UNSUPPORTED
|
-DRADIOLIB_EEPROM_UNSUPPORTED
|
||||||
-DPORTDUINO_LINUX_HARDWARE
|
-DPORTDUINO_LINUX_HARDWARE
|
||||||
-DHAS_UDP_MULTICAST
|
-DHAS_UDP_MULTICAST=1
|
||||||
-lpthread
|
-lpthread
|
||||||
-lstdc++fs
|
-lstdc++fs
|
||||||
-lbluetooth
|
-lbluetooth
|
||||||
|
@ -87,6 +87,9 @@
|
|||||||
</screenshots>
|
</screenshots>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
|
<release version="2.7.4" date="2025-07-19">
|
||||||
|
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.4</url>
|
||||||
|
</release>
|
||||||
<release version="2.7.3" date="2025-07-10">
|
<release version="2.7.3" date="2025-07-10">
|
||||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.3</url>
|
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.3</url>
|
||||||
</release>
|
</release>
|
||||||
|
7
debian/changelog
vendored
7
debian/changelog
vendored
@ -1,4 +1,4 @@
|
|||||||
meshtasticd (2.7.3.0) UNRELEASED; urgency=medium
|
meshtasticd (2.7.4.0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
[ Austin Lane ]
|
[ Austin Lane ]
|
||||||
* Initial packaging
|
* Initial packaging
|
||||||
@ -31,4 +31,7 @@ meshtasticd (2.7.3.0) UNRELEASED; urgency=medium
|
|||||||
[ Ubuntu ]
|
[ Ubuntu ]
|
||||||
* GitHub Actions Automatic version bump
|
* GitHub Actions Automatic version bump
|
||||||
|
|
||||||
-- Ubuntu <github-actions[bot]@users.noreply.github.com> Thu, 10 Jul 2025 16:29:27 +0000
|
[ ]
|
||||||
|
* GitHub Actions Automatic version bump
|
||||||
|
|
||||||
|
-- <github-actions[bot]@users.noreply.github.com> Sat, 19 Jul 2025 11:36:55 +0000
|
||||||
|
@ -6,7 +6,9 @@ default_envs = tbeam
|
|||||||
|
|
||||||
extra_configs =
|
extra_configs =
|
||||||
arch/*/*.ini
|
arch/*/*.ini
|
||||||
variants/*/platformio.ini
|
variants/*/platformio.ini ; Remove when all variants migrated to new dir structure
|
||||||
|
variants/*/*/platformio.ini
|
||||||
|
variants/*/diy/*/platformio.ini
|
||||||
src/graphics/niche/InkHUD/PlatformioConfig.ini
|
src/graphics/niche/InkHUD/PlatformioConfig.ini
|
||||||
|
|
||||||
description = Meshtastic
|
description = Meshtastic
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit f6448be7770a3521bf52407ff8f5fa5b9b06da7b
|
Subproject commit 15c1fbde882de953dec279160fa984d0e00569d0
|
@ -681,7 +681,16 @@ bool Power::setup()
|
|||||||
|
|
||||||
void Power::shutdown()
|
void Power::shutdown()
|
||||||
{
|
{
|
||||||
LOG_INFO("Shutting Down");
|
|
||||||
|
#if HAS_SCREEN
|
||||||
|
if (screen) {
|
||||||
|
screen->showSimpleBanner("Shutting Down...", 0); // stays on screen
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(ARCH_STM32WL)
|
||||||
|
playShutdownMelody();
|
||||||
|
#endif
|
||||||
|
nodeDB->saveToDisk();
|
||||||
|
|
||||||
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
|
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
|
||||||
#ifdef PIN_LED1
|
#ifdef PIN_LED1
|
||||||
@ -693,7 +702,11 @@ void Power::shutdown()
|
|||||||
#ifdef PIN_LED3
|
#ifdef PIN_LED3
|
||||||
ledOff(PIN_LED3);
|
ledOff(PIN_LED3);
|
||||||
#endif
|
#endif
|
||||||
doDeepSleep(DELAY_FOREVER, false, false);
|
doDeepSleep(DELAY_FOREVER, false, true);
|
||||||
|
#elif defined(ARCH_PORTDUINO)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
#else
|
||||||
|
LOG_WARN("FIXME implement shutdown for this platform");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +47,6 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
|
|||||||
playComboTune(); // Ping sent feedback
|
playComboTune(); // Ping sent feedback
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INPUT_BROKER_SHUTDOWN:
|
|
||||||
playShutdownMelody(); // Shutdown feedback
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// For other events, check if it's a printable character
|
// For other events, check if it's a printable character
|
||||||
if (event->kbchar >= 32 && event->kbchar <= 126) {
|
if (event->kbchar >= 32 && event->kbchar <= 126) {
|
||||||
@ -69,10 +65,7 @@ int32_t BuzzerFeedbackThread::runOnce()
|
|||||||
// This thread is primarily event-driven, but we can use runOnce
|
// This thread is primarily event-driven, but we can use runOnce
|
||||||
// for any periodic tasks if needed in the future
|
// for any periodic tasks if needed in the future
|
||||||
|
|
||||||
if (needsUpdate) {
|
needsUpdate = false;
|
||||||
needsUpdate = false;
|
|
||||||
// Could add any periodic processing here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run every 100ms when active, less frequently when idle
|
// Run every 100ms when active, less frequently when idle
|
||||||
return needsUpdate ? 100 : 1000;
|
return needsUpdate ? 100 : 1000;
|
||||||
|
@ -1001,7 +1001,7 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
// Insert favorite frames *after* collecting them all
|
// Insert favorite frames *after* collecting them all
|
||||||
if (!favoriteFrames.empty()) {
|
if (!favoriteFrames.empty()) {
|
||||||
fsi.positions.firstFavorite = numframes;
|
fsi.positions.firstFavorite = numframes;
|
||||||
for (auto &f : favoriteFrames) {
|
for (const auto &f : favoriteFrames) {
|
||||||
normalFrames[numframes++] = f;
|
normalFrames[numframes++] = f;
|
||||||
indicatorIcons.push_back(icon_node);
|
indicatorIcons.push_back(icon_node);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,6 @@ void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int1
|
|||||||
hour %= 12;
|
hour %= 12;
|
||||||
if (hour == 0)
|
if (hour == 0)
|
||||||
hour = 12;
|
hour = 12;
|
||||||
bool isPM = hour >= 12;
|
|
||||||
snprintf(timeString, sizeof(timeString), "%d:%02d", hour, minute);
|
snprintf(timeString, sizeof(timeString), "%d:%02d", hour, minute);
|
||||||
} else {
|
} else {
|
||||||
snprintf(timeString, sizeof(timeString), "%02d:%02d", hour, minute);
|
snprintf(timeString, sizeof(timeString), "%02d:%02d", hour, minute);
|
||||||
@ -367,7 +366,7 @@ void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
// hour hand radius and y coordinate
|
// hour hand radius and y coordinate
|
||||||
int16_t hourHandRadius = radius * 0.35;
|
int16_t hourHandRadius = radius * 0.35;
|
||||||
if (isHighResolution) {
|
if (isHighResolution) {
|
||||||
int16_t hourHandRadius = radius * 0.55;
|
hourHandRadius = radius * 0.55;
|
||||||
}
|
}
|
||||||
int16_t hourHandNoonY = centerY - hourHandRadius;
|
int16_t hourHandNoonY = centerY - hourHandRadius;
|
||||||
|
|
||||||
@ -386,7 +385,7 @@ void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
|
|
||||||
bool isPM = hour >= 12;
|
bool isPM = hour >= 12;
|
||||||
if (config.display.use_12h_clock) {
|
if (config.display.use_12h_clock) {
|
||||||
bool isPM = hour >= 12;
|
isPM = hour >= 12;
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
int yOffset = isHighResolution ? 1 : 0;
|
int yOffset = isHighResolution ? 1 : 0;
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
|
@ -825,9 +825,8 @@ void menuHandler::shutdownMenu()
|
|||||||
bannerOptions.optionsCount = 2;
|
bannerOptions.optionsCount = 2;
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
if (selected == 1) {
|
if (selected == 1) {
|
||||||
IF_SCREEN(screen->showSimpleBanner("Shutting Down...", 0));
|
InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_SHUTDOWN, .kbchar = 0, .touchX = 0, .touchY = 0};
|
||||||
nodeDB->saveToDisk();
|
inputBroker->injectInputEvent(&event);
|
||||||
power->shutdown();
|
|
||||||
} else {
|
} else {
|
||||||
menuQueue = power_menu;
|
menuQueue = power_menu;
|
||||||
screen->runNow();
|
screen->runNow();
|
||||||
|
@ -53,23 +53,21 @@ bool ButtonThread::initButton(const ButtonConfig &config)
|
|||||||
},
|
},
|
||||||
this);
|
this);
|
||||||
|
|
||||||
if (config.longPress != INPUT_BROKER_NONE) {
|
_longPress = config.longPress;
|
||||||
_longPress = config.longPress;
|
userButton.attachLongPressStart(
|
||||||
userButton.attachLongPressStart(
|
[](void *callerThread) -> void {
|
||||||
[](void *callerThread) -> void {
|
ButtonThread *thread = (ButtonThread *)callerThread;
|
||||||
ButtonThread *thread = (ButtonThread *)callerThread;
|
// if (millis() > 30000) // hold off 30s after boot
|
||||||
// if (millis() > 30000) // hold off 30s after boot
|
thread->btnEvent = BUTTON_EVENT_LONG_PRESSED;
|
||||||
thread->btnEvent = BUTTON_EVENT_LONG_PRESSED;
|
},
|
||||||
},
|
this);
|
||||||
this);
|
userButton.attachLongPressStop(
|
||||||
userButton.attachLongPressStop(
|
[](void *callerThread) -> void {
|
||||||
[](void *callerThread) -> void {
|
ButtonThread *thread = (ButtonThread *)callerThread;
|
||||||
ButtonThread *thread = (ButtonThread *)callerThread;
|
// if (millis() > 30000) // hold off 30s after boot
|
||||||
// if (millis() > 30000) // hold off 30s after boot
|
thread->btnEvent = BUTTON_EVENT_LONG_RELEASED;
|
||||||
thread->btnEvent = BUTTON_EVENT_LONG_RELEASED;
|
},
|
||||||
},
|
this);
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.doublePress != INPUT_BROKER_NONE) {
|
if (config.doublePress != INPUT_BROKER_NONE) {
|
||||||
_doublePress = config.doublePress;
|
_doublePress = config.doublePress;
|
||||||
@ -202,11 +200,11 @@ int32_t ButtonThread::runOnce()
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (_longPress != INPUT_BROKER_NONE) {
|
||||||
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
|
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
|
||||||
evt.inputEvent = _longPress;
|
evt.inputEvent = _longPress;
|
||||||
this->notifyObservers(&evt);
|
this->notifyObservers(&evt);
|
||||||
|
}
|
||||||
// Reset combination tracking
|
// Reset combination tracking
|
||||||
waitingForLongPress = false;
|
waitingForLongPress = false;
|
||||||
|
|
||||||
@ -253,7 +251,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
// may wake the board immediatedly.
|
// may wake the board immediatedly.
|
||||||
case BUTTON_EVENT_LONG_RELEASED: {
|
case BUTTON_EVENT_LONG_RELEASED: {
|
||||||
|
|
||||||
LOG_INFO("LONG PRESS RELEASE");
|
LOG_INFO("LONG PRESS RELEASE AFTER %u MILLIS", millis() - buttonPressStartTime);
|
||||||
if (millis() > 30000 && _longLongPress != INPUT_BROKER_NONE &&
|
if (millis() > 30000 && _longLongPress != INPUT_BROKER_NONE &&
|
||||||
(millis() - buttonPressStartTime) >= _longLongPressTime) {
|
(millis() - buttonPressStartTime) >= _longLongPressTime) {
|
||||||
evt.inputEvent = _longLongPress;
|
evt.inputEvent = _longLongPress;
|
||||||
|
@ -18,13 +18,13 @@ struct ButtonConfig {
|
|||||||
uint16_t longPressTime = 500;
|
uint16_t longPressTime = 500;
|
||||||
input_broker_event doublePress = INPUT_BROKER_NONE;
|
input_broker_event doublePress = INPUT_BROKER_NONE;
|
||||||
input_broker_event longLongPress = INPUT_BROKER_NONE;
|
input_broker_event longLongPress = INPUT_BROKER_NONE;
|
||||||
uint16_t longLongPressTime = 5000;
|
uint16_t longLongPressTime = 3900;
|
||||||
input_broker_event triplePress = INPUT_BROKER_NONE;
|
input_broker_event triplePress = INPUT_BROKER_NONE;
|
||||||
input_broker_event shortLong = INPUT_BROKER_NONE;
|
input_broker_event shortLong = INPUT_BROKER_NONE;
|
||||||
bool touchQuirk = false;
|
bool touchQuirk = false;
|
||||||
|
|
||||||
// Constructor to set required parameter
|
// Constructor to set required parameter
|
||||||
ButtonConfig(uint8_t pin = 0) : pinNumber(pin) {}
|
explicit ButtonConfig(uint8_t pin = 0) : pinNumber(pin) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef BUTTON_CLICK_MS
|
#ifndef BUTTON_CLICK_MS
|
||||||
@ -62,7 +62,7 @@ class ButtonThread : public Observable<const InputEvent *>, public concurrency::
|
|||||||
BUTTON_EVENT_COMBO_SHORT_LONG,
|
BUTTON_EVENT_COMBO_SHORT_LONG,
|
||||||
};
|
};
|
||||||
|
|
||||||
ButtonThread(const char *name);
|
explicit ButtonThread(const char *name);
|
||||||
int32_t runOnce() override;
|
int32_t runOnce() override;
|
||||||
OneButton userButton;
|
OneButton userButton;
|
||||||
void attachButtonInterrupts();
|
void attachButtonInterrupts();
|
||||||
|
@ -233,14 +233,7 @@ void ExpressLRSFiveWay::sendAdhocPing()
|
|||||||
// Contained as one method for easier remapping of buttons by user
|
// Contained as one method for easier remapping of buttons by user
|
||||||
void ExpressLRSFiveWay::shutdown()
|
void ExpressLRSFiveWay::shutdown()
|
||||||
{
|
{
|
||||||
LOG_INFO("Shutdown from long press");
|
sendKey(INPUT_BROKER_SHUTDOWN);
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
screen->startAlert("Shutting Down...");
|
|
||||||
// Don't set alerting = true. We don't want to auto-dismiss this alert.
|
|
||||||
|
|
||||||
playShutdownMelody(); // In case user adds a buzzer
|
|
||||||
|
|
||||||
shutdownAtMsec = millis() + 3000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressLRSFiveWay::click()
|
void ExpressLRSFiveWay::click()
|
||||||
|
@ -1042,8 +1042,9 @@ void setup()
|
|||||||
mainDelay.interruptFromISR(&higherWake);
|
mainDelay.interruptFromISR(&higherWake);
|
||||||
};
|
};
|
||||||
userConfigNoScreen.singlePress = INPUT_BROKER_USER_PRESS;
|
userConfigNoScreen.singlePress = INPUT_BROKER_USER_PRESS;
|
||||||
userConfigNoScreen.longPress = INPUT_BROKER_SHUTDOWN;
|
userConfigNoScreen.longPress = INPUT_BROKER_NONE;
|
||||||
userConfigNoScreen.longPressTime = 5000;
|
userConfigNoScreen.longPressTime = 500;
|
||||||
|
userConfigNoScreen.longLongPress = INPUT_BROKER_SHUTDOWN;
|
||||||
userConfigNoScreen.doublePress = INPUT_BROKER_SEND_PING;
|
userConfigNoScreen.doublePress = INPUT_BROKER_SEND_PING;
|
||||||
userConfigNoScreen.triplePress = INPUT_BROKER_GPS_TOGGLE;
|
userConfigNoScreen.triplePress = INPUT_BROKER_GPS_TOGGLE;
|
||||||
UserButtonThread->initButton(userConfigNoScreen);
|
UserButtonThread->initButton(userConfigNoScreen);
|
||||||
|
@ -121,7 +121,7 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id, bool t
|
|||||||
bool MeshPacketQueue::find(const NodeNum from, const PacketId id)
|
bool MeshPacketQueue::find(const NodeNum from, const PacketId id)
|
||||||
{
|
{
|
||||||
for (auto it = queue.begin(); it != queue.end(); it++) {
|
for (auto it = queue.begin(); it != queue.end(); it++) {
|
||||||
const auto p = (*it);
|
const auto *p = *it;
|
||||||
if (getFrom(p) == from && p->id == id) {
|
if (getFrom(p) == from && p->id == id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
#include "modules/NodeInfoModule.h"
|
#include "modules/NodeInfoModule.h"
|
||||||
#include "modules/PositionModule.h"
|
#include "modules/PositionModule.h"
|
||||||
|
#include "modules/RoutingModule.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -333,6 +334,21 @@ void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage
|
|||||||
fromNum++;
|
fromNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeshService::sendRoutingErrorResponse(meshtastic_Routing_Error error, const meshtastic_MeshPacket *mp)
|
||||||
|
{
|
||||||
|
if (!mp) {
|
||||||
|
LOG_WARN("Cannot send routing error response: null packet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the routing module to send the error response
|
||||||
|
if (routingModule) {
|
||||||
|
routingModule->sendAckNak(error, mp->from, mp->id, mp->channel);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Cannot send routing error response: no routing module");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MeshService::sendClientNotification(meshtastic_ClientNotification *n)
|
void MeshService::sendClientNotification(meshtastic_ClientNotification *n)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Send client notification to phone");
|
LOG_DEBUG("Send client notification to phone");
|
||||||
|
@ -148,6 +148,9 @@ class MeshService
|
|||||||
/// Send a ClientNotification to the phone
|
/// Send a ClientNotification to the phone
|
||||||
void sendClientNotification(meshtastic_ClientNotification *cn);
|
void sendClientNotification(meshtastic_ClientNotification *cn);
|
||||||
|
|
||||||
|
/// Send an error response to the phone
|
||||||
|
void sendRoutingErrorResponse(meshtastic_Routing_Error error, const meshtastic_MeshPacket *mp);
|
||||||
|
|
||||||
bool isToPhoneQueueEmpty();
|
bool isToPhoneQueueEmpty();
|
||||||
|
|
||||||
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
|
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
|
||||||
|
@ -1868,7 +1868,7 @@ UserLicenseStatus NodeDB::getLicenseStatus(uint32_t nodeNum)
|
|||||||
return info->user.is_licensed ? UserLicenseStatus::Licensed : UserLicenseStatus::NotLicensed;
|
return info->user.is_licensed ? UserLicenseStatus::Licensed : UserLicenseStatus::NotLicensed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodeDB::checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t keyToTest)
|
bool NodeDB::checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t &keyToTest)
|
||||||
{
|
{
|
||||||
if (keyToTest.size == 32) {
|
if (keyToTest.size == 32) {
|
||||||
uint8_t keyHash[32] = {0};
|
uint8_t keyHash[32] = {0};
|
||||||
|
@ -279,7 +279,7 @@ class NodeDB
|
|||||||
|
|
||||||
bool hasValidPosition(const meshtastic_NodeInfoLite *n);
|
bool hasValidPosition(const meshtastic_NodeInfoLite *n);
|
||||||
|
|
||||||
bool checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t keyToTest);
|
bool checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t &keyToTest);
|
||||||
|
|
||||||
bool backupPreferences(meshtastic_AdminMessage_BackupLocation location);
|
bool backupPreferences(meshtastic_AdminMessage_BackupLocation location);
|
||||||
bool restorePreferences(meshtastic_AdminMessage_BackupLocation location,
|
bool restorePreferences(meshtastic_AdminMessage_BackupLocation location,
|
||||||
|
@ -181,7 +181,7 @@ PacketHistory::PacketRecord *PacketHistory::find(NodeNum sender, PacketId id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Insert/Replace oldest PacketRecord in recentPackets. */
|
/** Insert/Replace oldest PacketRecord in recentPackets. */
|
||||||
void PacketHistory::insert(PacketRecord &r)
|
void PacketHistory::insert(const PacketRecord &r)
|
||||||
{
|
{
|
||||||
uint32_t now_millis = millis(); // Should not jump with time changes
|
uint32_t now_millis = millis(); // Should not jump with time changes
|
||||||
uint32_t OldtrxTimeMsec = 0;
|
uint32_t OldtrxTimeMsec = 0;
|
||||||
@ -308,7 +308,7 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketRecord *found = find(sender, id);
|
const PacketRecord *found = find(sender, id);
|
||||||
|
|
||||||
if (found == NULL) {
|
if (found == NULL) {
|
||||||
#if VERBOSE_PACKET_HISTORY
|
#if VERBOSE_PACKET_HISTORY
|
||||||
@ -327,7 +327,7 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N
|
|||||||
|
|
||||||
/* Check if a certain node was a relayer of a packet in the history given iterator
|
/* Check if a certain node was a relayer of a packet in the history given iterator
|
||||||
* @return true if node was indeed a relayer, false if not */
|
* @return true if node was indeed a relayer, false if not */
|
||||||
bool PacketHistory::wasRelayer(const uint8_t relayer, PacketRecord &r)
|
bool PacketHistory::wasRelayer(const uint8_t relayer, const PacketRecord &r)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < NUM_RELAYERS; i++) {
|
for (uint8_t i = 0; i < NUM_RELAYERS; i++) {
|
||||||
if (r.relayed_by[i] == relayer) {
|
if (r.relayed_by[i] == relayer) {
|
||||||
|
@ -31,11 +31,11 @@ class PacketHistory
|
|||||||
|
|
||||||
/** Insert/Replace oldest PacketRecord in mx_recentPackets.
|
/** Insert/Replace oldest PacketRecord in mx_recentPackets.
|
||||||
* @param r PacketRecord to insert or replace */
|
* @param r PacketRecord to insert or replace */
|
||||||
void insert(PacketRecord &r); // Insert or replace a packet record in the history
|
void insert(const PacketRecord &r); // Insert or replace a packet record in the history
|
||||||
|
|
||||||
/* Check if a certain node was a relayer of a packet in the history given iterator
|
/* Check if a certain node was a relayer of a packet in the history given iterator
|
||||||
* @return true if node was indeed a relayer, false if not */
|
* @return true if node was indeed a relayer, false if not */
|
||||||
bool wasRelayer(const uint8_t relayer, PacketRecord &r);
|
bool wasRelayer(const uint8_t relayer, const PacketRecord &r);
|
||||||
|
|
||||||
PacketHistory(const PacketHistory &); // non construction-copyable
|
PacketHistory(const PacketHistory &); // non construction-copyable
|
||||||
PacketHistory &operator=(const PacketHistory &); // non copyable
|
PacketHistory &operator=(const PacketHistory &); // non copyable
|
||||||
|
@ -686,7 +686,8 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
|
|||||||
LOG_WARN("Rate limit portnum %d", p.decoded.portnum);
|
LOG_WARN("Rate limit portnum %d", p.decoded.portnum);
|
||||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||||
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Text messages can only be sent once every 2 seconds");
|
service->sendRoutingErrorResponse(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED, &p);
|
||||||
|
// sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Text messages can only be sent once every 2 seconds");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lastPortNumToRadio[p.decoded.portnum] = millis();
|
lastPortNumToRadio[p.decoded.portnum] = millis();
|
||||||
|
@ -68,6 +68,11 @@ static int32_t reconnectETH()
|
|||||||
initApiServer();
|
initApiServer();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if HAS_UDP_MULTICAST
|
||||||
|
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||||
|
udpHandler->start();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ethStartupComplete = true;
|
ethStartupComplete = true;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
bool initEthernet();
|
bool initEthernet();
|
||||||
bool isEthernetAvailable();
|
bool isEthernetAvailable();
|
||||||
|
@ -480,7 +480,8 @@ typedef struct _meshtastic_Config_DisplayConfig {
|
|||||||
/* Number of seconds the screen stays on after pressing the user button or receiving a message
|
/* Number of seconds the screen stays on after pressing the user button or receiving a message
|
||||||
0 for default of one minute MAXUINT for always on */
|
0 for default of one minute MAXUINT for always on */
|
||||||
uint32_t screen_on_secs;
|
uint32_t screen_on_secs;
|
||||||
/* How the GPS coordinates are formatted on the OLED screen. */
|
/* Deprecated in 2.7.4: Unused
|
||||||
|
How the GPS coordinates are formatted on the OLED screen. */
|
||||||
meshtastic_Config_DisplayConfig_GpsCoordinateFormat gps_format;
|
meshtastic_Config_DisplayConfig_GpsCoordinateFormat gps_format;
|
||||||
/* Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
|
/* Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
|
||||||
Potentially useful for devices without user buttons. */
|
Potentially useful for devices without user buttons. */
|
||||||
|
@ -426,7 +426,10 @@ typedef enum _meshtastic_Routing_Error {
|
|||||||
/* Admin packet otherwise checks out, but uses a bogus or expired session key */
|
/* Admin packet otherwise checks out, but uses a bogus or expired session key */
|
||||||
meshtastic_Routing_Error_ADMIN_BAD_SESSION_KEY = 36,
|
meshtastic_Routing_Error_ADMIN_BAD_SESSION_KEY = 36,
|
||||||
/* Admin packet sent using PKC, but not from a public key on the admin key list */
|
/* Admin packet sent using PKC, but not from a public key on the admin key list */
|
||||||
meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37
|
meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37,
|
||||||
|
/* Airtime fairness rate limit exceeded for a packet
|
||||||
|
This typically enforced per portnum and is used to prevent a single node from monopolizing airtime */
|
||||||
|
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
||||||
} meshtastic_Routing_Error;
|
} meshtastic_Routing_Error;
|
||||||
|
|
||||||
/* The priority of this message for sending.
|
/* The priority of this message for sending.
|
||||||
@ -1222,8 +1225,8 @@ extern "C" {
|
|||||||
#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1))
|
#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1))
|
||||||
|
|
||||||
#define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE
|
#define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE
|
||||||
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED
|
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
||||||
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED+1))
|
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
||||||
|
|
||||||
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
||||||
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
||||||
|
@ -93,7 +93,11 @@ typedef enum _meshtastic_TelemetrySensorType {
|
|||||||
/* PCT2075 Temperature Sensor */
|
/* PCT2075 Temperature Sensor */
|
||||||
meshtastic_TelemetrySensorType_PCT2075 = 39,
|
meshtastic_TelemetrySensorType_PCT2075 = 39,
|
||||||
/* ADS1X15 ADC */
|
/* ADS1X15 ADC */
|
||||||
meshtastic_TelemetrySensorType_ADS1X15 = 40
|
meshtastic_TelemetrySensorType_ADS1X15 = 40,
|
||||||
|
/* ADS1X15 ADC_ALT */
|
||||||
|
meshtastic_TelemetrySensorType_ADS1X15_ALT = 41,
|
||||||
|
/* Sensirion SFA30 Formaldehyde sensor */
|
||||||
|
meshtastic_TelemetrySensorType_SFA30 = 42
|
||||||
} meshtastic_TelemetrySensorType;
|
} meshtastic_TelemetrySensorType;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
@ -287,6 +291,15 @@ typedef struct _meshtastic_AirQualityMetrics {
|
|||||||
/* CO2 sensor relative humidity in % */
|
/* CO2 sensor relative humidity in % */
|
||||||
bool has_co2_humidity;
|
bool has_co2_humidity;
|
||||||
float co2_humidity;
|
float co2_humidity;
|
||||||
|
/* Formaldehyde sensor formaldehyde concentration in ppb */
|
||||||
|
bool has_form_formaldehyde;
|
||||||
|
float form_formaldehyde;
|
||||||
|
/* Formaldehyde sensor relative humidity in %RH */
|
||||||
|
bool has_form_humidity;
|
||||||
|
float form_humidity;
|
||||||
|
/* Formaldehyde sensor temperature in degrees Celsius */
|
||||||
|
bool has_form_temperature;
|
||||||
|
float form_temperature;
|
||||||
} meshtastic_AirQualityMetrics;
|
} meshtastic_AirQualityMetrics;
|
||||||
|
|
||||||
/* Local device mesh statistics */
|
/* Local device mesh statistics */
|
||||||
@ -398,8 +411,8 @@ extern "C" {
|
|||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
||||||
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_ADS1X15
|
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SFA30
|
||||||
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_ADS1X15+1))
|
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SFA30+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -415,7 +428,7 @@ extern "C" {
|
|||||||
#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0}
|
#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_HostMetrics_init_default {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
|
#define meshtastic_HostMetrics_init_default {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
|
||||||
@ -424,7 +437,7 @@ extern "C" {
|
|||||||
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0}
|
#define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0}
|
||||||
#define meshtastic_HostMetrics_init_zero {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
|
#define meshtastic_HostMetrics_init_zero {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
|
||||||
@ -490,6 +503,9 @@ extern "C" {
|
|||||||
#define meshtastic_AirQualityMetrics_co2_tag 13
|
#define meshtastic_AirQualityMetrics_co2_tag 13
|
||||||
#define meshtastic_AirQualityMetrics_co2_temperature_tag 14
|
#define meshtastic_AirQualityMetrics_co2_temperature_tag 14
|
||||||
#define meshtastic_AirQualityMetrics_co2_humidity_tag 15
|
#define meshtastic_AirQualityMetrics_co2_humidity_tag 15
|
||||||
|
#define meshtastic_AirQualityMetrics_form_formaldehyde_tag 16
|
||||||
|
#define meshtastic_AirQualityMetrics_form_humidity_tag 17
|
||||||
|
#define meshtastic_AirQualityMetrics_form_temperature_tag 18
|
||||||
#define meshtastic_LocalStats_uptime_seconds_tag 1
|
#define meshtastic_LocalStats_uptime_seconds_tag 1
|
||||||
#define meshtastic_LocalStats_channel_utilization_tag 2
|
#define meshtastic_LocalStats_channel_utilization_tag 2
|
||||||
#define meshtastic_LocalStats_air_util_tx_tag 3
|
#define meshtastic_LocalStats_air_util_tx_tag 3
|
||||||
@ -597,7 +613,10 @@ X(a, STATIC, OPTIONAL, UINT32, particles_50um, 11) \
|
|||||||
X(a, STATIC, OPTIONAL, UINT32, particles_100um, 12) \
|
X(a, STATIC, OPTIONAL, UINT32, particles_100um, 12) \
|
||||||
X(a, STATIC, OPTIONAL, UINT32, co2, 13) \
|
X(a, STATIC, OPTIONAL, UINT32, co2, 13) \
|
||||||
X(a, STATIC, OPTIONAL, FLOAT, co2_temperature, 14) \
|
X(a, STATIC, OPTIONAL, FLOAT, co2_temperature, 14) \
|
||||||
X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15)
|
X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15) \
|
||||||
|
X(a, STATIC, OPTIONAL, FLOAT, form_formaldehyde, 16) \
|
||||||
|
X(a, STATIC, OPTIONAL, FLOAT, form_humidity, 17) \
|
||||||
|
X(a, STATIC, OPTIONAL, FLOAT, form_temperature, 18)
|
||||||
#define meshtastic_AirQualityMetrics_CALLBACK NULL
|
#define meshtastic_AirQualityMetrics_CALLBACK NULL
|
||||||
#define meshtastic_AirQualityMetrics_DEFAULT NULL
|
#define meshtastic_AirQualityMetrics_DEFAULT NULL
|
||||||
|
|
||||||
@ -686,7 +705,7 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
|
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
|
||||||
#define meshtastic_AirQualityMetrics_size 88
|
#define meshtastic_AirQualityMetrics_size 106
|
||||||
#define meshtastic_DeviceMetrics_size 27
|
#define meshtastic_DeviceMetrics_size 27
|
||||||
#define meshtastic_EnvironmentMetrics_size 113
|
#define meshtastic_EnvironmentMetrics_size 113
|
||||||
#define meshtastic_HealthMetrics_size 11
|
#define meshtastic_HealthMetrics_size 11
|
||||||
|
@ -4,8 +4,13 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/Router.h"
|
#include "mesh/Router.h"
|
||||||
|
|
||||||
#include <AsyncUDP.h>
|
#if HAS_ETHERNET && defined(ARCH_NRF52)
|
||||||
|
#include "mesh/eth/ethClient.h"
|
||||||
|
#else
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <AsyncUDP.h>
|
||||||
|
|
||||||
#if HAS_ETHERNET && defined(USE_WS5500)
|
#if HAS_ETHERNET && defined(USE_WS5500)
|
||||||
#include <ETHClass2.h>
|
#include <ETHClass2.h>
|
||||||
@ -22,11 +27,11 @@ class UdpMulticastHandler final
|
|||||||
void start()
|
void start()
|
||||||
{
|
{
|
||||||
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT, 64)) {
|
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT, 64)) {
|
||||||
#ifndef ARCH_PORTDUINO
|
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO)
|
||||||
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
|
LOG_DEBUG("UDP Listening on IP: %u.%u.%u.%u:%u", udpIpAddress[0], udpIpAddress[1], udpIpAddress[2], udpIpAddress[3],
|
||||||
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
|
UDP_MULTICAST_DEFAUL_PORT);
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG("UDP Listening");
|
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
|
||||||
#endif
|
#endif
|
||||||
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
|
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
|
||||||
} else {
|
} else {
|
||||||
@ -37,7 +42,10 @@ class UdpMulticastHandler final
|
|||||||
void onReceive(AsyncUDPPacket packet)
|
void onReceive(AsyncUDPPacket packet)
|
||||||
{
|
{
|
||||||
size_t packetLength = packet.length();
|
size_t packetLength = packet.length();
|
||||||
#ifndef ARCH_PORTDUINO
|
#if defined(ARCH_NRF52)
|
||||||
|
IPAddress ip = packet.remoteIP();
|
||||||
|
LOG_DEBUG("UDP broadcast from: %u.%u.%u.%u, len=%u", ip[0], ip[1], ip[2], ip[3], packetLength);
|
||||||
|
#elif !defined(ARCH_PORTDUINO)
|
||||||
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
|
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
|
||||||
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
|
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
|
||||||
#endif
|
#endif
|
||||||
@ -61,7 +69,11 @@ class UdpMulticastHandler final
|
|||||||
if (!mp || !udp) {
|
if (!mp || !udp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifndef ARCH_PORTDUINO
|
#if defined(ARCH_NRF52)
|
||||||
|
if (!isEthernetAvailable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#elif !defined(ARCH_PORTDUINO)
|
||||||
if (WiFi.status() != WL_CONNECTED) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1447,7 @@ void CannedMessageModule::drawEmotePickerScreen(OLEDDisplay *display, OLEDDispla
|
|||||||
int headerY = y;
|
int headerY = y;
|
||||||
int listTop = headerY + headerFontHeight + headerMargin;
|
int listTop = headerY + headerFontHeight + headerMargin;
|
||||||
|
|
||||||
int visibleRows = (display->getHeight() - listTop - 2) / rowHeight;
|
int _visibleRows = (display->getHeight() - listTop - 2) / rowHeight;
|
||||||
int numEmotes = graphics::numEmotes;
|
int numEmotes = graphics::numEmotes;
|
||||||
|
|
||||||
// Clamp highlight index
|
// Clamp highlight index
|
||||||
@ -1457,11 +1457,11 @@ void CannedMessageModule::drawEmotePickerScreen(OLEDDisplay *display, OLEDDispla
|
|||||||
emotePickerIndex = numEmotes - 1;
|
emotePickerIndex = numEmotes - 1;
|
||||||
|
|
||||||
// Determine which emote is at the top
|
// Determine which emote is at the top
|
||||||
int topIndex = emotePickerIndex - visibleRows / 2;
|
int topIndex = emotePickerIndex - _visibleRows / 2;
|
||||||
if (topIndex < 0)
|
if (topIndex < 0)
|
||||||
topIndex = 0;
|
topIndex = 0;
|
||||||
if (topIndex > numEmotes - visibleRows)
|
if (topIndex > numEmotes - _visibleRows)
|
||||||
topIndex = std::max(0, numEmotes - visibleRows);
|
topIndex = std::max(0, numEmotes - _visibleRows);
|
||||||
|
|
||||||
// Draw header/title
|
// Draw header/title
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
@ -1709,7 +1709,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
} else {
|
} else {
|
||||||
// Text: split by words and wrap inside word if needed
|
// Text: split by words and wrap inside word if needed
|
||||||
String text = token.second;
|
String text = token.second;
|
||||||
uint16_t pos = 0;
|
pos = 0;
|
||||||
while (pos < text.length()) {
|
while (pos < text.length()) {
|
||||||
// Find next space (or end)
|
// Find next space (or end)
|
||||||
int spacePos = text.indexOf(' ', pos);
|
int spacePos = text.indexOf(' ', pos);
|
||||||
@ -1753,7 +1753,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
int yLine = inputY;
|
int yLine = inputY;
|
||||||
for (auto &line : lines) {
|
for (auto &line : lines) {
|
||||||
int nextX = x;
|
int nextX = x;
|
||||||
for (auto &token : line) {
|
for (const auto &token : line) {
|
||||||
if (token.first) {
|
if (token.first) {
|
||||||
const graphics::Emote *emote = nullptr;
|
const graphics::Emote *emote = nullptr;
|
||||||
for (int j = 0; j < graphics::numEmotes; j++) {
|
for (int j = 0; j < graphics::numEmotes; j++) {
|
||||||
@ -1789,19 +1789,20 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
|
|
||||||
int topMsg;
|
int topMsg;
|
||||||
std::vector<int> rowHeights;
|
std::vector<int> rowHeights;
|
||||||
int visibleRows;
|
int _visibleRows;
|
||||||
|
|
||||||
// Draw header (To: ...)
|
// Draw header (To: ...)
|
||||||
drawHeader(display, x, y, buffer);
|
drawHeader(display, x, y, buffer);
|
||||||
|
|
||||||
// Shift message list upward by 3 pixels to reduce spacing between header and first message
|
// Shift message list upward by 3 pixels to reduce spacing between header and first message
|
||||||
const int listYOffset = y + FONT_HEIGHT_SMALL - 3;
|
const int listYOffset = y + FONT_HEIGHT_SMALL - 3;
|
||||||
visibleRows = (display->getHeight() - listYOffset) / baseRowSpacing;
|
_visibleRows = (display->getHeight() - listYOffset) / baseRowSpacing;
|
||||||
|
|
||||||
// Figure out which messages are visible and their needed heights
|
// Figure out which messages are visible and their needed heights
|
||||||
topMsg =
|
topMsg = (messagesCount > _visibleRows && currentMessageIndex >= _visibleRows - 1)
|
||||||
(messagesCount > visibleRows && currentMessageIndex >= visibleRows - 1) ? currentMessageIndex - visibleRows + 2 : 0;
|
? currentMessageIndex - _visibleRows + 2
|
||||||
int countRows = std::min(messagesCount, visibleRows);
|
: 0;
|
||||||
|
int countRows = std::min(messagesCount, _visibleRows);
|
||||||
|
|
||||||
// --- Build per-row max height based on all emotes in line ---
|
// --- Build per-row max height based on all emotes in line ---
|
||||||
for (int i = 0; i < countRows; i++) {
|
for (int i = 0; i < countRows; i++) {
|
||||||
@ -1828,7 +1829,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
int lineY = yCursor;
|
int lineY = yCursor;
|
||||||
const char *msg = getMessageByIndex(msgIdx);
|
const char *msg = getMessageByIndex(msgIdx);
|
||||||
int rowHeight = rowHeights[vis];
|
int rowHeight = rowHeights[vis];
|
||||||
bool highlight = (msgIdx == currentMessageIndex);
|
bool _highlight = (msgIdx == currentMessageIndex);
|
||||||
|
|
||||||
// --- Multi-emote tokenization ---
|
// --- Multi-emote tokenization ---
|
||||||
std::vector<std::pair<bool, String>> tokens; // (isEmote, token)
|
std::vector<std::pair<bool, String>> tokens; // (isEmote, token)
|
||||||
@ -1881,20 +1882,20 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
int textYOffset = (rowHeight - FONT_HEIGHT_SMALL) / 2;
|
int textYOffset = (rowHeight - FONT_HEIGHT_SMALL) / 2;
|
||||||
|
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
int nextX = x + (highlight ? 12 : 0);
|
int nextX = x + (_highlight ? 12 : 0);
|
||||||
if (highlight)
|
if (_highlight)
|
||||||
display->drawString(x + 0, lineY + textYOffset, ">");
|
display->drawString(x + 0, lineY + textYOffset, ">");
|
||||||
#else
|
#else
|
||||||
int scrollPadding = 8;
|
int scrollPadding = 8;
|
||||||
if (highlight) {
|
if (_highlight) {
|
||||||
display->fillRect(x + 0, lineY, display->getWidth() - scrollPadding, rowHeight);
|
display->fillRect(x + 0, lineY, display->getWidth() - scrollPadding, rowHeight);
|
||||||
display->setColor(BLACK);
|
display->setColor(BLACK);
|
||||||
}
|
}
|
||||||
int nextX = x + (highlight ? 2 : 0);
|
int nextX = x + (_highlight ? 2 : 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Draw all tokens left to right
|
// Draw all tokens left to right
|
||||||
for (auto &token : tokens) {
|
for (const auto &token : tokens) {
|
||||||
if (token.first) {
|
if (token.first) {
|
||||||
// Emote
|
// Emote
|
||||||
const graphics::Emote *emote = nullptr;
|
const graphics::Emote *emote = nullptr;
|
||||||
@ -1916,7 +1917,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef USE_EINK
|
#ifndef USE_EINK
|
||||||
if (highlight)
|
if (_highlight)
|
||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1924,11 +1925,11 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scrollbar
|
// Scrollbar
|
||||||
if (messagesCount > visibleRows) {
|
if (messagesCount > _visibleRows) {
|
||||||
int scrollHeight = display->getHeight() - listYOffset;
|
int scrollHeight = display->getHeight() - listYOffset;
|
||||||
int scrollTrackX = display->getWidth() - 6;
|
int scrollTrackX = display->getWidth() - 6;
|
||||||
display->drawRect(scrollTrackX, listYOffset, 4, scrollHeight);
|
display->drawRect(scrollTrackX, listYOffset, 4, scrollHeight);
|
||||||
int barHeight = (scrollHeight * visibleRows) / messagesCount;
|
int barHeight = (scrollHeight * _visibleRows) / messagesCount;
|
||||||
int scrollPos = listYOffset + (scrollHeight * topMsg) / messagesCount;
|
int scrollPos = listYOffset + (scrollHeight * topMsg) / messagesCount;
|
||||||
display->fillRect(scrollTrackX, scrollPos, 4, barHeight);
|
display->fillRect(scrollTrackX, scrollPos, 4, barHeight);
|
||||||
}
|
}
|
||||||
|
@ -107,11 +107,7 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
|
|||||||
return true;
|
return true;
|
||||||
// Power control
|
// Power control
|
||||||
case INPUT_BROKER_SHUTDOWN:
|
case INPUT_BROKER_SHUTDOWN:
|
||||||
LOG_ERROR("Shutting Down");
|
shutdownAtMsec = millis();
|
||||||
IF_SCREEN(screen->showSimpleBanner("Shutting Down..."));
|
|
||||||
nodeDB->saveToDisk();
|
|
||||||
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
|
|
||||||
// runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
73
src/platform/nrf52/AsyncUDP.cpp
Normal file
73
src/platform/nrf52/AsyncUDP.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "AsyncUDP.h"
|
||||||
|
|
||||||
|
#if HAS_ETHERNET
|
||||||
|
|
||||||
|
AsyncUDP::AsyncUDP() : OSThread("AsyncUDP"), localPort(0) {}
|
||||||
|
|
||||||
|
bool AsyncUDP::listenMulticast(IPAddress multicastIP, uint16_t port, uint8_t ttl)
|
||||||
|
{
|
||||||
|
if (!isMulticast(multicastIP))
|
||||||
|
return false;
|
||||||
|
localPort = port;
|
||||||
|
udp.beginMulticast(multicastIP, port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AsyncUDP::write(uint8_t b)
|
||||||
|
{
|
||||||
|
return udp.write(&b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AsyncUDP::write(const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
return udp.write(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncUDP::onPacket(const std::function<void(AsyncUDPPacket)> &callback)
|
||||||
|
{
|
||||||
|
_onPacket = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncUDP::writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port)
|
||||||
|
{
|
||||||
|
if (!udp.beginPacket(ip, port))
|
||||||
|
return false;
|
||||||
|
udp.write(data, len);
|
||||||
|
return udp.endPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsyncUDPPacket
|
||||||
|
AsyncUDPPacket::AsyncUDPPacket(EthernetUDP &source) : _udp(source), _remoteIP(source.remoteIP()), _remotePort(source.remotePort())
|
||||||
|
{
|
||||||
|
if (_udp.available() > 0) {
|
||||||
|
_readLength = _udp.read(_buffer, sizeof(_buffer));
|
||||||
|
} else {
|
||||||
|
_readLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress AsyncUDPPacket::remoteIP()
|
||||||
|
{
|
||||||
|
return _remoteIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AsyncUDPPacket::length()
|
||||||
|
{
|
||||||
|
return _readLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *AsyncUDPPacket::data()
|
||||||
|
{
|
||||||
|
return _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t AsyncUDP::runOnce()
|
||||||
|
{
|
||||||
|
if (_onPacket && udp.parsePacket() > 0) {
|
||||||
|
AsyncUDPPacket packet(udp);
|
||||||
|
_onPacket(packet);
|
||||||
|
}
|
||||||
|
return 5; // check every 5ms
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAS_ETHERNET
|
63
src/platform/nrf52/AsyncUDP.h
Normal file
63
src/platform/nrf52/AsyncUDP.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#ifndef ASYNC_UDP_H
|
||||||
|
#define ASYNC_UDP_H
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#if HAS_ETHERNET
|
||||||
|
|
||||||
|
#include "concurrency/OSThread.h"
|
||||||
|
#include <IPAddress.h>
|
||||||
|
#include <Print.h>
|
||||||
|
#include <RAK13800_W5100S.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class AsyncUDPPacket;
|
||||||
|
|
||||||
|
class AsyncUDP : public Print, private concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsyncUDP();
|
||||||
|
explicit operator bool() const { return localPort != 0; }
|
||||||
|
|
||||||
|
bool listenMulticast(IPAddress multicastIP, uint16_t port, uint8_t ttl = 64);
|
||||||
|
bool writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port);
|
||||||
|
|
||||||
|
size_t write(uint8_t b) override;
|
||||||
|
size_t write(const uint8_t *data, size_t len) override;
|
||||||
|
void onPacket(const std::function<void(AsyncUDPPacket)> &callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EthernetUDP udp;
|
||||||
|
uint16_t localPort;
|
||||||
|
std::function<void(AsyncUDPPacket)> _onPacket;
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AsyncUDPPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsyncUDPPacket(EthernetUDP &source);
|
||||||
|
|
||||||
|
IPAddress remoteIP();
|
||||||
|
uint16_t length();
|
||||||
|
const uint8_t *data();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EthernetUDP &_udp;
|
||||||
|
IPAddress _remoteIP;
|
||||||
|
uint16_t _remotePort;
|
||||||
|
size_t _readLength = 0;
|
||||||
|
|
||||||
|
static constexpr size_t BUF_SIZE = 512;
|
||||||
|
uint8_t _buffer[BUF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool isMulticast(const IPAddress &ip)
|
||||||
|
{
|
||||||
|
return (ip[0] & 0xF0) == 0xE0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAS_ETHERNET
|
||||||
|
|
||||||
|
#endif // ASYNC_UDP_H
|
@ -40,21 +40,8 @@ void powerCommandsCheck()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
|
||||||
if (shutdownAtMsec && screen) {
|
|
||||||
screen->showSimpleBanner("Shutting Down...", 0); // stays on screen
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (shutdownAtMsec && millis() > shutdownAtMsec) {
|
if (shutdownAtMsec && millis() > shutdownAtMsec) {
|
||||||
LOG_INFO("Shut down from admin command");
|
shutdownAtMsec = 0;
|
||||||
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
|
|
||||||
playShutdownMelody();
|
|
||||||
power->shutdown();
|
power->shutdown();
|
||||||
#elif defined(ARCH_PORTDUINO)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
#else
|
|
||||||
LOG_WARN("FIXME implement shutdown for this platform");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,47 +1,3 @@
|
|||||||
; Meshtastic DIY v1 by Nano VHF Schematic based on ESP32-WROOM-32 (38 pins) devkit & EBYTE E22 SX1262/SX1268 module
|
|
||||||
[env:meshtastic-diy-v1]
|
|
||||||
extends = esp32_base
|
|
||||||
board = esp32doit-devkit-v1
|
|
||||||
board_check = true
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-D DIY_V1
|
|
||||||
-D EBYTE_E22
|
|
||||||
-I variants/diy/v1
|
|
||||||
|
|
||||||
; Meshtastic DIY v1.1 new schematic based on ESP32-WROOM-32 & SX1262/SX1268 modules
|
|
||||||
[env:meshtastic-diy-v1_1]
|
|
||||||
extends = esp32_base
|
|
||||||
board = esp32doit-devkit-v1
|
|
||||||
board_level = extra
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-D DIY_V1
|
|
||||||
-D EBYTE_E22
|
|
||||||
-I variants/diy/v1_1
|
|
||||||
|
|
||||||
; Port to Disaster Radio's ESP32-v3 Dev Board
|
|
||||||
[env:meshtastic-dr-dev]
|
|
||||||
extends = esp32_base
|
|
||||||
board = esp32doit-devkit-v1
|
|
||||||
board_upload.maximum_size = 4194304
|
|
||||||
board_upload.maximum_ram_size = 532480
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-D DR_DEV
|
|
||||||
-D EBYTE_E22
|
|
||||||
-I variants/diy/dr-dev
|
|
||||||
|
|
||||||
; Hydra - Meshtastic DIY v1 hardware with some specific changes
|
|
||||||
[env:hydra]
|
|
||||||
extends = esp32_base
|
|
||||||
board = esp32doit-devkit-v1
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-D DIY_V1
|
|
||||||
-I variants/diy/hydra
|
|
||||||
|
|
||||||
|
|
||||||
; Promicro + E22(0)-xxxMM / RA-01SH modules board variant - DIY - without TCXO
|
; Promicro + E22(0)-xxxMM / RA-01SH modules board variant - DIY - without TCXO
|
||||||
[env:nrf52_promicro_diy_xtal]
|
[env:nrf52_promicro_diy_xtal]
|
||||||
extends = nrf52840_base
|
extends = nrf52840_base
|
||||||
@ -122,35 +78,3 @@ build_src_filter = ${nrf52_base.build_src_filter} +<../variants/diy/seeed-xiao-n
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52840_base.lib_deps}
|
${nrf52840_base.lib_deps}
|
||||||
debug_tool = jlink
|
debug_tool = jlink
|
||||||
|
|
||||||
; NanoVHF T-Energy-S3 + E22(0)-xxxM - DIY
|
|
||||||
[env:t-energy-s3_e22]
|
|
||||||
extends = esp32s3_base
|
|
||||||
board = esp32-s3-devkitc-1
|
|
||||||
board_build.partitions = default_16MB.csv
|
|
||||||
board_level = extra
|
|
||||||
board_upload.flash_size = 16MB ;Specify the FLASH capacity as 16MB
|
|
||||||
board_build.arduino.memory_type = qio_opi ;Enable internal PSRAM
|
|
||||||
build_unflags =
|
|
||||||
${esp32s3_base.build_unflags}
|
|
||||||
-D ARDUINO_USB_MODE=1
|
|
||||||
build_flags =
|
|
||||||
${esp32s3_base.build_flags}
|
|
||||||
-D EBYTE_ESP32_S3
|
|
||||||
-D BOARD_HAS_PSRAM
|
|
||||||
-D ARDUINO_USB_MODE=0
|
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
|
||||||
-I variants/diy/t-energy-s3_e22
|
|
||||||
|
|
||||||
; ESP32 C3 Super Mini Development Board
|
|
||||||
; https://www.espboards.dev/esp32/esp32-c3-super-mini/
|
|
||||||
[env:esp32c3_super_mini]
|
|
||||||
extends = esp32c3_base
|
|
||||||
board = esp32-c3-devkitm-1
|
|
||||||
build_flags =
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-D PRIVATE_HW
|
|
||||||
-I variants/diy/esp32c3_super_mini
|
|
||||||
-D ARDUINO_USB_MODE=1
|
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
|
||||||
board_level = extra
|
|
||||||
|
@ -8,11 +8,11 @@ build_flags =
|
|||||||
-D VTABLES_IN_FLASH=1
|
-D VTABLES_IN_FLASH=1
|
||||||
-D CONFIG_DISABLE_HAL_LOCKS=1
|
-D CONFIG_DISABLE_HAL_LOCKS=1
|
||||||
-O2
|
-O2
|
||||||
-I variants/betafpv_2400_tx_micro
|
-I variants/esp32/betafpv_2400_tx_micro
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyUSB0
|
;upload_port = /dev/ttyUSB0
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel @ ^1.12.0
|
@ -8,10 +8,10 @@ build_flags =
|
|||||||
-D VTABLES_IN_FLASH=1
|
-D VTABLES_IN_FLASH=1
|
||||||
-D CONFIG_DISABLE_HAL_LOCKS=1
|
-D CONFIG_DISABLE_HAL_LOCKS=1
|
||||||
-O2
|
-O2
|
||||||
-I variants/betafpv_900_tx_nano
|
-I variants/esp32/betafpv_900_tx_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyUSB0
|
;upload_port = /dev/ttyUSB0
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
@ -5,7 +5,7 @@ board = esp32doit-devkit-v1
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D CHATTER_2
|
-D CHATTER_2
|
||||||
-I variants/chatter2
|
-I variants/esp32/chatter2
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
11
variants/esp32/diy/dr-dev/platformio.ini
Normal file
11
variants/esp32/diy/dr-dev/platformio.ini
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
; Port to Disaster Radio's ESP32-v3 Dev Board
|
||||||
|
[env:meshtastic-dr-dev]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32doit-devkit-v1
|
||||||
|
board_upload.maximum_size = 4194304
|
||||||
|
board_upload.maximum_ram_size = 532480
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D DR_DEV
|
||||||
|
-D EBYTE_E22
|
||||||
|
-I variants/esp32/diy/dr-dev
|
8
variants/esp32/diy/hydra/platformio.ini
Normal file
8
variants/esp32/diy/hydra/platformio.ini
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
; Hydra - Meshtastic DIY v1 hardware with some specific changes
|
||||||
|
[env:hydra]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32doit-devkit-v1
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D DIY_V1
|
||||||
|
-I variants/esp32/diy/hydra
|
10
variants/esp32/diy/v1/platformio.ini
Normal file
10
variants/esp32/diy/v1/platformio.ini
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
; Meshtastic DIY v1 by Nano VHF Schematic based on ESP32-WROOM-32 (38 pins) devkit & EBYTE E22 SX1262/SX1268 module
|
||||||
|
[env:meshtastic-diy-v1]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32doit-devkit-v1
|
||||||
|
board_check = true
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D DIY_V1
|
||||||
|
-D EBYTE_E22
|
||||||
|
-I variants/esp32/diy/v1
|
10
variants/esp32/diy/v1_1/platformio.ini
Normal file
10
variants/esp32/diy/v1_1/platformio.ini
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
; Meshtastic DIY v1.1 new schematic based on ESP32-WROOM-32 & SX1262/SX1268 modules
|
||||||
|
[env:meshtastic-diy-v1_1]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32doit-devkit-v1
|
||||||
|
board_level = extra
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D DIY_V1
|
||||||
|
-D EBYTE_E22
|
||||||
|
-I variants/esp32/diy/v1_1
|
@ -5,7 +5,7 @@ board_level = extra
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/hackerboxes_esp32_io
|
-I variants/esp32/hackerboxes_esp32_io
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyUSB0
|
;upload_port = /dev/ttyUSB0
|
@ -4,4 +4,6 @@ extends = esp32_base
|
|||||||
board_level = extra
|
board_level = extra
|
||||||
board = heltec_wifi_lora_32
|
board = heltec_wifi_lora_32
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D HELTEC_V1 -I variants/heltec_v1
|
${esp32_base.build_flags}
|
||||||
|
-D HELTEC_V1
|
||||||
|
-I variants/esp32/heltec_v1
|
@ -4,5 +4,7 @@ board_level = extra
|
|||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = heltec_wifi_lora_32_V2
|
board = heltec_wifi_lora_32_V2
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D HELTEC_V2_1 -I variants/heltec_v2.1
|
${esp32_base.build_flags}
|
||||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-D HELTEC_V2_1
|
||||||
|
-I variants/esp32/heltec_v2.1
|
||||||
|
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
@ -4,4 +4,6 @@ board_level = extra
|
|||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = heltec_wifi_lora_32_V2
|
board = heltec_wifi_lora_32_V2
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D HELTEC_V2_0 -I variants/heltec_v2
|
${esp32_base.build_flags}
|
||||||
|
-D HELTEC_V2_0
|
||||||
|
-I variants/esp32/heltec_v2
|
@ -4,7 +4,7 @@ extends = esp32_base
|
|||||||
board = heltec_wifi_lora_32
|
board = heltec_wifi_lora_32
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-I variants/heltec_wireless_bridge
|
-I variants/esp32/heltec_wireless_bridge
|
||||||
-D HELTEC_WIRELESS_BRIDGE
|
-D HELTEC_WIRELESS_BRIDGE
|
||||||
-D BOARD_HAS_PSRAM
|
-D BOARD_HAS_PSRAM
|
||||||
-D RADIOLIB_EXCLUDE_LR11X0=1
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
@ -3,5 +3,7 @@ extends = esp32_base
|
|||||||
board = heltec_wireless_stick_lite
|
board = heltec_wireless_stick_lite
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D PRIVATE_HW -I variants/heltec_wsl_v2.1
|
${esp32_base.build_flags}
|
||||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-D PRIVATE_HW
|
||||||
|
-I variants/esp32/heltec_wsl_v2.1
|
||||||
|
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
@ -5,7 +5,8 @@ monitor_filters = esp32_exception_decoder
|
|||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32_base.build_src_filter}
|
${esp32_base.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -I variants/m5stack_core
|
${esp32_base.build_flags}
|
||||||
|
-I variants/esp32/m5stack_core
|
||||||
-DILI9341_DRIVER
|
-DILI9341_DRIVER
|
||||||
-DM5STACK
|
-DM5STACK
|
||||||
-DUSER_SETUP_LOADED
|
-DUSER_SETUP_LOADED
|
@ -5,7 +5,8 @@ board_check = true
|
|||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32_base.build_src_filter}
|
${esp32_base.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -I variants/m5stack_coreink
|
${esp32_base.build_flags}
|
||||||
|
-I variants/esp32/m5stack_coreink
|
||||||
;-D RADIOLIB_VERBOSE
|
;-D RADIOLIB_VERBOSE
|
||||||
-Ofast
|
-Ofast
|
||||||
-D__MCUXPRESSO
|
-D__MCUXPRESSO
|
@ -5,4 +5,6 @@ board = ttgo-t-beam
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D NANO_G1_EXPLORER -I variants/nano-g1-explorer
|
${esp32_base.build_flags}
|
||||||
|
-D NANO_G1_EXPLORER
|
||||||
|
-I variants/esp32/nano-g1-explorer
|
@ -5,4 +5,6 @@ board = ttgo-t-beam
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D NANO_G1 -I variants/nano-g1
|
${esp32_base.build_flags}
|
||||||
|
-D NANO_G1
|
||||||
|
-I variants/esp32/nano-g1
|
@ -8,7 +8,7 @@ build_flags =
|
|||||||
-DCONFIG_DISABLE_HAL_LOCKS=1
|
-DCONFIG_DISABLE_HAL_LOCKS=1
|
||||||
-DHAS_STK8XXX=1
|
-DHAS_STK8XXX=1
|
||||||
-O2
|
-O2
|
||||||
-Ivariants/radiomaster_900_bandit
|
-I variants/esp32/radiomaster_900_bandit
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
lib_deps =
|
@ -12,8 +12,8 @@ build_flags =
|
|||||||
-DVTABLES_IN_FLASH=1
|
-DVTABLES_IN_FLASH=1
|
||||||
-DCONFIG_DISABLE_HAL_LOCKS=1
|
-DCONFIG_DISABLE_HAL_LOCKS=1
|
||||||
-O2
|
-O2
|
||||||
-Ivariants/radiomaster_900_bandit_nano
|
-I variants/esp32/radiomaster_900_bandit_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
@ -7,8 +7,8 @@ build_flags =
|
|||||||
-DVTABLES_IN_FLASH=1
|
-DVTABLES_IN_FLASH=1
|
||||||
-DCONFIG_DISABLE_HAL_LOCKS=1
|
-DCONFIG_DISABLE_HAL_LOCKS=1
|
||||||
-O2
|
-O2
|
||||||
-Ivariants/radiomaster_900_bandit_nano
|
-I variants/esp32/radiomaster_900_bandit_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
@ -3,5 +3,7 @@ extends = esp32_base
|
|||||||
board = wiscore_rak11200
|
board = wiscore_rak11200
|
||||||
board_check = true
|
board_check = true
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D RAK_11200 -I variants/rak11200
|
${esp32_base.build_flags}
|
||||||
upload_speed = 115200
|
-D RAK_11200
|
||||||
|
-I variants/esp32/rak11200
|
||||||
|
upload_speed = 115200
|
@ -5,4 +5,6 @@ board = ttgo-t-beam
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D STATION_G1 -I variants/station-g1
|
${esp32_base.build_flags}
|
||||||
|
-D STATION_G1
|
||||||
|
-I variants/esp32/station-g1
|
@ -6,8 +6,10 @@ board_check = true
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TBEAM_V10 -I variants/tbeam
|
${esp32_base.build_flags}
|
||||||
|
-D TBEAM_V10
|
||||||
|
-I variants/esp32/tbeam
|
||||||
-DGPS_POWER_TOGGLE ; comment this line to disable double press function on the user button to turn off gps entirely.
|
-DGPS_POWER_TOGGLE ; comment this line to disable double press function on the user button to turn off gps entirely.
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
-mfix-esp32-psram-cache-issue
|
-mfix-esp32-psram-cache-issue
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
@ -4,4 +4,6 @@ board_level = extra
|
|||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TBEAM_V07 -I variants/tbeam_v07
|
${esp32_base.build_flags}
|
||||||
|
-D TBEAM_V07
|
||||||
|
-I variants/esp32/tbeam_v07
|
@ -3,5 +3,7 @@ board_level = extra
|
|||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-lora32-v1
|
board = ttgo-lora32-v1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TLORA_V1 -I variants/tlora_v1
|
${esp32_base.build_flags}
|
||||||
upload_speed = 115200
|
-D TLORA_V1
|
||||||
|
-I variants/esp32/tlora_v1
|
||||||
|
upload_speed = 115200
|
@ -3,5 +3,5 @@ board_level = extra
|
|||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-lora32-v1
|
board = ttgo-lora32-v1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TLORA_V1_3 -I variants/tlora_v1_3
|
${esp32_base.build_flags} -D TLORA_V1_3 -I variants/esp32/tlora_v1_3
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
@ -3,4 +3,6 @@ board_level = extra
|
|||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-lora32-v1
|
board = ttgo-lora32-v1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TLORA_V2 -I variants/tlora_v2
|
${esp32_base.build_flags}
|
||||||
|
-D TLORA_V2
|
||||||
|
-I variants/esp32/tlora_v2
|
@ -3,6 +3,6 @@ extends = esp32_base
|
|||||||
board = ttgo-lora32-v21
|
board = ttgo-lora32-v21
|
||||||
board_check = true
|
board_check = true
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TLORA_V2_1_16 -I variants/tlora_v2_1_16
|
${esp32_base.build_flags} -D TLORA_V2_1_16 -I variants/esp32/tlora_v2_1_16
|
||||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
@ -5,7 +5,7 @@ board = ttgo-lora32-v21
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D TLORA_V2_1_16
|
-D TLORA_V2_1_16
|
||||||
-I variants/tlora_v2_1_16
|
-I variants/esp32/tlora_v2_1_16
|
||||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
-D LORA_TCXO_GPIO=33
|
-D LORA_TCXO_GPIO=33
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
@ -4,4 +4,6 @@ board_level = extra
|
|||||||
board = ttgo-lora32-v21
|
board = ttgo-lora32-v21
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18
|
${esp32_base.build_flags}
|
||||||
|
-D TLORA_V2_1_18
|
||||||
|
-I variants/esp32/tlora_v2_1_18
|
@ -4,7 +4,7 @@ board = ttgo-lora32-v21
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D TLORA_V2_1_16
|
-D TLORA_V2_1_16
|
||||||
-I variants/tlora_v2_1_16
|
-I variants/esp32/tlora_v2_1_16
|
||||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
-D LORA_TCXO_GPIO=12
|
-D LORA_TCXO_GPIO=12
|
||||||
-D BUTTON_PIN=0
|
-D BUTTON_PIN=0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user