WIP: Pull request for diff purposes (original source code from meshtastic/firmware and my modified version) #1

Draft
pohui_pohui wants to merge 2 commits from original into master
55 changed files with 2026 additions and 96 deletions

25
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,25 @@
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
# [Optional] Uncomment this section to install additional packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends \
ca-certificates \
g++ \
git \
libbluetooth-dev \
libgpiod-dev \
liborcania-dev \
libssl-dev \
libulfius-dev \
libyaml-cpp-dev \
pipx \
pkg-config \
python3 \
python3-pip \
python3-venv \
python3-wheel \
wget \
zip \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN pipx install platformio==6.1.15

View File

@ -0,0 +1,25 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/cpp
{
"name": "Meshtastic Firmware Dev",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/python:1": {
"installTools": true,
"version": "latest"
}
},
"customizations": {
"vscode": {
"extensions": ["ms-vscode.cpptools", "platformio.platformio-ide"]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [4403],
// Run commands to prepare the container for use
"postCreateCommand": ".devcontainer/setup.sh"
}

3
.devcontainer/setup.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env sh
git submodule update --init

99
.github/ISSUE_TEMPLATE/Bug Report.yml vendored Normal file
View File

@ -0,0 +1,99 @@
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: dropdown
id: category
attributes:
label: Category
description: How would you catagorize this issue?
multiple: true
options:
- Hardware Compatibility
- BLE
- Serial
- WiFi
- Other
validations:
required: true
- type: dropdown
id: hardware
attributes:
label: Hardware
description: What hardware are you encountering this issue on?
multiple: true
options:
- Not Applicable
- T-Beam
- T-Beam S3
- T-Beam 0.7
- T-Lora v1
- T-Lora v1.3
- T-Lora v2 1.6
- T-Deck
- T-Echo
- T-Watch
- Rak4631
- Rak11200
- Rak11310
- Heltec v1
- Heltec v2
- Heltec v2.1
- Heltec V3
- Heltec Wireless Paper
- Heltec Wireless Tracker
- Heltec Mesh Node T114
- Heltec Vision Master E213
- Heltec Vision Master E290
- Heltec Vision Master T190
- Nano G1
- Nano G1 Explorer
- Nano G2 Ultra
- Raspberry Pi Pico (W)
- Relay v1
- Relay v2
- Seeed Wio Tracker 1110
- Seeed Card Tracker T1000-E
- Station G1
- Station G2
- unPhone
- CanaryOne
- Chatter
- Linux Native
- DIY
- Other
validations:
required: true
- type: input
id: version
attributes:
label: Firmware Version
description: This can be found on the device's screen or via one of the apps.
placeholder: x.x.x.yyyyyyy
validations:
required: true
- type: textarea
id: body
attributes:
label: Description
description: Please provide details on what steps you performed for this to happen.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: If you have any log output to help in diagnosing your bug, please provide it here.
render: Shell
validations:
required: false

46
.github/ISSUE_TEMPLATE/New Board.yml vendored Normal file
View File

@ -0,0 +1,46 @@
name: New Board
description: Request us to support new hardware
title: "[Board]: "
labels: ["enhancement", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for requesting a new board, this will not gurantee that we will support it, but will be on our radar.
- type: dropdown
id: soc
attributes:
label: SOC
description: What SOC does your board have?
multiple: true
options:
- NRF52
- ESP32
- Other
validations:
required: true
- type: input
id: lora
attributes:
label: Lora IC
description: What LoRa IC does the board have?
validations:
required: true
- type: input
id: link
attributes:
label: Product Link
description: Where can we find this product?
validations:
required: true
- type: textarea
id: body
attributes:
label: Description
description: Please provide any further details you think we may need.
validations:
required: true

31
.github/ISSUE_TEMPLATE/feature.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Feature Request
description: Request a new feature
title: "[Feature Request]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for your request this will not gurantee that we will implement it, but it will be reviewed.
- type: dropdown
id: soc
attributes:
label: Platform
description: What device platform will support your feature?
multiple: true
options:
- NRF52
- ESP32
- RP2040
- Linux Native
- Cross-Platform
- other
validations:
required: true
- type: textarea
id: body
attributes:
label: Description
description: Please provide details about your enhancement.
validations:
required: true

View File

@ -0,0 +1,94 @@
name: Setup Build Variant Composite Action
description: Variant build actions for Meshtastic Platform IO steps
inputs:
board:
description: The board to build for
required: true
github_token:
description: GitHub token
required: true
build-script-path:
description: Path to the build script
required: true
remove-debug-flags:
description: A space separated list of files to remove debug flags from
required: false
default: ""
ota-firmware-source:
description: The OTA firmware file to pull
required: false
default: ""
ota-firmware-target:
description: The target path to store the OTA firmware file
required: false
default: ""
artifact-paths:
description: A newline separated list of paths to store as artifacts
required: false
default: ""
include-web-ui:
description: Include the web UI in the build
required: false
default: "false"
arch:
description: Processor arch name
required: true
default: "esp32"
runs:
using: composite
steps:
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Pull web ui
if: inputs.include-web-ui == 'true'
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ inputs.github_token }}
- name: Unpack web ui
if: inputs.include-web-ui == 'true'
shell: bash
run: |
tar -xf build.tar -C data/static
rm build.tar
- name: Remove debug flags for release
shell: bash
if: inputs.remove-debug-flags != ''
run: |
for INI_FILE in ${{ inputs.remove-debug-flags }}; do
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
done
- name: Build ${{ inputs.board }}
shell: bash
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
- name: Pull OTA Firmware
if: inputs.ota-firmware-source != '' && inputs.ota-firmware-target != ''
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/firmware-ota
file: ${{ inputs.ota-firmware-source }}
target: ${{ inputs.ota-firmware-target }}
token: ${{ inputs.github_token }}
- name: Get release version string
shell: bash
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
${{ inputs.artifact-paths }}

