mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-20 17:52:35 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
035c4c6a38 | ||
|
|
41527cc965 | ||
|
|
0fa57648f4 | ||
|
|
4b13f18906 | ||
|
|
b7dde9f8d2 | ||
|
|
efd3ce5ab1 | ||
|
|
0073f6b24a | ||
|
|
dbad691651 | ||
|
|
6c3315025a | ||
|
|
11c2b67223 |
2
.github/actions/build-variant/action.yml
vendored
2
.github/actions/build-variant/action.yml
vendored
@@ -100,7 +100,7 @@ runs:
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
2
.github/workflows/build_debian_src.yml
vendored
2
.github/workflows/build_debian_src.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
||||
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
overwrite: true
|
||||
|
||||
2
.github/workflows/build_firmware.yml
vendored
2
.github/workflows/build_firmware.yml
vendored
@@ -70,7 +70,7 @@ jobs:
|
||||
echo "</details>" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
id: upload
|
||||
with:
|
||||
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
|
||||
|
||||
8
.github/workflows/build_one_target.yml
vendored
8
.github/workflows/build_one_target.yml
vendored
@@ -98,7 +98,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-*-*
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-*-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -146,7 +146,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
|
||||
22
.github/workflows/main_matrix.yml
vendored
22
.github/workflows/main_matrix.yml
vendored
@@ -173,7 +173,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
run: ls -R
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -200,7 +200,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -219,7 +219,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -260,14 +260,14 @@ jobs:
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -291,7 +291,7 @@ jobs:
|
||||
}' > firmware-${{ needs.version.outputs.long }}.json
|
||||
|
||||
- name: Save Release manifest artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: manifest-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -332,7 +332,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -349,7 +349,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -388,14 +388,14 @@ jobs:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Get firmware artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./publish
|
||||
|
||||
- name: Get manifest artifact
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: manifest-${{ needs.version.outputs.long }}
|
||||
path: ./publish
|
||||
|
||||
18
.github/workflows/merge_queue.yml
vendored
18
.github/workflows/merge_queue.yml
vendored
@@ -147,7 +147,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -176,7 +176,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -235,14 +235,14 @@ jobs:
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -292,7 +292,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -309,7 +309,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -347,7 +347,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/package_obs.yml
vendored
2
.github/workflows/package_obs.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/package_pio_deps.yml
vendored
2
.github/workflows/package_pio_deps.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
PLATFORMIO_CORE_DIR: pio/core
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
2
.github/workflows/package_ppa.yml
vendored
2
.github/workflows/package_ppa.yml
vendored
@@ -60,7 +60,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/pr_tests.yml
vendored
2
.github/workflows/pr_tests.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
|
||||
- name: Download test artifacts
|
||||
if: needs.native-tests.result != 'skipped'
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: report.sarif
|
||||
overwrite: true
|
||||
|
||||
12
.github/workflows/test_native.yml
vendored
12
.github/workflows/test_native.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
|
||||
- name: Save test results
|
||||
if: always() # run this step even if previous step failed
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
|
||||
@@ -137,7 +137,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download test artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -150,7 +150,7 @@ jobs:
|
||||
reporter: java-junit
|
||||
|
||||
- name: Download coverage artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
|
||||
path: code-coverage-report
|
||||
@@ -163,7 +163,7 @@ jobs:
|
||||
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
|
||||
|
||||
- name: Save Code Coverage Report
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: code-coverage-report-${{ steps.version.outputs.long }}
|
||||
path: code-coverage-report
|
||||
|
||||
@@ -9,7 +9,7 @@ plugins:
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.495
|
||||
- renovate@42.48.0
|
||||
- renovate@42.57.1
|
||||
- prettier@3.7.4
|
||||
- trufflehog@3.92.3
|
||||
- yamllint@1.37.1
|
||||
|
||||
@@ -123,7 +123,7 @@ lib_deps =
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/2746a1ce3804998460a2cb319b8ea8a238dfd8c9.zip
|
||||
https://github.com/meshtastic/device-ui/archive/862ed040c4ab44f0dfbbe492691f144886102588.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
|
||||
Submodule protobufs updated: 4095e59890...9beb80f1d3
@@ -31,6 +31,9 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
return useShortName ? "LongF" : "LongFast";
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||
return useShortName ? "LongT" : "LongTurbo";
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||
return useShortName ? "LongM" : "LongMod";
|
||||
break;
|
||||
|
||||
@@ -20,12 +20,41 @@
|
||||
#include "modules/KeyVerificationModule.h"
|
||||
|
||||
#include "modules/TraceRouteModule.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
extern uint16_t TFT_MESH;
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Caller must ensure the provided options array outlives the banner callback.
|
||||
template <typename T, size_t N, typename Callback>
|
||||
BannerOverlayOptions createStaticBannerOptions(const char *message, const MenuOption<T> (&options)[N],
|
||||
std::array<const char *, N> &labels, Callback &&onSelection)
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
labels[i] = options[i].label;
|
||||
}
|
||||
|
||||
const MenuOption<T> *optionsPtr = options;
|
||||
auto callback = std::function<void(const MenuOption<T> &, int)>(std::forward<Callback>(onSelection));
|
||||
|
||||
BannerOverlayOptions bannerOptions;
|
||||
bannerOptions.message = message;
|
||||
bannerOptions.optionsArrayPtr = labels.data();
|
||||
bannerOptions.optionsCount = static_cast<uint8_t>(N);
|
||||
bannerOptions.bannerCallback = [optionsPtr, callback](int selected) -> void { callback(optionsPtr[selected], selected); };
|
||||
return bannerOptions;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
menuHandler::screenMenus menuHandler::menuQueue = menu_none;
|
||||
bool test_enabled = false;
|
||||
uint8_t test_count = 0;
|
||||
@@ -197,48 +226,38 @@ void menuHandler::DeviceRolePicker()
|
||||
|
||||
void menuHandler::RadioPresetPicker()
|
||||
{
|
||||
static const char *optionsArray[] = {"Back", "LongSlow", "LongModerate", "LongFast", "MediumSlow",
|
||||
"MediumFast", "ShortSlow", "ShortFast", "ShortTurbo"};
|
||||
enum optionsNumbers {
|
||||
Back = 0,
|
||||
radiopreset_LongSlow = 1,
|
||||
radiopreset_LongModerate = 2,
|
||||
radiopreset_LongFast = 3,
|
||||
radiopreset_MediumSlow = 4,
|
||||
radiopreset_MediumFast = 5,
|
||||
radiopreset_ShortSlow = 6,
|
||||
radiopreset_ShortFast = 7,
|
||||
radiopreset_ShortTurbo = 8
|
||||
};
|
||||
BannerOverlayOptions bannerOptions;
|
||||
bannerOptions.message = "Radio Preset";
|
||||
bannerOptions.optionsArrayPtr = optionsArray;
|
||||
bannerOptions.optionsCount = 9;
|
||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||
if (selected == Back) {
|
||||
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||
screen->runNow();
|
||||
return;
|
||||
} else if (selected == radiopreset_LongSlow) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW;
|
||||
} else if (selected == radiopreset_LongModerate) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE;
|
||||
} else if (selected == radiopreset_LongFast) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||
} else if (selected == radiopreset_MediumSlow) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW;
|
||||
} else if (selected == radiopreset_MediumFast) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST;
|
||||
} else if (selected == radiopreset_ShortSlow) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW;
|
||||
} else if (selected == radiopreset_ShortFast) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST;
|
||||
} else if (selected == radiopreset_ShortTurbo) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO;
|
||||
}
|
||||
service->reloadConfig(SEGMENT_CONFIG);
|
||||
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||
static const RadioPresetOption presetOptions[] = {
|
||||
{"Back", OptionsAction::Back},
|
||||
{"LongTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO},
|
||||
{"LongModerate", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE},
|
||||
{"LongFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST},
|
||||
{"MediumSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW},
|
||||
{"MediumFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST},
|
||||
{"ShortSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW},
|
||||
{"ShortFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST},
|
||||
{"ShortTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO},
|
||||
};
|
||||
|
||||
constexpr size_t presetCount = sizeof(presetOptions) / sizeof(presetOptions[0]);
|
||||
static std::array<const char *, presetCount> presetLabels{};
|
||||
|
||||
auto bannerOptions =
|
||||
createStaticBannerOptions("Radio Preset", presetOptions, presetLabels, [](const RadioPresetOption &option, int) -> void {
|
||||
if (option.action == OptionsAction::Back) {
|
||||
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||
screen->runNow();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!option.hasValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
config.lora.modem_preset = option.value;
|
||||
service->reloadConfig(SEGMENT_CONFIG);
|
||||
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||
});
|
||||
|
||||
screen->showOverlayBanner(bannerOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,5 +99,24 @@ class menuHandler
|
||||
static void BluetoothToggleMenu();
|
||||
};
|
||||
|
||||
/* Generic Menu Options designations */
|
||||
enum class OptionsAction { Back, Select };
|
||||
|
||||
template <typename T> struct MenuOption {
|
||||
const char *label;
|
||||
OptionsAction action;
|
||||
bool hasValue;
|
||||
T value;
|
||||
|
||||
MenuOption(const char *labelIn, OptionsAction actionIn, T valueIn)
|
||||
: label(labelIn), action(actionIn), hasValue(true), value(valueIn)
|
||||
{
|
||||
}
|
||||
|
||||
MenuOption(const char *labelIn, OptionsAction actionIn) : label(labelIn), action(actionIn), hasValue(false), value() {}
|
||||
};
|
||||
|
||||
using RadioPresetOption = MenuOption<meshtastic_Config_LoRaConfig_ModemPreset>;
|
||||
|
||||
} // namespace graphics
|
||||
#endif
|
||||
@@ -428,10 +428,17 @@ void setup()
|
||||
#endif
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
RTCQuality ourQuality = RTCQualityDevice;
|
||||
|
||||
std::string timeCommandResult = exec("timedatectl status | grep synchronized | grep yes -c");
|
||||
if (timeCommandResult[0] == '1') {
|
||||
ourQuality = RTCQualityNTP;
|
||||
}
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = time(NULL);
|
||||
tv.tv_usec = 0;
|
||||
perhapsSetRTC(RTCQualityDevice, &tv);
|
||||
perhapsSetRTC(ourQuality, &tv);
|
||||
#endif
|
||||
|
||||
powerMonInit();
|
||||
|
||||
@@ -96,6 +96,8 @@ class Channels
|
||||
|
||||
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
|
||||
|
||||
int16_t getHash(ChannelIndex i) { return hashes[i]; }
|
||||
|
||||
private:
|
||||
/** Given a channel index, change to use the crypto key specified by that index
|
||||
*
|
||||
@@ -113,8 +115,6 @@ class Channels
|
||||
*/
|
||||
int16_t generateHash(ChannelIndex channelNum);
|
||||
|
||||
int16_t getHash(ChannelIndex i) { return hashes[i]; }
|
||||
|
||||
/**
|
||||
* Validate a channel, fixing any errors as needed
|
||||
*/
|
||||
|
||||
@@ -503,6 +503,11 @@ void RadioInterface::applyModemConfig()
|
||||
cr = 5;
|
||||
sf = 10;
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||
bw = (myRegion->wideLora) ? 1625.0 : 500;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
break;
|
||||
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 5;
|
||||
@@ -539,13 +544,26 @@ void RadioInterface::applyModemConfig()
|
||||
}
|
||||
|
||||
if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) {
|
||||
static const char *err_string = "Regional frequency range is smaller than bandwidth. Fall back to default preset";
|
||||
LOG_ERROR(err_string);
|
||||
const float regionSpanKHz = (myRegion->freqEnd - myRegion->freqStart) * 1000.0f;
|
||||
const float requestedBwKHz = bw;
|
||||
const bool isWideRequest = requestedBwKHz >= 499.5f; // treat as 500 kHz preset
|
||||
const char *presetName =
|
||||
DisplayFormatters::getModemPresetDisplayName(loraConfig.modem_preset, false, loraConfig.use_preset);
|
||||
|
||||
char err_string[160];
|
||||
if (isWideRequest) {
|
||||
snprintf(err_string, sizeof(err_string), "%s region too narrow for 500kHz preset (%s). Falling back to LongFast.",
|
||||
myRegion->name, presetName);
|
||||
} else {
|
||||
snprintf(err_string, sizeof(err_string), "%s region span %.0fkHz < requested %.0fkHz. Falling back to LongFast.",
|
||||
myRegion->name, regionSpanKHz, requestedBwKHz);
|
||||
}
|
||||
LOG_ERROR("%s", err_string);
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
|
||||
cn->level = meshtastic_LogRecord_Level_ERROR;
|
||||
sprintf(cn->message, err_string);
|
||||
snprintf(cn->message, sizeof(cn->message), "%s", err_string);
|
||||
service->sendClientNotification(cn);
|
||||
|
||||
// Set to default modem preset
|
||||
|
||||
@@ -692,7 +692,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
|
||||
// Store a copy of encrypted packet for MQTT
|
||||
DEBUG_HEAP_BEFORE;
|
||||
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
|
||||
p_encrypted = packetPool.allocCopy(*p);
|
||||
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
||||
|
||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||
|
||||
@@ -91,6 +91,9 @@ class Router : protected concurrency::OSThread, protected PacketHistory
|
||||
before us */
|
||||
uint32_t rxDupe = 0, txRelayCanceled = 0;
|
||||
|
||||
// pointer to the encrypted packet
|
||||
meshtastic_MeshPacket *p_encrypted;
|
||||
|
||||
protected:
|
||||
friend class RoutingModule;
|
||||
|
||||
|
||||
@@ -293,7 +293,8 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
|
||||
typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
||||
/* Long Range - Fast */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0,
|
||||
/* Long Range - Slow */
|
||||
/* Long Range - Slow
|
||||
Deprecated in 2.7: Unpopular slow preset. */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW = 1,
|
||||
/* Very Long Range - Slow
|
||||
Deprecated in 2.5: Works only with txco and is unusably slow */
|
||||
@@ -311,7 +312,10 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
||||
/* Short Range - Turbo
|
||||
This is the fastest preset and the only one with 500kHz bandwidth.
|
||||
It is not legal to use in all regions due to this wider bandwidth. */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8,
|
||||
/* Long Range - Turbo
|
||||
This preset performs similarly to LongFast, but with 500Khz bandwidth. */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO = 9
|
||||
} meshtastic_Config_LoRaConfig_ModemPreset;
|
||||
|
||||
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
|
||||
@@ -689,8 +693,8 @@ extern "C" {
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1))
|
||||
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO+1))
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO+1))
|
||||
|
||||
#define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
||||
#define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN
|
||||
|
||||
@@ -24,6 +24,9 @@ PB_BIND(meshtastic_Data, meshtastic_Data, 2)
|
||||
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_StoreForwardPlusPlus, meshtastic_StoreForwardPlusPlus, 2)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
||||
|
||||
|
||||
@@ -121,6 +124,8 @@ PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -478,6 +478,17 @@ typedef enum _meshtastic_Routing_Error {
|
||||
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
||||
} meshtastic_Routing_Error;
|
||||
|
||||
/* enum message type? */
|
||||
typedef enum _meshtastic_StoreForwardPlusPlus_SFPP_message_type {
|
||||
/* message hash without chain hash means that no, it is not on the chain */
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE = 0,
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CHAIN_QUERY = 1,
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST = 3,
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE = 4,
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_FIRSTHALF = 5,
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF = 6
|
||||
} meshtastic_StoreForwardPlusPlus_SFPP_message_type;
|
||||
|
||||
/* The priority of this message for sending.
|
||||
Higher priorities are sent first (when managing the transmit queue).
|
||||
This field is never sent over the air, it is only used internally inside of a local device node.
|
||||
@@ -782,6 +793,24 @@ typedef struct _meshtastic_KeyVerification {
|
||||
meshtastic_KeyVerification_hash2_t hash2;
|
||||
} meshtastic_KeyVerification;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_message_hash_t;
|
||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_commit_hash_t;
|
||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_root_hash_t;
|
||||
typedef PB_BYTES_ARRAY_T(240) meshtastic_StoreForwardPlusPlus_message_t;
|
||||
/* The actual over-the-mesh message doing store and forward++ */
|
||||
typedef struct _meshtastic_StoreForwardPlusPlus { /* */
|
||||
meshtastic_StoreForwardPlusPlus_SFPP_message_type sfpp_message_type;
|
||||
meshtastic_StoreForwardPlusPlus_message_hash_t message_hash;
|
||||
meshtastic_StoreForwardPlusPlus_commit_hash_t commit_hash;
|
||||
meshtastic_StoreForwardPlusPlus_root_hash_t root_hash;
|
||||
/* encapsulated message to share (may be split in half) */
|
||||
meshtastic_StoreForwardPlusPlus_message_t message;
|
||||
uint32_t encapsulated_id;
|
||||
uint32_t encapsulated_to;
|
||||
uint32_t encapsulated_from;
|
||||
uint32_t encapsulated_rxtime;
|
||||
} meshtastic_StoreForwardPlusPlus;
|
||||
|
||||
/* Waypoint message, used to share arbitrary locations across the mesh */
|
||||
typedef struct _meshtastic_Waypoint {
|
||||
/* Id of the waypoint */
|
||||
@@ -1310,6 +1339,10 @@ extern "C" {
|
||||
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
||||
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
||||
|
||||
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE
|
||||
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MAX meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF
|
||||
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_ARRAYSIZE ((meshtastic_StoreForwardPlusPlus_SFPP_message_type)(meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF+1))
|
||||
|
||||
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
||||
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
||||
#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX+1))
|
||||
@@ -1338,6 +1371,8 @@ extern "C" {
|
||||
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
||||
|
||||
|
||||
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_ENUMTYPE meshtastic_StoreForwardPlusPlus_SFPP_message_type
|
||||
|
||||
|
||||
|
||||
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
||||
@@ -1380,6 +1415,7 @@ extern "C" {
|
||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
||||
#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
|
||||
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
||||
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||
@@ -1411,6 +1447,7 @@ extern "C" {
|
||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
||||
#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
|
||||
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
||||
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||
@@ -1489,6 +1526,15 @@ extern "C" {
|
||||
#define meshtastic_KeyVerification_nonce_tag 1
|
||||
#define meshtastic_KeyVerification_hash1_tag 2
|
||||
#define meshtastic_KeyVerification_hash2_tag 3
|
||||
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_tag 1
|
||||
#define meshtastic_StoreForwardPlusPlus_message_hash_tag 2
|
||||
#define meshtastic_StoreForwardPlusPlus_commit_hash_tag 3
|
||||
#define meshtastic_StoreForwardPlusPlus_root_hash_tag 4
|
||||
#define meshtastic_StoreForwardPlusPlus_message_tag 5
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_id_tag 6
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_to_tag 7
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_from_tag 8
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_rxtime_tag 9
|
||||
#define meshtastic_Waypoint_id_tag 1
|
||||
#define meshtastic_Waypoint_latitude_i_tag 2
|
||||
#define meshtastic_Waypoint_longitude_i_tag 3
|
||||
@@ -1705,6 +1751,19 @@ X(a, STATIC, SINGULAR, BYTES, hash2, 3)
|
||||
#define meshtastic_KeyVerification_CALLBACK NULL
|
||||
#define meshtastic_KeyVerification_DEFAULT NULL
|
||||
|
||||
#define meshtastic_StoreForwardPlusPlus_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, sfpp_message_type, 1) \
|
||||
X(a, STATIC, SINGULAR, BYTES, message_hash, 2) \
|
||||
X(a, STATIC, SINGULAR, BYTES, commit_hash, 3) \
|
||||
X(a, STATIC, SINGULAR, BYTES, root_hash, 4) \
|
||||
X(a, STATIC, SINGULAR, BYTES, message, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_id, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_to, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_from, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9)
|
||||
#define meshtastic_StoreForwardPlusPlus_CALLBACK NULL
|
||||
#define meshtastic_StoreForwardPlusPlus_DEFAULT NULL
|
||||
|
||||
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
||||
@@ -1980,6 +2039,7 @@ extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Data_msg;
|
||||
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
||||
extern const pb_msgdesc_t meshtastic_StoreForwardPlusPlus_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
||||
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
||||
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
||||
@@ -2013,6 +2073,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
||||
#define meshtastic_Data_fields &meshtastic_Data_msg
|
||||
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
||||
#define meshtastic_StoreForwardPlusPlus_fields &meshtastic_StoreForwardPlusPlus_msg
|
||||
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
||||
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
||||
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
||||
@@ -2069,6 +2130,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
#define meshtastic_QueueStatus_size 23
|
||||
#define meshtastic_RouteDiscovery_size 256
|
||||
#define meshtastic_Routing_size 259
|
||||
#define meshtastic_StoreForwardPlusPlus_size 371
|
||||
#define meshtastic_ToRadio_size 504
|
||||
#define meshtastic_User_size 115
|
||||
#define meshtastic_Waypoint_size 165
|
||||
|
||||
@@ -86,6 +86,9 @@ typedef enum _meshtastic_PortNum {
|
||||
/* Paxcounter lib included in the firmware
|
||||
ENCODING: protobuf */
|
||||
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
||||
/* Store and Forward++ module included in the firmware
|
||||
ENCODING: protobuf */
|
||||
meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP = 35,
|
||||
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
||||
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
||||
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#if ARCH_PORTDUINO
|
||||
#include "input/LinuxInputImpl.h"
|
||||
#include "input/SeesawRotary.h"
|
||||
#include "modules/Native/StoreForwardPlusPlus.h"
|
||||
#include "modules/Telemetry/HostMetrics.h"
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
@@ -243,6 +244,7 @@ void setupModules()
|
||||
#endif
|
||||
#if ARCH_PORTDUINO
|
||||
new HostMetricsModule();
|
||||
new StoreForwardPlusPlusModule();
|
||||
#endif
|
||||
#if HAS_TELEMETRY
|
||||
new DeviceTelemetryModule();
|
||||
|
||||
1042
src/modules/Native/StoreForwardPlusPlus.cpp
Normal file
1042
src/modules/Native/StoreForwardPlusPlus.cpp
Normal file
File diff suppressed because it is too large
Load Diff
212
src/modules/Native/StoreForwardPlusPlus.h
Normal file
212
src/modules/Native/StoreForwardPlusPlus.h
Normal file
@@ -0,0 +1,212 @@
|
||||
#pragma once
|
||||
#include "Channels.h"
|
||||
#include "ProtobufModule.h"
|
||||
#include "Router.h"
|
||||
#include "SinglePortModule.h"
|
||||
#include "sqlite3.h"
|
||||
|
||||
/**
|
||||
* Store and forward ++ module
|
||||
* There's an obvious need for a store-and-forward mechanism in Meshtastic.
|
||||
* This module takes heavy inspiration from Git, building a chain of messages that can be synced between nodes.
|
||||
* Each message is hashed, and the chain is built by hashing the previous commit hash and the current message hash.
|
||||
* Nodes can request missing messages by requesting the next message after a given commit hash.
|
||||
*
|
||||
* The current focus is text messages, limited to the primary channel.
|
||||
*
|
||||
* Each chain is identified by a root hash, which is derived from the channelHash, the local nodenum, and the timestamp when
|
||||
* created.
|
||||
*
|
||||
* Each message is also given a message hash, derived from the encrypted payload, the to, from, id.
|
||||
* Notably not the timestamp, as we want these to match across nodes, even if the timestamps differ.
|
||||
*
|
||||
* The authoritative node for the chain will generate a commit hash for each message when adding it to the chain.
|
||||
* The first message's commit hash is derived from the root hash and the message hash.
|
||||
* Subsequent messages' commit hashes are derived from the previous commit hash and the current message hash.
|
||||
* This allows a node to see only the last commit hash, and confirm it hasn't missed any messages.
|
||||
*
|
||||
* Nodes can request the next message in the chain by sending a LINK_REQUEST message with the root hash and the last known commit
|
||||
* hash. Any node that has the next message can respond with a LINK_PROVIDE message containing the next message.
|
||||
*
|
||||
* When a satellite node sees a new text message, it stores it in a scratch database.
|
||||
* These messages are periodically offered to the authoritative node for inclusion in the chain.
|
||||
*
|
||||
* The LINK_PROVIDE message does double-duty, sending both on-chain and off-chain messages.
|
||||
* The differentiator is whether the commit hash is set or left empty.
|
||||
*
|
||||
* When a satellite node receives a canonical link message, it checks if it has the message in scratch.
|
||||
* And evicts it when adding it to the canonical chain.
|
||||
*
|
||||
* This approach allows a node to know whether it has seen a given message before, or if it is new coming via SFPP.
|
||||
* If new, and the timestamp is within the rebroadcast timeout, it will process that message as if it were just received from the
|
||||
* mesh, allowing it to be decrypted, shown to the user, and rebroadcast.
|
||||
*/
|
||||
class StoreForwardPlusPlusModule : public ProtobufModule<meshtastic_StoreForwardPlusPlus>, private concurrency::OSThread
|
||||
{
|
||||
struct link_object {
|
||||
uint32_t to;
|
||||
uint32_t from;
|
||||
uint32_t id;
|
||||
uint32_t rx_time = 0;
|
||||
ChannelHash channel_hash;
|
||||
uint8_t encrypted_bytes[256] = {0};
|
||||
size_t encrypted_len;
|
||||
uint8_t message_hash[32] = {0};
|
||||
size_t message_hash_len = 0;
|
||||
uint8_t root_hash[32] = {0};
|
||||
size_t root_hash_len = 0;
|
||||
uint8_t commit_hash[32] = {0};
|
||||
size_t commit_hash_len = 0;
|
||||
uint32_t counter = 0;
|
||||
std::string payload;
|
||||
bool validObject = true; // set this false when a chain calulation fails, etc.
|
||||
};
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
*
|
||||
*/
|
||||
StoreForwardPlusPlusModule();
|
||||
|
||||
/*
|
||||
-Override the wantPacket method.
|
||||
*/
|
||||
virtual bool wantPacket(const meshtastic_MeshPacket *p) override
|
||||
{
|
||||
switch (p->decoded.portnum) {
|
||||
case meshtastic_PortNum_TEXT_MESSAGE_APP:
|
||||
case meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Called to handle a particular incoming message
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||
it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
|
||||
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_StoreForwardPlusPlus *t) override;
|
||||
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
private:
|
||||
sqlite3 *ppDb;
|
||||
sqlite3_stmt *chain_insert_stmt;
|
||||
sqlite3_stmt *scratch_insert_stmt;
|
||||
sqlite3_stmt *checkDup;
|
||||
sqlite3_stmt *checkScratch;
|
||||
sqlite3_stmt *removeScratch;
|
||||
sqlite3_stmt *updatePayloadStmt;
|
||||
sqlite3_stmt *getPayloadFromScratchStmt;
|
||||
sqlite3_stmt *fromScratchStmt;
|
||||
sqlite3_stmt *fromScratchByHashStmt;
|
||||
sqlite3_stmt *getNextHashStmt;
|
||||
sqlite3_stmt *getChainEndStmt;
|
||||
sqlite3_stmt *getLinkStmt;
|
||||
sqlite3_stmt *getHashFromRootStmt;
|
||||
sqlite3_stmt *addRootToMappingsStmt;
|
||||
sqlite3_stmt *getRootFromChannelHashStmt;
|
||||
sqlite3_stmt *getFullRootHashStmt;
|
||||
sqlite3_stmt *setChainCountStmt;
|
||||
sqlite3_stmt *getChainCountStmt;
|
||||
|
||||
// For a given Meshtastic ChannelHash, fills the root_hash buffer with a 32-byte root hash
|
||||
// returns true if the root hash was found
|
||||
bool getRootFromChannelHash(ChannelHash, uint8_t *);
|
||||
|
||||
// For a given root hash, returns the ChannelHash
|
||||
// can handle partial root hashes
|
||||
ChannelHash getChannelHashFromRoot(uint8_t *_root_hash, size_t);
|
||||
|
||||
// given a root hash and commit hash, returns the next commit hash in the chain
|
||||
// can handle partial root and commit hashes, always fills the buffer with 32 bytes
|
||||
// returns true if a next hash was found
|
||||
bool getNextHash(uint8_t *, size_t, uint8_t *, size_t, uint8_t *);
|
||||
|
||||
// For a given Meshtastic ChannelHash, fills the root_hash buffer with a 32-byte root hash
|
||||
// but this function will add the root hash if it is not already present
|
||||
// returns true if the hash is new
|
||||
bool getOrAddRootFromChannelHash(ChannelHash, uint8_t *);
|
||||
|
||||
// adds the ChannelHash and root_hash to the mappings table
|
||||
void addRootToMappings(ChannelHash, uint8_t *);
|
||||
|
||||
// gets the tip of the chain for the given root hash
|
||||
link_object getChainEndLinkObject(uint8_t *, size_t);
|
||||
|
||||
// requests the next message in the chain from the mesh network
|
||||
// Sends a LINK_REQUEST message
|
||||
void requestNextMessage(uint8_t *, size_t, uint8_t *, size_t);
|
||||
|
||||
// sends a LINK_PROVIDE message broadcasting the given link object
|
||||
void broadcastLink(uint8_t *, size_t);
|
||||
|
||||
// sends a LINK_PROVIDE message broadcasting the given link object from scratch message store
|
||||
bool sendFromScratch(uint8_t);
|
||||
|
||||
// Adds the given link object to the canonical chain database
|
||||
bool addToChain(link_object &);
|
||||
|
||||
// Adds an incoming text message to the scratch database
|
||||
bool addToScratch(link_object &);
|
||||
|
||||
// sends a CANON_ANNOUNCE message, specifying the given root and commit hashes
|
||||
void canonAnnounce(uint8_t *, uint8_t *, uint8_t *, uint32_t);
|
||||
|
||||
// checks if the message hash is present in the canonical chain database
|
||||
bool isInDB(uint8_t *, size_t);
|
||||
|
||||
// checks if the message hash is present in the scratch database
|
||||
bool isInScratch(uint8_t *, size_t);
|
||||
|
||||
// retrieves a link object from the scratch database
|
||||
link_object getFromScratch(uint8_t *, size_t);
|
||||
|
||||
// removes a link object from the scratch database
|
||||
void removeFromScratch(uint8_t *, size_t);
|
||||
|
||||
// fills the payload section with the decrypted data for the given message hash
|
||||
// probably not needed for production, but useful for testing
|
||||
void updatePayload(uint8_t *, size_t, std::string);
|
||||
|
||||
// Takes the decrypted MeshPacket and the encrypted packet copy, and builds a link_object
|
||||
// Generates a message hash, but does not set the commit hash
|
||||
link_object ingestTextPacket(const meshtastic_MeshPacket &, const meshtastic_MeshPacket *);
|
||||
|
||||
// ingests a LINK_PROVIDE message and builds a link_object
|
||||
// confirms the root hash and commit hash
|
||||
link_object ingestLinkMessage(meshtastic_StoreForwardPlusPlus *);
|
||||
|
||||
// retrieves a link object from the canonical chain database given a message hash
|
||||
link_object getLink(uint8_t *, size_t);
|
||||
|
||||
// puts the encrypted payload back into the queue as if it were just received
|
||||
void rebroadcastLinkObject(link_object &);
|
||||
|
||||
// Check if an incoming link object's commit hash matches the calculated commit hash
|
||||
bool checkCommitHash(link_object &lo, uint8_t *commit_hash_bytes, size_t hash_len);
|
||||
|
||||
// given a partial root hash, looks up the full 32-byte root hash
|
||||
// returns true if found
|
||||
bool lookUpFullRootHash(uint8_t *partial_root_hash, size_t partial_root_hash_len, uint8_t *full_root_hash);
|
||||
|
||||
// update the mappings table to set the chain count for the given root hash
|
||||
void setChainCount(uint8_t *, size_t, uint32_t);
|
||||
|
||||
// query the mappings table for the chain count for the given root hash
|
||||
uint32_t getChainCount(uint8_t *, size_t);
|
||||
|
||||
// Track if we have a scheduled runOnce pending
|
||||
// useful to not accudentally delay a scheduled runOnce
|
||||
bool pendingRun = false;
|
||||
|
||||
// Once we have multiple chain types, we can extend this
|
||||
enum chain_types {
|
||||
channel_chain = 0,
|
||||
};
|
||||
|
||||
uint32_t rebroadcastTimeout = 3600; // Messages older than this (in seconds) will not be rebroadcast
|
||||
};
|
||||
@@ -786,6 +786,10 @@ bool loadConfig(const char *configPath)
|
||||
}
|
||||
}
|
||||
|
||||
if (yamlConfig["StoreAndForward"]) {
|
||||
portduino_config.sfpp_stratum0 = (yamlConfig["StoreAndForward"]["Stratum0"]).as<bool>(false);
|
||||
}
|
||||
|
||||
if (yamlConfig["General"]) {
|
||||
portduino_config.MaxNodes = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
|
||||
portduino_config.maxtophone = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
|
||||
|
||||
@@ -169,6 +169,9 @@ extern struct portduino_config_struct {
|
||||
int configDisplayMode = 0;
|
||||
bool has_configDisplayMode = false;
|
||||
|
||||
// Store and Forward++
|
||||
bool sfpp_stratum0 = false;
|
||||
|
||||
// General
|
||||
std::string mac_address = "";
|
||||
bool mac_address_explicit = false;
|
||||
|
||||
@@ -45,6 +45,7 @@ build_flags = ${native_base.build_flags} -Os -lX11 -linput -lxkbcommon -ffunctio
|
||||
!pkg-config --libs openssl --silence-errors || :
|
||||
!pkg-config --cflags --libs sdl2 --silence-errors || :
|
||||
!pkg-config --cflags --libs libbsd-overlay --silence-errors || :
|
||||
!pkg-config --cflags --libs sqlite3 --silence-errors || :
|
||||
build_src_filter =
|
||||
${native_base.build_src_filter}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user