mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-22 11:17:49 +10:00
Compare commits
107
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cd2ba5479 | ||
|
|
f9876cfe9c | ||
|
|
85de193845 | ||
|
|
fb2c008c89 | ||
|
|
dd9ab7f0e1 | ||
|
|
729c39fb86 | ||
|
|
038430db23 | ||
|
|
d5cd6f87a0 | ||
|
|
de42d96adf | ||
|
|
e2dd845051 | ||
|
|
6366633cd4 | ||
|
|
1c0f43c8e2 | ||
|
|
89a9e0b99d | ||
|
|
4dc8d6e400 | ||
|
|
e0f97c9306 | ||
|
|
6b1c01ce02 | ||
|
|
70296b47bc | ||
|
|
0cf4a2951a | ||
|
|
124936b6cf | ||
|
|
fd60c9b3be | ||
|
|
a0a4c5bc79 | ||
|
|
0fe8d4ccc7 | ||
|
|
00fdf2c9aa | ||
|
|
253ab458ef | ||
|
|
b4a4d2db4e | ||
|
|
6b8cf164e9 | ||
|
|
812aa35f09 | ||
|
|
e7802d960f | ||
|
|
077ee02426 | ||
|
|
46ea39af45 | ||
|
|
25a5f178e1 | ||
|
|
c144ee77a7 | ||
|
|
b62bdbc46a | ||
|
|
f18a92e8c5 | ||
|
|
2e44de262e | ||
|
|
1d756ae574 | ||
|
|
8aac9f2e8e | ||
|
|
33e5a04508 | ||
|
|
6cf3485d07 | ||
|
|
9421eba027 | ||
|
|
27fbfd03d6 | ||
|
|
353740623f | ||
|
|
cdcbf4c615 | ||
|
|
395469d20a | ||
|
|
86170171a7 | ||
|
|
57766d47a8 | ||
|
|
e5dbcf5bce | ||
|
|
4c3a3ca47d | ||
|
|
78371dfdb7 | ||
|
|
ca32889893 | ||
|
|
35cd600c54 | ||
|
|
70076a4b27 | ||
|
|
f1a8900288 | ||
|
|
16bc89ea57 | ||
|
|
6edf74e8f1 | ||
|
|
7f280dd556 | ||
|
|
2396aa77ca | ||
|
|
d3cbbfd345 | ||
|
|
c003ab0eee | ||
|
|
4fcf7fe027 | ||
|
|
9cc79b1d1e | ||
|
|
403fa15a3f | ||
|
|
b0087fd328 | ||
|
|
fb74e1d182 | ||
|
|
29a7866fc1 | ||
|
|
2f552d15e5 | ||
|
|
892e0922ff | ||
|
|
d21d6c1301 | ||
|
|
031aecac66 | ||
|
|
7c10caa78b | ||
|
|
5196ee39cb | ||
|
|
02a5a91da0 | ||
|
|
b2a89b8136 | ||
|
|
15019e8663 | ||
|
|
35814fd4bc | ||
|
|
6aabbedc00 | ||
|
|
eb72ee0fc1 | ||
|
|
7480378aed | ||
|
|
7c21d7761c | ||
|
|
2c654454cf | ||
|
|
9afadde2f4 | ||
|
|
66a961cb75 | ||
|
|
e1aaafb77a | ||
|
|
9d710041c4 | ||
|
|
b41efc17ba | ||
|
|
9bda080e3d | ||
|
|
9f7cbf1b4f | ||
|
|
93e2bc7058 | ||
|
|
7a1c32b89a | ||
|
|
88d8ab53c8 | ||
|
|
183f68ba00 | ||
|
|
9f32995d7f | ||
|
|
c2c06ed0ad | ||
|
|
9abd07bb05 | ||
|
|
fdcc0e12aa | ||
|
|
8b34c4ff05 | ||
|
|
9af8c58c40 | ||
|
|
58ebd5bcdb | ||
|
|
d1e5be515a | ||
|
|
f9e71c3fb9 | ||
|
|
bfcfca2e46 | ||
|
|
a2a6b236b7 | ||
|
|
3c7053c66a | ||
|
|
e45c0e4d40 | ||
|
|
57a9a5ca21 | ||
|
|
6749367a73 | ||
|
|
a8e2446f00 |
@@ -68,6 +68,12 @@ runs:
|
|||||||
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
|
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
|
||||||
done
|
done
|
||||||
|
|
||||||
|
- name: PlatformIO ${{ inputs.arch }} download cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.platformio/.cache
|
||||||
|
key: pio-cache-${{ inputs.arch }}-${{ hashFiles('.github/actions/**', '**.ini') }}
|
||||||
|
|
||||||
- name: Build ${{ inputs.board }}
|
- name: Build ${{ inputs.board }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
|
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
|
||||||
@@ -83,13 +89,13 @@ runs:
|
|||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
${{ inputs.artifact-paths }}
|
${{ inputs.artifact-paths }}
|
||||||
|
|||||||
@@ -20,19 +20,16 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update --fix-missing
|
sudo apt-get -y update --fix-missing
|
||||||
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev
|
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
cache: pip
|
||||||
# - name: Cache python libs
|
cache-dependency-path: |
|
||||||
# uses: actions/cache@v4
|
.github/actions/**
|
||||||
# id: cache-pip # needed in if test
|
**.ini
|
||||||
# with:
|
|
||||||
# path: ~/.cache/pip
|
|
||||||
# key: ${{ runner.os }}-pip
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
- name: Upgrade python tools
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
name: Setup native build
|
||||||
|
description: Install libraries needed for building the Native/Portduino build
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Setup base
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
|
- name: Install libs needed for native build
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
name: Build Debian Source Package
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
PPA_GPG_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
series:
|
||||||
|
description: Ubuntu/Debian series to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
build_location:
|
||||||
|
description: Location where build will execute
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-debian-src:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: meshtasticd
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y software-properties-common build-essential devscripts equivs
|
||||||
|
sudo add-apt-repository ppa:meshtastic/build-tools -y
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
|
||||||
|
|
||||||
|
- name: Import GPG key
|
||||||
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||||
|
id: gpg
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: ${{ inputs.build_location }}
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Fetch libdeps, package debian source
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: debian/ci_pack_sdeb.sh
|
||||||
|
env:
|
||||||
|
SERIES: ${{ inputs.series }}
|
||||||
|
GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }}
|
||||||
|
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||||
|
|
||||||
|
- name: Store binaries as an artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
|
overwrite: true
|
||||||
|
path: |
|
||||||
|
meshtasticd_${{ steps.version.outputs.deb }}*
|
||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Docker login
|
- name: Docker login
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: meshtastic/meshtasticd:${{ steps.version.outputs.version }}
|
tags: meshtastic/meshtasticd:${{ steps.version.outputs.long }}
|
||||||
|
|
||||||
- name: Docker build and push
|
- name: Docker build and push
|
||||||
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||||
|
|||||||
@@ -10,12 +10,6 @@ jobs:
|
|||||||
build-native:
|
build-native:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
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 libusb-1.0-0-dev libi2c-dev
|
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -23,29 +17,21 @@ jobs:
|
|||||||
ref: ${{github.event.pull_request.head.ref}}
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- name: Upgrade python tools
|
- name: Setup native build
|
||||||
shell: bash
|
id: base
|
||||||
run: |
|
uses: ./.github/actions/setup-native
|
||||||
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
|
- name: Build Native
|
||||||
run: bin/build-native.sh
|
run: bin/build-native.sh
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
name: firmware-native-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
release/meshtasticd_linux_x86_64
|
release/meshtasticd_linux_x86_64
|
||||||
|
|||||||
@@ -39,13 +39,13 @@ jobs:
|
|||||||
run: bin/build-native.sh
|
run: bin/build-native.sh
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
release/meshtasticd_linux_aarch64
|
release/meshtasticd_linux_aarch64
|
||||||
|
|||||||
@@ -39,13 +39,13 @@ jobs:
|
|||||||
run: bin/build-native.sh
|
run: bin/build-native.sh
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-armv7l-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
release/meshtasticd_linux_armv7l
|
release/meshtasticd_linux_armv7l
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
name: Daily Packaging
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: 0 9 * * *
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- debian/**
|
||||||
|
- "*.rpkg"
|
||||||
|
- .github/workflows/nightly_packaging.yml
|
||||||
|
- .github/workflows/build_debian_src.yml
|
||||||
|
- .github/workflows/package_ppa.yml
|
||||||
|
- .github/workflows/package_obs.yml
|
||||||
|
- .github/workflows/hook_copr.yml
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
package-ppa:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
series: [plucky, oracular, noble, jammy]
|
||||||
|
uses: ./.github/workflows/package_ppa.yml
|
||||||
|
with:
|
||||||
|
ppa_repo: ppa:meshtastic/daily
|
||||||
|
series: ${{ matrix.series }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
package-obs:
|
||||||
|
uses: ./.github/workflows/package_obs.yml
|
||||||
|
with:
|
||||||
|
obs_project: home:meshtastic:daily
|
||||||
|
series: unstable
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
hook-copr:
|
||||||
|
uses: ./.github/workflows/hook_copr.yml
|
||||||
|
with:
|
||||||
|
copr_project: daily
|
||||||
|
secrets: inherit
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
name: Trigger COPR build
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
COPR_HOOK_DAILY:
|
||||||
|
COPR_HOOK_ALPHA:
|
||||||
|
COPR_HOOK_BETA:
|
||||||
|
inputs:
|
||||||
|
copr_project:
|
||||||
|
description: COPR project to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-copr-hook:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
ref: ${{ github.ref }}
|
||||||
|
repository: ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Install Python dependencies
|
||||||
|
run: |
|
||||||
|
pip install requests
|
||||||
|
|
||||||
|
- name: Trigger COPR build
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
import requests
|
||||||
|
|
||||||
|
project_name = "${{ inputs.copr_project }}"
|
||||||
|
if project_name == "daily":
|
||||||
|
hook_secret = "${{ secrets.COPR_HOOK_DAILY }}"
|
||||||
|
project_id = 160277
|
||||||
|
elif project_name == "alpha":
|
||||||
|
hook_secret = "${{ secrets.COPR_HOOK_ALPHA }}"
|
||||||
|
project_id = 160278
|
||||||
|
elif project_name == "beta":
|
||||||
|
hook_secret = "${{ secrets.COPR_HOOK_BETA }}"
|
||||||
|
project_id = 160279
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unknown COPR project: {project_name}")
|
||||||
|
|
||||||
|
webhook_url = f"https://copr.fedorainfracloud.org/webhooks/github/{project_id}/{hook_secret}/meshtasticd/"
|
||||||
|
copr_payload = {
|
||||||
|
"ref": "${{ github.ref }}",
|
||||||
|
"after": "${{ github.sha }}",
|
||||||
|
"repository": {
|
||||||
|
"clone_url": "${{ github.server_url }}/${{ github.repository }}.git",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r = requests.post(webhook_url, json=copr_payload, headers={"X-GitHub-Event": "push"})
|
||||||
|
r.raise_for_status()
|
||||||
@@ -137,6 +137,16 @@ jobs:
|
|||||||
package-native:
|
package-native:
|
||||||
uses: ./.github/workflows/package_amd64.yml
|
uses: ./.github/workflows/package_amd64.yml
|
||||||
|
|
||||||
|
build-debian-src:
|
||||||
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
with:
|
||||||
|
series: UNRELEASED
|
||||||
|
build_location: local
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
test-native:
|
||||||
|
uses: ./.github/workflows/test_native.yml
|
||||||
|
|
||||||
build-docker:
|
build-docker:
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
uses: ./.github/workflows/build_docker.yml
|
uses: ./.github/workflows/build_docker.yml
|
||||||
@@ -189,7 +199,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
@@ -198,7 +208,7 @@ jobs:
|
|||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./firmware-*.bin
|
./firmware-*.bin
|
||||||
@@ -215,7 +225,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -229,12 +239,12 @@ jobs:
|
|||||||
chmod +x ./output/device-update.sh
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: ./*.elf
|
path: ./*.elf
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
@@ -242,8 +252,8 @@ jobs:
|
|||||||
- uses: scruplelesswizard/comment-artifact@main
|
- uses: scruplelesswizard/comment-artifact@main
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation"
|
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
release-artifacts:
|
release-artifacts:
|
||||||
@@ -257,6 +267,7 @@ jobs:
|
|||||||
package-raspbian,
|
package-raspbian,
|
||||||
package-raspbian-armv7l,
|
package-raspbian-armv7l,
|
||||||
package-native,
|
package-native,
|
||||||
|
build-debian-src,
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -268,73 +279,70 @@ jobs:
|
|||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: |
|
||||||
|
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: local
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: actions/create-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
id: create_release
|
id: create_release
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }} Alpha
|
name: Meshtastic Firmware ${{ steps.version.outputs.long }} Alpha
|
||||||
tag_name: v${{ steps.version.outputs.version }}
|
tag_name: v${{ steps.version.outputs.long }}
|
||||||
body: |
|
body: |
|
||||||
Autogenerated by github action, developer should edit as required before publishing...
|
Autogenerated by github action, developer should edit as required before publishing...
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
|
|
||||||
- name: Download deb files
|
- name: Download deb files
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
pattern: meshtasticd_${{ steps.version.outputs.long }}_*.deb
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
|
- name: Download source deb
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: firmware-debian-${{ steps.version.outputs.deb }}~UNRELEASED-src
|
||||||
|
merge-multiple: true
|
||||||
|
path: ./output/debian-src
|
||||||
|
|
||||||
|
- name: Zip source deb
|
||||||
|
working-directory: output
|
||||||
|
run: zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
|
||||||
|
|
||||||
# For diagnostics
|
# For diagnostics
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -lR
|
run: ls -lR
|
||||||
|
|
||||||
- name: Add raspbian aarch64 .deb
|
- name: Add deb files to release
|
||||||
uses: actions/upload-release-asset@v1
|
run: |
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd_${{ steps.version.outputs.long }}_arm64.deb
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd_${{ steps.version.outputs.long }}_armhf.deb
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd_${{ steps.version.outputs.long }}_amd64.deb
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ secrets.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
|
- name: Bump version.properties
|
||||||
run: >-
|
run: >-
|
||||||
bin/bump_version.py
|
bin/bump_version.py
|
||||||
|
|
||||||
|
- name: Update debian changelog
|
||||||
|
run: >-
|
||||||
|
debian/ci_changelog.sh
|
||||||
|
|
||||||
- name: Create version.properties pull request
|
- name: Create version.properties pull request
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v7
|
||||||
with:
|
with:
|
||||||
title: Bump version.properties
|
title: Bump version.properties
|
||||||
add-paths: |
|
add-paths: |
|
||||||
version.properties
|
version.properties
|
||||||
|
debian/changelog
|
||||||
|
|
||||||
release-firmware:
|
release-firmware:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -354,12 +362,12 @@ jobs:
|
|||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -372,37 +380,24 @@ jobs:
|
|||||||
chmod +x ./output/device-update.sh
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./elfs
|
path: ./elfs
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip debug elfs
|
||||||
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./elfs
|
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./elfs
|
||||||
|
|
||||||
# For diagnostics
|
# For diagnostics
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -lR
|
run: ls -lR
|
||||||
|
|
||||||
- name: Add bins to release
|
- name: Add bins and debug elfs to release
|
||||||
uses: actions/upload-release-asset@v1
|
run: |
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ secrets.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
|
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
name: firmware-native-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -77,14 +77,14 @@ jobs:
|
|||||||
package: meshtasticd
|
package: meshtasticd
|
||||||
package_root: .debpkg
|
package_root: .debpkg
|
||||||
maintainer: Jonathan Bennett
|
maintainer: Jonathan Bennett
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
version: ${{ steps.version.outputs.long }} # refs/tags/v*.*.*
|
||||||
arch: amd64
|
arch: amd64
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
||||||
desc: Native Linux Meshtastic binary.
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
name: meshtasticd_${{ steps.version.outputs.long }}_amd64.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
name: Package for OpenSUSE Build Service
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
OBS_PASSWORD:
|
||||||
|
required: true
|
||||||
|
PPA_GPG_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
obs_project:
|
||||||
|
description: Meshtastic OBS project to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
series:
|
||||||
|
description: Debian series to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-debian-src:
|
||||||
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
series: ${{ inputs.series }}
|
||||||
|
build_location: obs
|
||||||
|
|
||||||
|
package-obs:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: build-debian-src
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: meshtasticd
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Install OpenSUSE Build Service deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo 'deb http://download.opensuse.org/repositories/openSUSE:/Tools/xUbuntu_24.04/ /' | sudo tee /etc/apt/sources.list.d/openSUSE:Tools.list
|
||||||
|
curl -fsSL https://download.opensuse.org/repositories/openSUSE:Tools/xUbuntu_24.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/openSUSE_Tools.gpg > /dev/null
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y osc
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: obs
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -lah
|
||||||
|
|
||||||
|
- name: Configure osc
|
||||||
|
env:
|
||||||
|
OBS_USERNAME: meshtastic
|
||||||
|
run: |
|
||||||
|
# Setup OpenSUSE Build Service credentials
|
||||||
|
mkdir -p ~/.config/osc
|
||||||
|
echo "[general]" > ~/.config/osc/oscrc
|
||||||
|
echo "apiurl=https://api.opensuse.org" >> ~/.config/osc/oscrc
|
||||||
|
echo "[https://api.opensuse.org]" >> ~/.config/osc/oscrc
|
||||||
|
echo "user=${{ env.OBS_USERNAME }}" >> ~/.config/osc/oscrc
|
||||||
|
echo "pass=${{ secrets.OBS_PASSWORD }}" >> ~/.config/osc/oscrc
|
||||||
|
echo "credentials_mgr_class=osc.credentials.PlaintextConfigFileCredentialsManager" >> ~/.config/osc/oscrc
|
||||||
|
# Create a temporary directory for osc checkout
|
||||||
|
mkdir -p osc
|
||||||
|
|
||||||
|
# Intentionally fail if credentials are invalid
|
||||||
|
# Update secrets if this returns `401`
|
||||||
|
- name: Verify OBS authentication
|
||||||
|
run: osc token
|
||||||
|
|
||||||
|
- name: Upload package to OBS
|
||||||
|
shell: bash
|
||||||
|
working-directory: osc
|
||||||
|
env:
|
||||||
|
OBS_PROJECT: ${{ inputs.obs_project }}
|
||||||
|
OBS_PACKAGE: meshtasticd
|
||||||
|
run: |
|
||||||
|
# Initialize the package in the current directory
|
||||||
|
osc checkout --output-dir . $OBS_PROJECT $OBS_PACKAGE
|
||||||
|
|
||||||
|
# Remove the existing package files
|
||||||
|
rm -rf *.dsc *.tar.xz
|
||||||
|
|
||||||
|
# Copy new package files to the directory
|
||||||
|
cp $GITHUB_WORKSPACE/*.dsc .
|
||||||
|
cp $GITHUB_WORKSPACE/*.tar.xz .
|
||||||
|
|
||||||
|
# Add/Remove the files
|
||||||
|
osc addremove
|
||||||
|
|
||||||
|
# Commit changes and push to OpenSUSE Build Service
|
||||||
|
osc commit -m "GitHub Actions: ${{ steps.version.outputs.deb }}~${{ inputs.series }}"
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
name: Package for Launchpad PPA
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
PPA_GPG_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
ppa_repo:
|
||||||
|
description: Meshtastic PPA to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
series:
|
||||||
|
description: Ubuntu series to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-debian-src:
|
||||||
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
series: ${{ inputs.series }}
|
||||||
|
build_location: ppa
|
||||||
|
|
||||||
|
package-ppa:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: build-debian-src
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: meshtasticd
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y dput
|
||||||
|
|
||||||
|
- name: Import GPG key
|
||||||
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||||
|
id: gpg
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: ppa
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -lah
|
||||||
|
|
||||||
|
- name: Publish with dput
|
||||||
|
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||||
|
run: |
|
||||||
|
dput ${{ inputs.ppa_repo }} meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes
|
||||||
@@ -32,13 +32,13 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -77,14 +77,14 @@ jobs:
|
|||||||
package: meshtasticd
|
package: meshtasticd
|
||||||
package_root: .debpkg
|
package_root: .debpkg
|
||||||
maintainer: Jonathan Bennett
|
maintainer: Jonathan Bennett
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
version: ${{ steps.version.outputs.long }} # refs/tags/v*.*.*
|
||||||
arch: arm64
|
arch: arm64
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
||||||
desc: Native Linux Meshtastic binary.
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
name: meshtasticd_${{ steps.version.outputs.long }}_arm64.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-armv7l-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -77,14 +77,14 @@ jobs:
|
|||||||
package: meshtasticd
|
package: meshtasticd
|
||||||
package_root: .debpkg
|
package_root: .debpkg
|
||||||
maintainer: Jonathan Bennett
|
maintainer: Jonathan Bennett
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
version: ${{ steps.version.outputs.long }} # refs/tags/v*.*.*
|
||||||
arch: armhf
|
arch: armhf
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
||||||
desc: Native Linux Meshtastic binary.
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
name: meshtasticd_${{ steps.version.outputs.long }}_armhf.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
name: Trigger release workflows upon Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published, released]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
package-ppa:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
series: [plucky, oracular, noble, jammy]
|
||||||
|
uses: ./.github/workflows/package_ppa.yml
|
||||||
|
with:
|
||||||
|
ppa_repo: |-
|
||||||
|
ppa:meshtastic/${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
series: ${{ matrix.series }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
package-obs:
|
||||||
|
uses: ./.github/workflows/package_obs.yml
|
||||||
|
with:
|
||||||
|
obs_project: |-
|
||||||
|
home:meshtastic:${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
series: |-
|
||||||
|
${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
# hook-copr:
|
||||||
|
# uses: ./.github/workflows/hook_copr.yml
|
||||||
|
# with:
|
||||||
|
# copr_project: |-
|
||||||
|
# ${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
# secrets: inherit
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
name: Run Tests on Native platform
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
env:
|
||||||
|
LCOV_CAPTURE_FLAGS: --quiet --capture --include "${PWD}/src/*" --exclude '*/src/mesh/generated/*' --directory .pio/build/coverage/src --base-directory "${PWD}"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
simulator-tests:
|
||||||
|
name: Native Simulator Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Setup native build
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-native
|
||||||
|
|
||||||
|
- name: Install simulator dependencies
|
||||||
|
run: pip install -U dotmap
|
||||||
|
|
||||||
|
# We now run integration test before other build steps (to quickly see runtime failures)
|
||||||
|
- name: Build for native/coverage
|
||||||
|
run: platformio run -e coverage
|
||||||
|
|
||||||
|
- name: Capture initial coverage information
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --initial --output-file coverage_base.info
|
||||||
|
sed -i -e "s#${PWD}#.#" coverage_base.info # Make paths relative.
|
||||||
|
|
||||||
|
- name: Integration test
|
||||||
|
run: |
|
||||||
|
.pio/build/coverage/program &
|
||||||
|
PID=$!
|
||||||
|
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
|
||||||
|
echo "Simulator started, launching python test..."
|
||||||
|
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||||
|
wait
|
||||||
|
|
||||||
|
- name: Capture coverage information
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
run: |
|
||||||
|
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name integration --output-file coverage_integration.info
|
||||||
|
sed -i -e "s#${PWD}#.#" coverage_integration.info # Make paths relative.
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Save coverage information
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
with:
|
||||||
|
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: ./coverage_*.info
|
||||||
|
|
||||||
|
platformio-tests:
|
||||||
|
name: Native PlatformIO Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Setup native build
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-native
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
# Disable (comment-out) BUILD_EPOCH. It causes a full rebuild between tests and resets the
|
||||||
|
# coverage information each time.
|
||||||
|
- name: Disable BUILD_EPOCH
|
||||||
|
run: sed -i 's/-DBUILD_EPOCH=$UNIX_TIME/#-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
|
||||||
|
|
||||||
|
- name: PlatformIO Tests
|
||||||
|
run: platformio test -e coverage -v --junit-output-path testreport.xml
|
||||||
|
|
||||||
|
- name: Save test results
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: ./testreport.xml
|
||||||
|
|
||||||
|
- name: Capture coverage information
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name tests --output-file coverage_tests.info
|
||||||
|
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||||
|
|
||||||
|
- name: Save coverage information
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
with:
|
||||||
|
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: ./coverage_*.info
|
||||||
|
|
||||||
|
generate-reports:
|
||||||
|
name: Generate Test Reports
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions: # Needed for dorny/test-reporter.
|
||||||
|
contents: read
|
||||||
|
actions: read
|
||||||
|
checks: write
|
||||||
|
needs:
|
||||||
|
- simulator-tests
|
||||||
|
- platformio-tests
|
||||||
|
if: always()
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download test artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Test Report
|
||||||
|
uses: dorny/test-reporter@v1.9.1
|
||||||
|
with:
|
||||||
|
name: PlatformIO Tests
|
||||||
|
path: testreport.xml
|
||||||
|
reporter: java-junit
|
||||||
|
|
||||||
|
- name: Download coverage artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}.zip
|
||||||
|
path: code-coverage-report
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Generate Code Coverage Report
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
lcov --quiet --add-tracefile code-coverage-report/coverage_base.info --add-tracefile code-coverage-report/coverage_integration.info --add-tracefile code-coverage-report/coverage_tests.info --output-file code-coverage-report/coverage_src.info
|
||||||
|
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@v4
|
||||||
|
with:
|
||||||
|
name: code-coverage-report-${{ steps.version.outputs.long }}.zip
|
||||||
|
path: code-coverage-report
|
||||||
@@ -6,79 +6,8 @@ on:
|
|||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-simulator:
|
native-tests:
|
||||||
runs-on: ubuntu-latest
|
uses: ./.github/workflows/test_native.yml
|
||||||
env:
|
|
||||||
LCOV_CAPTURE_FLAGS: --quiet --capture --include "${PWD}/src/*" --exclude '*/src/mesh/generated/*' --directory .pio/build/coverage/src --base-directory "${PWD}"
|
|
||||||
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 libusb-1.0-0-dev libi2c-dev
|
|
||||||
sudo apt-get install -y lcov
|
|
||||||
|
|
||||||
- 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 dotmap
|
|
||||||
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/coverage
|
|
||||||
run: |
|
|
||||||
platformio run -e coverage
|
|
||||||
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --initial --output-file coverage_base.info
|
|
||||||
|
|
||||||
- name: Integration test
|
|
||||||
run: |
|
|
||||||
.pio/build/coverage/program &
|
|
||||||
PID=$!
|
|
||||||
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
|
|
||||||
echo "Simulator started, launching python test..."
|
|
||||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
|
||||||
wait
|
|
||||||
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name integration --output-file coverage_integration.info
|
|
||||||
|
|
||||||
- name: PlatformIO Tests
|
|
||||||
run: |
|
|
||||||
platformio test -e coverage --junit-output-path testreport.xml
|
|
||||||
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name tests --output-file coverage_tests.info
|
|
||||||
|
|
||||||
- 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
|
|
||||||
|
|
||||||
- name: Generate Code Coverage Report
|
|
||||||
run: |
|
|
||||||
lcov --quiet --add-tracefile coverage_base.info --add-tracefile coverage_integration.info --add-tracefile coverage_tests.info --output-file coverage_src.info
|
|
||||||
mkdir code-coverage-report
|
|
||||||
genhtml --quiet --legend --prefix "${PWD}" coverage_src.info --output-directory code-coverage-report
|
|
||||||
mv coverage_*.info code-coverage-report
|
|
||||||
|
|
||||||
- name: Save Code Coverage Report
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: code-coverage-report
|
|
||||||
path: code-coverage-report
|
|
||||||
|
|
||||||
hardware-tests:
|
hardware-tests:
|
||||||
runs-on: test-runner
|
runs-on: test-runner
|
||||||
|
|||||||
@@ -22,12 +22,16 @@ jobs:
|
|||||||
- name: Run Trunk Fmt
|
- name: Run Trunk Fmt
|
||||||
run: trunk fmt
|
run: trunk fmt
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
- name: Commit and push changes
|
- name: Commit and push changes
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name "github-actions[bot]"
|
git config --global user.name "github-actions[bot]"
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git add .
|
git add .
|
||||||
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
|
git commit -m "Add firmware version ${{ steps.version.outputs.long }}"
|
||||||
git push
|
git push
|
||||||
|
|
||||||
- name: Comment on PR
|
- name: Comment on PR
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Update submodule
|
- name: Update submodule
|
||||||
|
if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
run: |
|
run: |
|
||||||
git submodule update --remote protobufs
|
git submodule update --remote protobufs
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
.pio
|
.pio
|
||||||
|
pio
|
||||||
|
pio.tar
|
||||||
|
web
|
||||||
|
web.tar
|
||||||
|
|
||||||
# ignore vscode IDE settings files
|
# ignore vscode IDE settings files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ lib_deps =
|
|||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
https://github.com/pine64/libch341-spi-userspace#a9b17e3452f7fb747000d9b4ad4409155b39f6ef
|
https://github.com/pine64/libch341-spi-userspace#a9b17e3452f7fb747000d9b4ad4409155b39f6ef
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ platform_packages = framework-arduinopico@https://github.com/earlephilhower/ardu
|
|||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags} -Wno-unused-variable
|
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
|
||||||
-Isrc/platform/rp2xx0
|
-Isrc/platform/rp2xx0
|
||||||
-D__PLAT_RP2040__
|
-D__PLAT_RP2350__
|
||||||
# -D _POSIX_THREADS
|
# -D _POSIX_THREADS
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp> -<platform/rp2xx0/pico_sleep> -<platform/rp2xx0/hardware_rosc>
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
config.yaml
|
||||||
+42
-7
@@ -12,12 +12,6 @@ Lora:
|
|||||||
# IRQ: 17
|
# IRQ: 17
|
||||||
# Reset: 22
|
# Reset: 22
|
||||||
|
|
||||||
# Module: RF95 # Adafruit RFM9x
|
|
||||||
# Reset: 25
|
|
||||||
# CS: 7
|
|
||||||
# IRQ: 22
|
|
||||||
# Busy: 23
|
|
||||||
|
|
||||||
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
|
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
|
||||||
# Reset: 22
|
# Reset: 22
|
||||||
# CS: 7
|
# CS: 7
|
||||||
@@ -29,6 +23,47 @@ Lora:
|
|||||||
# Busy: 20
|
# Busy: 20
|
||||||
# Reset: 18
|
# Reset: 18
|
||||||
|
|
||||||
|
### The Radxa Zero 3E/W employs multiple gpio chips.
|
||||||
|
### Each gpio pin must be unique, but can be assigned to a specific gpio chip and line.
|
||||||
|
### In case solely a no. is given, the default gpio chip and pin == line will be employed.
|
||||||
|
###
|
||||||
|
# Module: sx1262 # Radxa Zero 3E/W + Ebyte E22-900M30S
|
||||||
|
# DIO2_AS_RF_SWITCH: true
|
||||||
|
# DIO3_TCXO_VOLTAGE: 1.8
|
||||||
|
# CS: # NSS PIN_24 -> chip 4, line 22
|
||||||
|
# pin: 24
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 22
|
||||||
|
# SCK: # SCK PIN_23 -> chip 4, line 18
|
||||||
|
# pin: 23
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 18
|
||||||
|
# Busy: # BUSY PIN_29 -> chip 3!, line 11
|
||||||
|
# pin: 29
|
||||||
|
# gpiochip: 3
|
||||||
|
# line: 11
|
||||||
|
# MOSI: # MOSI PIN_19 -> chip 4, line 19
|
||||||
|
# pin: 19
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 19
|
||||||
|
# MISO: # MISO PIN_21 -> chip 4, line 21
|
||||||
|
# pin: 21
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 21
|
||||||
|
# Reset: # NRST PIN_27 -> chip 4, line 10
|
||||||
|
# pin: 27
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 10
|
||||||
|
# IRQ: # DIO1 PIN_28 -> chip 4, line 11
|
||||||
|
# pin: 28
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 11
|
||||||
|
# RXen: # RXEN PIN_22 -> chip 3!, line 17
|
||||||
|
# pin: 22
|
||||||
|
# gpiochip: 3
|
||||||
|
# line: 17
|
||||||
|
# TXen: RADIOLIB_NC # TXEN no PIN, no line, fallback to default gpio chip
|
||||||
|
|
||||||
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
|
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
|
||||||
# CS: 21
|
# CS: 21
|
||||||
# IRQ: 16
|
# IRQ: 16
|
||||||
@@ -45,7 +80,7 @@ Lora:
|
|||||||
|
|
||||||
# spiSpeed: 2000000
|
# spiSpeed: 2000000
|
||||||
|
|
||||||
### Set gpio chip to use in /dev/. Defaults to 0.
|
### Set default/fallback gpio chip to use in /dev/. Defaults to 0.
|
||||||
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
|
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
|
||||||
# gpiochip: 4
|
# gpiochip: 4
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Module: RF95 # Adafruit RFM9x
|
||||||
|
# Reset: 25
|
||||||
|
# CS: 7
|
||||||
|
# IRQ: 22
|
||||||
|
# Busy: 23
|
||||||
@@ -73,7 +73,7 @@ shift "$((OPTIND - 1))"
|
|||||||
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
||||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
$ESPTOOL_CMD erase_flash
|
$ESPTOOL_CMD erase_flash
|
||||||
$ESPTOOL_CMD write_flash 0x00 ${FILENAME}
|
$ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
|
||||||
# Account for S3 board's different OTA partition
|
# Account for S3 board's different OTA partition
|
||||||
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
|
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
|
||||||
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||||
|
|||||||
+7
-4
@@ -1,6 +1,8 @@
|
|||||||
import configparser
|
import configparser
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import os
|
||||||
|
run_number = os.getenv('GITHUB_RUN_NUMBER', '0')
|
||||||
|
build_location = os.getenv('BUILD_LOCATION', 'local')
|
||||||
|
|
||||||
def readProps(prefsLoc):
|
def readProps(prefsLoc):
|
||||||
"""Read the version of our project as a string"""
|
"""Read the version of our project as a string"""
|
||||||
@@ -11,6 +13,7 @@ def readProps(prefsLoc):
|
|||||||
verObj = dict(
|
verObj = dict(
|
||||||
short="{}.{}.{}".format(version["major"], version["minor"], version["build"]),
|
short="{}.{}.{}".format(version["major"], version["minor"], version["build"]),
|
||||||
long="unset",
|
long="unset",
|
||||||
|
deb="unset",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
|
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
|
||||||
@@ -27,13 +30,13 @@ def readProps(prefsLoc):
|
|||||||
# if isDirty:
|
# if isDirty:
|
||||||
# # short for 'dirty', we want to keep our verstrings source for protobuf reasons
|
# # short for 'dirty', we want to keep our verstrings source for protobuf reasons
|
||||||
# suffix = sha + "-d"
|
# suffix = sha + "-d"
|
||||||
verObj["long"] = "{}.{}.{}.{}".format(
|
verObj["long"] = "{}.{}".format(verObj["short"], suffix)
|
||||||
version["major"], version["minor"], version["build"], suffix
|
verObj["deb"] = "{}.{}~{}{}".format(verObj["short"], run_number, build_location, sha)
|
||||||
)
|
|
||||||
except:
|
except:
|
||||||
# print("Unexpected error:", sys.exc_info()[0])
|
# print("Unexpected error:", sys.exc_info()[0])
|
||||||
# traceback.print_exc()
|
# traceback.print_exc()
|
||||||
verObj["long"] = verObj["short"]
|
verObj["long"] = verObj["short"]
|
||||||
|
verObj["deb"] = "{}.{}~{}".format(verObj["short"], run_number, build_location)
|
||||||
|
|
||||||
# print("firmware version " + verStr)
|
# print("firmware version " + verStr)
|
||||||
return verObj
|
return verObj
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
function meshtastic_version {
|
||||||
|
meshtastic_version=$(python3 bin/buildinfo.py short)
|
||||||
|
echo -n "$meshtastic_version"
|
||||||
|
}
|
||||||
|
function git_commits_num {
|
||||||
|
total_commits=$(git rev-list --all --count)
|
||||||
|
echo -n "$total_commits"
|
||||||
|
}
|
||||||
|
function git_commit_sha {
|
||||||
|
commit_sha=$(git rev-parse --short HEAD)
|
||||||
|
echo -n "$commit_sha"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.debhelper
|
||||||
|
debhelper-build-stamp
|
||||||
|
meshtasticd
|
||||||
|
files
|
||||||
|
meshtasticd.substvars
|
||||||
|
meshtasticd.postrm.debhelper
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
meshtasticd (2.5.20.0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* Initial packaging
|
||||||
|
* GitHub Actions Automatic version bump
|
||||||
|
|
||||||
|
-- Austin Lane <github-actions[bot]@users.noreply.github.com> Mon, 13 Jan 2025 19:24:14 +0000
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
export DEBEMAIL="github-actions[bot]@users.noreply.github.com"
|
||||||
|
PKG_VERSION=$(python3 bin/buildinfo.py short)
|
||||||
|
|
||||||
|
dch --newversion "$PKG_VERSION.0" \
|
||||||
|
--distribution UNRELEASED \
|
||||||
|
"GitHub Actions Automatic version bump"
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
export DEBEMAIL="jbennett@incomsystems.biz"
|
||||||
|
export PLATFORMIO_LIBDEPS_DIR=pio/libdeps
|
||||||
|
export PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||||
|
export PLATFORMIO_CORE_DIR=pio/core
|
||||||
|
|
||||||
|
# Download libraries to `pio`
|
||||||
|
platformio pkg install -e native
|
||||||
|
platformio pkg install -e native -t platformio/tool-scons@4.40502.0
|
||||||
|
# Compress `pio` directory to prevent dh_clean from sanitizing it
|
||||||
|
tar -cf pio.tar pio/
|
||||||
|
rm -rf pio
|
||||||
|
# Download the latest meshtastic/web release build.tar to `web.tar`
|
||||||
|
curl -L https://github.com/meshtastic/web/releases/download/latest/build.tar -o web.tar
|
||||||
|
|
||||||
|
package=$(dpkg-parsechangelog --show-field Source)
|
||||||
|
|
||||||
|
rm -rf debian/changelog
|
||||||
|
dch --create --distribution "$SERIES" --package "$package" --newversion "$PKG_VERSION~$SERIES" \
|
||||||
|
"GitHub Actions Automatic packaging for $PKG_VERSION~$SERIES"
|
||||||
|
|
||||||
|
# Build the source deb
|
||||||
|
debuild -S -nc -k"$GPG_KEY_ID"
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
Source: meshtasticd
|
||||||
|
Section: misc
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Austin Lane <vidplace7@gmail.com>
|
||||||
|
Build-Depends: debhelper-compat (= 13),
|
||||||
|
tar,
|
||||||
|
gzip,
|
||||||
|
platformio,
|
||||||
|
python3-protobuf,
|
||||||
|
python3-grpcio,
|
||||||
|
git,
|
||||||
|
g++,
|
||||||
|
pkg-config,
|
||||||
|
libyaml-cpp-dev,
|
||||||
|
libgpiod-dev,
|
||||||
|
libbluetooth-dev,
|
||||||
|
libusb-1.0-0-dev,
|
||||||
|
libi2c-dev,
|
||||||
|
openssl,
|
||||||
|
libssl-dev,
|
||||||
|
libulfius-dev,
|
||||||
|
liborcania-dev
|
||||||
|
Standards-Version: 4.6.2
|
||||||
|
Homepage: https://github.com/meshtastic/firmware
|
||||||
|
Rules-Requires-Root: no
|
||||||
|
|
||||||
|
Package: meshtasticd
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Description: Meshtastic daemon for communicating with Meshtastic devices
|
||||||
|
Meshtastic is an off-grid text communication platform that uses inexpensive
|
||||||
|
LoRa radios.
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
etc/meshtasticd
|
||||||
|
etc/meshtasticd/config.d
|
||||||
|
etc/meshtasticd/available.d
|
||||||
|
usr/share/meshtasticd/web
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
.pio/build/native/meshtasticd usr/sbin
|
||||||
|
|
||||||
|
bin/config.yaml etc/meshtasticd
|
||||||
|
bin/config.d/* etc/meshtasticd/available.d
|
||||||
|
|
||||||
|
bin/meshtasticd.service lib/systemd/system
|
||||||
|
|
||||||
|
web/* usr/share/meshtasticd/web
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# export DH_VERBOSE = 1
|
||||||
|
|
||||||
|
# Use the "dh" sequencer
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
# https://docs.platformio.org/en/latest/envvars.html
|
||||||
|
PIO_ENV:=\
|
||||||
|
PLATFORMIO_CORE_DIR=pio/core \
|
||||||
|
PLATFORMIO_LIBDEPS_DIR=pio/libdeps \
|
||||||
|
PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||||
|
|
||||||
|
override_dh_auto_build:
|
||||||
|
# Extract tarballs within source deb
|
||||||
|
tar -xf pio.tar
|
||||||
|
mkdir -p web && tar -xf web.tar -C web
|
||||||
|
gunzip web/ -r
|
||||||
|
# Build with platformio
|
||||||
|
$(PIO_ENV) platformio run -e native
|
||||||
|
# Move the binary and default config to the correct name
|
||||||
|
mv .pio/build/native/program .pio/build/native/meshtasticd
|
||||||
|
cp bin/config-dist.yaml bin/config.yaml
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
pio.tar
|
||||||
|
web.tar
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
extend-diff-ignore = "\.pio"
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# meshtasticd spec file for RPM-based distributions
|
||||||
|
#
|
||||||
|
# Build locally with:
|
||||||
|
# ```
|
||||||
|
# sudo dnf install rpkg-util
|
||||||
|
# rpkg local
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# See:
|
||||||
|
# - https://docs.pagure.org/rpkg-util/v3/index.html
|
||||||
|
# - https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/
|
||||||
|
|
||||||
|
Name: meshtasticd
|
||||||
|
# Version Ex: 2.5.19
|
||||||
|
Version: {{{ meshtastic_version }}}
|
||||||
|
# Release Ex: 9127.daily.gitd7f5f620.fc41
|
||||||
|
Release: {{{ git_commits_num }}}%{?copr_projectname:.%{copr_projectname}}.git{{{ git_commit_sha }}}%{?dist}
|
||||||
|
VCS: {{{ git_dir_vcs }}}
|
||||||
|
Summary: Meshtastic daemon for communicating with Meshtastic devices
|
||||||
|
|
||||||
|
License: GPL-3.0
|
||||||
|
URL: https://github.com/meshtastic/firmware
|
||||||
|
Source0: {{{ git_dir_pack }}}
|
||||||
|
Source1: https://github.com/meshtastic/web/releases/download/latest/build.tar
|
||||||
|
|
||||||
|
BuildRequires: systemd-rpm-macros
|
||||||
|
BuildRequires: python3-devel
|
||||||
|
BuildRequires: platformio
|
||||||
|
BuildRequires: python3dist(protobuf)
|
||||||
|
BuildRequires: python3dist(grpcio[protobuf])
|
||||||
|
BuildRequires: python3dist(grpcio-tools)
|
||||||
|
BuildRequires: git-core
|
||||||
|
BuildRequires: gcc-c++
|
||||||
|
BuildRequires: pkgconfig(yaml-cpp)
|
||||||
|
BuildRequires: pkgconfig(libgpiod)
|
||||||
|
BuildRequires: pkgconfig(bluez)
|
||||||
|
BuildRequires: pkgconfig(libusb-1.0)
|
||||||
|
BuildRequires: libi2c-devel
|
||||||
|
# Web components:
|
||||||
|
BuildRequires: pkgconfig(openssl)
|
||||||
|
BuildRequires: pkgconfig(liborcania)
|
||||||
|
BuildRequires: pkgconfig(libyder)
|
||||||
|
BuildRequires: pkgconfig(libulfius)
|
||||||
|
|
||||||
|
%description
|
||||||
|
Meshtastic daemon for controlling Meshtastic devices. Meshtastic is an off-grid
|
||||||
|
text communication platform that uses inexpensive LoRa radios.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
{{{ git_dir_setup_macro }}}
|
||||||
|
# Unpack the web files
|
||||||
|
mkdir -p web
|
||||||
|
tar -xf %{SOURCE1} -C web
|
||||||
|
gzip -dr web
|
||||||
|
|
||||||
|
%build
|
||||||
|
# Use the “native” environment from platformio to build a Linux binary
|
||||||
|
platformio run -e native
|
||||||
|
|
||||||
|
%install
|
||||||
|
mkdir -p %{buildroot}%{_sbindir}
|
||||||
|
install -m 0755 .pio/build/native/program %{buildroot}%{_sbindir}/meshtasticd
|
||||||
|
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd
|
||||||
|
install -m 0644 bin/config-dist.yaml %{buildroot}%{_sysconfdir}/meshtasticd/config.yaml
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/config.d
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/available.d
|
||||||
|
cp -r bin/config.d/* %{buildroot}%{_sysconfdir}/meshtasticd/available.d
|
||||||
|
|
||||||
|
install -D -m 0644 bin/meshtasticd.service %{buildroot}%{_unitdir}/meshtasticd.service
|
||||||
|
|
||||||
|
# Install the web files under /usr/share/meshtasticd/web
|
||||||
|
mkdir -p %{buildroot}%{_datadir}/meshtasticd/web
|
||||||
|
cp -r web/* %{buildroot}%{_datadir}/meshtasticd/web
|
||||||
|
|
||||||
|
%files
|
||||||
|
%license LICENSE
|
||||||
|
%doc README.md
|
||||||
|
%{_sbindir}/meshtasticd
|
||||||
|
%dir %{_sysconfdir}/meshtasticd
|
||||||
|
%dir %{_sysconfdir}/meshtasticd/config.d
|
||||||
|
%dir %{_sysconfdir}/meshtasticd/available.d
|
||||||
|
%config(noreplace) %{_sysconfdir}/meshtasticd/config.yaml
|
||||||
|
%config %{_sysconfdir}/meshtasticd/available.d/*
|
||||||
|
%{_unitdir}/meshtasticd.service
|
||||||
|
%dir %{_datadir}/meshtasticd
|
||||||
|
%dir %{_datadir}/meshtasticd/web
|
||||||
|
%{_datadir}/meshtasticd/web/*
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
%autochangelog
|
||||||
+3
-38
@@ -3,42 +3,7 @@
|
|||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
default_envs = tbeam
|
default_envs = tbeam
|
||||||
;default_envs = pico
|
|
||||||
;default_envs = tbeam-s3-core
|
|
||||||
;default_envs = tbeam0.7
|
|
||||||
;default_envs = heltec-v1
|
|
||||||
;default_envs = heltec-v2_0
|
|
||||||
;default_envs = heltec-v2_1
|
|
||||||
;default_envs = heltec-wireless-tracker
|
|
||||||
;default_envs = chatter2
|
|
||||||
;default_envs = tlora-v1
|
|
||||||
;default_envs = tlora_v1_3
|
|
||||||
;default_envs = tlora-v2
|
|
||||||
;default_envs = tlora-v2-1-1_6
|
|
||||||
;default_envs = tlora-v2-1-1_6-tcxo
|
|
||||||
;default_envs = tlora-v3-3-0-tcxo
|
|
||||||
;default_envs = tlora-t3s3-v1
|
|
||||||
;default_envs = t-echo
|
|
||||||
;default_envs = canaryone
|
|
||||||
;default_envs = native
|
|
||||||
;default_envs = nano-g1
|
|
||||||
;default_envs = pca10059_diy_eink
|
|
||||||
;default_envs = meshtastic-diy-v1
|
|
||||||
;default_envs = meshtastic-diy-v1_1
|
|
||||||
;default_envs = meshtastic-dr-dev
|
|
||||||
;default_envs = m5stack-coreink
|
|
||||||
;default_envs = rak4631
|
|
||||||
;default_envs = rak4631_eth_gw
|
|
||||||
;default_envs = rak2560
|
|
||||||
;default_envs = rak_wismeshtap
|
|
||||||
;default_envs = wio-e5
|
|
||||||
;default_envs = radiomaster_900_bandit_nano
|
|
||||||
;default_envs = radiomaster_900_bandit_micro
|
|
||||||
;default_envs = radiomaster_900_bandit
|
|
||||||
;default_envs = heltec_vision_master_t190
|
|
||||||
;default_envs = heltec_vision_master_e213
|
|
||||||
;default_envs = heltec_vision_master_e290
|
|
||||||
;default_envs = heltec_mesh_node_t114
|
|
||||||
extra_configs =
|
extra_configs =
|
||||||
arch/*/*.ini
|
arch/*/*.ini
|
||||||
variants/*/platformio.ini
|
variants/*/platformio.ini
|
||||||
@@ -84,7 +49,7 @@ build_flags = -Wno-missing-field-initializers
|
|||||||
-DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1
|
-DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1
|
||||||
-DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
|
-DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
|
||||||
#-DBUILD_EPOCH=$UNIX_TIME
|
#-DBUILD_EPOCH=$UNIX_TIME
|
||||||
;-D OLED_PL
|
#-D OLED_PL=1
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_filters = direct
|
monitor_filters = direct
|
||||||
@@ -123,7 +88,7 @@ lib_deps =
|
|||||||
|
|
||||||
[radiolib_base]
|
[radiolib_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
jgromes/RadioLib@7.1.0
|
jgromes/RadioLib@7.1.2
|
||||||
|
|
||||||
; Common libs for environmental measurements in telemetry module
|
; Common libs for environmental measurements in telemetry module
|
||||||
; (not included in native / portduino)
|
; (not included in native / portduino)
|
||||||
|
|||||||
+1
-1
Submodule protobufs updated: c55f120a9c...76f806e1bb
+18
-1
@@ -9,6 +9,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
@@ -102,6 +103,8 @@ bool copyFile(const char *from, const char *to)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
#elif defined(FSCom)
|
#elif defined(FSCom)
|
||||||
|
// take SPI Lock
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
unsigned char cbuffer[16];
|
unsigned char cbuffer[16];
|
||||||
|
|
||||||
File f1 = FSCom.open(from, FILE_O_READ);
|
File f1 = FSCom.open(from, FILE_O_READ);
|
||||||
@@ -145,16 +148,23 @@ bool renameFile(const char *pathFrom, const char *pathTo)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif defined(FSCom)
|
#elif defined(FSCom)
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
// take SPI Lock
|
||||||
|
spiLock->lock();
|
||||||
// rename was fixed for ESP32 IDF LittleFS in April
|
// rename was fixed for ESP32 IDF LittleFS in April
|
||||||
return FSCom.rename(pathFrom, pathTo);
|
bool result = FSCom.rename(pathFrom, pathTo);
|
||||||
|
spiLock->unlock();
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
|
// copyFile does its own locking.
|
||||||
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
|
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +174,7 @@ bool renameFile(const char *pathFrom, const char *pathTo)
|
|||||||
* @brief Get the list of files in a directory.
|
* @brief Get the list of files in a directory.
|
||||||
*
|
*
|
||||||
* This function returns a list of files in a directory. The list includes the full path of each file.
|
* This function returns a list of files in a directory. The list includes the full path of each file.
|
||||||
|
* We can't use SPILOCK here because of recursion. Callers of this function should use SPILOCK.
|
||||||
*
|
*
|
||||||
* @param dirname The name of the directory.
|
* @param dirname The name of the directory.
|
||||||
* @param levels The number of levels of subdirectories to list.
|
* @param levels The number of levels of subdirectories to list.
|
||||||
@@ -212,6 +223,7 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists the contents of a directory.
|
* Lists the contents of a directory.
|
||||||
|
* We can't use SPILOCK here because of recursion. Callers of this function should use SPILOCK.
|
||||||
*
|
*
|
||||||
* @param dirname The name of the directory to list.
|
* @param dirname The name of the directory to list.
|
||||||
* @param levels The number of levels of subdirectories to list.
|
* @param levels The number of levels of subdirectories to list.
|
||||||
@@ -325,18 +337,21 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
void rmDir(const char *dirname)
|
void rmDir(const char *dirname)
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||||
listDir(dirname, 10, true);
|
listDir(dirname, 10, true);
|
||||||
#elif defined(ARCH_NRF52)
|
#elif defined(ARCH_NRF52)
|
||||||
// nRF52 implementation of LittleFS has a recursive delete function
|
// nRF52 implementation of LittleFS has a recursive delete function
|
||||||
FSCom.rmdir_r(dirname);
|
FSCom.rmdir_r(dirname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsInit()
|
void fsInit()
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
if (!FSBegin()) {
|
if (!FSBegin()) {
|
||||||
LOG_ERROR("Filesystem mount failed");
|
LOG_ERROR("Filesystem mount failed");
|
||||||
// assert(0); This auto-formats the partition, so no need to fail here.
|
// assert(0); This auto-formats the partition, so no need to fail here.
|
||||||
@@ -347,6 +362,7 @@ void fsInit()
|
|||||||
LOG_DEBUG("Filesystem files:");
|
LOG_DEBUG("Filesystem files:");
|
||||||
#endif
|
#endif
|
||||||
listDir("/", 10);
|
listDir("/", 10);
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +372,7 @@ void fsInit()
|
|||||||
void setupSDCard()
|
void setupSDCard()
|
||||||
{
|
{
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||||
|
|
||||||
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
||||||
|
|||||||
+25
-5
@@ -5,6 +5,14 @@
|
|||||||
// Only way to work on both esp32 and nrf52
|
// Only way to work on both esp32 and nrf52
|
||||||
static File openFile(const char *filename, bool fullAtomic)
|
static File openFile(const char *filename, bool fullAtomic)
|
||||||
{
|
{
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
|
LOG_DEBUG("Opening %s, fullAtomic=%d", filename, fullAtomic);
|
||||||
|
#ifdef ARCH_NRF52
|
||||||
|
lfs_assert_failed = false;
|
||||||
|
File file = FSCom.open(filename, FILE_O_WRITE);
|
||||||
|
file.seek(0);
|
||||||
|
return file;
|
||||||
|
#endif
|
||||||
if (!fullAtomic)
|
if (!fullAtomic)
|
||||||
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
||||||
|
|
||||||
@@ -13,7 +21,6 @@ static File openFile(const char *filename, bool fullAtomic)
|
|||||||
|
|
||||||
// clear any previous LFS errors
|
// clear any previous LFS errors
|
||||||
lfs_assert_failed = false;
|
lfs_assert_failed = false;
|
||||||
|
|
||||||
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,14 +60,26 @@ bool SafeFile::close()
|
|||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
spiLock->lock();
|
||||||
|
#ifdef ARCH_NRF52
|
||||||
|
f.truncate();
|
||||||
|
#endif
|
||||||
f.close();
|
f.close();
|
||||||
|
spiLock->unlock();
|
||||||
|
|
||||||
|
#ifdef ARCH_NRF52
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
if (!testReadback())
|
if (!testReadback())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// brief window of risk here ;-)
|
{ // Scope for lock
|
||||||
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
concurrency::LockGuard g(spiLock);
|
||||||
LOG_ERROR("Can't remove old pref file");
|
// brief window of risk here ;-)
|
||||||
return false;
|
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
||||||
|
LOG_ERROR("Can't remove old pref file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String filenameTmp = filename;
|
String filenameTmp = filename;
|
||||||
@@ -76,6 +95,7 @@ bool SafeFile::close()
|
|||||||
/// Read our (closed) tempfile back in and compare the hash
|
/// Read our (closed) tempfile back in and compare the hash
|
||||||
bool SafeFile::testReadback()
|
bool SafeFile::testReadback()
|
||||||
{
|
{
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
bool lfs_failed = lfs_assert_failed;
|
bool lfs_failed = lfs_assert_failed;
|
||||||
lfs_assert_failed = false;
|
lfs_assert_failed = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
|||||||
+8
-7
@@ -178,13 +178,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define TCA9535_ADDR 0x20
|
#define TCA9535_ADDR 0x20
|
||||||
#define TCA9555_ADDR 0x26
|
#define TCA9555_ADDR 0x26
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// GPS
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
#ifndef GPS_THREAD_INTERVAL
|
|
||||||
#define GPS_THREAD_INTERVAL 200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Touchscreen
|
// Touchscreen
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -206,6 +199,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define VEXT_ON_VALUE LOW
|
#define VEXT_ON_VALUE LOW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// GPS
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef GPS_BAUDRATE
|
#ifndef GPS_BAUDRATE
|
||||||
#define GPS_BAUDRATE 9600
|
#define GPS_BAUDRATE 9600
|
||||||
#define GPS_BAUDRATE_FIXED 0
|
#define GPS_BAUDRATE_FIXED 0
|
||||||
@@ -213,6 +210,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define GPS_BAUDRATE_FIXED 1
|
#define GPS_BAUDRATE_FIXED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef GPS_THREAD_INTERVAL
|
||||||
|
#define GPS_THREAD_INTERVAL 200
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Step #2: follow with defines common to the architecture;
|
/* Step #2: follow with defines common to the architecture;
|
||||||
also enable HAS_ option not specifically disabled by variant.h */
|
also enable HAS_ option not specifically disabled by variant.h */
|
||||||
#include "architecture.h"
|
#include "architecture.h"
|
||||||
|
|||||||
@@ -35,7 +35,11 @@ template <typename T, std::size_t N> std::size_t array_count(const T (&)[N])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||||
|
#if defined(RAK2560)
|
||||||
|
HardwareSerial *GPS::_serial_gps = &Serial2;
|
||||||
|
#else
|
||||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||||
|
#endif
|
||||||
#elif defined(ARCH_RP2040)
|
#elif defined(ARCH_RP2040)
|
||||||
SerialUART *GPS::_serial_gps = &Serial1;
|
SerialUART *GPS::_serial_gps = &Serial1;
|
||||||
#else
|
#else
|
||||||
@@ -1190,6 +1194,8 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
||||||
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
||||||
|
|
||||||
|
PROBE_SIMPLE("LS20031", "$PMTK605*31", "MC-1513", GNSS_MODEL_LS20031, 500);
|
||||||
|
|
||||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
|
|||||||
+2
-1
@@ -29,7 +29,8 @@ typedef enum {
|
|||||||
GNSS_MODEL_MTK_L76B,
|
GNSS_MODEL_MTK_L76B,
|
||||||
GNSS_MODEL_MTK_PA1616S,
|
GNSS_MODEL_MTK_PA1616S,
|
||||||
GNSS_MODEL_AG3335,
|
GNSS_MODEL_AG3335,
|
||||||
GNSS_MODEL_AG3352
|
GNSS_MODEL_AG3352,
|
||||||
|
GNSS_MODEL_LS20031
|
||||||
} GnssModel_t;
|
} GnssModel_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -1015,7 +1015,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
|||||||
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
|
||||||
} else if (strcmp(msg, "♥️") == 0 || strcmp(msg, "\U0001F9E1") == 0 || strcmp(msg, "\U00002763") == 0 ||
|
} else if (strcmp(msg, "♥️") == 0 || strcmp(msg, "\U0001F9E1") == 0 || strcmp(msg, "\U00002763") == 0 ||
|
||||||
strcmp(msg, "\U00002764") == 0 || strcmp(msg, "\U0001F495") == 0 || strcmp(msg, "\U0001F496") == 0 ||
|
strcmp(msg, "\U00002764") == 0 || strcmp(msg, "\U0001F495") == 0 || strcmp(msg, "\U0001F496") == 0 ||
|
||||||
strcmp(msg, "\U0001F497") == 0 || strcmp(msg, "\U0001F496") == 0) {
|
strcmp(msg, "\U0001F497") == 0 || strcmp(msg, "\U0001F498") == 0) {
|
||||||
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
|
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
|
||||||
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
|
||||||
} else {
|
} else {
|
||||||
@@ -1506,7 +1506,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
#elif defined(USE_ST7567)
|
#elif defined(USE_ST7567)
|
||||||
dispdev = new ST7567Wire(address.address, -1, -1, geometry,
|
dispdev = new ST7567Wire(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO && !HAS_TFT
|
||||||
if (settingsMap[displayPanel] != no_screen) {
|
if (settingsMap[displayPanel] != no_screen) {
|
||||||
LOG_DEBUG("Make TFTDisplay!");
|
LOG_DEBUG("Make TFTDisplay!");
|
||||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||||
|
|||||||
@@ -20,9 +20,15 @@
|
|||||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
// The screen is bigger so use bigger fonts
|
// The screen is bigger so use bigger fonts
|
||||||
|
#ifdef OLED_PL
|
||||||
|
#define FONT_SMALL ArialMT_Plain_16_PL // Height: 19
|
||||||
|
#define FONT_MEDIUM ArialMT_Plain_24_PL // Height: 28
|
||||||
|
#define FONT_LARGE ArialMT_Plain_24_PL // Height: 28
|
||||||
|
#else
|
||||||
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
||||||
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
|
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
|
||||||
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
|
#define FONT_LARGE ArialMT_Plain_24 // Height: 28
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef OLED_PL
|
#ifdef OLED_PL
|
||||||
#define FONT_SMALL ArialMT_Plain_10_PL
|
#define FONT_SMALL ArialMT_Plain_10_PL
|
||||||
@@ -41,6 +47,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef OLED_PL
|
||||||
|
#define FONT_MEDIUM ArialMT_Plain_16_PL // Height: 19
|
||||||
|
#else
|
||||||
#ifdef OLED_UA
|
#ifdef OLED_UA
|
||||||
#define FONT_MEDIUM ArialMT_Plain_16_UA // Height: 19
|
#define FONT_MEDIUM ArialMT_Plain_16_UA // Height: 19
|
||||||
#else
|
#else
|
||||||
@@ -50,6 +59,10 @@
|
|||||||
#define FONT_MEDIUM ArialMT_Plain_16 // Height: 19
|
#define FONT_MEDIUM ArialMT_Plain_16 // Height: 19
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef OLED_PL
|
||||||
|
#define FONT_LARGE ArialMT_Plain_24_PL // Height: 28
|
||||||
|
#else
|
||||||
#ifdef OLED_UA
|
#ifdef OLED_UA
|
||||||
#define FONT_LARGE ArialMT_Plain_24_UA // Height: 28
|
#define FONT_LARGE ArialMT_Plain_24_UA // Height: 28
|
||||||
#else
|
#else
|
||||||
@@ -60,6 +73,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _fontHeight(font) ((font)[1] + 1) // height is position 1
|
#define _fontHeight(font) ((font)[1] + 1) // height is position 1
|
||||||
|
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
|
|||||||
|
|
||||||
class LGFX : public lgfx::LGFX_Device
|
class LGFX : public lgfx::LGFX_Device
|
||||||
{
|
{
|
||||||
lgfx::Panel_LCD *_panel_instance;
|
lgfx::Panel_Device *_panel_instance;
|
||||||
lgfx::Bus_SPI _bus_instance;
|
lgfx::Bus_SPI _bus_instance;
|
||||||
|
|
||||||
lgfx::ITouch *_touch_instance;
|
lgfx::ITouch *_touch_instance;
|
||||||
@@ -366,10 +366,21 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
_panel_instance = new lgfx::Panel_ST7735;
|
_panel_instance = new lgfx::Panel_ST7735;
|
||||||
else if (settingsMap[displayPanel] == st7735s)
|
else if (settingsMap[displayPanel] == st7735s)
|
||||||
_panel_instance = new lgfx::Panel_ST7735S;
|
_panel_instance = new lgfx::Panel_ST7735S;
|
||||||
|
else if (settingsMap[displayPanel] == st7796)
|
||||||
|
_panel_instance = new lgfx::Panel_ST7796;
|
||||||
else if (settingsMap[displayPanel] == ili9341)
|
else if (settingsMap[displayPanel] == ili9341)
|
||||||
_panel_instance = new lgfx::Panel_ILI9341;
|
_panel_instance = new lgfx::Panel_ILI9341;
|
||||||
else if (settingsMap[displayPanel] == ili9342)
|
else if (settingsMap[displayPanel] == ili9342)
|
||||||
_panel_instance = new lgfx::Panel_ILI9342;
|
_panel_instance = new lgfx::Panel_ILI9342;
|
||||||
|
else if (settingsMap[displayPanel] == ili9488)
|
||||||
|
_panel_instance = new lgfx::Panel_ILI9488;
|
||||||
|
else if (settingsMap[displayPanel] == hx8357d)
|
||||||
|
_panel_instance = new lgfx::Panel_HX8357D;
|
||||||
|
else {
|
||||||
|
_panel_instance = new lgfx::Panel_NULL;
|
||||||
|
LOG_ERROR("Unknown display panel configured!");
|
||||||
|
}
|
||||||
|
|
||||||
auto buscfg = _bus_instance.config();
|
auto buscfg = _bus_instance.config();
|
||||||
buscfg.spi_mode = 0;
|
buscfg.spi_mode = 0;
|
||||||
buscfg.spi_host = settingsMap[displayspidev];
|
buscfg.spi_host = settingsMap[displayspidev];
|
||||||
@@ -383,12 +394,12 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
LOG_DEBUG("Height: %d, Width: %d ", settingsMap[displayHeight], settingsMap[displayWidth]);
|
LOG_DEBUG("Height: %d, Width: %d ", settingsMap[displayHeight], settingsMap[displayWidth]);
|
||||||
cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable)
|
cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable)
|
||||||
cfg.pin_rst = settingsMap[displayReset];
|
cfg.pin_rst = settingsMap[displayReset];
|
||||||
cfg.panel_width = settingsMap[displayWidth]; // actual displayable width
|
cfg.panel_width = settingsMap[displayWidth]; // actual displayable width
|
||||||
cfg.panel_height = settingsMap[displayHeight]; // actual displayable height
|
cfg.panel_height = settingsMap[displayHeight]; // actual displayable height
|
||||||
cfg.offset_x = settingsMap[displayOffsetX]; // Panel offset amount in X direction
|
cfg.offset_x = settingsMap[displayOffsetX]; // Panel offset amount in X direction
|
||||||
cfg.offset_y = settingsMap[displayOffsetY]; // Panel offset amount in Y direction
|
cfg.offset_y = settingsMap[displayOffsetY]; // Panel offset amount in Y direction
|
||||||
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is mirrored)
|
cfg.offset_rotation = settingsMap[displayOffsetRotate]; // Rotation direction value offset 0~7 (4~7 is mirrored)
|
||||||
cfg.invert = settingsMap[displayInvert]; // Set to true if the light/darkness of the panel is reversed
|
cfg.invert = settingsMap[displayInvert]; // Set to true if the light/darkness of the panel is reversed
|
||||||
|
|
||||||
_panel_instance->config(cfg);
|
_panel_instance->config(cfg);
|
||||||
|
|
||||||
@@ -410,7 +421,7 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
touch_cfg.y_max = settingsMap[displayWidth] - 1;
|
touch_cfg.y_max = settingsMap[displayWidth] - 1;
|
||||||
touch_cfg.pin_int = settingsMap[touchscreenIRQ];
|
touch_cfg.pin_int = settingsMap[touchscreenIRQ];
|
||||||
touch_cfg.bus_shared = true;
|
touch_cfg.bus_shared = true;
|
||||||
touch_cfg.offset_rotation = 1;
|
touch_cfg.offset_rotation = settingsMap[touchscreenRotate];
|
||||||
if (settingsMap[touchscreenI2CAddr] != -1) {
|
if (settingsMap[touchscreenI2CAddr] != -1) {
|
||||||
touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
|
touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const uint8_t ArialMT_Plain_10_CS[] PROGMEM = {
|
|||||||
0x20, // First char: 32
|
0x20, // First char: 32
|
||||||
0xE0, // Number of chars: 224
|
0xE0, // Number of chars: 224
|
||||||
// Jump Table:
|
// Jump Table:
|
||||||
0xFF, 0xFF, 0x00, 0x0A, // 32
|
0xFF, 0xFF, 0x00, 0x03, // 32
|
||||||
0x00, 0x00, 0x04, 0x03, // 33
|
0x00, 0x00, 0x04, 0x03, // 33
|
||||||
0x00, 0x04, 0x05, 0x04, // 34
|
0x00, 0x04, 0x05, 0x04, // 34
|
||||||
0x00, 0x09, 0x09, 0x06, // 35
|
0x00, 0x09, 0x09, 0x06, // 35
|
||||||
@@ -453,7 +453,7 @@ const uint8_t ArialMT_Plain_16_CS[] PROGMEM = {
|
|||||||
0x20, // First char: 32
|
0x20, // First char: 32
|
||||||
0xE0, // Number of chars: 224
|
0xE0, // Number of chars: 224
|
||||||
// Jump Table:
|
// Jump Table:
|
||||||
0xFF, 0xFF, 0x00, 0x10, // 32
|
0xFF, 0xFF, 0x00, 0x04, // 32
|
||||||
0x00, 0x00, 0x08, 0x04, // 33
|
0x00, 0x00, 0x08, 0x04, // 33
|
||||||
0x00, 0x08, 0x0D, 0x06, // 34
|
0x00, 0x08, 0x0D, 0x06, // 34
|
||||||
0x00, 0x15, 0x1A, 0x0A, // 35
|
0x00, 0x15, 0x1A, 0x0A, // 35
|
||||||
@@ -1036,7 +1036,7 @@ const uint8_t ArialMT_Plain_24_CS[] PROGMEM = {
|
|||||||
0x20, // First char: 32
|
0x20, // First char: 32
|
||||||
0xE0, // Number of chars: 224
|
0xE0, // Number of chars: 224
|
||||||
// Jump Table:
|
// Jump Table:
|
||||||
0xFF, 0xFF, 0x00, 0x18, // 32
|
0xFF, 0xFF, 0x00, 0x06, // 32
|
||||||
0x00, 0x00, 0x13, 0x06, // 33
|
0x00, 0x00, 0x13, 0x06, // 33
|
||||||
0x00, 0x13, 0x1A, 0x08, // 34
|
0x00, 0x13, 0x1A, 0x08, // 34
|
||||||
0x00, 0x2D, 0x33, 0x0E, // 35
|
0x00, 0x2D, 0x33, 0x0E, // 35
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
|||||||
#elif __MBED__
|
#elif __MBED__
|
||||||
#define PROGMEM
|
#define PROGMEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const uint8_t ArialMT_Plain_10_PL[] PROGMEM;
|
extern const uint8_t ArialMT_Plain_10_PL[] PROGMEM;
|
||||||
|
extern const uint8_t ArialMT_Plain_16_PL[] PROGMEM;
|
||||||
|
extern const uint8_t ArialMT_Plain_24_PL[] PROGMEM;
|
||||||
#endif
|
#endif
|
||||||
+41
-99
@@ -92,6 +92,7 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
|
|||||||
#include "mesh/raspihttp/PiWebServer.h"
|
#include "mesh/raspihttp/PiWebServer.h"
|
||||||
#include "platform/portduino/PortduinoGlue.h"
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
#include "platform/portduino/USBHal.h"
|
#include "platform/portduino/USBHal.h"
|
||||||
|
#include <cstdlib>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -364,6 +365,8 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
initSPI();
|
||||||
|
|
||||||
OSThread::setup();
|
OSThread::setup();
|
||||||
|
|
||||||
ledPeriodic = new Periodic("Blink", ledBlinker);
|
ledPeriodic = new Periodic("Blink", ledBlinker);
|
||||||
@@ -640,8 +643,6 @@ void setup()
|
|||||||
rp2040Setup();
|
rp2040Setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initSPI(); // needed here before reading from littleFS
|
|
||||||
|
|
||||||
// We do this as early as possible because this loads preferences from flash
|
// We do this as early as possible because this loads preferences from flash
|
||||||
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
|
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
|
||||||
nodeDB = new NodeDB;
|
nodeDB = new NodeDB;
|
||||||
@@ -825,116 +826,56 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
if (settingsMap[use_sx1262]) {
|
const struct {
|
||||||
if (!rIf) {
|
configNames cfgName;
|
||||||
LOG_DEBUG("Activate sx1262 radio on SPI port %s", settingsStrings[spidev].c_str());
|
std::string strName;
|
||||||
|
} loraModules[] = {{use_rf95, "RF95"}, {use_sx1262, "sx1262"}, {use_sx1268, "sx1268"}, {use_sx1280, "sx1280"},
|
||||||
|
{use_lr1110, "lr1110"}, {use_lr1120, "lr1120"}, {use_lr1121, "lr1121"}, {use_llcc68, "LLCC68"}};
|
||||||
|
// as one can't use a function pointer to the class constructor:
|
||||||
|
auto loraModuleInterface = [](configNames cfgName, LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
|
||||||
|
RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy) {
|
||||||
|
switch (cfgName) {
|
||||||
|
case use_rf95:
|
||||||
|
return (RadioInterface *)new RF95Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_sx1262:
|
||||||
|
return (RadioInterface *)new SX1262Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_sx1268:
|
||||||
|
return (RadioInterface *)new SX1268Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_sx1280:
|
||||||
|
return (RadioInterface *)new SX1280Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_lr1110:
|
||||||
|
return (RadioInterface *)new LR1110Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_lr1120:
|
||||||
|
return (RadioInterface *)new LR1120Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_lr1121:
|
||||||
|
return (RadioInterface *)new LR1121Interface(hal, cs, irq, rst, busy);
|
||||||
|
case use_llcc68:
|
||||||
|
return (RadioInterface *)new LLCC68Interface(hal, cs, irq, rst, busy);
|
||||||
|
default:
|
||||||
|
assert(0); // shouldn't happen
|
||||||
|
return (RadioInterface *)nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (auto &loraModule : loraModules) {
|
||||||
|
if (settingsMap[loraModule.cfgName] && !rIf) {
|
||||||
|
LOG_DEBUG("Activate %s radio on SPI port %s", loraModule.strName.c_str(), settingsStrings[spidev].c_str());
|
||||||
if (settingsStrings[spidev] == "ch341") {
|
if (settingsStrings[spidev] == "ch341") {
|
||||||
RadioLibHAL = ch341Hal;
|
RadioLibHAL = ch341Hal;
|
||||||
} else {
|
} else {
|
||||||
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
}
|
}
|
||||||
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = loraModuleInterface(loraModule.cfgName, (LockingArduinoHal *)RadioLibHAL, settingsMap[cs_pin],
|
||||||
settingsMap[busy]);
|
settingsMap[irq_pin], settingsMap[reset_pin], settingsMap[busy_pin]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("No SX1262 radio");
|
LOG_WARN("No %s radio", loraModule.strName.c_str());
|
||||||
delete rIf;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("SX1262 init success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (settingsMap[use_rf95]) {
|
|
||||||
if (!rIf) {
|
|
||||||
LOG_DEBUG("Activate rf95 radio on SPI port %s", settingsStrings[spidev].c_str());
|
|
||||||
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
|
||||||
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
|
||||||
settingsMap[busy]);
|
|
||||||
if (!rIf->init()) {
|
|
||||||
LOG_WARN("No RF95 radio");
|
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("RF95 init success");
|
LOG_INFO("%s init success", loraModule.strName.c_str());
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (settingsMap[use_sx1280]) {
|
|
||||||
if (!rIf) {
|
|
||||||
LOG_DEBUG("Activate sx1280 radio on SPI port %s", settingsStrings[spidev].c_str());
|
|
||||||
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
|
||||||
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
|
||||||
settingsMap[busy]);
|
|
||||||
if (!rIf->init()) {
|
|
||||||
LOG_WARN("No SX1280 radio");
|
|
||||||
delete rIf;
|
|
||||||
rIf = NULL;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("SX1280 init success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (settingsMap[use_lr1110]) {
|
|
||||||
if (!rIf) {
|
|
||||||
LOG_DEBUG("Activate lr1110 radio on SPI port %s", settingsStrings[spidev].c_str());
|
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
|
||||||
rIf = new LR1110Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
|
||||||
settingsMap[busy]);
|
|
||||||
if (!rIf->init()) {
|
|
||||||
LOG_WARN("No LR1110 radio");
|
|
||||||
delete rIf;
|
|
||||||
rIf = NULL;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("LR1110 init success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (settingsMap[use_lr1120]) {
|
|
||||||
if (!rIf) {
|
|
||||||
LOG_DEBUG("Activate lr1120 radio on SPI port %s", settingsStrings[spidev].c_str());
|
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
|
||||||
rIf = new LR1120Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
|
||||||
settingsMap[busy]);
|
|
||||||
if (!rIf->init()) {
|
|
||||||
LOG_WARN("No LR1120 radio");
|
|
||||||
delete rIf;
|
|
||||||
rIf = NULL;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("LR1120 init success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (settingsMap[use_lr1121]) {
|
|
||||||
if (!rIf) {
|
|
||||||
LOG_DEBUG("Activate lr1121 radio on SPI port %s", settingsStrings[spidev].c_str());
|
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
|
||||||
rIf = new LR1121Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
|
||||||
settingsMap[busy]);
|
|
||||||
if (!rIf->init()) {
|
|
||||||
LOG_WARN("No LR1121 radio");
|
|
||||||
delete rIf;
|
|
||||||
rIf = NULL;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("LR1121 init success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (settingsMap[use_sx1268]) {
|
|
||||||
if (!rIf) {
|
|
||||||
LOG_DEBUG("Activate sx1268 radio on SPI port %s", settingsStrings[spidev].c_str());
|
|
||||||
RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
|
||||||
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
|
||||||
settingsMap[busy]);
|
|
||||||
if (!rIf->init()) {
|
|
||||||
LOG_WARN("No SX1268 radio");
|
|
||||||
delete rIf;
|
|
||||||
rIf = NULL;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("SX1268 init success");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(HW_SPI1_DEVICE)
|
#elif defined(HW_SPI1_DEVICE)
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings);
|
||||||
#else // HW_SPI1_DEVICE
|
#else // HW_SPI1_DEVICE
|
||||||
@@ -1159,6 +1100,7 @@ void setup()
|
|||||||
#if __has_include(<ulfius.h>)
|
#if __has_include(<ulfius.h>)
|
||||||
if (settingsMap[webserverport] != -1) {
|
if (settingsMap[webserverport] != -1) {
|
||||||
piwebServerThread = new PiWebServerThread();
|
piwebServerThread = new PiWebServerThread();
|
||||||
|
std::atexit([] { delete piwebServerThread; });
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
initApiServer(TCPPort);
|
initApiServer(TCPPort);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "modules/RoutingModule.h"
|
#include "modules/RoutingModule.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
std::vector<MeshModule *> *MeshModule::modules;
|
std::vector<MeshModule *> *MeshModule::modules;
|
||||||
@@ -29,7 +30,9 @@ void MeshModule::setup() {}
|
|||||||
|
|
||||||
MeshModule::~MeshModule()
|
MeshModule::~MeshModule()
|
||||||
{
|
{
|
||||||
assert(0); // FIXME - remove from list of modules once someone needs this feature
|
auto it = std::find(modules->begin(), modules->end(), this);
|
||||||
|
assert(it != modules->end());
|
||||||
|
modules->erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
|
meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
|
||||||
|
|||||||
@@ -69,7 +69,11 @@ bool MeshPacketQueue::enqueue(meshtastic_MeshPacket *p)
|
|||||||
{
|
{
|
||||||
// no space - try to replace a lower priority packet in the queue
|
// no space - try to replace a lower priority packet in the queue
|
||||||
if (queue.size() >= maxLen) {
|
if (queue.size() >= maxLen) {
|
||||||
return replaceLowerPriorityPacket(p);
|
bool replaced = replaceLowerPriorityPacket(p);
|
||||||
|
if (!replaced) {
|
||||||
|
LOG_WARN("TX queue is full, and there is no lower-priority packet available to evict in favour of 0x%08x", p->id);
|
||||||
|
}
|
||||||
|
return replaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the correct position using upper_bound to maintain a stable order
|
// Find the correct position using upper_bound to maintain a stable order
|
||||||
@@ -113,7 +117,10 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id, bool t
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
|
/**
|
||||||
|
* Attempt to find a lower-priority packet in the queue and replace it with the provided one.
|
||||||
|
* @return True if the replacement succeeded, false otherwise
|
||||||
|
*/
|
||||||
bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
|
bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -122,11 +129,12 @@ bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the packet at the back has a lower priority than the new packet
|
// Check if the packet at the back has a lower priority than the new packet
|
||||||
auto &backPacket = queue.back();
|
auto *backPacket = queue.back();
|
||||||
if (!backPacket->tx_after && backPacket->priority < p->priority) {
|
if (!backPacket->tx_after && backPacket->priority < p->priority) {
|
||||||
|
LOG_WARN("Dropping packet 0x%08x to make room in the TX queue for higher-priority packet 0x%08x", backPacket->id, p->id);
|
||||||
// Remove the back packet
|
// Remove the back packet
|
||||||
packetPool.release(backPacket);
|
|
||||||
queue.pop_back();
|
queue.pop_back();
|
||||||
|
packetPool.release(backPacket);
|
||||||
// Insert the new packet in the correct order
|
// Insert the new packet in the correct order
|
||||||
enqueue(p);
|
enqueue(p);
|
||||||
return true;
|
return true;
|
||||||
@@ -139,8 +147,12 @@ bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
|
|||||||
for (; refPacket->tx_after && it != queue.begin(); refPacket = *--it)
|
for (; refPacket->tx_after && it != queue.begin(); refPacket = *--it)
|
||||||
;
|
;
|
||||||
if (!refPacket->tx_after && refPacket->priority < p->priority) {
|
if (!refPacket->tx_after && refPacket->priority < p->priority) {
|
||||||
|
LOG_WARN("Dropping non-late packet 0x%08x to make room in the TX queue for higher-priority packet 0x%08x",
|
||||||
|
refPacket->id, p->id);
|
||||||
|
queue.erase(it);
|
||||||
packetPool.release(refPacket);
|
packetPool.release(refPacket);
|
||||||
enqueue(refPacket);
|
// Insert the new packet in the correct order
|
||||||
|
enqueue(p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class MeshService
|
|||||||
void sendToPhone(meshtastic_MeshPacket *p);
|
void sendToPhone(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/// Send an MQTT message to the phone for client proxying
|
/// Send an MQTT message to the phone for client proxying
|
||||||
void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m);
|
virtual void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m);
|
||||||
|
|
||||||
/// Send a ClientNotification to the phone
|
/// Send a ClientNotification to the phone
|
||||||
void sendClientNotification(meshtastic_ClientNotification *cn);
|
void sendClientNotification(meshtastic_ClientNotification *cn);
|
||||||
|
|||||||
+35
-12
@@ -13,6 +13,7 @@
|
|||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "SafeFile.h"
|
#include "SafeFile.h"
|
||||||
#include "TypeConversions.h"
|
#include "TypeConversions.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -409,6 +410,13 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
|
|||||||
rebootAtMsec = millis() + (5 * 1000);
|
rebootAtMsec = millis() + (5 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3)) && defined(HAS_TFT)
|
||||||
|
// as long as PhoneAPI shares BT and TFT app switch BT off
|
||||||
|
config.bluetooth.enabled = false;
|
||||||
|
if (moduleConfig.external_notification.nag_timeout == 60)
|
||||||
|
moduleConfig.external_notification.nag_timeout = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
return didFactoryReset;
|
return didFactoryReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,12 +424,15 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
|
|||||||
{
|
{
|
||||||
LOG_INFO("Perform factory reset!");
|
LOG_INFO("Perform factory reset!");
|
||||||
// first, remove the "/prefs" (this removes most prefs)
|
// first, remove the "/prefs" (this removes most prefs)
|
||||||
rmDir("/prefs");
|
spiLock->lock();
|
||||||
|
rmDir("/prefs"); // this uses spilock internally...
|
||||||
|
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
|
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
|
||||||
LOG_ERROR("Could not remove rangetest.csv file");
|
LOG_ERROR("Could not remove rangetest.csv file");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
spiLock->unlock();
|
||||||
// second, install default state (this will deal with the duplicate mac address issue)
|
// second, install default state (this will deal with the duplicate mac address issue)
|
||||||
installDefaultDeviceState();
|
installDefaultDeviceState();
|
||||||
installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds
|
installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds
|
||||||
@@ -906,6 +917,7 @@ LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t
|
|||||||
{
|
{
|
||||||
LoadFileResult state = LoadFileResult::OTHER_FAILURE;
|
LoadFileResult state = LoadFileResult::OTHER_FAILURE;
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
|
|
||||||
auto f = FSCom.open(filename, FILE_O_READ);
|
auto f = FSCom.open(filename, FILE_O_READ);
|
||||||
|
|
||||||
@@ -939,12 +951,14 @@ void NodeDB::loadFromDisk()
|
|||||||
// disk we will still factoryReset to restore things.
|
// disk we will still factoryReset to restore things.
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
spiLock->lock();
|
||||||
if (FSCom.exists("/static/static"))
|
if (FSCom.exists("/static/static"))
|
||||||
rmDir("/static/static"); // Remove bad static web files bundle from initial 2.5.13 release
|
rmDir("/static/static"); // Remove bad static web files bundle from initial 2.5.13 release
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
||||||
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES_FS * sizeof(meshtastic_NodeInfo),
|
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES_FS * meshtastic_NodeInfoLite_size,
|
||||||
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
|
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
|
||||||
|
|
||||||
// See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786
|
// See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786
|
||||||
@@ -985,8 +999,11 @@ void NodeDB::loadFromDisk()
|
|||||||
// Make sure we load hard coded admin keys even when the configuration file has none.
|
// Make sure we load hard coded admin keys even when the configuration file has none.
|
||||||
// Initialize admin_key_count to zero
|
// Initialize admin_key_count to zero
|
||||||
byte numAdminKeys = 0;
|
byte numAdminKeys = 0;
|
||||||
|
#if defined(USERPREFS_USE_ADMIN_KEY_0) || defined(USERPREFS_USE_ADMIN_KEY_1) || defined(USERPREFS_USE_ADMIN_KEY_2)
|
||||||
uint16_t sum = 0;
|
uint16_t sum = 0;
|
||||||
|
#endif
|
||||||
#ifdef USERPREFS_USE_ADMIN_KEY_0
|
#ifdef USERPREFS_USE_ADMIN_KEY_0
|
||||||
|
|
||||||
for (uint8_t b = 0; b < 32; b++) {
|
for (uint8_t b = 0; b < 32; b++) {
|
||||||
sum += config.security.admin_key[0].bytes[b];
|
sum += config.security.admin_key[0].bytes[b];
|
||||||
}
|
}
|
||||||
@@ -995,8 +1012,6 @@ void NodeDB::loadFromDisk()
|
|||||||
LOG_INFO("Admin 0 key zero. Loading hard coded key from user preferences.");
|
LOG_INFO("Admin 0 key zero. Loading hard coded key from user preferences.");
|
||||||
memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32);
|
memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32);
|
||||||
config.security.admin_key[0].size = 32;
|
config.security.admin_key[0].size = 32;
|
||||||
config.security.admin_key_count = numAdminKeys;
|
|
||||||
saveToDisk(SEGMENT_CONFIG);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1010,8 +1025,6 @@ void NodeDB::loadFromDisk()
|
|||||||
LOG_INFO("Admin 1 key zero. Loading hard coded key from user preferences.");
|
LOG_INFO("Admin 1 key zero. Loading hard coded key from user preferences.");
|
||||||
memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32);
|
memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32);
|
||||||
config.security.admin_key[1].size = 32;
|
config.security.admin_key[1].size = 32;
|
||||||
config.security.admin_key_count = numAdminKeys;
|
|
||||||
saveToDisk(SEGMENT_CONFIG);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1025,10 +1038,14 @@ void NodeDB::loadFromDisk()
|
|||||||
LOG_INFO("Admin 2 key zero. Loading hard coded key from user preferences.");
|
LOG_INFO("Admin 2 key zero. Loading hard coded key from user preferences.");
|
||||||
memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32);
|
memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32);
|
||||||
config.security.admin_key[2].size = 32;
|
config.security.admin_key[2].size = 32;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (numAdminKeys > 0) {
|
||||||
|
LOG_INFO("Saving %d hard coded admin keys.", numAdminKeys);
|
||||||
config.security.admin_key_count = numAdminKeys;
|
config.security.admin_key_count = numAdminKeys;
|
||||||
saveToDisk(SEGMENT_CONFIG);
|
saveToDisk(SEGMENT_CONFIG);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
|
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
|
||||||
&meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
&meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
||||||
@@ -1087,9 +1104,6 @@ void NodeDB::loadFromDisk()
|
|||||||
bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct,
|
bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct,
|
||||||
bool fullAtomic)
|
bool fullAtomic)
|
||||||
{
|
{
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
concurrency::LockGuard g(spiLock);
|
|
||||||
#endif
|
|
||||||
bool okay = false;
|
bool okay = false;
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
auto f = SafeFile(filename, fullAtomic);
|
auto f = SafeFile(filename, fullAtomic);
|
||||||
@@ -1117,7 +1131,9 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
|
|||||||
bool NodeDB::saveChannelsToDisk()
|
bool NodeDB::saveChannelsToDisk()
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
FSCom.mkdir("/prefs");
|
FSCom.mkdir("/prefs");
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
return saveProto(channelFileName, meshtastic_ChannelFile_size, &meshtastic_ChannelFile_msg, &channelFile);
|
return saveProto(channelFileName, meshtastic_ChannelFile_size, &meshtastic_ChannelFile_msg, &channelFile);
|
||||||
}
|
}
|
||||||
@@ -1125,12 +1141,15 @@ bool NodeDB::saveChannelsToDisk()
|
|||||||
bool NodeDB::saveDeviceStateToDisk()
|
bool NodeDB::saveDeviceStateToDisk()
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
FSCom.mkdir("/prefs");
|
FSCom.mkdir("/prefs");
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
// Note: if MAX_NUM_NODES=100 and meshtastic_NodeInfoLite_size=166, so will be approximately 17KB
|
// Note: if MAX_NUM_NODES=100 and meshtastic_NodeInfoLite_size=166, so will be approximately 17KB
|
||||||
// Because so huge we _must_ not use fullAtomic, because the filesystem is probably too small to hold two copies of this
|
// Because so huge we _must_ not use fullAtomic, because the filesystem is probably too small to hold two copies of this
|
||||||
return saveProto(prefFileName, sizeof(devicestate) + numMeshNodes * meshtastic_NodeInfoLite_size, &meshtastic_DeviceState_msg,
|
size_t deviceStateSize;
|
||||||
&devicestate, false);
|
pb_get_encoded_size(&deviceStateSize, meshtastic_DeviceState_fields, &devicestate);
|
||||||
|
return saveProto(prefFileName, deviceStateSize, &meshtastic_DeviceState_msg, &devicestate, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodeDB::saveToDiskNoRetry(int saveWhat)
|
bool NodeDB::saveToDiskNoRetry(int saveWhat)
|
||||||
@@ -1138,7 +1157,9 @@ bool NodeDB::saveToDiskNoRetry(int saveWhat)
|
|||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
FSCom.mkdir("/prefs");
|
FSCom.mkdir("/prefs");
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
if (saveWhat & SEGMENT_CONFIG) {
|
if (saveWhat & SEGMENT_CONFIG) {
|
||||||
config.has_device = true;
|
config.has_device = true;
|
||||||
@@ -1189,7 +1210,9 @@ bool NodeDB::saveToDisk(int saveWhat)
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
LOG_ERROR("Failed to save to disk, retrying");
|
LOG_ERROR("Failed to save to disk, retrying");
|
||||||
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
|
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
|
||||||
|
spiLock->lock();
|
||||||
FSCom.format();
|
FSCom.format();
|
||||||
|
spiLock->unlock();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
success = saveToDiskNoRetry(saveWhat);
|
success = saveToDiskNoRetry(saveWhat);
|
||||||
|
|||||||
+1
-1
@@ -145,7 +145,7 @@ class NodeDB
|
|||||||
return &meshNodes->at(x);
|
return &meshNodes->at(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
virtual meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
||||||
size_t getNumMeshNodes() { return numMeshNodes; }
|
size_t getNumMeshNodes() { return numMeshNodes; }
|
||||||
|
|
||||||
// returns true if the maximum number of nodes is reached or we are running low on memory
|
// returns true if the maximum number of nodes is reached or we are running low on memory
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "PhoneAPI.h"
|
#include "PhoneAPI.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "RadioInterface.h"
|
#include "RadioInterface.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "TypeConversions.h"
|
#include "TypeConversions.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "xmodem.h"
|
#include "xmodem.h"
|
||||||
@@ -54,7 +55,9 @@ void PhoneAPI::handleStartConfig()
|
|||||||
// even if we were already connected - restart our state machine
|
// even if we were already connected - restart our state machine
|
||||||
state = STATE_SEND_MY_INFO;
|
state = STATE_SEND_MY_INFO;
|
||||||
pauseBluetoothLogging = true;
|
pauseBluetoothLogging = true;
|
||||||
|
spiLock->lock();
|
||||||
filesManifest = getFiles("/", 10);
|
filesManifest = getFiles("/", 10);
|
||||||
|
spiLock->unlock();
|
||||||
LOG_DEBUG("Got %d files in manifest", filesManifest.size());
|
LOG_DEBUG("Got %d files in manifest", filesManifest.size());
|
||||||
|
|
||||||
LOG_INFO("Start API client config");
|
LOG_INFO("Start API client config");
|
||||||
|
|||||||
+10
-10
@@ -91,16 +91,16 @@ void RF95Interface::setTransmitEnable(bool txon)
|
|||||||
#ifdef RF95_TXEN
|
#ifdef RF95_TXEN
|
||||||
digitalWrite(RF95_TXEN, txon ? 1 : 0);
|
digitalWrite(RF95_TXEN, txon ? 1 : 0);
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO
|
||||||
if (settingsMap[txen] != RADIOLIB_NC) {
|
if (settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[txen], txon ? 1 : 0);
|
digitalWrite(settingsMap[txen_pin], txon ? 1 : 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RF95_RXEN
|
#ifdef RF95_RXEN
|
||||||
digitalWrite(RF95_RXEN, txon ? 0 : 1);
|
digitalWrite(RF95_RXEN, txon ? 0 : 1);
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO
|
||||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
if (settingsMap[rxen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[rxen], txon ? 0 : 1);
|
digitalWrite(settingsMap[rxen_pin], txon ? 0 : 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -164,13 +164,13 @@ bool RF95Interface::init()
|
|||||||
digitalWrite(RF95_RXEN, 1);
|
digitalWrite(RF95_RXEN, 1);
|
||||||
#endif
|
#endif
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (settingsMap[txen] != RADIOLIB_NC) {
|
if (settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
pinMode(settingsMap[txen], OUTPUT);
|
pinMode(settingsMap[txen_pin], OUTPUT);
|
||||||
digitalWrite(settingsMap[txen], 0);
|
digitalWrite(settingsMap[txen_pin], 0);
|
||||||
}
|
}
|
||||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
if (settingsMap[rxen_pin] != RADIOLIB_NC) {
|
||||||
pinMode(settingsMap[rxen], OUTPUT);
|
pinMode(settingsMap[rxen_pin], OUTPUT);
|
||||||
digitalWrite(settingsMap[rxen], 0);
|
digitalWrite(settingsMap[rxen_pin], 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
setTransmitEnable(false);
|
setTransmitEnable(false);
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
|||||||
|
|
||||||
void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
|
void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_PORT
|
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
|
||||||
std::string out = DEBUG_PORT.mt_sprintf("%s (id=0x%08x fr=0x%08x to=0x%08x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id,
|
std::string out = DEBUG_PORT.mt_sprintf("%s (id=0x%08x fr=0x%08x to=0x%08x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id,
|
||||||
p->from, p->to, p->want_ack, p->hop_limit, p->channel);
|
p->from, p->to, p->want_ack, p->hop_limit, p->channel);
|
||||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ void RadioLibInterface::onNotify(uint32_t notification)
|
|||||||
uint32_t xmitMsec = getPacketTime(txp);
|
uint32_t xmitMsec = getPacketTime(txp);
|
||||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG("%d packets remain in the TX queue", txQueue.getMaxLen() - txQueue.getFree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,8 +298,8 @@ void RadioLibInterface::setTransmitDelay()
|
|||||||
if (p->tx_after) {
|
if (p->tx_after) {
|
||||||
unsigned long add_delay = p->rx_rssi ? getTxDelayMsecWeighted(p->rx_snr) : getTxDelayMsec();
|
unsigned long add_delay = p->rx_rssi ? getTxDelayMsecWeighted(p->rx_snr) : getTxDelayMsec();
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
p->tx_after = max(p->tx_after + add_delay, now + add_delay);
|
p->tx_after = min(max(p->tx_after + add_delay, now + add_delay), now + 2 * getTxDelayMsecWeightedWorst(p->rx_snr));
|
||||||
notifyLater(now - p->tx_after, TRANSMIT_DELAY_COMPLETED, false);
|
notifyLater(p->tx_after - now, TRANSMIT_DELAY_COMPLETED, false);
|
||||||
} else if (p->rx_snr == 0 && p->rx_rssi == 0) {
|
} else if (p->rx_snr == 0 && p->rx_rssi == 0) {
|
||||||
/* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally.
|
/* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally.
|
||||||
* This assumption is valid because of the offset generated by the radio to account for the noise
|
* This assumption is valid because of the offset generated by the radio to account for the noise
|
||||||
@@ -431,6 +432,7 @@ void RadioLibInterface::handleReceiveInterrupt()
|
|||||||
// nodes.
|
// nodes.
|
||||||
meshtastic_MeshPacket *mp = packetPool.allocZeroed();
|
meshtastic_MeshPacket *mp = packetPool.allocZeroed();
|
||||||
|
|
||||||
|
// Keep the assigned fields in sync with src/mqtt/MQTT.cpp:onReceiveProto
|
||||||
mp->from = radioBuffer.header.from;
|
mp->from = radioBuffer.header.from;
|
||||||
mp->to = radioBuffer.header.to;
|
mp->to = radioBuffer.header.to;
|
||||||
mp->id = radioBuffer.header.id;
|
mp->id = radioBuffer.header.id;
|
||||||
@@ -500,14 +502,13 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
|
|||||||
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // Transmitter off now
|
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // Transmitter off now
|
||||||
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
|
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
|
||||||
} else {
|
} else {
|
||||||
|
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register
|
||||||
|
// bits
|
||||||
|
enableInterrupt(isrTxLevel0);
|
||||||
lastTxStart = millis();
|
lastTxStart = millis();
|
||||||
printPacket("Started Tx", txp);
|
printPacket("Started Tx", txp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register
|
|
||||||
// bits
|
|
||||||
enableInterrupt(isrTxLevel0);
|
|
||||||
|
|
||||||
return res == RADIOLIB_ERR_NONE;
|
return res == RADIOLIB_ERR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -187,7 +187,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't override if a channel was requested and no need to set it when PKI is enforced
|
// don't override if a channel was requested and no need to set it when PKI is enforced
|
||||||
if (!p->channel && !p->pki_encrypted) {
|
if (!p->channel && !p->pki_encrypted && !isBroadcast(p->to)) {
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
|
||||||
if (node) {
|
if (node) {
|
||||||
p->channel = node->channel;
|
p->channel = node->channel;
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@ class Router : protected concurrency::OSThread
|
|||||||
* RadioInterface calls this to queue up packets that have been received from the radio. The router is now responsible for
|
* RadioInterface calls this to queue up packets that have been received from the radio. The router is now responsible for
|
||||||
* freeing the packet
|
* freeing the packet
|
||||||
*/
|
*/
|
||||||
void enqueueReceivedMessage(meshtastic_MeshPacket *p);
|
virtual void enqueueReceivedMessage(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet on a suitable interface. This routine will
|
* Send a packet on a suitable interface. This routine will
|
||||||
|
|||||||
@@ -51,9 +51,9 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000;
|
float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000;
|
||||||
if (settingsMap[sx126x_ant_sw] != RADIOLIB_NC) {
|
if (settingsMap[sx126x_ant_sw_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[sx126x_ant_sw], HIGH);
|
digitalWrite(settingsMap[sx126x_ant_sw_pin], HIGH);
|
||||||
pinMode(settingsMap[sx126x_ant_sw], OUTPUT);
|
pinMode(settingsMap[sx126x_ant_sw_pin], OUTPUT);
|
||||||
}
|
}
|
||||||
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
|
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
|
||||||
#elif !defined(SX126X_DIO3_TCXO_VOLTAGE)
|
#elif !defined(SX126X_DIO3_TCXO_VOLTAGE)
|
||||||
@@ -121,8 +121,9 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
// no effect
|
// no effect
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (res == RADIOLIB_ERR_NONE) {
|
if (res == RADIOLIB_ERR_NONE) {
|
||||||
LOG_DEBUG("Use MCU pin %i as RXEN and pin %i as TXEN to control RF switching", settingsMap[rxen], settingsMap[txen]);
|
LOG_DEBUG("Use MCU pin %i as RXEN and pin %i as TXEN to control RF switching", settingsMap[rxen_pin],
|
||||||
lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]);
|
settingsMap[txen_pin]);
|
||||||
|
lora.setRfSwitchPins(settingsMap[rxen_pin], settingsMap[txen_pin]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifndef SX126X_RXEN
|
#ifndef SX126X_RXEN
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ template <typename T> bool SX128xInterface<T>::init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
if (settingsMap[rxen_pin] != RADIOLIB_NC) {
|
||||||
pinMode(settingsMap[rxen], OUTPUT);
|
pinMode(settingsMap[rxen_pin], OUTPUT);
|
||||||
digitalWrite(settingsMap[rxen], LOW); // Set low before becoming an output
|
digitalWrite(settingsMap[rxen_pin], LOW); // Set low before becoming an output
|
||||||
}
|
}
|
||||||
if (settingsMap[txen] != RADIOLIB_NC) {
|
if (settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
pinMode(settingsMap[txen], OUTPUT);
|
pinMode(settingsMap[txen_pin], OUTPUT);
|
||||||
digitalWrite(settingsMap[txen], LOW); // Set low before becoming an output
|
digitalWrite(settingsMap[txen_pin], LOW); // Set low before becoming an output
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
||||||
@@ -93,8 +93,8 @@ template <typename T> bool SX128xInterface<T>::init()
|
|||||||
lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN);
|
lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN);
|
||||||
}
|
}
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO
|
||||||
if (res == RADIOLIB_ERR_NONE && settingsMap[rxen] != RADIOLIB_NC && settingsMap[txen] != RADIOLIB_NC) {
|
if (res == RADIOLIB_ERR_NONE && settingsMap[rxen_pin] != RADIOLIB_NC && settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]);
|
lora.setRfSwitchPins(settingsMap[rxen_pin], settingsMap[txen_pin]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -174,11 +174,11 @@ template <typename T> void SX128xInterface<T>::setStandby()
|
|||||||
LOG_ERROR("SX128x standby %s%d", radioLibErr, err);
|
LOG_ERROR("SX128x standby %s%d", radioLibErr, err);
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
if (settingsMap[rxen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[rxen], LOW);
|
digitalWrite(settingsMap[rxen_pin], LOW);
|
||||||
}
|
}
|
||||||
if (settingsMap[txen] != RADIOLIB_NC) {
|
if (settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[txen], LOW);
|
digitalWrite(settingsMap[txen_pin], LOW);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power
|
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power
|
||||||
@@ -210,11 +210,11 @@ template <typename T> void SX128xInterface<T>::addReceiveMetadata(meshtastic_Mes
|
|||||||
template <typename T> void SX128xInterface<T>::configHardwareForSend()
|
template <typename T> void SX128xInterface<T>::configHardwareForSend()
|
||||||
{
|
{
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (settingsMap[txen] != RADIOLIB_NC) {
|
if (settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[txen], HIGH);
|
digitalWrite(settingsMap[txen_pin], HIGH);
|
||||||
}
|
}
|
||||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
if (settingsMap[rxen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[rxen], LOW);
|
digitalWrite(settingsMap[rxen_pin], LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -241,11 +241,11 @@ template <typename T> void SX128xInterface<T>::startReceive()
|
|||||||
setStandby();
|
setStandby();
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
if (settingsMap[rxen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[rxen], HIGH);
|
digitalWrite(settingsMap[rxen_pin], HIGH);
|
||||||
}
|
}
|
||||||
if (settingsMap[txen] != RADIOLIB_NC) {
|
if (settingsMap[txen_pin] != RADIOLIB_NC) {
|
||||||
digitalWrite(settingsMap[txen], LOW);
|
digitalWrite(settingsMap[txen_pin], LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -66,8 +66,9 @@ static int32_t reconnectETH()
|
|||||||
syslog.enable();
|
syslog.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// initWebServer();
|
#if !MESHTASTIC_EXCLUDE_SOCKETAPI
|
||||||
initApiServer();
|
initApiServer();
|
||||||
|
#endif
|
||||||
|
|
||||||
ethStartupComplete = true;
|
ethStartupComplete = true;
|
||||||
}
|
}
|
||||||
@@ -107,6 +108,11 @@ static int32_t reconnectETH()
|
|||||||
bool initEthernet()
|
bool initEthernet()
|
||||||
{
|
{
|
||||||
if (config.network.eth_enabled) {
|
if (config.network.eth_enabled) {
|
||||||
|
#ifdef PIN_ETH_POWER_EN
|
||||||
|
pinMode(PIN_ETH_POWER_EN, OUTPUT);
|
||||||
|
digitalWrite(PIN_ETH_POWER_EN, HIGH); // Power up.
|
||||||
|
delay(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PIN_ETHERNET_RESET
|
#ifdef PIN_ETHERNET_RESET
|
||||||
pinMode(PIN_ETHERNET_RESET, OUTPUT);
|
pinMode(PIN_ETHERNET_RESET, OUTPUT);
|
||||||
@@ -115,6 +121,12 @@ bool initEthernet()
|
|||||||
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
|
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAK11310 // Initialize the SPI port
|
||||||
|
ETH_SPI_PORT.setSCK(PIN_SPI0_SCK);
|
||||||
|
ETH_SPI_PORT.setTX(PIN_SPI0_MOSI);
|
||||||
|
ETH_SPI_PORT.setRX(PIN_SPI0_MISO);
|
||||||
|
ETH_SPI_PORT.begin();
|
||||||
|
#endif
|
||||||
Ethernet.init(ETH_SPI_PORT, PIN_ETHERNET_SS);
|
Ethernet.init(ETH_SPI_PORT, PIN_ETHERNET_SS);
|
||||||
|
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ PB_BIND(meshtastic_Config_SessionkeyConfig, meshtastic_Config_SessionkeyConfig,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,14 @@ typedef enum _meshtastic_Config_NetworkConfig_AddressMode {
|
|||||||
meshtastic_Config_NetworkConfig_AddressMode_STATIC = 1
|
meshtastic_Config_NetworkConfig_AddressMode_STATIC = 1
|
||||||
} meshtastic_Config_NetworkConfig_AddressMode;
|
} meshtastic_Config_NetworkConfig_AddressMode;
|
||||||
|
|
||||||
|
/* Available flags auxiliary network protocols */
|
||||||
|
typedef enum _meshtastic_Config_NetworkConfig_ProtocolFlags {
|
||||||
|
/* Do not broadcast packets over any network protocol */
|
||||||
|
meshtastic_Config_NetworkConfig_ProtocolFlags_NO_BROADCAST = 0,
|
||||||
|
/* Enable broadcasting packets via UDP over the local network */
|
||||||
|
meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST = 1
|
||||||
|
} meshtastic_Config_NetworkConfig_ProtocolFlags;
|
||||||
|
|
||||||
/* How the GPS coordinates are displayed on the OLED screen. */
|
/* How the GPS coordinates are displayed on the OLED screen. */
|
||||||
typedef enum _meshtastic_Config_DisplayConfig_GpsCoordinateFormat {
|
typedef enum _meshtastic_Config_DisplayConfig_GpsCoordinateFormat {
|
||||||
/* GPS coordinates are displayed in the normal decimal degrees format:
|
/* GPS coordinates are displayed in the normal decimal degrees format:
|
||||||
@@ -429,6 +437,8 @@ typedef struct _meshtastic_Config_NetworkConfig {
|
|||||||
meshtastic_Config_NetworkConfig_IpV4Config ipv4_config;
|
meshtastic_Config_NetworkConfig_IpV4Config ipv4_config;
|
||||||
/* rsyslog Server and Port */
|
/* rsyslog Server and Port */
|
||||||
char rsyslog_server[33];
|
char rsyslog_server[33];
|
||||||
|
/* Flags for enabling/disabling network protocols */
|
||||||
|
uint32_t enabled_protocols;
|
||||||
} meshtastic_Config_NetworkConfig;
|
} meshtastic_Config_NetworkConfig;
|
||||||
|
|
||||||
/* Display Config */
|
/* Display Config */
|
||||||
@@ -613,6 +623,10 @@ extern "C" {
|
|||||||
#define _meshtastic_Config_NetworkConfig_AddressMode_MAX meshtastic_Config_NetworkConfig_AddressMode_STATIC
|
#define _meshtastic_Config_NetworkConfig_AddressMode_MAX meshtastic_Config_NetworkConfig_AddressMode_STATIC
|
||||||
#define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC+1))
|
#define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC+1))
|
||||||
|
|
||||||
|
#define _meshtastic_Config_NetworkConfig_ProtocolFlags_MIN meshtastic_Config_NetworkConfig_ProtocolFlags_NO_BROADCAST
|
||||||
|
#define _meshtastic_Config_NetworkConfig_ProtocolFlags_MAX meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST
|
||||||
|
#define _meshtastic_Config_NetworkConfig_ProtocolFlags_ARRAYSIZE ((meshtastic_Config_NetworkConfig_ProtocolFlags)(meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DEC
|
#define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DEC
|
||||||
#define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MAX meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR
|
#define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MAX meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR
|
||||||
#define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((meshtastic_Config_DisplayConfig_GpsCoordinateFormat)(meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR+1))
|
#define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((meshtastic_Config_DisplayConfig_GpsCoordinateFormat)(meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR+1))
|
||||||
@@ -674,7 +688,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0}
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
||||||
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
|
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
|
||||||
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
|
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
|
||||||
@@ -685,7 +699,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0}
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
||||||
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
|
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
|
||||||
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
|
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
|
||||||
@@ -739,6 +753,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_NetworkConfig_address_mode_tag 7
|
#define meshtastic_Config_NetworkConfig_address_mode_tag 7
|
||||||
#define meshtastic_Config_NetworkConfig_ipv4_config_tag 8
|
#define meshtastic_Config_NetworkConfig_ipv4_config_tag 8
|
||||||
#define meshtastic_Config_NetworkConfig_rsyslog_server_tag 9
|
#define meshtastic_Config_NetworkConfig_rsyslog_server_tag 9
|
||||||
|
#define meshtastic_Config_NetworkConfig_enabled_protocols_tag 10
|
||||||
#define meshtastic_Config_DisplayConfig_screen_on_secs_tag 1
|
#define meshtastic_Config_DisplayConfig_screen_on_secs_tag 1
|
||||||
#define meshtastic_Config_DisplayConfig_gps_format_tag 2
|
#define meshtastic_Config_DisplayConfig_gps_format_tag 2
|
||||||
#define meshtastic_Config_DisplayConfig_auto_screen_carousel_secs_tag 3
|
#define meshtastic_Config_DisplayConfig_auto_screen_carousel_secs_tag 3
|
||||||
@@ -867,7 +882,8 @@ X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \
|
X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \
|
||||||
X(a, STATIC, SINGULAR, UENUM, address_mode, 7) \
|
X(a, STATIC, SINGULAR, UENUM, address_mode, 7) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8) \
|
X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8) \
|
||||||
X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9)
|
X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, enabled_protocols, 10)
|
||||||
#define meshtastic_Config_NetworkConfig_CALLBACK NULL
|
#define meshtastic_Config_NetworkConfig_CALLBACK NULL
|
||||||
#define meshtastic_Config_NetworkConfig_DEFAULT NULL
|
#define meshtastic_Config_NetworkConfig_DEFAULT NULL
|
||||||
#define meshtastic_Config_NetworkConfig_ipv4_config_MSGTYPE meshtastic_Config_NetworkConfig_IpV4Config
|
#define meshtastic_Config_NetworkConfig_ipv4_config_MSGTYPE meshtastic_Config_NetworkConfig_IpV4Config
|
||||||
@@ -972,12 +988,12 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg;
|
|||||||
#define meshtastic_Config_DisplayConfig_size 30
|
#define meshtastic_Config_DisplayConfig_size 30
|
||||||
#define meshtastic_Config_LoRaConfig_size 85
|
#define meshtastic_Config_LoRaConfig_size 85
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||||
#define meshtastic_Config_NetworkConfig_size 196
|
#define meshtastic_Config_NetworkConfig_size 202
|
||||||
#define meshtastic_Config_PositionConfig_size 62
|
#define meshtastic_Config_PositionConfig_size 62
|
||||||
#define meshtastic_Config_PowerConfig_size 52
|
#define meshtastic_Config_PowerConfig_size 52
|
||||||
#define meshtastic_Config_SecurityConfig_size 178
|
#define meshtastic_Config_SecurityConfig_size 178
|
||||||
#define meshtastic_Config_SessionkeyConfig_size 0
|
#define meshtastic_Config_SessionkeyConfig_size 0
|
||||||
#define meshtastic_Config_size 199
|
#define meshtastic_Config_size 205
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ typedef enum _meshtastic_Language {
|
|||||||
meshtastic_Language_GREEK = 13,
|
meshtastic_Language_GREEK = 13,
|
||||||
/* Norwegian */
|
/* Norwegian */
|
||||||
meshtastic_Language_NORWEGIAN = 14,
|
meshtastic_Language_NORWEGIAN = 14,
|
||||||
|
/* Slovenian */
|
||||||
|
meshtastic_Language_SLOVENIAN = 15,
|
||||||
/* Simplified Chinese (experimental) */
|
/* Simplified Chinese (experimental) */
|
||||||
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
|
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
|
||||||
/* Traditional Chinese (experimental) */
|
/* Traditional Chinese (experimental) */
|
||||||
@@ -71,6 +73,8 @@ typedef struct _meshtastic_NodeFilter {
|
|||||||
bool position_switch;
|
bool position_switch;
|
||||||
/* Filter nodes by matching name string */
|
/* Filter nodes by matching name string */
|
||||||
char node_name[16];
|
char node_name[16];
|
||||||
|
/* Filter based on channel */
|
||||||
|
int8_t channel;
|
||||||
} meshtastic_NodeFilter;
|
} meshtastic_NodeFilter;
|
||||||
|
|
||||||
typedef struct _meshtastic_NodeHighlight {
|
typedef struct _meshtastic_NodeHighlight {
|
||||||
@@ -138,10 +142,10 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}}
|
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}}
|
||||||
#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, ""}
|
#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, "", 0}
|
||||||
#define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""}
|
#define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""}
|
||||||
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}}
|
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}}
|
||||||
#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, ""}
|
#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, "", 0}
|
||||||
#define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""}
|
#define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
@@ -151,6 +155,7 @@ extern "C" {
|
|||||||
#define meshtastic_NodeFilter_hops_away_tag 4
|
#define meshtastic_NodeFilter_hops_away_tag 4
|
||||||
#define meshtastic_NodeFilter_position_switch_tag 5
|
#define meshtastic_NodeFilter_position_switch_tag 5
|
||||||
#define meshtastic_NodeFilter_node_name_tag 6
|
#define meshtastic_NodeFilter_node_name_tag 6
|
||||||
|
#define meshtastic_NodeFilter_channel_tag 7
|
||||||
#define meshtastic_NodeHighlight_chat_switch_tag 1
|
#define meshtastic_NodeHighlight_chat_switch_tag 1
|
||||||
#define meshtastic_NodeHighlight_position_switch_tag 2
|
#define meshtastic_NodeHighlight_position_switch_tag 2
|
||||||
#define meshtastic_NodeHighlight_telemetry_switch_tag 3
|
#define meshtastic_NodeHighlight_telemetry_switch_tag 3
|
||||||
@@ -198,7 +203,8 @@ X(a, STATIC, SINGULAR, BOOL, offline_switch, 2) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, public_key_switch, 3) \
|
X(a, STATIC, SINGULAR, BOOL, public_key_switch, 3) \
|
||||||
X(a, STATIC, SINGULAR, INT32, hops_away, 4) \
|
X(a, STATIC, SINGULAR, INT32, hops_away, 4) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, position_switch, 5) \
|
X(a, STATIC, SINGULAR, BOOL, position_switch, 5) \
|
||||||
X(a, STATIC, SINGULAR, STRING, node_name, 6)
|
X(a, STATIC, SINGULAR, STRING, node_name, 6) \
|
||||||
|
X(a, STATIC, SINGULAR, INT32, channel, 7)
|
||||||
#define meshtastic_NodeFilter_CALLBACK NULL
|
#define meshtastic_NodeFilter_CALLBACK NULL
|
||||||
#define meshtastic_NodeFilter_DEFAULT NULL
|
#define meshtastic_NodeFilter_DEFAULT NULL
|
||||||
|
|
||||||
@@ -222,8 +228,8 @@ extern const pb_msgdesc_t meshtastic_NodeHighlight_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size
|
#define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size
|
||||||
#define meshtastic_DeviceUIConfig_size 117
|
#define meshtastic_DeviceUIConfig_size 128
|
||||||
#define meshtastic_NodeFilter_size 36
|
#define meshtastic_NodeFilter_size 47
|
||||||
#define meshtastic_NodeHighlight_size 25
|
#define meshtastic_NodeHighlight_size 25
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
|
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
|
||||||
#define meshtastic_LocalConfig_size 735
|
#define meshtastic_LocalConfig_size 741
|
||||||
#define meshtastic_LocalModuleConfig_size 699
|
#define meshtastic_LocalModuleConfig_size 699
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "mesh/wifi/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Led.h"
|
#include "Led.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "serialization/JSON.h"
|
#include "serialization/JSON.h"
|
||||||
#include <FSCommon.h>
|
#include <FSCommon.h>
|
||||||
@@ -236,6 +237,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
void htmlDeleteDir(const char *dirname)
|
void htmlDeleteDir(const char *dirname)
|
||||||
{
|
{
|
||||||
|
|
||||||
File root = FSCom.open(dirname);
|
File root = FSCom.open(dirname);
|
||||||
if (!root) {
|
if (!root) {
|
||||||
return;
|
return;
|
||||||
@@ -318,6 +320,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||||
|
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
auto fileList = htmlListDir("/static", 10);
|
auto fileList = htmlListDir("/static", 10);
|
||||||
|
|
||||||
// create json output structure
|
// create json output structure
|
||||||
@@ -349,9 +352,12 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->setHeader("Content-Type", "application/json");
|
res->setHeader("Content-Type", "application/json");
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
res->setHeader("Access-Control-Allow-Methods", "DELETE");
|
res->setHeader("Access-Control-Allow-Methods", "DELETE");
|
||||||
|
|
||||||
if (params->getQueryParameter("delete", paramValDelete)) {
|
if (params->getQueryParameter("delete", paramValDelete)) {
|
||||||
std::string pathDelete = "/" + paramValDelete;
|
std::string pathDelete = "/" + paramValDelete;
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
if (FSCom.remove(pathDelete.c_str())) {
|
if (FSCom.remove(pathDelete.c_str())) {
|
||||||
|
|
||||||
LOG_INFO("%s", pathDelete.c_str());
|
LOG_INFO("%s", pathDelete.c_str());
|
||||||
JSONObject jsonObjOuter;
|
JSONObject jsonObjOuter;
|
||||||
jsonObjOuter["status"] = new JSONValue("ok");
|
jsonObjOuter["status"] = new JSONValue("ok");
|
||||||
@@ -360,6 +366,7 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
delete value;
|
delete value;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
LOG_INFO("%s", pathDelete.c_str());
|
LOG_INFO("%s", pathDelete.c_str());
|
||||||
JSONObject jsonObjOuter;
|
JSONObject jsonObjOuter;
|
||||||
jsonObjOuter["status"] = new JSONValue("Error");
|
jsonObjOuter["status"] = new JSONValue("Error");
|
||||||
@@ -393,6 +400,8 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
filenameGzip = "/static/index.html.gz";
|
filenameGzip = "/static/index.html.gz";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
|
|
||||||
if (FSCom.exists(filename.c_str())) {
|
if (FSCom.exists(filename.c_str())) {
|
||||||
file = FSCom.open(filename.c_str());
|
file = FSCom.open(filename.c_str());
|
||||||
if (!file.available()) {
|
if (!file.available()) {
|
||||||
@@ -410,6 +419,7 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
file = FSCom.open(filenameGzip.c_str());
|
file = FSCom.open(filenameGzip.c_str());
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
if (!file.available()) {
|
if (!file.available()) {
|
||||||
|
|
||||||
LOG_WARN("File not available - %s", filenameGzip.c_str());
|
LOG_WARN("File not available - %s", filenameGzip.c_str());
|
||||||
res->println("Web server is running.<br><br>The content you are looking for can't be found. Please see: <a "
|
res->println("Web server is running.<br><br>The content you are looking for can't be found. Please see: <a "
|
||||||
"href=https://meshtastic.org/docs/software/web-client/>FAQ</a>.<br><br><a "
|
"href=https://meshtastic.org/docs/software/web-client/>FAQ</a>.<br><br><a "
|
||||||
@@ -535,6 +545,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
// concepts of the body parser functionality easier to understand.
|
// concepts of the body parser functionality easier to understand.
|
||||||
std::string pathname = "/static/" + filename;
|
std::string pathname = "/static/" + filename;
|
||||||
|
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
// Create a new file to stream the data into
|
// Create a new file to stream the data into
|
||||||
File file = FSCom.open(pathname.c_str(), FILE_O_WRITE);
|
File file = FSCom.open(pathname.c_str(), FILE_O_WRITE);
|
||||||
size_t fileLength = 0;
|
size_t fileLength = 0;
|
||||||
@@ -571,6 +582,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
file.flush();
|
file.flush();
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
res->printf("<p>Saved %d bytes to %s</p>", (int)fileLength, pathname.c_str());
|
res->printf("<p>Saved %d bytes to %s</p>", (int)fileLength, pathname.c_str());
|
||||||
}
|
}
|
||||||
if (!didwrite) {
|
if (!didwrite) {
|
||||||
@@ -642,9 +654,11 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
|||||||
jsonObjMemory["heap_free"] = new JSONValue((int)memGet.getFreeHeap());
|
jsonObjMemory["heap_free"] = new JSONValue((int)memGet.getFreeHeap());
|
||||||
jsonObjMemory["psram_total"] = new JSONValue((int)memGet.getPsramSize());
|
jsonObjMemory["psram_total"] = new JSONValue((int)memGet.getPsramSize());
|
||||||
jsonObjMemory["psram_free"] = new JSONValue((int)memGet.getFreePsram());
|
jsonObjMemory["psram_free"] = new JSONValue((int)memGet.getFreePsram());
|
||||||
|
spiLock->lock();
|
||||||
jsonObjMemory["fs_total"] = new JSONValue((int)FSCom.totalBytes());
|
jsonObjMemory["fs_total"] = new JSONValue((int)FSCom.totalBytes());
|
||||||
jsonObjMemory["fs_used"] = new JSONValue((int)FSCom.usedBytes());
|
jsonObjMemory["fs_used"] = new JSONValue((int)FSCom.usedBytes());
|
||||||
jsonObjMemory["fs_free"] = new JSONValue(int(FSCom.totalBytes() - FSCom.usedBytes()));
|
jsonObjMemory["fs_free"] = new JSONValue(int(FSCom.totalBytes() - FSCom.usedBytes()));
|
||||||
|
spiLock->unlock();
|
||||||
|
|
||||||
// data->power
|
// data->power
|
||||||
JSONObject jsonObjPower;
|
JSONObject jsonObjPower;
|
||||||
@@ -725,7 +739,6 @@ void handleNodes(HTTPRequest *req, HTTPResponse *res)
|
|||||||
node["position"] = new JSONValue(position);
|
node["position"] = new JSONValue(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject user;
|
|
||||||
node["long_name"] = new JSONValue(tempNodeInfo->user.long_name);
|
node["long_name"] = new JSONValue(tempNodeInfo->user.long_name);
|
||||||
node["short_name"] = new JSONValue(tempNodeInfo->user.short_name);
|
node["short_name"] = new JSONValue(tempNodeInfo->user.short_name);
|
||||||
char macStr[18];
|
char macStr[18];
|
||||||
@@ -787,6 +800,7 @@ void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
LOG_INFO("Delete files from /static/* : ");
|
LOG_INFO("Delete files from /static/* : ");
|
||||||
|
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
htmlDeleteDir("/static");
|
htmlDeleteDir("/static");
|
||||||
|
|
||||||
res->println("<p><hr><p><a href=/admin>Back to admin</a>");
|
res->println("<p><hr><p><a href=/admin>Back to admin</a>");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
@@ -55,9 +56,12 @@ bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count)
|
|||||||
/// Write to an arduino file
|
/// Write to an arduino file
|
||||||
bool writecb(pb_ostream_t *stream, const uint8_t *buf, size_t count)
|
bool writecb(pb_ostream_t *stream, const uint8_t *buf, size_t count)
|
||||||
{
|
{
|
||||||
|
spiLock->lock();
|
||||||
auto file = (Print *)stream->state;
|
auto file = (Print *)stream->state;
|
||||||
// LOG_DEBUG("writing %d bytes to protobuf file", count);
|
// LOG_DEBUG("writing %d bytes to protobuf file", count);
|
||||||
return file->write(buf, count) == count;
|
bool status = file->write(buf, count) == count;
|
||||||
|
spiLock->unlock();
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -82,8 +82,6 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"
|
|||||||
volatile bool isWebServerReady;
|
volatile bool isWebServerReady;
|
||||||
volatile bool isCertReady;
|
volatile bool isCertReady;
|
||||||
|
|
||||||
HttpAPI webAPI;
|
|
||||||
|
|
||||||
PiWebServerThread *piwebServerThread;
|
PiWebServerThread *piwebServerThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,7 +245,7 @@ int handleAPIv1ToRadio(const struct _u_request *req, struct _u_response *res, vo
|
|||||||
portduinoVFS->mountpoint(configWeb.rootPath);
|
portduinoVFS->mountpoint(configWeb.rootPath);
|
||||||
|
|
||||||
LOG_DEBUG("Received %d bytes from PUT request", s);
|
LOG_DEBUG("Received %d bytes from PUT request", s);
|
||||||
webAPI.handleToRadio(buffer, s);
|
static_cast<HttpAPI *>(user_data)->handleToRadio(buffer, s);
|
||||||
LOG_DEBUG("end web->radio ");
|
LOG_DEBUG("end web->radio ");
|
||||||
return U_CALLBACK_COMPLETE;
|
return U_CALLBACK_COMPLETE;
|
||||||
}
|
}
|
||||||
@@ -279,7 +277,7 @@ int handleAPIv1FromRadio(const struct _u_request *req, struct _u_response *res,
|
|||||||
|
|
||||||
if (valueAll == "true") {
|
if (valueAll == "true") {
|
||||||
while (len) {
|
while (len) {
|
||||||
len = webAPI.getFromRadio(txBuf);
|
len = static_cast<HttpAPI *>(user_data)->getFromRadio(txBuf);
|
||||||
ulfius_set_response_properties(res, U_OPT_STATUS, 200, U_OPT_BINARY_BODY, txBuf, len);
|
ulfius_set_response_properties(res, U_OPT_STATUS, 200, U_OPT_BINARY_BODY, txBuf, len);
|
||||||
const char *tmpa = (const char *)txBuf;
|
const char *tmpa = (const char *)txBuf;
|
||||||
ulfius_set_string_body_response(res, 200, tmpa);
|
ulfius_set_string_body_response(res, 200, tmpa);
|
||||||
@@ -289,7 +287,7 @@ int handleAPIv1FromRadio(const struct _u_request *req, struct _u_response *res,
|
|||||||
}
|
}
|
||||||
// Otherwise, just return one protobuf
|
// Otherwise, just return one protobuf
|
||||||
} else {
|
} else {
|
||||||
len = webAPI.getFromRadio(txBuf);
|
len = static_cast<HttpAPI *>(user_data)->getFromRadio(txBuf);
|
||||||
const char *tmpa = (const char *)txBuf;
|
const char *tmpa = (const char *)txBuf;
|
||||||
ulfius_set_binary_body_response(res, 200, tmpa, len);
|
ulfius_set_binary_body_response(res, 200, tmpa, len);
|
||||||
// LOG_DEBUG("\n----webAPI response:");
|
// LOG_DEBUG("\n----webAPI response:");
|
||||||
@@ -497,10 +495,10 @@ PiWebServerThread::PiWebServerThread()
|
|||||||
u_map_put(instanceWeb.default_headers, "Access-Control-Allow-Origin", "*");
|
u_map_put(instanceWeb.default_headers, "Access-Control-Allow-Origin", "*");
|
||||||
// Maximum body size sent by the client is 1 Kb
|
// Maximum body size sent by the client is 1 Kb
|
||||||
instanceWeb.max_post_body_size = 1024;
|
instanceWeb.max_post_body_size = 1024;
|
||||||
ulfius_add_endpoint_by_val(&instanceWeb, "GET", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, NULL);
|
ulfius_add_endpoint_by_val(&instanceWeb, "GET", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, &webAPI);
|
||||||
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, NULL);
|
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, &webAPI);
|
||||||
ulfius_add_endpoint_by_val(&instanceWeb, "PUT", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, configWeb.rootPath);
|
ulfius_add_endpoint_by_val(&instanceWeb, "PUT", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, &webAPI);
|
||||||
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, NULL);
|
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, &webAPI);
|
||||||
|
|
||||||
// Add callback function to all endpoints for the Web Server
|
// Add callback function to all endpoints for the Web Server
|
||||||
ulfius_add_endpoint_by_val(&instanceWeb, "GET", NULL, "/*", 2, &callback_static_file, &configWeb);
|
ulfius_add_endpoint_by_val(&instanceWeb, "GET", NULL, "/*", 2, &callback_static_file, &configWeb);
|
||||||
@@ -525,10 +523,9 @@ PiWebServerThread::~PiWebServerThread()
|
|||||||
u_map_clean(&configWeb.mime_types);
|
u_map_clean(&configWeb.mime_types);
|
||||||
|
|
||||||
ulfius_stop_framework(&instanceWeb);
|
ulfius_stop_framework(&instanceWeb);
|
||||||
ulfius_stop_framework(&instanceWeb);
|
ulfius_clean_instance(&instanceWeb);
|
||||||
free(configWeb.rootPath);
|
free(configWeb.rootPath);
|
||||||
ulfius_clean_instance(&instanceService);
|
free(key_pem);
|
||||||
ulfius_clean_instance(&instanceService);
|
|
||||||
free(cert_pem);
|
free(cert_pem);
|
||||||
LOG_INFO("End framework");
|
LOG_INFO("End framework");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,24 +23,6 @@ struct _file_config {
|
|||||||
char *rootPath;
|
char *rootPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PiWebServerThread
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
char *key_pem = NULL;
|
|
||||||
char *cert_pem = NULL;
|
|
||||||
// struct _u_map mime_types;
|
|
||||||
std::string webrootpath;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PiWebServerThread();
|
|
||||||
~PiWebServerThread();
|
|
||||||
int CreateSSLCertificate();
|
|
||||||
int CheckSSLandLoad();
|
|
||||||
uint32_t requestRestart = 0;
|
|
||||||
struct _u_instance instanceWeb;
|
|
||||||
struct _u_instance instanceService;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HttpAPI : public PhoneAPI
|
class HttpAPI : public PhoneAPI
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -55,6 +37,24 @@ class HttpAPI : public PhoneAPI
|
|||||||
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
|
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PiWebServerThread
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
char *key_pem = NULL;
|
||||||
|
char *cert_pem = NULL;
|
||||||
|
// struct _u_map mime_types;
|
||||||
|
std::string webrootpath;
|
||||||
|
HttpAPI webAPI;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PiWebServerThread();
|
||||||
|
~PiWebServerThread();
|
||||||
|
int CreateSSLCertificate();
|
||||||
|
int CheckSSLandLoad();
|
||||||
|
uint32_t requestRestart = 0;
|
||||||
|
struct _u_instance instanceWeb;
|
||||||
|
};
|
||||||
|
|
||||||
extern PiWebServerThread *piwebServerThread;
|
extern PiWebServerThread *piwebServerThread;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ static void onNetworkConnected()
|
|||||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WEBSERVER
|
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WEBSERVER
|
||||||
initWebServer();
|
initWebServer();
|
||||||
#endif
|
#endif
|
||||||
|
#if !MESHTASTIC_EXCLUDE_SOCKETAPI
|
||||||
initApiServer();
|
initApiServer();
|
||||||
|
#endif
|
||||||
APStartupComplete = true;
|
APStartupComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +143,11 @@ static int32_t reconnectWiFi()
|
|||||||
delay(5000);
|
delay(5000);
|
||||||
|
|
||||||
if (!WiFi.isConnected()) {
|
if (!WiFi.isConnected()) {
|
||||||
|
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||||
|
WiFi.mode(WIFI_MODE_NULL);
|
||||||
|
WiFi.useStaticBuffers(true);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
#endif
|
||||||
WiFi.begin(wifiName, wifiPsw);
|
WiFi.begin(wifiName, wifiPsw);
|
||||||
}
|
}
|
||||||
isReconnecting = false;
|
isReconnecting = false;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
#include <FSCommon.h>
|
#include <FSCommon.h>
|
||||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
|
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
|
||||||
@@ -358,12 +359,15 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
|||||||
}
|
}
|
||||||
case meshtastic_AdminMessage_delete_file_request_tag: {
|
case meshtastic_AdminMessage_delete_file_request_tag: {
|
||||||
LOG_DEBUG("Client requesting to delete file: %s", r->delete_file_request);
|
LOG_DEBUG("Client requesting to delete file: %s", r->delete_file_request);
|
||||||
|
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
if (FSCom.remove(r->delete_file_request)) {
|
if (FSCom.remove(r->delete_file_request)) {
|
||||||
LOG_DEBUG("Successfully deleted file");
|
LOG_DEBUG("Successfully deleted file");
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Failed to delete file");
|
LOG_DEBUG("Failed to delete file");
|
||||||
}
|
}
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decompress for Phone (EUD)
|
// Decompress for Phone (EUD)
|
||||||
auto decompressedCopy = packetPool.allocCopy(mp);
|
|
||||||
auto uncompressed = cloneTAKPacketData(t);
|
auto uncompressed = cloneTAKPacketData(t);
|
||||||
uncompressed.is_compressed = false;
|
uncompressed.is_compressed = false;
|
||||||
if (t->has_contact) {
|
if (t->has_contact) {
|
||||||
@@ -188,6 +187,7 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast
|
|||||||
LOG_DEBUG("Decompressed chat to_callsign: %d bytes", length);
|
LOG_DEBUG("Decompressed chat to_callsign: %d bytes", length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto decompressedCopy = packetPool.allocCopy(mp);
|
||||||
decompressedCopy->decoded.payload.size =
|
decompressedCopy->decoded.payload.size =
|
||||||
pb_encode_to_bytes(decompressedCopy->decoded.payload.bytes, sizeof(decompressedCopy->decoded.payload),
|
pb_encode_to_bytes(decompressedCopy->decoded.payload.bytes, sizeof(decompressedCopy->decoded.payload),
|
||||||
meshtastic_TAKPacket_fields, &uncompressed);
|
meshtastic_TAKPacket_fields, &uncompressed);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h" // needed for button bypass
|
#include "PowerFSM.h" // needed for button bypass
|
||||||
|
#include "SPILock.h"
|
||||||
#include "detect/ScanI2C.h"
|
#include "detect/ScanI2C.h"
|
||||||
#include "input/ScanAndSelect.h"
|
#include "input/ScanAndSelect.h"
|
||||||
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
||||||
@@ -982,6 +983,7 @@ bool CannedMessageModule::interceptingKeyboardInput()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !HAS_TFT
|
||||||
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
@@ -1140,6 +1142,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif //! HAS_TFT
|
||||||
|
|
||||||
ProcessMessage CannedMessageModule::handleReceived(const meshtastic_MeshPacket &mp)
|
ProcessMessage CannedMessageModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
@@ -1182,8 +1185,10 @@ bool CannedMessageModule::saveProtoForModule()
|
|||||||
{
|
{
|
||||||
bool okay = true;
|
bool okay = true;
|
||||||
|
|
||||||
#ifdef FS
|
#ifdef FSCom
|
||||||
FS.mkdir("/prefs");
|
spiLock->lock();
|
||||||
|
FSCom.mkdir("/prefs");
|
||||||
|
spiLock->unlock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
okay &= nodeDB->saveProto(cannedMessagesConfigFile, meshtastic_CannedMessageModuleConfig_size,
|
okay &= nodeDB->saveProto(cannedMessagesConfigFile, meshtastic_CannedMessageModuleConfig_size,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "airtime.h"
|
#include "airtime.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "gps/GeoCoord.h"
|
#include "gps/GeoCoord.h"
|
||||||
@@ -205,6 +206,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
|
|||||||
LOG_DEBUG("gpsStatus->getDOP() %d", gpsStatus->getDOP());
|
LOG_DEBUG("gpsStatus->getDOP() %d", gpsStatus->getDOP());
|
||||||
LOG_DEBUG("-----------------------------------------");
|
LOG_DEBUG("-----------------------------------------");
|
||||||
*/
|
*/
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
if (!FSBegin()) {
|
if (!FSBegin()) {
|
||||||
LOG_DEBUG("An Error has occurred while mounting the filesystem");
|
LOG_DEBUG("An Error has occurred while mounting the filesystem");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ class RoutingModule : public ProtobufModule<meshtastic_Routing>
|
|||||||
*/
|
*/
|
||||||
RoutingModule();
|
RoutingModule();
|
||||||
|
|
||||||
void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit = 0);
|
virtual void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
|
||||||
|
uint8_t hopLimit = 0);
|
||||||
|
|
||||||
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
|
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
|
||||||
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);
|
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ CGRadSensSensor cgRadSens;
|
|||||||
#include "Sensor/T1000xSensor.h"
|
#include "Sensor/T1000xSensor.h"
|
||||||
T1000xSensor t1000xSensor;
|
T1000xSensor t1000xSensor;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
#include "Sensor/IndicatorSensor.h"
|
||||||
|
IndicatorSensor indicatorSensor;
|
||||||
|
#endif
|
||||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||||
|
|
||||||
@@ -103,6 +107,9 @@ int32_t EnvironmentTelemetryModule::runOnce()
|
|||||||
LOG_INFO("Environment Telemetry: init");
|
LOG_INFO("Environment Telemetry: init");
|
||||||
// it's possible to have this module enabled, only for displaying values on the screen.
|
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||||
// therefore, we should only enable the sensor loop if measurement is also enabled
|
// therefore, we should only enable the sensor loop if measurement is also enabled
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
result = indicatorSensor.runOnce();
|
||||||
|
#endif
|
||||||
#ifdef T1000X_SENSOR_EN
|
#ifdef T1000X_SENSOR_EN
|
||||||
result = t1000xSensor.runOnce();
|
result = t1000xSensor.runOnce();
|
||||||
#elif !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
|
#elif !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
|
||||||
@@ -215,7 +222,11 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Display "Env. From: ..." on its own
|
// Display "Env. From: ..." on its own
|
||||||
display->drawString(x, y, "Env. From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
|
display->drawString(x, y, "Env. From: " + String(lastSender) + " (" + String(agoSecs) + "s)");
|
||||||
|
|
||||||
|
// Prepare sensor data strings
|
||||||
|
String sensorData[10];
|
||||||
|
int sensorCount = 0;
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.has_temperature ||
|
if (lastMeasurement.variant.environment_metrics.has_temperature ||
|
||||||
lastMeasurement.variant.environment_metrics.has_relative_humidity) {
|
lastMeasurement.variant.environment_metrics.has_relative_humidity) {
|
||||||
@@ -225,38 +236,83 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
|
|||||||
String(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
|
String(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue with the remaining details
|
sensorData[sensorCount++] =
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
"Temp/Hum: " + last_temp + " / " + String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%";
|
||||||
"Temp/Hum: " + last_temp + " / " +
|
|
||||||
String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
|
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
sensorData[sensorCount++] =
|
||||||
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA");
|
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.voltage != 0) {
|
if (lastMeasurement.variant.environment_metrics.voltage != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
sensorData[sensorCount++] = "Volt/Cur: " + String(lastMeasurement.variant.environment_metrics.voltage, 0) + "V / " +
|
||||||
"Volt/Cur: " + String(lastMeasurement.variant.environment_metrics.voltage, 0) + "V / " +
|
String(lastMeasurement.variant.environment_metrics.current, 0) + "mA";
|
||||||
String(lastMeasurement.variant.environment_metrics.current, 0) + "mA");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.iaq != 0) {
|
if (lastMeasurement.variant.environment_metrics.iaq != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL), "IAQ: " + String(lastMeasurement.variant.environment_metrics.iaq));
|
sensorData[sensorCount++] = "IAQ: " + String(lastMeasurement.variant.environment_metrics.iaq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.distance != 0)
|
if (lastMeasurement.variant.environment_metrics.distance != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
sensorData[sensorCount++] = "Water Level: " + String(lastMeasurement.variant.environment_metrics.distance, 0) + "mm";
|
||||||
"Water Level: " + String(lastMeasurement.variant.environment_metrics.distance, 0) + "mm");
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.weight != 0)
|
if (lastMeasurement.variant.environment_metrics.weight != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
sensorData[sensorCount++] = "Weight: " + String(lastMeasurement.variant.environment_metrics.weight, 0) + "kg";
|
||||||
"Weight: " + String(lastMeasurement.variant.environment_metrics.weight, 0) + "kg");
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.radiation != 0)
|
if (lastMeasurement.variant.environment_metrics.radiation != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
sensorData[sensorCount++] = "Rad: " + String(lastMeasurement.variant.environment_metrics.radiation, 2) + "µR/h";
|
||||||
"Rad: " + String(lastMeasurement.variant.environment_metrics.radiation, 2) + "µR/h");
|
}
|
||||||
|
|
||||||
|
if (lastMeasurement.variant.environment_metrics.lux != 0) {
|
||||||
|
sensorData[sensorCount++] = "Illuminance: " + String(lastMeasurement.variant.environment_metrics.lux, 2) + "lx";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastMeasurement.variant.environment_metrics.white_lux != 0) {
|
||||||
|
sensorData[sensorCount++] = "W_Lux: " + String(lastMeasurement.variant.environment_metrics.white_lux, 2) + "lx";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scrollOffset = 0;
|
||||||
|
static bool scrollingDown = true;
|
||||||
|
static uint32_t lastScrollTime = millis();
|
||||||
|
|
||||||
|
// Determine how many lines we can fit on display
|
||||||
|
// Calculated once only: display dimensions don't change during runtime.
|
||||||
|
static int maxLines = 0;
|
||||||
|
if (!maxLines) {
|
||||||
|
const int16_t paddingTop = _fontHeight(FONT_SMALL); // Heading text
|
||||||
|
const int16_t paddingBottom = 8; // Indicator dots
|
||||||
|
maxLines = (display->getHeight() - paddingTop - paddingBottom) / _fontHeight(FONT_SMALL);
|
||||||
|
assert(maxLines > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw as many lines of data as we can fit
|
||||||
|
int linesToShow = min(maxLines, sensorCount);
|
||||||
|
for (int i = 0; i < linesToShow; i++) {
|
||||||
|
int index = (scrollOffset + i) % sensorCount;
|
||||||
|
display->drawString(x, y += _fontHeight(FONT_SMALL), sensorData[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only scroll if there are more than 3 sensor data lines
|
||||||
|
if (sensorCount > 3) {
|
||||||
|
// Update scroll offset every 5 seconds
|
||||||
|
if (millis() - lastScrollTime > 5000) {
|
||||||
|
if (scrollingDown) {
|
||||||
|
scrollOffset++;
|
||||||
|
if (scrollOffset + linesToShow >= sensorCount) {
|
||||||
|
scrollingDown = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scrollOffset--;
|
||||||
|
if (scrollOffset <= 0) {
|
||||||
|
scrollingDown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastScrollTime = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
|
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
|
||||||
@@ -270,8 +326,10 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
|
|||||||
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
|
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
|
||||||
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
|
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
|
||||||
t->variant.environment_metrics.temperature);
|
t->variant.environment_metrics.temperature);
|
||||||
LOG_INFO("(Received from %s): voltage=%f, IAQ=%d, distance=%f, lux=%f", sender, t->variant.environment_metrics.voltage,
|
LOG_INFO("(Received from %s): voltage=%f, IAQ=%d, distance=%f, lux=%f, white_lux=%f", sender,
|
||||||
t->variant.environment_metrics.iaq, t->variant.environment_metrics.distance, t->variant.environment_metrics.lux);
|
t->variant.environment_metrics.voltage, t->variant.environment_metrics.iaq,
|
||||||
|
t->variant.environment_metrics.distance, t->variant.environment_metrics.lux,
|
||||||
|
t->variant.environment_metrics.white_lux);
|
||||||
|
|
||||||
LOG_INFO("(Received from %s): wind speed=%fm/s, direction=%d degrees, weight=%fkg", sender,
|
LOG_INFO("(Received from %s): wind speed=%fm/s, direction=%d degrees, weight=%fkg", sender,
|
||||||
t->variant.environment_metrics.wind_speed, t->variant.environment_metrics.wind_direction,
|
t->variant.environment_metrics.wind_speed, t->variant.environment_metrics.wind_direction,
|
||||||
@@ -298,6 +356,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
|
|||||||
m->which_variant = meshtastic_Telemetry_environment_metrics_tag;
|
m->which_variant = meshtastic_Telemetry_environment_metrics_tag;
|
||||||
m->variant.environment_metrics = meshtastic_EnvironmentMetrics_init_zero;
|
m->variant.environment_metrics = meshtastic_EnvironmentMetrics_init_zero;
|
||||||
|
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
valid = valid && indicatorSensor.getMetrics(m);
|
||||||
|
hasSensor = true;
|
||||||
|
#endif
|
||||||
#ifdef T1000X_SENSOR_EN // add by WayenWeng
|
#ifdef T1000X_SENSOR_EN // add by WayenWeng
|
||||||
valid = valid && t1000xSensor.getMetrics(m);
|
valid = valid && t1000xSensor.getMetrics(m);
|
||||||
hasSensor = true;
|
hasSensor = true;
|
||||||
@@ -410,7 +472,6 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
|
|||||||
valid = valid && cgRadSens.getMetrics(m);
|
valid = valid && cgRadSens.getMetrics(m);
|
||||||
hasSensor = true;
|
hasSensor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return valid && hasSensor;
|
return valid && hasSensor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,44 +99,45 @@ bool PowerTelemetryModule::wantUIFrame()
|
|||||||
void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_SMALL);
|
||||||
display->drawString(x, y, "Power Telemetry");
|
|
||||||
if (lastMeasurementPacket == nullptr) {
|
if (lastMeasurementPacket == nullptr) {
|
||||||
display->setFont(FONT_SMALL);
|
// In case of no valid packet, display "Power Telemetry", "No measurement"
|
||||||
display->drawString(x, y += _fontHeight(FONT_MEDIUM), "No measurement");
|
display->drawString(x, y, "Power Telemetry");
|
||||||
|
display->drawString(x, y += _fontHeight(FONT_SMALL), "No measurement");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode the last power packet
|
||||||
meshtastic_Telemetry lastMeasurement;
|
meshtastic_Telemetry lastMeasurement;
|
||||||
|
|
||||||
uint32_t agoSecs = service->GetTimeSinceMeshPacket(lastMeasurementPacket);
|
uint32_t agoSecs = service->GetTimeSinceMeshPacket(lastMeasurementPacket);
|
||||||
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
||||||
|
|
||||||
const meshtastic_Data &p = lastMeasurementPacket->decoded;
|
const meshtastic_Data &p = lastMeasurementPacket->decoded;
|
||||||
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
||||||
display->setFont(FONT_SMALL);
|
display->drawString(x, y, "Measurement Error");
|
||||||
display->drawString(x, y += _fontHeight(FONT_MEDIUM), "Measurement Error");
|
|
||||||
LOG_ERROR("Unable to decode last packet");
|
LOG_ERROR("Unable to decode last packet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display "Pow. From: ..."
|
||||||
|
display->drawString(x, y, "Pow. From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
|
||||||
|
|
||||||
// Display current and voltage based on ...power_metrics.has_[channel/voltage/current]... flags
|
// Display current and voltage based on ...power_metrics.has_[channel/voltage/current]... flags
|
||||||
display->setFont(FONT_SMALL);
|
|
||||||
display->drawString(x, y += _fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
|
|
||||||
if (lastMeasurement.variant.power_metrics.has_ch1_voltage || lastMeasurement.variant.power_metrics.has_ch1_current) {
|
if (lastMeasurement.variant.power_metrics.has_ch1_voltage || lastMeasurement.variant.power_metrics.has_ch1_current) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
||||||
"Ch1 Volt: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 2) +
|
"Ch1: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 2) +
|
||||||
"V / Curr: " + String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA");
|
"V " + String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA");
|
||||||
}
|
}
|
||||||
if (lastMeasurement.variant.power_metrics.has_ch2_voltage || lastMeasurement.variant.power_metrics.has_ch2_current) {
|
if (lastMeasurement.variant.power_metrics.has_ch2_voltage || lastMeasurement.variant.power_metrics.has_ch2_current) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
||||||
"Ch2 Volt: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 2) +
|
"Ch2: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 2) +
|
||||||
"V / Curr: " + String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA");
|
"V " + String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA");
|
||||||
}
|
}
|
||||||
if (lastMeasurement.variant.power_metrics.has_ch3_voltage || lastMeasurement.variant.power_metrics.has_ch3_current) {
|
if (lastMeasurement.variant.power_metrics.has_ch3_voltage || lastMeasurement.variant.power_metrics.has_ch3_current) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
||||||
"Ch3 Volt: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 2) +
|
"Ch3: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 2) +
|
||||||
"V / Curr: " + String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA");
|
"V " + String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
#include "BME680Sensor.h"
|
#include "BME680Sensor.h"
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "TelemetrySensor.h"
|
#include "TelemetrySensor.h"
|
||||||
|
|
||||||
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
|
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
|
||||||
@@ -75,6 +76,7 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
|||||||
void BME680Sensor::loadState()
|
void BME680Sensor::loadState()
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
auto file = FSCom.open(bsecConfigFileName, FILE_O_READ);
|
auto file = FSCom.open(bsecConfigFileName, FILE_O_READ);
|
||||||
if (file) {
|
if (file) {
|
||||||
file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
|
file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
|
||||||
@@ -84,6 +86,7 @@ void BME680Sensor::loadState()
|
|||||||
} else {
|
} else {
|
||||||
LOG_INFO("No %s state found (File: %s)", sensorName, bsecConfigFileName);
|
LOG_INFO("No %s state found (File: %s)", sensorName, bsecConfigFileName);
|
||||||
}
|
}
|
||||||
|
spiLock->unlock();
|
||||||
#else
|
#else
|
||||||
LOG_ERROR("ERROR: Filesystem not implemented");
|
LOG_ERROR("ERROR: Filesystem not implemented");
|
||||||
#endif
|
#endif
|
||||||
@@ -92,6 +95,7 @@ void BME680Sensor::loadState()
|
|||||||
void BME680Sensor::updateState()
|
void BME680Sensor::updateState()
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
spiLock->lock();
|
||||||
bool update = false;
|
bool update = false;
|
||||||
if (stateUpdateCounter == 0) {
|
if (stateUpdateCounter == 0) {
|
||||||
/* First state update when IAQ accuracy is >= 3 */
|
/* First state update when IAQ accuracy is >= 3 */
|
||||||
@@ -127,6 +131,7 @@ void BME680Sensor::updateState()
|
|||||||
LOG_INFO("Can't write %s state (File: %s)", sensorName, bsecConfigFileName);
|
LOG_INFO("Can't write %s state (File: %s)", sensorName, bsecConfigFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spiLock->unlock();
|
||||||
#else
|
#else
|
||||||
LOG_ERROR("ERROR: Filesystem not implemented");
|
LOG_ERROR("ERROR: Filesystem not implemented");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -41,13 +41,12 @@ void CGRadSensSensor::begin(TwoWire *wire, uint8_t addr)
|
|||||||
float CGRadSensSensor::getStaticRadiation()
|
float CGRadSensSensor::getStaticRadiation()
|
||||||
{
|
{
|
||||||
// Read a register, following the same pattern as the RCWL9620Sensor
|
// Read a register, following the same pattern as the RCWL9620Sensor
|
||||||
uint32_t data;
|
|
||||||
_wire->beginTransmission(_addr); // Transfer data to addr.
|
_wire->beginTransmission(_addr); // Transfer data to addr.
|
||||||
_wire->write(0x06); // Radiation intensity (static period T = 500 sec)
|
_wire->write(0x06); // Radiation intensity (static period T = 500 sec)
|
||||||
if (_wire->endTransmission() == 0) {
|
if (_wire->endTransmission() == 0) {
|
||||||
if (_wire->requestFrom(_addr, (uint8_t)3)) {
|
if (_wire->requestFrom(_addr, (uint8_t)3)) {
|
||||||
; // Request 3 bytes
|
; // Request 3 bytes
|
||||||
data = _wire->read();
|
uint32_t data = _wire->read();
|
||||||
data <<= 8;
|
data <<= 8;
|
||||||
data |= _wire->read();
|
data |= _wire->read();
|
||||||
data <<= 8;
|
data <<= 8;
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(SENSECAP_INDICATOR)
|
||||||
|
|
||||||
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
|
#include "IndicatorSensor.h"
|
||||||
|
#include "TelemetrySensor.h"
|
||||||
|
#include "serialization/cobs.h"
|
||||||
|
#include <Adafruit_Sensor.h>
|
||||||
|
#include <driver/uart.h>
|
||||||
|
|
||||||
|
IndicatorSensor::IndicatorSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "Indicator") {}
|
||||||
|
|
||||||
|
#define SENSOR_BUF_SIZE (512)
|
||||||
|
|
||||||
|
uint8_t buf[SENSOR_BUF_SIZE]; // recv
|
||||||
|
uint8_t data[SENSOR_BUF_SIZE]; // decode
|
||||||
|
|
||||||
|
#define ACK_PKT_PARA "ACK"
|
||||||
|
|
||||||
|
enum sensor_pkt_type {
|
||||||
|
PKT_TYPE_ACK = 0x00, // uin32_t
|
||||||
|
PKT_TYPE_CMD_COLLECT_INTERVAL = 0xA0, // uin32_t
|
||||||
|
PKT_TYPE_CMD_BEEP_ON = 0xA1, // uin32_t ms: on time
|
||||||
|
PKT_TYPE_CMD_BEEP_OFF = 0xA2,
|
||||||
|
PKT_TYPE_CMD_SHUTDOWN = 0xA3, // uin32_t
|
||||||
|
PKT_TYPE_CMD_POWER_ON = 0xA4,
|
||||||
|
PKT_TYPE_SENSOR_SCD41_TEMP = 0xB0, // float
|
||||||
|
PKT_TYPE_SENSOR_SCD41_HUMIDITY = 0xB1, // float
|
||||||
|
PKT_TYPE_SENSOR_SCD41_CO2 = 0xB2, // float
|
||||||
|
PKT_TYPE_SENSOR_AHT20_TEMP = 0xB3, // float
|
||||||
|
PKT_TYPE_SENSOR_AHT20_HUMIDITY = 0xB4, // float
|
||||||
|
PKT_TYPE_SENSOR_TVOC_INDEX = 0xB5, // float
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cmd_send(uint8_t cmd, const char *p_data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t send_buf[32] = {0};
|
||||||
|
uint8_t send_data[32] = {0};
|
||||||
|
|
||||||
|
if (len > 31) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t index = 1;
|
||||||
|
|
||||||
|
send_data[0] = cmd;
|
||||||
|
|
||||||
|
if (len > 0 && p_data != NULL) {
|
||||||
|
memcpy(&send_data[1], p_data, len);
|
||||||
|
index += len;
|
||||||
|
}
|
||||||
|
cobs_encode_result ret = cobs_encode(send_buf, sizeof(send_buf), send_data, index);
|
||||||
|
|
||||||
|
// LOG_DEBUG("cobs TX status:%d, len:%d, type 0x%x", ret.status, ret.out_len, cmd);
|
||||||
|
|
||||||
|
if (ret.status == COBS_ENCODE_OK) {
|
||||||
|
return uart_write_bytes(SENSOR_PORT_NUM, send_buf, ret.out_len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t IndicatorSensor::runOnce()
|
||||||
|
{
|
||||||
|
LOG_INFO("%s: init", sensorName);
|
||||||
|
setup();
|
||||||
|
return 2 * DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; // give it some time to start up
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndicatorSensor::setup()
|
||||||
|
{
|
||||||
|
uart_config_t uart_config = {
|
||||||
|
.baud_rate = SENSOR_BAUD_RATE,
|
||||||
|
.data_bits = UART_DATA_8_BITS,
|
||||||
|
.parity = UART_PARITY_DISABLE,
|
||||||
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||||
|
.source_clk = UART_SCLK_APB,
|
||||||
|
};
|
||||||
|
int intr_alloc_flags = 0;
|
||||||
|
char buffer[11];
|
||||||
|
|
||||||
|
uart_driver_install(SENSOR_PORT_NUM, SENSOR_BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags);
|
||||||
|
uart_param_config(SENSOR_PORT_NUM, &uart_config);
|
||||||
|
uart_set_pin(SENSOR_PORT_NUM, SENSOR_RP2040_TXD, SENSOR_RP2040_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||||
|
cmd_send(PKT_TYPE_CMD_POWER_ON, NULL, 0);
|
||||||
|
// measure and send only once every minute, for the phone API
|
||||||
|
const char *interval = ultoa(60000, buffer, 10);
|
||||||
|
cmd_send(PKT_TYPE_CMD_COLLECT_INTERVAL, interval, strlen(interval) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||||
|
{
|
||||||
|
cobs_decode_result ret;
|
||||||
|
int len = uart_read_bytes(SENSOR_PORT_NUM, buf, (SENSOR_BUF_SIZE - 1), 100 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
|
float value = 0.0;
|
||||||
|
uint8_t *p_buf_start = buf;
|
||||||
|
uint8_t *p_buf_end = buf;
|
||||||
|
if (len > 0) {
|
||||||
|
while (p_buf_start < (buf + len)) {
|
||||||
|
p_buf_end = p_buf_start;
|
||||||
|
while (p_buf_end < (buf + len)) {
|
||||||
|
if (*p_buf_end == 0x00) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p_buf_end++;
|
||||||
|
}
|
||||||
|
// decode buf
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
ret = cobs_decode(data, sizeof(data), p_buf_start, p_buf_end - p_buf_start);
|
||||||
|
|
||||||
|
// LOG_DEBUG("cobs RX status:%d, len:%d, type:0x%x ", ret.status, ret.out_len, data[0]);
|
||||||
|
|
||||||
|
if (ret.out_len > 1 && ret.status == COBS_DECODE_OK) {
|
||||||
|
|
||||||
|
value = 0.0;
|
||||||
|
uint8_t pkt_type = data[0];
|
||||||
|
switch (pkt_type) {
|
||||||
|
case PKT_TYPE_SENSOR_SCD41_CO2: {
|
||||||
|
memcpy(&value, &data[1], sizeof(value));
|
||||||
|
// LOG_DEBUG("CO2: %.1f", value);
|
||||||
|
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PKT_TYPE_SENSOR_AHT20_TEMP: {
|
||||||
|
memcpy(&value, &data[1], sizeof(value));
|
||||||
|
// LOG_DEBUG("Temp: %.1f", value);
|
||||||
|
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
||||||
|
measurement->variant.environment_metrics.has_temperature = true;
|
||||||
|
measurement->variant.environment_metrics.temperature = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PKT_TYPE_SENSOR_AHT20_HUMIDITY: {
|
||||||
|
memcpy(&value, &data[1], sizeof(value));
|
||||||
|
// LOG_DEBUG("Humidity: %.1f", value);
|
||||||
|
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
||||||
|
measurement->variant.environment_metrics.has_relative_humidity = true;
|
||||||
|
measurement->variant.environment_metrics.relative_humidity = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PKT_TYPE_SENSOR_TVOC_INDEX: {
|
||||||
|
memcpy(&value, &data[1], sizeof(value));
|
||||||
|
// LOG_DEBUG("Tvoc: %.1f", value);
|
||||||
|
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
||||||
|
measurement->variant.environment_metrics.has_iaq = true;
|
||||||
|
measurement->variant.environment_metrics.iaq = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_buf_start = p_buf_end + 1; // next message
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
|
|
||||||
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
|
#include "TelemetrySensor.h"
|
||||||
|
|
||||||
|
class IndicatorSensor : public TelemetrySensor
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual void setup() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
IndicatorSensor();
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
#include "NAU7802Sensor.h"
|
#include "NAU7802Sensor.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "SafeFile.h"
|
#include "SafeFile.h"
|
||||||
#include "TelemetrySensor.h"
|
#include "TelemetrySensor.h"
|
||||||
#include <Throttle.h>
|
#include <Throttle.h>
|
||||||
@@ -111,13 +112,16 @@ bool NAU7802Sensor::saveCalibrationData()
|
|||||||
} else {
|
} else {
|
||||||
okay = true;
|
okay = true;
|
||||||
}
|
}
|
||||||
|
spiLock->lock();
|
||||||
okay &= file.close();
|
okay &= file.close();
|
||||||
|
spiLock->unlock();
|
||||||
|
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NAU7802Sensor::loadCalibrationData()
|
bool NAU7802Sensor::loadCalibrationData()
|
||||||
{
|
{
|
||||||
|
spiLock->lock();
|
||||||
auto file = FSCom.open(nau7802ConfigFileName, FILE_O_READ);
|
auto file = FSCom.open(nau7802ConfigFileName, FILE_O_READ);
|
||||||
bool okay = false;
|
bool okay = false;
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -134,6 +138,7 @@ bool NAU7802Sensor::loadCalibrationData()
|
|||||||
} else {
|
} else {
|
||||||
LOG_INFO("No %s state found (File: %s)", sensorName, nau7802ConfigFileName);
|
LOG_INFO("No %s state found (File: %s)", sensorName, nau7802ConfigFileName);
|
||||||
}
|
}
|
||||||
|
spiLock->unlock();
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-30
@@ -2,6 +2,7 @@
|
|||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
|
#include "ServiceEnvelope.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/Channels.h"
|
#include "mesh/Channels.h"
|
||||||
@@ -25,7 +26,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <Throttle.h>
|
#include <Throttle.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <pb_decode.h>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
@@ -47,23 +47,6 @@ static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for cha
|
|||||||
|
|
||||||
static bool isMqttServerAddressPrivate = false;
|
static bool isMqttServerAddressPrivate = false;
|
||||||
|
|
||||||
// meshtastic_ServiceEnvelope that automatically releases dynamically allocated memory when it goes out of scope.
|
|
||||||
struct DecodedServiceEnvelope : public meshtastic_ServiceEnvelope {
|
|
||||||
DecodedServiceEnvelope() = delete;
|
|
||||||
DecodedServiceEnvelope(const uint8_t *payload, size_t length)
|
|
||||||
: meshtastic_ServiceEnvelope(meshtastic_ServiceEnvelope_init_default),
|
|
||||||
validDecode(pb_decode_from_bytes(payload, length, &meshtastic_ServiceEnvelope_msg, this))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~DecodedServiceEnvelope()
|
|
||||||
{
|
|
||||||
if (validDecode)
|
|
||||||
pb_release(&meshtastic_ServiceEnvelope_msg, this);
|
|
||||||
}
|
|
||||||
// Clients must check that this is true before using.
|
|
||||||
const bool validDecode;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
||||||
{
|
{
|
||||||
const DecodedServiceEnvelope e(payload, length);
|
const DecodedServiceEnvelope e(payload, length);
|
||||||
@@ -93,12 +76,22 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_INFO("Received MQTT topic %s, len=%u", topic, length);
|
LOG_INFO("Received MQTT topic %s, len=%u", topic, length);
|
||||||
|
if (e.packet->hop_limit > HOP_MAX || e.packet->hop_start > HOP_MAX) {
|
||||||
|
LOG_INFO("Invalid hop_limit(%u) or hop_start(%u)", e.packet->hop_limit, e.packet->hop_start);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UniquePacketPoolPacket p = packetPool.allocUniqueCopy(*e.packet);
|
UniquePacketPoolPacket p = packetPool.allocUniqueZeroed();
|
||||||
|
p->from = e.packet->from;
|
||||||
|
p->to = e.packet->to;
|
||||||
|
p->id = e.packet->id;
|
||||||
|
p->channel = e.packet->channel;
|
||||||
|
p->hop_limit = e.packet->hop_limit;
|
||||||
|
p->hop_start = e.packet->hop_start;
|
||||||
|
p->want_ack = e.packet->want_ack;
|
||||||
p->via_mqtt = true; // Mark that the packet was received via MQTT
|
p->via_mqtt = true; // Mark that the packet was received via MQTT
|
||||||
// Unset received SNR/RSSI which might have been added by the MQTT gateway
|
p->which_payload_variant = e.packet->which_payload_variant;
|
||||||
p->rx_snr = 0;
|
memcpy(&p->decoded, &e.packet->decoded, std::max(sizeof(p->decoded), sizeof(p->encrypted)));
|
||||||
p->rx_rssi = 0;
|
|
||||||
|
|
||||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
if (moduleConfig.mqtt.encryption_enabled) {
|
if (moduleConfig.mqtt.encryption_enabled) {
|
||||||
@@ -299,7 +292,9 @@ void mqttInit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HAS_NETWORKING
|
#if HAS_NETWORKING
|
||||||
MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient), mqttQueue(MAX_MQTT_QUEUE)
|
MQTT::MQTT() : MQTT(std::unique_ptr<MQTTClient>(new MQTTClient())) {}
|
||||||
|
MQTT::MQTT(std::unique_ptr<MQTTClient> _mqttClient)
|
||||||
|
: concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE), mqttClient(std::move(_mqttClient)), pubSub(*mqttClient)
|
||||||
#else
|
#else
|
||||||
MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
|
MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
|
||||||
#endif
|
#endif
|
||||||
@@ -437,20 +432,20 @@ void MQTT::reconnect()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Use non-TLS-encrypted session");
|
LOG_INFO("Use non-TLS-encrypted session");
|
||||||
pubSub.setClient(mqttClient);
|
pubSub.setClient(*mqttClient);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
pubSub.setClient(mqttClient);
|
pubSub.setClient(*mqttClient);
|
||||||
#endif
|
#endif
|
||||||
#elif HAS_NETWORKING
|
#elif HAS_NETWORKING
|
||||||
pubSub.setClient(mqttClient);
|
pubSub.setClient(*mqttClient);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::pair<String, uint16_t> hostAndPort = parseHostAndPort(serverAddr, serverPort);
|
std::pair<String, uint16_t> hostAndPort = parseHostAndPort(serverAddr, serverPort);
|
||||||
serverAddr = hostAndPort.first.c_str();
|
serverAddr = hostAndPort.first.c_str();
|
||||||
serverPort = hostAndPort.second;
|
serverPort = hostAndPort.second;
|
||||||
pubSub.setServer(serverAddr, serverPort);
|
pubSub.setServer(serverAddr, serverPort);
|
||||||
pubSub.setBufferSize(512);
|
pubSub.setBufferSize(1024);
|
||||||
|
|
||||||
LOG_INFO("Connect directly to MQTT server %s, port: %d, username: %s, password: %s", serverAddr, serverPort, mqttUsername,
|
LOG_INFO("Connect directly to MQTT server %s, port: %d, username: %s, password: %s", serverAddr, serverPort, mqttUsername,
|
||||||
mqttPassword);
|
mqttPassword);
|
||||||
@@ -461,7 +456,7 @@ void MQTT::reconnect()
|
|||||||
enabled = true; // Start running background process again
|
enabled = true; // Start running background process again
|
||||||
runASAP = true;
|
runASAP = true;
|
||||||
reconnectCount = 0;
|
reconnectCount = 0;
|
||||||
isMqttServerAddressPrivate = isPrivateIpAddress(mqttClient.remoteIP());
|
isMqttServerAddressPrivate = isPrivateIpAddress(mqttClient->remoteIP());
|
||||||
|
|
||||||
publishNodeInfo();
|
publishNodeInfo();
|
||||||
sendSubscriptions();
|
sendSubscriptions();
|
||||||
@@ -627,8 +622,7 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp_encrypted, const meshtastic_Me
|
|||||||
// mp_decoded will not be decoded when it's PKI encrypted and not directed to us
|
// mp_decoded will not be decoded when it's PKI encrypted and not directed to us
|
||||||
if (mp_decoded.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
if (mp_decoded.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
// For uplinking other's packets, check if it's not OK to MQTT or if it's an older packet without the bitfield
|
// For uplinking other's packets, check if it's not OK to MQTT or if it's an older packet without the bitfield
|
||||||
bool dontUplink = !mp_decoded.decoded.has_bitfield ||
|
bool dontUplink = !mp_decoded.decoded.has_bitfield || !(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK);
|
||||||
(mp_decoded.decoded.has_bitfield && !(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK));
|
|
||||||
// check for the lowest bit of the data bitfield set false, and the use of one of the default keys.
|
// check for the lowest bit of the data bitfield set false, and the use of one of the default keys.
|
||||||
if (!isFromUs(&mp_decoded) && !isMqttServerAddressPrivate && dontUplink &&
|
if (!isFromUs(&mp_decoded) && !isMqttServerAddressPrivate && dontUplink &&
|
||||||
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
|
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
|
||||||
|
|||||||
+23
-17
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#if HAS_NETWORKING
|
#if HAS_NETWORKING
|
||||||
#include <PubSubClient.h>
|
#include <PubSubClient.h>
|
||||||
|
#include <memory>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_MQTT_QUEUE 16
|
#define MAX_MQTT_QUEUE 16
|
||||||
@@ -32,24 +33,7 @@
|
|||||||
*/
|
*/
|
||||||
class MQTT : private concurrency::OSThread
|
class MQTT : private concurrency::OSThread
|
||||||
{
|
{
|
||||||
// supposedly the current version is busted:
|
|
||||||
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
|
|
||||||
#if HAS_WIFI
|
|
||||||
WiFiClient mqttClient;
|
|
||||||
#if !defined(ARCH_PORTDUINO)
|
|
||||||
#if (defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3) || defined(RPI_PICO)
|
|
||||||
WiFiClientSecure wifiSecureClient;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if HAS_ETHERNET
|
|
||||||
EthernetClient mqttClient;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if HAS_NETWORKING
|
|
||||||
PubSubClient pubSub;
|
|
||||||
#endif
|
|
||||||
MQTT();
|
MQTT();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,7 +77,29 @@ class MQTT : private concurrency::OSThread
|
|||||||
|
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
#ifndef PIO_UNIT_TESTING
|
||||||
private:
|
private:
|
||||||
|
#endif
|
||||||
|
// supposedly the current version is busted:
|
||||||
|
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
|
||||||
|
#if HAS_WIFI
|
||||||
|
using MQTTClient = WiFiClient;
|
||||||
|
#if !defined(ARCH_PORTDUINO)
|
||||||
|
#if (defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3) || defined(RPI_PICO)
|
||||||
|
WiFiClientSecure wifiSecureClient;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if HAS_ETHERNET
|
||||||
|
using MQTTClient = EthernetClient;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_NETWORKING
|
||||||
|
std::unique_ptr<MQTTClient> mqttClient;
|
||||||
|
PubSubClient pubSub;
|
||||||
|
explicit MQTT(std::unique_ptr<MQTTClient> mqttClient);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string cryptTopic = "/2/e/"; // msh/2/e/CHANNELID/NODEID
|
std::string cryptTopic = "/2/e/"; // msh/2/e/CHANNELID/NODEID
|
||||||
std::string jsonTopic = "/2/json/"; // msh/2/json/CHANNELID/NODEID
|
std::string jsonTopic = "/2/json/"; // msh/2/json/CHANNELID/NODEID
|
||||||
std::string mapTopic = "/2/map/"; // For protobuf-encoded MapReport messages
|
std::string mapTopic = "/2/map/"; // For protobuf-encoded MapReport messages
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#include "ServiceEnvelope.h"
|
||||||
|
#include "mesh-pb-constants.h"
|
||||||
|
#include <pb_decode.h>
|
||||||
|
|
||||||
|
DecodedServiceEnvelope::DecodedServiceEnvelope(const uint8_t *payload, size_t length)
|
||||||
|
: meshtastic_ServiceEnvelope(meshtastic_ServiceEnvelope_init_default),
|
||||||
|
validDecode(pb_decode_from_bytes(payload, length, &meshtastic_ServiceEnvelope_msg, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DecodedServiceEnvelope::DecodedServiceEnvelope(DecodedServiceEnvelope &&other)
|
||||||
|
: meshtastic_ServiceEnvelope(meshtastic_ServiceEnvelope_init_zero), validDecode(other.validDecode)
|
||||||
|
{
|
||||||
|
std::swap(packet, other.packet);
|
||||||
|
std::swap(channel_id, other.channel_id);
|
||||||
|
std::swap(gateway_id, other.gateway_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
DecodedServiceEnvelope::~DecodedServiceEnvelope()
|
||||||
|
{
|
||||||
|
if (validDecode)
|
||||||
|
pb_release(&meshtastic_ServiceEnvelope_msg, this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mesh/generated/meshtastic/mqtt.pb.h"
|
||||||
|
|
||||||
|
// meshtastic_ServiceEnvelope that automatically releases dynamically allocated memory when it goes out of scope.
|
||||||
|
struct DecodedServiceEnvelope : public meshtastic_ServiceEnvelope {
|
||||||
|
DecodedServiceEnvelope(const uint8_t *payload, size_t length);
|
||||||
|
DecodedServiceEnvelope(DecodedServiceEnvelope &) = delete;
|
||||||
|
DecodedServiceEnvelope(DecodedServiceEnvelope &&);
|
||||||
|
~DecodedServiceEnvelope();
|
||||||
|
// Clients must check that this is true before using.
|
||||||
|
const bool validDecode;
|
||||||
|
};
|
||||||
@@ -44,11 +44,7 @@ class BluetoothPhoneAPI : public PhoneAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check the current underlying physical link to see if the client is currently connected
|
/// Check the current underlying physical link to see if the client is currently connected
|
||||||
virtual bool checkIsConnected() override
|
virtual bool checkIsConnected() override { return Bluefruit.connected(connectionHandle); }
|
||||||
{
|
|
||||||
BLEConnection *connection = Bluefruit.Connection(connectionHandle);
|
|
||||||
return connection->connected();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static BluetoothPhoneAPI *bluetoothPhoneAPI;
|
static BluetoothPhoneAPI *bluetoothPhoneAPI;
|
||||||
@@ -214,7 +210,10 @@ void NRF52Bluetooth::shutdown()
|
|||||||
LOG_INFO("NRF52 bluetooth disconnecting handle %d", i);
|
LOG_INFO("NRF52 bluetooth disconnecting handle %d", i);
|
||||||
Bluefruit.disconnect(i);
|
Bluefruit.disconnect(i);
|
||||||
}
|
}
|
||||||
delay(100); // wait for ondisconnect;
|
// Wait for disconnection
|
||||||
|
while (Bluefruit.connected())
|
||||||
|
yield();
|
||||||
|
LOG_INFO("All bluetooth connections ended");
|
||||||
}
|
}
|
||||||
Bluefruit.Advertising.stop();
|
Bluefruit.Advertising.stop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ void getMacAddr(uint8_t *dmac)
|
|||||||
if (strlen(optionMac) >= 12) {
|
if (strlen(optionMac) >= 12) {
|
||||||
MAC_from_string(optionMac, dmac);
|
MAC_from_string(optionMac, dmac);
|
||||||
} else {
|
} else {
|
||||||
uint32_t hwId;
|
uint32_t hwId = {0};
|
||||||
sscanf(optionMac, "%u", &hwId);
|
sscanf(optionMac, "%u", &hwId);
|
||||||
dmac[0] = 0x80;
|
dmac[0] = 0x80;
|
||||||
dmac[1] = 0;
|
dmac[1] = 0;
|
||||||
@@ -104,7 +104,7 @@ void getMacAddr(uint8_t *dmac)
|
|||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
struct hci_dev_info di;
|
struct hci_dev_info di = {0};
|
||||||
di.dev_id = 0;
|
di.dev_id = 0;
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
int btsock;
|
int btsock;
|
||||||
@@ -134,21 +134,10 @@ void portduinoSetup()
|
|||||||
{
|
{
|
||||||
printf("Set up Meshtastic on Portduino...\n");
|
printf("Set up Meshtastic on Portduino...\n");
|
||||||
int max_GPIO = 0;
|
int max_GPIO = 0;
|
||||||
const configNames GPIO_lines[] = {cs,
|
const configNames GPIO_lines[] = {
|
||||||
irq,
|
cs_pin, irq_pin, busy_pin, reset_pin, sx126x_ant_sw_pin, txen_pin,
|
||||||
busy,
|
rxen_pin, displayDC, displayCS, displayBacklight, displayBacklightPWMChannel, displayReset,
|
||||||
reset,
|
touchscreenCS, touchscreenIRQ, user};
|
||||||
sx126x_ant_sw,
|
|
||||||
txen,
|
|
||||||
rxen,
|
|
||||||
displayDC,
|
|
||||||
displayCS,
|
|
||||||
displayBacklight,
|
|
||||||
displayBacklightPWMChannel,
|
|
||||||
displayReset,
|
|
||||||
touchscreenCS,
|
|
||||||
touchscreenIRQ,
|
|
||||||
user};
|
|
||||||
|
|
||||||
std::string gpioChipName = "gpiochip";
|
std::string gpioChipName = "gpiochip";
|
||||||
settingsStrings[i2cdev] = "";
|
settingsStrings[i2cdev] = "";
|
||||||
@@ -231,6 +220,9 @@ void portduinoSetup()
|
|||||||
dmac[3] = hash[3];
|
dmac[3] = hash[3];
|
||||||
dmac[4] = hash[4];
|
dmac[4] = hash[4];
|
||||||
dmac[5] = hash[5];
|
dmac[5] = hash[5];
|
||||||
|
char macBuf[13] = {0};
|
||||||
|
sprintf(macBuf, "%02X%02X%02X%02X%02X%02X", dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
|
||||||
|
settingsStrings[mac_address] = macBuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,11 +232,11 @@ void portduinoSetup()
|
|||||||
std::cout << "Please set a MAC Address in config.yaml using either MACAddress or MACAddressSource." << std::endl;
|
std::cout << "Please set a MAC Address in config.yaml using either MACAddress or MACAddressSource." << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
std::cout << "MAC Address: " << std::hex << +dmac[0] << +dmac[1] << +dmac[2] << +dmac[3] << +dmac[4] << +dmac[5] << std::endl;
|
printf("MAC ADDRESS: %02X:%02X:%02X:%02X:%02X:%02X\n", dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
|
||||||
// Rather important to set this, if not running simulated.
|
// Rather important to set this, if not running simulated.
|
||||||
randomSeed(time(NULL));
|
randomSeed(time(NULL));
|
||||||
|
|
||||||
gpioChipName += std::to_string(settingsMap[gpiochip]);
|
std::string defaultGpioChipName = gpioChipName + std::to_string(settingsMap[default_gpiochip]);
|
||||||
|
|
||||||
for (configNames i : GPIO_lines) {
|
for (configNames i : GPIO_lines) {
|
||||||
if (settingsMap.count(i) && settingsMap[i] > max_GPIO)
|
if (settingsMap.count(i) && settingsMap[i] > max_GPIO)
|
||||||
@@ -254,65 +246,51 @@ void portduinoSetup()
|
|||||||
gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need.
|
gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need.
|
||||||
|
|
||||||
// Need to bind all the configured GPIO pins so they're not simulated
|
// Need to bind all the configured GPIO pins so they're not simulated
|
||||||
// TODO: Can we do this in the for loop above?
|
|
||||||
// TODO: If one of these fails, we should log and terminate
|
// TODO: If one of these fails, we should log and terminate
|
||||||
if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) {
|
if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) {
|
||||||
if (initGPIOPin(settingsMap[user], gpioChipName) != ERRNO_OK) {
|
if (initGPIOPin(settingsMap[user], defaultGpioChipName, settingsMap[user]) != ERRNO_OK) {
|
||||||
settingsMap[user] = RADIOLIB_NC;
|
settingsMap[user] = RADIOLIB_NC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settingsMap[displayPanel] != no_screen) {
|
if (settingsMap[displayPanel] != no_screen) {
|
||||||
if (settingsMap[displayCS] > 0)
|
if (settingsMap[displayCS] > 0)
|
||||||
initGPIOPin(settingsMap[displayCS], gpioChipName);
|
initGPIOPin(settingsMap[displayCS], defaultGpioChipName, settingsMap[displayCS]);
|
||||||
if (settingsMap[displayDC] > 0)
|
if (settingsMap[displayDC] > 0)
|
||||||
initGPIOPin(settingsMap[displayDC], gpioChipName);
|
initGPIOPin(settingsMap[displayDC], defaultGpioChipName, settingsMap[displayDC]);
|
||||||
if (settingsMap[displayBacklight] > 0)
|
if (settingsMap[displayBacklight] > 0)
|
||||||
initGPIOPin(settingsMap[displayBacklight], gpioChipName);
|
initGPIOPin(settingsMap[displayBacklight], defaultGpioChipName, settingsMap[displayBacklight]);
|
||||||
if (settingsMap[displayReset] > 0)
|
if (settingsMap[displayReset] > 0)
|
||||||
initGPIOPin(settingsMap[displayReset], gpioChipName);
|
initGPIOPin(settingsMap[displayReset], defaultGpioChipName, settingsMap[displayReset]);
|
||||||
}
|
}
|
||||||
if (settingsMap[touchscreenModule] != no_touchscreen) {
|
if (settingsMap[touchscreenModule] != no_touchscreen) {
|
||||||
if (settingsMap[touchscreenCS] > 0)
|
if (settingsMap[touchscreenCS] > 0)
|
||||||
initGPIOPin(settingsMap[touchscreenCS], gpioChipName);
|
initGPIOPin(settingsMap[touchscreenCS], defaultGpioChipName, settingsMap[touchscreenCS]);
|
||||||
if (settingsMap[touchscreenIRQ] > 0)
|
if (settingsMap[touchscreenIRQ] > 0)
|
||||||
initGPIOPin(settingsMap[touchscreenIRQ], gpioChipName);
|
initGPIOPin(settingsMap[touchscreenIRQ], defaultGpioChipName, settingsMap[touchscreenIRQ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only initialize the radio pins when dealing with real, kernel controlled SPI hardware
|
// Only initialize the radio pins when dealing with real, kernel controlled SPI hardware
|
||||||
if (settingsStrings[spidev] != "" && settingsStrings[spidev] != "ch341") {
|
if (settingsStrings[spidev] != "" && settingsStrings[spidev] != "ch341") {
|
||||||
if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) {
|
const struct {
|
||||||
if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) {
|
configNames pin;
|
||||||
settingsMap[cs] = RADIOLIB_NC;
|
configNames gpiochip;
|
||||||
}
|
configNames line;
|
||||||
}
|
} pinMappings[] = {{cs_pin, cs_gpiochip, cs_line},
|
||||||
if (settingsMap.count(irq) > 0 && settingsMap[irq] != RADIOLIB_NC) {
|
{irq_pin, irq_gpiochip, irq_line},
|
||||||
if (initGPIOPin(settingsMap[irq], gpioChipName) != ERRNO_OK) {
|
{busy_pin, busy_gpiochip, busy_line},
|
||||||
settingsMap[irq] = RADIOLIB_NC;
|
{reset_pin, reset_gpiochip, reset_line},
|
||||||
}
|
{rxen_pin, rxen_gpiochip, rxen_line},
|
||||||
}
|
{txen_pin, txen_gpiochip, txen_line},
|
||||||
if (settingsMap.count(busy) > 0 && settingsMap[busy] != RADIOLIB_NC) {
|
{sx126x_ant_sw_pin, sx126x_ant_sw_gpiochip, sx126x_ant_sw_line}};
|
||||||
if (initGPIOPin(settingsMap[busy], gpioChipName) != ERRNO_OK) {
|
for (auto &pinMap : pinMappings) {
|
||||||
settingsMap[busy] = RADIOLIB_NC;
|
auto setMapIter = settingsMap.find(pinMap.pin);
|
||||||
}
|
if (setMapIter != settingsMap.end() && setMapIter->second != RADIOLIB_NC) {
|
||||||
}
|
if (initGPIOPin(setMapIter->second, gpioChipName + std::to_string(settingsMap[pinMap.gpiochip]),
|
||||||
if (settingsMap.count(reset) > 0 && settingsMap[reset] != RADIOLIB_NC) {
|
settingsMap[pinMap.line]) != ERRNO_OK) {
|
||||||
if (initGPIOPin(settingsMap[reset], gpioChipName) != ERRNO_OK) {
|
printf("Error setting pin number %d. It may not exist, or may already be in use.\n",
|
||||||
settingsMap[reset] = RADIOLIB_NC;
|
settingsMap[pinMap.line]);
|
||||||
}
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (settingsMap.count(sx126x_ant_sw) > 0 && settingsMap[sx126x_ant_sw] != RADIOLIB_NC) {
|
|
||||||
if (initGPIOPin(settingsMap[sx126x_ant_sw], gpioChipName) != ERRNO_OK) {
|
|
||||||
settingsMap[sx126x_ant_sw] = RADIOLIB_NC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (settingsMap.count(rxen) > 0 && settingsMap[rxen] != RADIOLIB_NC) {
|
|
||||||
if (initGPIOPin(settingsMap[rxen], gpioChipName) != ERRNO_OK) {
|
|
||||||
settingsMap[rxen] = RADIOLIB_NC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (settingsMap.count(txen) > 0 && settingsMap[txen] != RADIOLIB_NC) {
|
|
||||||
if (initGPIOPin(settingsMap[txen], gpioChipName) != ERRNO_OK) {
|
|
||||||
settingsMap[txen] = RADIOLIB_NC;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SPI.begin(settingsStrings[spidev].c_str());
|
SPI.begin(settingsStrings[spidev].c_str());
|
||||||
@@ -329,13 +307,13 @@ void portduinoSetup()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int initGPIOPin(int pinNum, const std::string gpioChipName)
|
int initGPIOPin(int pinNum, const std::string gpioChipName, int line)
|
||||||
{
|
{
|
||||||
#ifdef PORTDUINO_LINUX_HARDWARE
|
#ifdef PORTDUINO_LINUX_HARDWARE
|
||||||
std::string gpio_name = "GPIO" + std::to_string(pinNum);
|
std::string gpio_name = "GPIO" + std::to_string(pinNum);
|
||||||
try {
|
try {
|
||||||
GPIOPin *csPin;
|
GPIOPin *csPin;
|
||||||
csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), pinNum, gpio_name.c_str());
|
csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), line, gpio_name.c_str());
|
||||||
csPin->setSilent();
|
csPin->setSilent();
|
||||||
gpioBind(csPin);
|
gpioBind(csPin);
|
||||||
return ERRNO_OK;
|
return ERRNO_OK;
|
||||||
@@ -373,42 +351,58 @@ bool loadConfig(const char *configPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (yamlConfig["Lora"]) {
|
if (yamlConfig["Lora"]) {
|
||||||
settingsMap[use_sx1262] = false;
|
const struct {
|
||||||
settingsMap[use_rf95] = false;
|
configNames cfgName;
|
||||||
settingsMap[use_sx1280] = false;
|
std::string strName;
|
||||||
settingsMap[use_lr1110] = false;
|
} loraModules[] = {{use_rf95, "RF95"}, {use_sx1262, "sx1262"}, {use_sx1268, "sx1268"}, {use_sx1280, "sx1280"},
|
||||||
settingsMap[use_lr1120] = false;
|
{use_lr1110, "lr1110"}, {use_lr1120, "lr1120"}, {use_lr1121, "lr1121"}, {use_llcc68, "LLCC68"}};
|
||||||
settingsMap[use_lr1121] = false;
|
for (auto &loraModule : loraModules) {
|
||||||
settingsMap[use_sx1268] = false;
|
settingsMap[loraModule.cfgName] = false;
|
||||||
|
|
||||||
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1262") {
|
|
||||||
settingsMap[use_sx1262] = true;
|
|
||||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "RF95") {
|
|
||||||
settingsMap[use_rf95] = true;
|
|
||||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1280") {
|
|
||||||
settingsMap[use_sx1280] = true;
|
|
||||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "lr1110") {
|
|
||||||
settingsMap[use_lr1110] = true;
|
|
||||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "lr1120") {
|
|
||||||
settingsMap[use_lr1120] = true;
|
|
||||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "lr1121") {
|
|
||||||
settingsMap[use_lr1121] = true;
|
|
||||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1268") {
|
|
||||||
settingsMap[use_sx1268] = true;
|
|
||||||
}
|
}
|
||||||
|
if (yamlConfig["Lora"]["Module"]) {
|
||||||
|
for (auto &loraModule : loraModules) {
|
||||||
|
if (yamlConfig["Lora"]["Module"].as<std::string>("") == loraModule.strName) {
|
||||||
|
settingsMap[loraModule.cfgName] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
|
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
|
||||||
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<float>(0) * 1000;
|
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<float>(0) * 1000;
|
||||||
if (settingsMap[dio3_tcxo_voltage] == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false)) {
|
if (settingsMap[dio3_tcxo_voltage] == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false)) {
|
||||||
settingsMap[dio3_tcxo_voltage] = 1800; // default millivolts for "true"
|
settingsMap[dio3_tcxo_voltage] = 1800; // default millivolts for "true"
|
||||||
}
|
}
|
||||||
settingsMap[cs] = yamlConfig["Lora"]["CS"].as<int>(RADIOLIB_NC);
|
|
||||||
settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as<int>(RADIOLIB_NC);
|
// backwards API compatibility and to globally set gpiochip once
|
||||||
settingsMap[busy] = yamlConfig["Lora"]["Busy"].as<int>(RADIOLIB_NC);
|
int defaultGpioChip = settingsMap[default_gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0);
|
||||||
settingsMap[reset] = yamlConfig["Lora"]["Reset"].as<int>(RADIOLIB_NC);
|
|
||||||
settingsMap[txen] = yamlConfig["Lora"]["TXen"].as<int>(RADIOLIB_NC);
|
const struct {
|
||||||
settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as<int>(RADIOLIB_NC);
|
configNames pin;
|
||||||
settingsMap[sx126x_ant_sw] = yamlConfig["Lora"]["SX126X_ANT_SW"].as<int>(RADIOLIB_NC);
|
configNames gpiochip;
|
||||||
settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0);
|
configNames line;
|
||||||
|
std::string strName;
|
||||||
|
} pinMappings[] = {
|
||||||
|
{cs_pin, cs_gpiochip, cs_line, "CS"},
|
||||||
|
{irq_pin, irq_gpiochip, irq_line, "IRQ"},
|
||||||
|
{busy_pin, busy_gpiochip, busy_line, "Busy"},
|
||||||
|
{reset_pin, reset_gpiochip, reset_line, "Reset"},
|
||||||
|
{txen_pin, txen_gpiochip, txen_line, "TXen"},
|
||||||
|
{rxen_pin, rxen_gpiochip, rxen_line, "RXen"},
|
||||||
|
{sx126x_ant_sw_pin, sx126x_ant_sw_gpiochip, sx126x_ant_sw_line, "SX126X_ANT_SW"},
|
||||||
|
};
|
||||||
|
for (auto &pinMap : pinMappings) {
|
||||||
|
if (yamlConfig["Lora"][pinMap.strName].IsMap()) {
|
||||||
|
settingsMap[pinMap.pin] = yamlConfig["Lora"][pinMap.strName]["pin"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[pinMap.line] = yamlConfig["Lora"][pinMap.strName]["line"].as<int>(settingsMap[pinMap.pin]);
|
||||||
|
settingsMap[pinMap.gpiochip] = yamlConfig["Lora"][pinMap.strName]["gpiochip"].as<int>(defaultGpioChip);
|
||||||
|
} else { // backwards API compatibility
|
||||||
|
settingsMap[pinMap.pin] = yamlConfig["Lora"][pinMap.strName].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[pinMap.line] = settingsMap[pinMap.pin];
|
||||||
|
settingsMap[pinMap.gpiochip] = defaultGpioChip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as<int>(2000000);
|
settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as<int>(2000000);
|
||||||
settingsStrings[lora_usb_serial_num] = yamlConfig["Lora"]["USB_Serialnum"].as<std::string>("");
|
settingsStrings[lora_usb_serial_num] = yamlConfig["Lora"]["USB_Serialnum"].as<std::string>("");
|
||||||
settingsMap[lora_usb_pid] = yamlConfig["Lora"]["USB_PID"].as<int>(0x5512);
|
settingsMap[lora_usb_pid] = yamlConfig["Lora"]["USB_PID"].as<int>(0x5512);
|
||||||
|
|||||||
@@ -5,27 +5,42 @@
|
|||||||
#include "platform/portduino/USBHal.h"
|
#include "platform/portduino/USBHal.h"
|
||||||
|
|
||||||
enum configNames {
|
enum configNames {
|
||||||
use_sx1262,
|
default_gpiochip,
|
||||||
cs,
|
cs_pin,
|
||||||
irq,
|
cs_line,
|
||||||
busy,
|
cs_gpiochip,
|
||||||
reset,
|
irq_pin,
|
||||||
sx126x_ant_sw,
|
irq_line,
|
||||||
txen,
|
irq_gpiochip,
|
||||||
rxen,
|
busy_pin,
|
||||||
|
busy_line,
|
||||||
|
busy_gpiochip,
|
||||||
|
reset_pin,
|
||||||
|
reset_line,
|
||||||
|
reset_gpiochip,
|
||||||
|
txen_pin,
|
||||||
|
txen_line,
|
||||||
|
txen_gpiochip,
|
||||||
|
rxen_pin,
|
||||||
|
rxen_line,
|
||||||
|
rxen_gpiochip,
|
||||||
|
sx126x_ant_sw_pin,
|
||||||
|
sx126x_ant_sw_line,
|
||||||
|
sx126x_ant_sw_gpiochip,
|
||||||
dio2_as_rf_switch,
|
dio2_as_rf_switch,
|
||||||
dio3_tcxo_voltage,
|
dio3_tcxo_voltage,
|
||||||
use_rf95,
|
use_rf95,
|
||||||
|
use_sx1262,
|
||||||
|
use_sx1268,
|
||||||
use_sx1280,
|
use_sx1280,
|
||||||
use_lr1110,
|
use_lr1110,
|
||||||
use_lr1120,
|
use_lr1120,
|
||||||
use_lr1121,
|
use_lr1121,
|
||||||
use_sx1268,
|
use_llcc68,
|
||||||
lora_usb_serial_num,
|
lora_usb_serial_num,
|
||||||
lora_usb_pid,
|
lora_usb_pid,
|
||||||
lora_usb_vid,
|
lora_usb_vid,
|
||||||
user,
|
user,
|
||||||
gpiochip,
|
|
||||||
spidev,
|
spidev,
|
||||||
spiSpeed,
|
spiSpeed,
|
||||||
i2cdev,
|
i2cdev,
|
||||||
@@ -75,7 +90,7 @@ extern std::map<configNames, int> settingsMap;
|
|||||||
extern std::map<configNames, std::string> settingsStrings;
|
extern std::map<configNames, std::string> settingsStrings;
|
||||||
extern std::ofstream traceFile;
|
extern std::ofstream traceFile;
|
||||||
extern Ch341Hal *ch341Hal;
|
extern Ch341Hal *ch341Hal;
|
||||||
int initGPIOPin(int pinNum, std::string gpioChipname);
|
int initGPIOPin(int pinNum, std::string gpioChipname, int line);
|
||||||
bool loadConfig(const char *configPath);
|
bool loadConfig(const char *configPath);
|
||||||
static bool ends_with(std::string_view str, std::string_view suffix);
|
static bool ends_with(std::string_view str, std::string_view suffix);
|
||||||
void getMacAddr(uint8_t *dmac);
|
void getMacAddr(uint8_t *dmac);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user