49
.github/actions/setup-base/action.yml vendored Normal file
View File

@ -0,0 +1,49 @@
name: "Setup Build Base Composite Action"
description: "Base build actions for Meshtastic Platform IO steps"
runs:
using: "composite"
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Uncomment build epoch
shell: bash
run: |
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
- name: Install dependencies
shell: bash
run: |
sudo apt-get -y update --fix-missing
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.x
# - name: Cache python libs
# uses: actions/cache@v4
# id: cache-pip # needed in if test
# with:
# path: ~/.cache/pip
# key: ${{ runner.os }}-pip
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U --no-build-isolation --no-cache-dir "setuptools<72"
pip install -U platformio adafruit-nrfutil --no-build-isolation
pip install -U poetry --no-build-isolation
pip install -U meshtastic --pre --no-build-isolation
- name: Upgrade platformio
shell: bash
run: |
pio upgrade

26
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,26 @@
version: 2
updates:
- package-ecosystem: docker
directory: devcontainer
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific
- package-ecosystem: docker
directory: /
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific
- package-ecosystem: gitsubmodule
directory: /
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific
- package-ecosystem: github-actions
directory: /.github/workflows
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific

15
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,15 @@
### ❌ (Please delete all these tips and replace them with your text) ❌
## Thank you for sending in a pull request, here's some tips to get started!
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed.
- Please also enable "Allow edits by maintainers".
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord

34
.github/workflows/build_esp32.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Build ESP32
on:
workflow_call:
inputs:
board:
required: true
type: string
jobs:
build-esp32:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ESP32
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
remove-debug-flags: >-
./arch/esp32/esp32.ini
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini
build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware.bin
ota-firmware-target: release/bleota.bin
artifact-paths: |
release/*.bin
release/*.elf
include-web-ui: true
arch: esp32

35
.github/workflows/build_esp32_c3.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: Build ESP32-C3
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32-c3:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ESP32-C3
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
remove-debug-flags: >-
./arch/esp32/esp32.ini
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini
build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware-c3.bin
ota-firmware-target: release/bleota-c3.bin
artifact-paths: |
release/*.bin
release/*.elf
arch: esp32c3

36
.github/workflows/build_esp32_c6.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Build ESP32-C6
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32-c6:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ESP32-C6
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
remove-debug-flags: >-
./arch/esp32/esp32.ini
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini
./arch/esp32/esp32c6.ini
build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware-c3.bin
ota-firmware-target: release/bleota-c3.bin
artifact-paths: |
release/*.bin
release/*.elf
arch: esp32c6

34
.github/workflows/build_esp32_s3.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Build ESP32-S3
on:
workflow_call:
inputs:
board:
required: true
type: string
jobs:
build-esp32-s3:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ESP32-S3
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
remove-debug-flags: >-
./arch/esp32/esp32.ini
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini
build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware-s3.bin
ota-firmware-target: release/bleota-s3.bin
artifact-paths: |
release/*.bin
release/*.elf
include-web-ui: true
arch: esp32s3

85
.github/workflows/build_native.yml vendored Normal file
View File

@ -0,0 +1,85 @@
name: Build Native
on: workflow_call
permissions:
contents: write
packages: write
jobs:
build-native:
runs-on: ubuntu-latest
steps:
- name: Install libs needed for native build
shell: bash
run: |
sudo apt-get update --fix-missing
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U meshtastic --pre
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Build Native
run: bin/build-native.sh
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-native-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
release/meshtasticd_linux_x86_64
bin/config-dist.yaml
- name: Docker login
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/login-action@v3
continue-on-error: true # FIXME: Failing docker login auth
with:
username: meshtastic
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
- name: Docker setup
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
continue-on-error: true # FIXME: Failing docker login auth
uses: docker/setup-buildx-action@v3
- name: Docker build and push tagged versions
if: ${{ github.event_name == 'workflow_dispatch' }}
continue-on-error: true # FIXME: Failing docker login auth
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
- name: Docker build and push
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
continue-on-error: true # FIXME: Failing docker login auth
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
tags: meshtastic/device-simulator:latest

28
.github/workflows/build_nrf52.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: Build NRF52
on:
workflow_call:
inputs:
board:
required: true
type: string
jobs:
build-nrf52:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build NRF52
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
build-script-path: bin/build-nrf52.sh
artifact-paths: |
release/*.hex
release/*.uf2
release/*.elf
release/*.zip
arch: nrf52840

52
.github/workflows/build_raspbian.yml vendored Normal file
View File

@ -0,0 +1,52 @@
name: Build Raspbian
on: workflow_call
permissions:
contents: write
packages: write
jobs:
build-raspbian:
runs-on: [self-hosted, linux, ARM64]
steps:
- name: Install libbluetooth
shell: bash
run: |
apt-get update -y --fix-missing
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U meshtastic --pre
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Build Raspbian
run: bin/build-native.sh
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
release/meshtasticd_linux_aarch64
bin/config-dist.yaml

View File

@ -0,0 +1,52 @@
name: Build Raspbian Arm
on: workflow_call
permissions:
contents: write
packages: write
jobs:
build-raspbian-armv7l:
runs-on: [self-hosted, linux, ARM]
steps:
- name: Install libbluetooth
shell: bash
run: |
apt-get update -y --fix-missing
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U meshtastic --pre
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Build Raspbian
run: bin/build-native.sh
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
release/meshtasticd_linux_armv7l
bin/config-dist.yaml

26
.github/workflows/build_rpi2040.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: Build RPI2040
on:
workflow_call:
inputs:
board:
required: true
type: string
jobs:
build-rpi2040:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Raspberry Pi 2040
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
build-script-path: bin/build-rpi2040.sh
artifact-paths: |
release/*.uf2
release/*.elf
arch: rp2040

27
.github/workflows/build_stm32.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Build STM32
on:
workflow_call:
inputs:
board:
required: true
type: string
jobs:
build-stm32:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build STM32WL
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
build-script-path: bin/build-stm32.sh
artifact-paths: |
release/*.hex
release/*.bin
release/*.elf
arch: stm32

View File

@ -0,0 +1,35 @@
name: Generate UsersPrefs JSON manifest
on:
push:
paths:
- userPrefs.h
branches:
- master
jobs:
generate-userprefs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Clang
run: sudo apt-get install -y clang
- name: Install trunk
run: curl https://get.trunk.io -fsSL | bash
- name: Generate userPrefs.jsom
run: python3 ./bin/build-userprefs-json.py
- name: Trunk format json
run: trunk format userPrefs.json
- name: Commit userPrefs.json
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
git add userPrefs.json
git commit -m "Update userPrefs.json"
git push

401
.github/workflows/main_matrix.yml vendored Normal file
View File

@ -0,0 +1,401 @@
name: CI
concurrency:
group: ci-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
# # Triggers the workflow on push but only for the master branch
push:
branches: [master, develop]
paths-ignore:
- "**.md"
- version.properties
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
pull_request_target:
branches: [master, develop]
paths-ignore:
- "**.md"
#- "**.yml"
workflow_dispatch:
jobs:
setup:
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32, check]
runs-on: ubuntu-latest
steps:
- id: checkout
uses: actions/checkout@v4
name: Checkout base
- id: jsonStep
run: |
if [[ "${{ github.head_ref }}" == "" ]]; then
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
else
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
fi
echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} Head: ${{ github.head_ref }} Ref: ${{ github.ref }} Targets: $TARGETS"
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
outputs:
esp32: ${{ steps.jsonStep.outputs.esp32 }}
esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }}
esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }}
esp32c6: ${{ steps.jsonStep.outputs.esp32c6 }}
nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }}
rp2040: ${{ steps.jsonStep.outputs.rp2040 }}
stm32: ${{ steps.jsonStep.outputs.stm32 }}
check: ${{ steps.jsonStep.outputs.check }}
check:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.check) }}
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Check ${{ matrix.board }}
run: bin/check-all.sh ${{ matrix.board }}
build-esp32:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32) }}
uses: ./.github/workflows/build_esp32.yml
with:
board: ${{ matrix.board }}
build-esp32-s3:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32s3) }}
uses: ./.github/workflows/build_esp32_s3.yml
with:
board: ${{ matrix.board }}
build-esp32-c3:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32c3) }}
uses: ./.github/workflows/build_esp32_c3.yml
with:
board: ${{ matrix.board }}
build-esp32-c6:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32c6) }}
uses: ./.github/workflows/build_esp32_c6.yml
with:
board: ${{ matrix.board }}
build-nrf52:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.nrf52840) }}
uses: ./.github/workflows/build_nrf52.yml
with:
board: ${{ matrix.board }}
build-rpi2040:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.rp2040) }}
uses: ./.github/workflows/build_rpi2040.yml
with:
board: ${{ matrix.board }}
build-stm32:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.stm32) }}
uses: ./.github/workflows/build_stm32.yml
with:
board: ${{ matrix.board }}
package-raspbian:
uses: ./.github/workflows/package_raspbian.yml
package-raspbian-armv7l:
uses: ./.github/workflows/package_raspbian_armv7l.yml
package-native:
uses: ./.github/workflows/package_amd64.yml
after-checks:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
needs: [check]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
gather-artifacts:
permissions:
contents: write
pull-requests: write
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
runs-on: ubuntu-latest
needs:
[
build-esp32,
build-esp32-s3,
build-esp32-c3,
build-esp32-c6,
build-nrf52,
build-rpi2040,
build-stm32,
]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v4
with:
path: ./
pattern: firmware-${{matrix.arch}}-*
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Move files up
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v4
with:
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
overwrite: true
path: |
./firmware-*.bin
./firmware-*.uf2
./firmware-*.hex
./firmware-*-ota.zip
./device-*.sh
./device-*.bat
./littlefs-*.bin
./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30
- uses: actions/download-artifact@v4
with:
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
- name: Repackage in single elfs zip
uses: actions/upload-artifact@v4
with:
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: ./*.elf
retention-days: 30
- uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }}
with:
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }}
release-artifacts:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
needs: [
gather-artifacts,
package-raspbian,
package-raspbian-armv7l,
package-native,
]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Create release
uses: actions/create-release@v1
id: create_release
with:
draft: true
prerelease: true
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }} Alpha
tag_name: v${{ steps.version.outputs.version }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Download deb files
uses: actions/download-artifact@v4
with:
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
merge-multiple: true
path: ./output
# For diagnostics
- name: Display structure of downloaded files
run: ls -lR
- name: Add raspbian aarch64 .deb
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
asset_content_type: application/vnd.debian.binary-package
- name: Add raspbian armv7l .deb
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
asset_content_type: application/vnd.debian.binary-package
- name: Add raspbian amd64 .deb
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
asset_content_type: application/vnd.debian.binary-package
- name: Bump version.properties
run: >-
bin/bump_version.py
- name: Create version.properties pull request
uses: peter-evans/create-pull-request@v7
with:
title: Bump version.properties
add-paths: |
version.properties
release-firmware:
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-artifacts]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- uses: actions/download-artifact@v4
with:
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
- name: Display structure of downloaded files
run: ls -lR
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
- uses: actions/download-artifact@v4
with:
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
merge-multiple: true
path: ./elfs
- name: Zip firmware
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./elfs
# For diagnostics
- name: Display structure of downloaded files
run: ls -lR
- name: Add bins to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
asset_path: ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add debug elfs to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
asset_path: ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip

19
.github/workflows/nightly.yml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Nightly
on:
schedule:
- cron: 0 8 * * 1-5
workflow_dispatch: {}
jobs:
trunk_check:
name: Trunk Check Upload
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Trunk Check
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
with:
trunk-token: ${{ secrets.TRUNK_TOKEN }}

81
.github/workflows/package_amd64.yml vendored Normal file
View File

@ -0,0 +1,81 @@
name: Package Native
on:
workflow_call:
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
build-native:
uses: ./.github/workflows/build_native.yml
package-native:
runs-on: ubuntu-22.04
needs: build-native
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: firmware-native-${{ steps.version.outputs.version }}.zip
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: build .debpkg
run: |
mkdir -p .debpkg/DEBIAN
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
chmod +x .debpkg/DEBIAN/conffiles
- uses: jiro4989/build-deb-action@v3
with:
package: meshtasticd
package_root: .debpkg
maintainer: Jonathan Bennett
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
arch: amd64
depends: libyaml-cpp0.7, openssl, libulfius2.7
desc: Native Linux Meshtastic binary.
- uses: actions/upload-artifact@v4
with:
name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
overwrite: true
path: |
./*.deb

81
.github/workflows/package_raspbian.yml vendored Normal file
View File

@ -0,0 +1,81 @@
name: Package Raspbian
on:
workflow_call:
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
build-raspbian:
uses: ./.github/workflows/build_raspbian.yml
package-raspbian:
runs-on: ubuntu-22.04
needs: build-raspbian
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: build .debpkg
run: |
mkdir -p .debpkg/DEBIAN
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
chmod +x .debpkg/DEBIAN/conffiles
- uses: jiro4989/build-deb-action@v3
with:
package: meshtasticd
package_root: .debpkg
maintainer: Jonathan Bennett
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
arch: arm64
depends: libyaml-cpp0.7, openssl, libulfius2.7
desc: Native Linux Meshtastic binary.
- uses: actions/upload-artifact@v4
with:
name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
overwrite: true
path: |
./*.deb

View File

@ -0,0 +1,81 @@
name: Package Raspbian
on:
workflow_call:
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
build-raspbian_armv7l:
uses: ./.github/workflows/build_raspbian_armv7l.yml
package-raspbian_armv7l:
runs-on: ubuntu-22.04
needs: build-raspbian_armv7l
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: build .debpkg
run: |
mkdir -p .debpkg/DEBIAN
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
chmod +x .debpkg/DEBIAN/conffiles
- uses: jiro4989/build-deb-action@v3
with:
package: meshtasticd
package_root: .debpkg
maintainer: Jonathan Bennett
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
arch: armhf
depends: libyaml-cpp0.7, openssl, libulfius2.7
desc: Native Linux Meshtastic binary.
- uses: actions/upload-artifact@v4
with:
name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
overwrite: true
path: |
./*.deb

View File

@ -0,0 +1,41 @@
---
name: Flawfinder Scan
on:
push:
branches: [master, develop]
paths-ignore:
- "**.md"
- "version.properties"
jobs:
flawfinder:
runs-on: ubuntu-latest
name: Flawfinder
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v4
# step 2
- name: flawfinder_scan
uses: david-a-wheeler/flawfinder@2.0.19
with:
arguments: "--sarif ./"
output: "flawfinder_report.sarif"
# step 3
- name: save report as pipeline artifact
uses: actions/upload-artifact@v4
with:
name: flawfinder_report.sarif
overwrite: true
path: flawfinder_report.sarif
# step 4
- name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: flawfinder_report.sarif
category: flawfinder

View File

@ -0,0 +1,43 @@
---
name: Semgrep Full Scan
on:
workflow_dispatch:
branches:
- master
schedule:
- cron: "0 1 * * 6"
jobs:
semgrep-full:
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v4
# step 2
- name: full scan
run: |
semgrep \
--sarif --output report.sarif \
--metrics=off \
--config="p/default"
# step 3
- name: save report as pipeline artifact
uses: actions/upload-artifact@v4
with:
name: report.sarif
overwrite: true
path: report.sarif
# step 4
- name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: report.sarif
category: semgrep

View File

@ -0,0 +1,25 @@
---
name: Semgrep Differential Scan
on: pull_request
jobs:
semgrep-diff:
runs-on: ubuntu-22.04
container:
image: semgrep/semgrep
steps:
# step 1
- name: clone application source code
uses: actions/checkout@v4
with:
fetch-depth: 0
# step 2
- name: differential scan
run: |
semgrep scan \
--error \
--metrics=off \
--baseline-commit ${{ github.event.pull_request.base.sha }} \
--config="p/default"

106
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,106 @@
name: End to end tests
on:
schedule:
- cron: "0 0 * * *" # Run every day at midnight
workflow_dispatch: {}
jobs:
test-simulator:
runs-on: ubuntu-latest
steps:
- name: Install libbluetooth
shell: bash
run: |
sudo apt-get update --fix-missing
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
pip install -U platformio adafruit-nrfutil
pip install -U meshtastic --pre
- name: Upgrade platformio
shell: bash
run: |
pio upgrade
- name: Build Native
run: bin/build-native.sh
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native
run: platformio run -e native
- name: Integration test
run: |
.pio/build/native/program & sleep 10 # 5 seconds was not enough
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: PlatformIO Tests
run: platformio test -e native --junit-output-path testreport.xml
- name: Test Report
uses: dorny/test-reporter@v1.9.1
if: success() || failure() # run this step even if previous step failed
with:
name: PlatformIO Tests
path: testreport.xml
reporter: java-junit
hardware-tests:
runs-on: test-runner
steps:
- name: Checkout code
uses: actions/checkout@v4
# - uses: actions/setup-python@v5
# with:
# python-version: '3.10'
# pipx install "setuptools<72"
- name: Upgrade python tools
shell: bash
run: |
pipx install adafruit-nrfutil
pipx install poetry
pipx install meshtastic --pip-args=--pre
- name: Install PlatformIO from script
shell: bash
run: |
curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
python3 get-platformio.py
- name: Upgrade platformio
shell: bash
run: |
export PATH=$PATH:$HOME/.local/bin
pio upgrade
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install dependencies, setup devices and run
shell: bash
run: |
git submodule update --init --recursive
cd meshtestic/
pnpm install
pnpm run setup
pnpm run test

22
.github/workflows/trunk-check.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Pull Request
on: [pull_request]
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions: read-all
jobs:
trunk_check:
name: Trunk Check Runner
runs-on: ubuntu-latest
permissions:
checks: write # For trunk to post annotations
contents: read # For repo checkout
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Trunk Check
uses: trunk-io/trunk-action@v1

34
.github/workflows/update_protobufs.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Update protobufs and regenerate classes
on: workflow_dispatch
jobs:
update-protobufs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: true
- name: Update submodule
run: |
git submodule update --remote protobufs
- name: Download nanopb
run: |
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9-linux-x86.tar.gz
tar xvzf nanopb-0.4.9-linux-x86.tar.gz
mv nanopb-0.4.9-linux-x86 nanopb-0.4.9
- name: Re-generate protocol buffers
run: |
./bin/regen-protos.sh
- name: Create pull request
uses: peter-evans/create-pull-request@v7
with:
title: Update protobufs and classes
add-paths: |
protobufs
src/mesh

9
.trunk/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*out
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml
tmp

2
.trunk/configs/.bandit Normal file
View File

@ -0,0 +1,2 @@
[bandit]
skips = B101

View File

@ -0,0 +1,6 @@
Language: Cpp
IndentWidth: 4
ColumnLimit: 130
PointerAlignment: Right
BreakBeforeBraces: Linux
AllowShortFunctionsOnASingleLine: Inline

3
.trunk/configs/.flake8 Normal file
View File

@ -0,0 +1,3 @@
# Autoformatter friendly flake8 config (all formatting rules disabled)
[flake8]
extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5

View File

@ -0,0 +1,4 @@
# Following source doesn't work in most setups
ignored:
- SC1090
- SC1091

View File

@ -0,0 +1,2 @@
[settings]
profile=black

View File

@ -0,0 +1,10 @@
# Autoformatter friendly markdownlint config (all formatting rules disabled)
default: true
blank_lines: false
bullet: false
html: false
indentation: false
line_length: false
spaces: false
url: false
whitespace: false

View File

@ -0,0 +1,10 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154
disable=SC2248
disable=SC2250
# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091
#

View File

@ -0,0 +1,10 @@
rules:
quoted-strings:
required: only-when-needed
extra-allowed: ["{|}"]
empty-values:
forbid-in-block-mappings: false
forbid-in-flow-mappings: true
key-duplicates: {}
octal-values:
forbid-implicit-octal: true

5
.trunk/configs/ruff.toml Normal file
View File

@ -0,0 +1,5 @@
# Generic, formatter-friendly config.
select = ["B", "D3", "D4", "E", "F"]
# Never enforce `E501` (line length violations). This should be handled by formatters.
ignore = ["E501"]

View File

@ -0,0 +1,14 @@
module.exports = {
plugins: [
{
name: "preset-default",
params: {
overrides: {
removeViewBox: false, // https://github.com/svg/svgo/issues/1128
sortAttrs: true,
removeOffCanvasPaths: true,
},
},
},
],
};

49
.trunk/trunk.yaml Normal file
View File

@ -0,0 +1,49 @@
version: 0.1
cli:
version: 1.22.7
plugins:
sources:
- id: trunk
ref: v1.6.4
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- trufflehog@3.82.12
- yamllint@1.35.1
- bandit@1.7.10
- checkov@3.2.256
- terrascan@1.19.9
- trivy@0.55.2
#- trufflehog@3.63.2-rc0
- taplo@0.9.3
- ruff@0.7.0
- isort@5.13.2
- markdownlint@0.42.0
- oxipng@9.1.2
- svgo@3.3.2
- actionlint@1.7.3
- flake8@7.1.1
- hadolint@2.12.0
- shfmt@3.6.0
- shellcheck@0.10.0
- black@24.10.0
- git-diff-check
- gitleaks@8.21.1
- clang-format@16.0.3
- prettier@3.3.3
ignore:
- linters: [ALL]
paths:
- bin/**
runtimes:
enabled:
- python@3.10.8
- go@1.21.0
- node@18.12.1
actions:
disabled:
- trunk-announce
enabled:
- trunk-fmt-pre-commit
- trunk-check-pre-push
- trunk-upgrade-available

11
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "trunk.io",
"trunk.enableWindows": true,
"files.insertFinalNewline": false,
"files.trimFinalNewlines": false,
"cmake.configureOnOpen": false,
"[cpp]": {
"editor.defaultFormatter": "trunk.io"
}
}

15
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "PlatformIO",
"task": "Build",
"problemMatcher": ["$platformio"],
"group": {
"kind": "build",
"isDefault": true
},
"label": "PlatformIO: Build"
}
]
}

18
README.md Normal file
View File

@ -0,0 +1,18 @@
# Meshtastic Firmware
![GitHub release downloads](https://img.shields.io/github/downloads/meshtastic/firmware/total)
[![CI](https://img.shields.io/github/actions/workflow/status/meshtastic/firmware/main_matrix.yml?branch=master&label=actions&logo=github&color=yellow)](https://github.com/meshtastic/firmware/actions/workflows/ci.yml)
[![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/firmware)](https://cla-assistant.io/meshtastic/firmware)
[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/)
[![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
## Overview
This repository contains the device firmware for the Meshtastic project.
- **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
- **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
## Stats
![Alt](https://repobeats.axiom.co/api/embed/a92f097d9197ae853e780ec53d7d126e545629ab.svg "Repobeats analytics image")

View File

@ -2,7 +2,7 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = native
default_envs = tbeam
;default_envs = pico
;default_envs = tbeam-s3-core
;default_envs = tbeam0.7
@ -96,7 +96,7 @@ lib_deps =
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@^0.4.9
erriez/ErriezCRC32@^1.0.1
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
check_skip_packages = yes
@ -161,6 +161,6 @@ lib_deps =
https://github.com/KodinLanewave/INA3221@^1.0.1
lewisxhe/SensorLib@0.2.0
mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1

View File

@ -476,6 +476,18 @@ bool GPS::setup()
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
_serial_gps->write("$PMTK886,1*29\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_MTK_PA1616S) {
// PA1616S is used in some GPS breakout boards from Adafruit
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
_serial_gps->write("$PMTK353,1,0,0,0,0*2A\r\n");
// Above command will reset the GPS and takes longer before it will accept new commands
delay(1000);
// Only ask for RMC and GGA (GNRMC and GNGGA)
_serial_gps->write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
delay(250);
// Enable SBAS / WAAS
_serial_gps->write("$PMTK301,2*2E\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
msglen = makeCASPacket(0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
@ -1144,6 +1156,7 @@ GnssModel_t GPS::probe(int serialSpeed)
delay(20);
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
UBXChecksum(cfg_rate, sizeof(cfg_rate));

View File

@ -34,6 +34,7 @@ typedef enum {
GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN,
GNSS_MODEL_MTK_L76B,
GNSS_MODEL_MTK_PA1616S,
GNSS_MODEL_AG3335,
GNSS_MODEL_AG3352
} GnssModel_t;

View File

@ -557,8 +557,10 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
if (role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
initConfigIntervals();
initModuleConfigIntervals();
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.display.screen_on_secs = 1;
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300;

View File

@ -591,19 +591,20 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
skipHandle = true;
}
bool shouldIgnoreNonstandardPorts =
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
#if USERPREFS_EVENT_MODE
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
(p->decoded.portnum == meshtastic_PortNum_ATAK_FORWARDER || p->decoded.portnum == meshtastic_PortNum_ATAK_PLUGIN ||
p->decoded.portnum == meshtastic_PortNum_PAXCOUNTER_APP || p->decoded.portnum == meshtastic_PortNum_IP_TUNNEL_APP ||
p->decoded.portnum == meshtastic_PortNum_AUDIO_APP || p->decoded.portnum == meshtastic_PortNum_PRIVATE_APP ||
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP ||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP ||
p->decoded.portnum == meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
LOG_DEBUG("Ignoring packet on blacklisted portnum during event");
shouldIgnoreNonstandardPorts = true;
#endif
if (shouldIgnoreNonstandardPorts && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
IS_ONE_OF(p->decoded.portnum, meshtastic_PortNum_ATAK_FORWARDER, meshtastic_PortNum_ATAK_PLUGIN,
meshtastic_PortNum_PAXCOUNTER_APP, meshtastic_PortNum_IP_TUNNEL_APP, meshtastic_PortNum_AUDIO_APP,
meshtastic_PortNum_PRIVATE_APP, meshtastic_PortNum_DETECTION_SENSOR_APP, meshtastic_PortNum_RANGE_TEST_APP,
meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
LOG_DEBUG("Ignoring packet on blacklisted portnum for CORE_PORTNUMS_ONLY");
cancelSending(p->from, p->id);
skipHandle = true;
}
#endif
} else {
printPacket("packet decoding failed or skipped (no PSK?)", p);
}

View File

@ -93,7 +93,7 @@ int32_t ExternalNotificationModule::runOnce()
nagCycleCutoff = UINT32_MAX;
LOG_INFO("Turning off external notification: ");
for (int i = 0; i < 3; i++) {
setExternalOff(i);
setExternalState(i, false);
externalTurnedOn[i] = 0;
LOG_INFO("%d ", i);
}
@ -114,17 +114,17 @@ int32_t ExternalNotificationModule::runOnce()
if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
getExternal(0) ? setExternalOff(0) : setExternalOn(0);
setExternalState(0, !getExternal(0));
}
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
getExternal(1) ? setExternalOff(1) : setExternalOn(1);
setExternalState(0, !getExternal(1));
}
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
setExternalState(0, !getExternal(2));
}
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
@ -203,86 +203,42 @@ bool ExternalNotificationModule::wantPacket(const meshtastic_MeshPacket *p)
}
/**
* Sets the external notification on for the specified index.
* Sets the external notification for the specified index.
*
* @param index The index of the external notification to turn on.
* @param index The index of the external notification to change state.
* @param on Whether we are turning things on (true) or off (false).
*/
void ExternalNotificationModule::setExternalOn(uint8_t index)
void ExternalNotificationModule::setExternalState(uint8_t index, bool on)
{
externalCurrentState[index] = 1;
externalCurrentState[index] = on;
externalTurnedOn[index] = millis();
switch (index) {
case 1:
#ifdef UNPHONE
unphone.vibe(true); // the unPhone's vibration motor is on a i2c GPIO expander
unphone.vibe(on); // the unPhone's vibration motor is on a i2c GPIO expander
#endif
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, true);
digitalWrite(moduleConfig.external_notification.output_vibra, on);
break;
case 2:
if (moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
digitalWrite(moduleConfig.external_notification.output_buzzer, on);
break;
default:
if (output > 0)
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
break;
}
#ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) {
rgb.setColor(red, green, blue);
}
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
analogWrite(RGBLED_GREEN, 255 - green);
analogWrite(RGBLED_BLUE, 255 - blue);
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, red);
analogWrite(RGBLED_GREEN, green);
analogWrite(RGBLED_BLUE, blue);
#endif
#ifdef HAS_NEOPIXEL
pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
pixels.show();
#endif
#ifdef UNPHONE
unphone.rgb(red, green, blue);
#endif
#ifdef T_WATCH_S3
drv.go();
#endif
}
void ExternalNotificationModule::setExternalOff(uint8_t index)
{
externalCurrentState[index] = 0;
externalTurnedOn[index] = millis();
switch (index) {
case 1:
#ifdef UNPHONE
unphone.vibe(false); // the unPhone's vibration motor is on a i2c GPIO expander
#endif
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, false);
break;
case 2:
if (moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
break;
default:
if (output > 0)
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
digitalWrite(output, (moduleConfig.external_notification.active ? on : !on));
break;
}
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = 0;
green = 0;
blue = 0;
if (!on) {
red = 0;
green = 0;
blue = 0;
}
#endif
#ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) {
rgb.setColor(red, green, blue);
@ -304,10 +260,12 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
#ifdef UNPHONE
unphone.rgb(red, green, blue);
#endif
#endif
#ifdef T_WATCH_S3
drv.stop();
if (on) {
drv.go();
} else {
drv.stop();
}
#endif
}
@ -379,19 +337,19 @@ ExternalNotificationModule::ExternalNotificationModule()
LOG_INFO("Using Pin %i in digital mode", output);
pinMode(output, OUTPUT);
}
setExternalOff(0);
setExternalState(0, false);
externalTurnedOn[0] = 0;
if (moduleConfig.external_notification.output_vibra) {
LOG_INFO("Using Pin %i for vibra motor", moduleConfig.external_notification.output_vibra);
pinMode(moduleConfig.external_notification.output_vibra, OUTPUT);
setExternalOff(1);
setExternalState(1, false);
externalTurnedOn[1] = 0;
}
if (moduleConfig.external_notification.output_buzzer) {
if (!moduleConfig.external_notification.use_pwm) {
LOG_INFO("Using Pin %i for buzzer", moduleConfig.external_notification.output_buzzer);
pinMode(moduleConfig.external_notification.output_buzzer, OUTPUT);
setExternalOff(2);
setExternalState(2, false);
externalTurnedOn[2] = 0;
} else {
config.device.buzzer_gpio = config.device.buzzer_gpio ? config.device.buzzer_gpio : PIN_BUZZER;
@ -449,7 +407,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (containsBell) {
LOG_INFO("externalNotificationModule - Notification Bell");
isNagging = true;
setExternalOn(0);
setExternalState(0, true);
if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else {
@ -462,7 +420,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (containsBell) {
LOG_INFO("externalNotificationModule - Notification Bell (Vibra)");
isNagging = true;
setExternalOn(1);
setExternalState(1, true);
if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else {
@ -476,7 +434,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
LOG_INFO("externalNotificationModule - Notification Bell (Buzzer)");
isNagging = true;
if (!moduleConfig.external_notification.use_pwm) {
setExternalOn(2);
setExternalState(2, true);
} else {
#ifdef HAS_I2S
audioThread->beginRttl(rtttlConfig.ringtone, strlen_P(rtttlConfig.ringtone));
@ -495,7 +453,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (moduleConfig.external_notification.alert_message) {
LOG_INFO("externalNotificationModule - Notification Module");
isNagging = true;
setExternalOn(0);
setExternalState(0, true);
if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else {
@ -506,7 +464,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (moduleConfig.external_notification.alert_message_vibra) {
LOG_INFO("externalNotificationModule - Notification Module (Vibra)");
isNagging = true;
setExternalOn(1);
setExternalState(1, true);
if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else {
@ -518,7 +476,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
LOG_INFO("externalNotificationModule - Notification Module (Buzzer)");
isNagging = true;
if (!moduleConfig.external_notification.use_pwm && !moduleConfig.external_notification.use_i2s_as_buzzer) {
setExternalOn(2);
setExternalState(2, true);
} else {
#ifdef HAS_I2S
if (moduleConfig.external_notification.use_i2s_as_buzzer) {

View File

@ -34,8 +34,7 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
uint32_t nagCycleCutoff = 1;
void setExternalOn(uint8_t index = 0);
void setExternalOff(uint8_t index = 0);
void setExternalState(uint8_t index = 0, bool on = false);
bool getExternal(uint8_t index = 0);
void setMute(bool mute) { isMuted = mute; }

View File

@ -1,8 +1,5 @@
#define HAS_SCREEN 0
#define HAS_RADIO 1
#define HAS_SCREEN 1
#define CANNED_MESSAGE_MODULE_ENABLE 1
#define HAS_GPS 0
#define HAS_GPS 1
#define MAX_RX_TOPHONE settingsMap[maxtophone]
#define MAX_NUM_NODES settingsMap[maxnodes]
#define RADIOLIB_GODMODE 1
#define ARCH_PORTDUINO 1
#define MAX_NUM_NODES settingsMap[maxnodes]