mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-14 06:42:34 +00:00
Compare commits
324 Commits
v1.3.9.921
...
v1.3.22.c7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c725a6b65f | ||
|
|
9c6da233b9 | ||
|
|
0f2aa7660d | ||
|
|
9f78dff25f | ||
|
|
e7dfd14917 | ||
|
|
bc47dd574b | ||
|
|
41d5ccc29f | ||
|
|
aead7a23f9 | ||
|
|
c9fd591942 | ||
|
|
c81fbd867d | ||
|
|
cfb76290cb | ||
|
|
46e13d23d9 | ||
|
|
45b2c169aa | ||
|
|
90baf9d8a0 | ||
|
|
a390fc7ea8 | ||
|
|
e0f912ab2a | ||
|
|
646d6f5615 | ||
|
|
cf00ac593f | ||
|
|
ff9f973a1d | ||
|
|
7a50ab4de2 | ||
|
|
c80f260fba | ||
|
|
a7d527c3c3 | ||
|
|
2e2c485f4c | ||
|
|
388865aba7 | ||
|
|
21c6e595a1 | ||
|
|
4a2522dbd3 | ||
|
|
877d72cbad | ||
|
|
63238cb810 | ||
|
|
e87c5d8d34 | ||
|
|
f9bbbfccb3 | ||
|
|
089c91a7ac | ||
|
|
9a5ff935f9 | ||
|
|
515a411e8c | ||
|
|
52f299ec49 | ||
|
|
9285316c78 | ||
|
|
cf380e6cb6 | ||
|
|
c3c359c0cb | ||
|
|
68465f294a | ||
|
|
f63b876b71 | ||
|
|
22fca01323 | ||
|
|
d4a4bcf91a | ||
|
|
d726ed6e7c | ||
|
|
349f6bf502 | ||
|
|
192c10d6d7 | ||
|
|
be8fb73204 | ||
|
|
bc9a4367d1 | ||
|
|
3d3511ceeb | ||
|
|
74e926ef00 | ||
|
|
f3a433f906 | ||
|
|
3c6a2f7bb6 | ||
|
|
1996a2a193 | ||
|
|
b40abbf3ad | ||
|
|
af335e9c06 | ||
|
|
8684fd1c49 | ||
|
|
49e47f3e6d | ||
|
|
d0a8a3018d | ||
|
|
7566ee1fea | ||
|
|
43d48d4fb9 | ||
|
|
2a6633a666 | ||
|
|
0146761850 | ||
|
|
0943e5f500 | ||
|
|
a1dc350231 | ||
|
|
d5a258cebd | ||
|
|
125f76d984 | ||
|
|
b127479961 | ||
|
|
d18aa2e7cb | ||
|
|
d301144efe | ||
|
|
058b5ceddd | ||
|
|
e85baf00c4 | ||
|
|
4a6cad6e46 | ||
|
|
bc05f98685 | ||
|
|
6e671d808a | ||
|
|
1df3dd5f78 | ||
|
|
c9822dee93 | ||
|
|
e1783df49f | ||
|
|
6b8afdadc2 | ||
|
|
f918548e44 | ||
|
|
a1b07ed6aa | ||
|
|
b059fb9e8e | ||
|
|
553b35d0ad | ||
|
|
04478081c6 | ||
|
|
7bd07db2a8 | ||
|
|
5c44c4f772 | ||
|
|
7ff940409e | ||
|
|
cb5c32490c | ||
|
|
e0b63c6692 | ||
|
|
dc8d1d9a84 | ||
|
|
710e2694ef | ||
|
|
7594140afc | ||
|
|
e793d933c6 | ||
|
|
9d8f9613d4 | ||
|
|
61427528b6 | ||
|
|
47ad27f9f6 | ||
|
|
77f096e56c | ||
|
|
5106433572 | ||
|
|
4458b470aa | ||
|
|
90957e6994 | ||
|
|
b73fd32f71 | ||
|
|
2a3272b7d0 | ||
|
|
3fd756900a | ||
|
|
beb8bc9e72 | ||
|
|
1ad5cdc93c | ||
|
|
e8e72d2e08 | ||
|
|
1d0badd468 | ||
|
|
9e87be4f22 | ||
|
|
97899aed26 | ||
|
|
0ee4ba4975 | ||
|
|
bbcccde787 | ||
|
|
42c285bc31 | ||
|
|
c831242f25 | ||
|
|
3c6f36c8f7 | ||
|
|
dfde6cc9c1 | ||
|
|
7816800012 | ||
|
|
ebf132ad21 | ||
|
|
67cf3018b5 | ||
|
|
eafbef0c2f | ||
|
|
4ab831c103 | ||
|
|
3df5ec0b11 | ||
|
|
c5c2765fb4 | ||
|
|
df9e9bc223 | ||
|
|
1ff0032c20 | ||
|
|
18024f1d25 | ||
|
|
313c50d6cf | ||
|
|
80e08f6de9 | ||
|
|
5a256323e2 | ||
|
|
45495c51e6 | ||
|
|
40ded630d0 | ||
|
|
432d06741e | ||
|
|
03b7f2f837 | ||
|
|
2e1b895791 | ||
|
|
9821a0535b | ||
|
|
0b666b827d | ||
|
|
235cacf9b9 | ||
|
|
db28a1562e | ||
|
|
f61d2d9eb4 | ||
|
|
5aef58e87f | ||
|
|
77a2054254 | ||
|
|
48ee995e0d | ||
|
|
c7dfd245e3 | ||
|
|
4e813b098a | ||
|
|
e57dbdd26c | ||
|
|
9512ea45de | ||
|
|
0d09767efd | ||
|
|
5828e6f423 | ||
|
|
c7a9ce7f49 | ||
|
|
95f091041b | ||
|
|
f33e6a0e66 | ||
|
|
fe8bfdb762 | ||
|
|
e8afd4fb4b | ||
|
|
71a43a97cc | ||
|
|
b34b26518b | ||
|
|
b9f25eb85c | ||
|
|
a7fbe024e4 | ||
|
|
1f7fee8e2a | ||
|
|
b8e7c6ee7a | ||
|
|
06b2ed4ebe | ||
|
|
32245a1a8d | ||
|
|
f6982ca726 | ||
|
|
03bbc5eff4 | ||
|
|
0767c0b0e8 | ||
|
|
0d574e35c6 | ||
|
|
b88e75cf2a | ||
|
|
6306c53bfe | ||
|
|
8db57601bf | ||
|
|
1b8830e7df | ||
|
|
0411401184 | ||
|
|
2ee003f2a1 | ||
|
|
5678221ead | ||
|
|
c5f3cad0f9 | ||
|
|
f3c15eb6cc | ||
|
|
e218bba87e | ||
|
|
c04d62158b | ||
|
|
03affc9e73 | ||
|
|
25bf97316d | ||
|
|
1ef70a2489 | ||
|
|
76ef240a3d | ||
|
|
3f171b29f7 | ||
|
|
dca6c27c9d | ||
|
|
2631a9324e | ||
|
|
c64f4bbb11 | ||
|
|
94f7e7037d | ||
|
|
a0b4b4efa1 | ||
|
|
d68d85590b | ||
|
|
800a4200ef | ||
|
|
9c50a76ea2 | ||
|
|
4a41694ec5 | ||
|
|
6bb3861e95 | ||
|
|
e8262540d4 | ||
|
|
2b6f632a50 | ||
|
|
bddab68110 | ||
|
|
c4f69cbcc0 | ||
|
|
85f5c7a40b | ||
|
|
e0c5e4d441 | ||
|
|
8dfdc11af9 | ||
|
|
ba1937de39 | ||
|
|
2e45d4f0fd | ||
|
|
b1f309545e | ||
|
|
22764425f7 | ||
|
|
5e8d49d24b | ||
|
|
53e9f4df46 | ||
|
|
33938f73a6 | ||
|
|
e4484270b1 | ||
|
|
964510ef52 | ||
|
|
b108540b08 | ||
|
|
db35b92b6f | ||
|
|
5d22efd8a8 | ||
|
|
49ccb77e43 | ||
|
|
3d0d45a695 | ||
|
|
2e39900f78 | ||
|
|
5e82423331 | ||
|
|
dd8111e737 | ||
|
|
9b02841506 | ||
|
|
3c5a096873 | ||
|
|
93521f7b39 | ||
|
|
bdcdc1485c | ||
|
|
fdc10acfdd | ||
|
|
ac93e3196e | ||
|
|
e5439c21ab | ||
|
|
7f9bb5748e | ||
|
|
894b091553 | ||
|
|
7576270423 | ||
|
|
6b8f83cd71 | ||
|
|
fdc3a6e432 | ||
|
|
49d8c581bd | ||
|
|
c15da3c104 | ||
|
|
12c46ced45 | ||
|
|
3ed9a05ac6 | ||
|
|
3b4c8ad0e2 | ||
|
|
d9e2e09149 | ||
|
|
97713b2daa | ||
|
|
7799e1b7e6 | ||
|
|
38913bb661 | ||
|
|
14cbc439ab | ||
|
|
6d15b9b82a | ||
|
|
2035ddf5a9 | ||
|
|
e91dedaab5 | ||
|
|
54bf02352f | ||
|
|
3f415e3e8e | ||
|
|
7133e6e89b | ||
|
|
e1d49a3632 | ||
|
|
f26fb9408e | ||
|
|
1e48989e2d | ||
|
|
e48285a33a | ||
|
|
7f0fd642ec | ||
|
|
5ee8c56c94 | ||
|
|
4940822ae8 | ||
|
|
8b42b78033 | ||
|
|
a7f4263db4 | ||
|
|
348e78718d | ||
|
|
0ec6771cf7 | ||
|
|
5e7b372345 | ||
|
|
6b0ce6b729 | ||
|
|
c07976438b | ||
|
|
eb6dd6b53d | ||
|
|
ea86f76393 | ||
|
|
b699e5e6cd | ||
|
|
4fb0cfa909 | ||
|
|
bb5b10eef3 | ||
|
|
b5cc304336 | ||
|
|
1812843363 | ||
|
|
628740d6d1 | ||
|
|
251365dca7 | ||
|
|
223c706e91 | ||
|
|
5e109d9648 | ||
|
|
2b769279ae | ||
|
|
8f8eff6f95 | ||
|
|
02fe597f3f | ||
|
|
4d611ba2f0 | ||
|
|
403a0b2ddc | ||
|
|
211273cc08 | ||
|
|
8ba0a9bf87 | ||
|
|
f84286d138 | ||
|
|
b980f3e311 | ||
|
|
399e053ebd | ||
|
|
d6b20ea623 | ||
|
|
caac2ecb83 | ||
|
|
7ae8601ba5 | ||
|
|
8f038ced15 | ||
|
|
3a1f20821e | ||
|
|
057131b459 | ||
|
|
1040b0988a | ||
|
|
2ca0290662 | ||
|
|
163774bb1f | ||
|
|
6a8724213e | ||
|
|
cf64da21fb | ||
|
|
c0d40895f8 | ||
|
|
50326fbb6b | ||
|
|
98cd19ea0f | ||
|
|
ca3192b3dc | ||
|
|
e1f28982cf | ||
|
|
8e996e3e63 | ||
|
|
53cc090814 | ||
|
|
bfc2d30a46 | ||
|
|
516dff5b09 | ||
|
|
4df0e910b8 | ||
|
|
3a5f492106 | ||
|
|
2dbb9075a3 | ||
|
|
e5715a0048 | ||
|
|
629db8c718 | ||
|
|
cc2a84afcd | ||
|
|
6c1dc0d71a | ||
|
|
9e97fac252 | ||
|
|
3a9086dfc5 | ||
|
|
a0f34a8d0a | ||
|
|
359b41d869 | ||
|
|
04723bd1a0 | ||
|
|
89d6990a92 | ||
|
|
96f20287ff | ||
|
|
d8ba25747b | ||
|
|
e66c01f0e6 | ||
|
|
aaea2e7456 | ||
|
|
4de5944474 | ||
|
|
76e48178c8 | ||
|
|
13fa7c1628 | ||
|
|
b957001629 | ||
|
|
9b6b224af4 | ||
|
|
4785367915 | ||
|
|
7c12234a9c | ||
|
|
c6a2e26876 | ||
|
|
06aae85e45 | ||
|
|
a2df441e1f | ||
|
|
d246c31548 | ||
|
|
19589bf12d | ||
|
|
ba984aebfa |
@@ -1,11 +0,0 @@
|
||||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Ubuntu version: bionic, focal
|
||||
ARG VARIANT="focal"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install python3-distutils python3-pip
|
||||
RUN pip3 install platformio meshtastic adafruit-nrfutil
|
||||
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip -O /tmp/protoc.zip && cd /tmp && unzip protoc.zip && chmod a+x bin/protoc && cp bin/protoc /usr/local/bin
|
||||
@@ -1,32 +0,0 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu
|
||||
{
|
||||
"name": "Ubuntu",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Ubuntu version: focal, bionic
|
||||
"args": { "VARIANT": "focal" }
|
||||
},
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"platformio.platformio-ide",
|
||||
"xaver.clang-format"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "uname -a",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode",
|
||||
|
||||
"postCreateCommand": "git submodule update --init"
|
||||
}
|
||||
146
.github/workflows/main.yml
vendored
146
.github/workflows/main.yml
vendored
@@ -1,146 +0,0 @@
|
||||
name: Continuous Integration (Legacy serial build)
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the master branch
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
ci-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install cppcheck
|
||||
run: |
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools and install platformio
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Check everything
|
||||
run: bin/check-all.sh
|
||||
|
||||
ci-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
# We actually want to run this every time
|
||||
# if: steps.cache-pip.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio meshtastic adafruit-nrfutil
|
||||
|
||||
# - name: Cache platformio
|
||||
# uses: actions/cache@v1
|
||||
# id: cache-platformio # needed in if test
|
||||
# with:
|
||||
# path: ~/.platformio
|
||||
# key: ${{ runner.os }}-platformio
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/meshtastic-web"
|
||||
file: "build.tar"
|
||||
target: "build.tar"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unpack web ui
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
# We now run integration test before other build steps (to quickly see runtime failures)
|
||||
- name: Build for native
|
||||
run: platformio run -e native
|
||||
- name: Integration test
|
||||
run: |
|
||||
.pio/build/native/program &
|
||||
sleep 20 # 5 seconds was not enough
|
||||
echo "Simulator started, launching python test..."
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
|
||||
- name: Cat bin/build-all.sh
|
||||
run: |
|
||||
cat bin/build-all.sh
|
||||
|
||||
- name: Build everything
|
||||
run: bin/build-all.sh
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}.zip
|
||||
path: release/archive/firmware-${{ steps.version.outputs.version }}.zip
|
||||
retention-days: 90
|
||||
|
||||
- name: Store debugging elf files as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: debug-elfs
|
||||
path: release/archive/elfs-*.zip
|
||||
retention-days: 7
|
||||
|
||||
- name: Download firmware.zip
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}.zip
|
||||
path: ./
|
||||
|
||||
- name: Pull request artifacts
|
||||
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
|
||||
uses: gavv/pull-request-artifacts@v1.0.0
|
||||
with:
|
||||
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
artifacts-branch: artifacts
|
||||
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
|
||||
10
.github/workflows/main_matrix.yml
vendored
10
.github/workflows/main_matrix.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Continuous Integration
|
||||
name: CI
|
||||
on:
|
||||
# # Triggers the workflow on push but only for the master branch
|
||||
push:
|
||||
@@ -37,7 +37,10 @@ jobs:
|
||||
- board: rak4631
|
||||
- board: rak4631_eink
|
||||
- board: t-echo
|
||||
|
||||
- board: nano-g1
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -91,6 +94,9 @@ jobs:
|
||||
- board: heltec-v2.1
|
||||
- board: tbeam0.7
|
||||
- board: meshtastic-diy-v1
|
||||
- board: nano-g1
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
10
.github/workflows/update_protobufs.yml
vendored
10
.github/workflows/update_protobufs.yml
vendored
@@ -13,13 +13,13 @@ jobs:
|
||||
|
||||
- name: Update submodule
|
||||
run: |
|
||||
git submodule update --remote proto
|
||||
git submodule update --remote protobufs
|
||||
|
||||
- name: Download nanopb
|
||||
run: |
|
||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.5-linux-x86.tar.gz
|
||||
tar xvzf nanopb-0.4.5-linux-x86.tar.gz
|
||||
mv nanopb-0.4.5-linux-x86 nanopb-0.4.5
|
||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.6-linux-x86.tar.gz
|
||||
tar xvzf nanopb-0.4.6-linux-x86.tar.gz
|
||||
mv nanopb-0.4.6-linux-x86 nanopb-0.4.6
|
||||
|
||||
- name: Re-generate protocol buffers
|
||||
run: |
|
||||
@@ -29,5 +29,5 @@ jobs:
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
add-paths: |
|
||||
proto
|
||||
protobufs
|
||||
src/mesh
|
||||
|
||||
7
.gitmodules
vendored
7
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "proto"]
|
||||
path = proto
|
||||
[submodule "protobufs"]
|
||||
path = protobufs
|
||||
url = https://github.com/meshtastic/Meshtastic-protobufs.git
|
||||
[submodule "design"]
|
||||
path = design
|
||||
url = https://github.com/meshtastic/meshtastic-design.git
|
||||
|
||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -51,7 +51,8 @@
|
||||
"iterator": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"iostream": "cpp",
|
||||
"esp_nimble_hci.h": "c"
|
||||
"esp_nimble_hci.h": "c",
|
||||
"map": "cpp"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"Blox",
|
||||
@@ -73,10 +74,5 @@
|
||||
"cmake.configureOnOpen": true,
|
||||
"protoc": {
|
||||
"compile_on_save": false,
|
||||
"compile_all_path": "/home/kevinh/development/meshtastic/meshtastic-esp32/proto",
|
||||
"options": [
|
||||
"--java_out=/tmp",
|
||||
"-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto"
|
||||
]
|
||||
}
|
||||
}
|
||||
16
Dockerfile
16
Dockerfile
@@ -1,16 +0,0 @@
|
||||
FROM ubuntu
|
||||
MAINTAINER Kevin Hester <kevinh@geeksville.com>
|
||||
|
||||
RUN apt-get update
|
||||
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim
|
||||
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py
|
||||
RUN python3 get-platformio.py
|
||||
RUN git clone https://github.com/meshtastic/Meshtastic-device.git
|
||||
RUN cd Meshtastic-device; git submodule update --init --recursive
|
||||
# only build the simulator
|
||||
RUN sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' Meshtastic-device/bin/build-all.sh
|
||||
RUN sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' Meshtastic-device/bin/build-all.sh
|
||||
RUN sed -i 's/echo "Building Filesystem.*/exit/' Meshtastic-device/bin/build-all.sh
|
||||
RUN . ~/.platformio/penv/bin/activate; cd Meshtastic-device; ./bin/build-all.sh
|
||||
|
||||
CMD ["/Meshtastic-device/release/latest/bins/universal/meshtasticd_linux_amd64"]
|
||||
25
README.md
25
README.md
@@ -1,23 +1,18 @@
|
||||
# Meshtastic-device
|
||||
[](https://open.vscode.dev/meshtastic/Meshtastic-device)
|
||||
[](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main_matrix.yml)
|
||||

|
||||
# Meshtastic Firmware
|
||||
|
||||

|
||||
[](https://github.com/meshtastic/repo/actions/workflows/main_matrix.yml)
|
||||
[](https://cla-assistant.io/meshtastic/Meshtastic-device)
|
||||
[](https://opencollective.com/meshtastic/)
|
||||
[](https://opencollective.com/meshtastic/)
|
||||
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
|
||||
|
||||
## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project.
|
||||
## Overview
|
||||
|
||||
Update Instructions
|
||||
This repository contains the device firmware for the Meshtastic project.
|
||||
|
||||
[Using Meshtastic Flasher](https://meshtastic.org/docs/getting-started/meshtastic-flasher)
|
||||
|
||||
Manual Method
|
||||
|
||||
[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32)
|
||||
|
||||
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52)
|
||||
|
||||
For developer information and specific building instructions, please see the [developer documentation](https://meshtastic.org/docs/developers)
|
||||
**[Building Instructions](https://meshtastic.org/docs/developers/Firmware/build)**
|
||||
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
||||
|
||||
## Stats
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ set -e
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
|
||||
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1"
|
||||
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1 m5stack-core m5stack-coreink"
|
||||
#BOARDS_ESP32=tbeam
|
||||
|
||||
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||
|
||||
@@ -28,12 +28,12 @@ IF "__%FILENAME%__" == "____" (
|
||||
)
|
||||
IF EXIST %FILENAME% (
|
||||
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
|
||||
%PYTHON% -m esptool --baud 921600 erase_flash
|
||||
%PYTHON% -m esptool --baud 921600 write_flash 0x1000 system-info.bin
|
||||
%PYTHON% -m esptool --baud 115200 erase_flash
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x1000 system-info.bin
|
||||
for %%f in (littlefs-*.bin) do (
|
||||
%PYTHON% -m esptool --baud 921600 write_flash 0x00390000 %%f
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00390000 %%f
|
||||
)
|
||||
%PYTHON% -m esptool --baud 921600 write_flash 0x10000 %FILENAME%
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME%
|
||||
) else (
|
||||
echo "Invalid file: %FILENAME%"
|
||||
goto HELP
|
||||
|
||||
@@ -28,9 +28,9 @@ IF "__%FILENAME%__" == "____" (
|
||||
)
|
||||
IF EXIST %FILENAME% (
|
||||
echo Trying to flash update %FILENAME%
|
||||
%PYTHON% -m esptool --baud 921600 write_flash 0x10000 %FILENAME%
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME%
|
||||
echo Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used
|
||||
%PYTHON% -m esptool --baud 921600 erase_region 0xe000 0x2000
|
||||
%PYTHON% -m esptool --baud 115200 erase_region 0xe000 0x2000
|
||||
) else (
|
||||
echo "Invalid file: %FILENAME%"
|
||||
goto HELP
|
||||
|
||||
@@ -44,9 +44,9 @@ shift "$((OPTIND-1))"
|
||||
|
||||
if [ -f "${FILENAME}" ]; then
|
||||
echo "Trying to flash update ${FILENAME}."
|
||||
$PYTHON -m esptool --baud 921600 write_flash 0x10000 ${FILENAME}
|
||||
$PYTHON -m esptool --baud 115200 write_flash 0x10000 ${FILENAME}
|
||||
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
|
||||
$PYTHON -m esptool --baud 921600 erase_region 0xe000 0x2000
|
||||
$PYTHON -m esptool --baud 115200 erase_region 0xe000 0x2000
|
||||
else
|
||||
echo "Invalid file: ${FILENAME}"
|
||||
show_help
|
||||
|
||||
@@ -17,7 +17,7 @@ Import("projenv")
|
||||
|
||||
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
|
||||
verObj = readProps(prefsLoc)
|
||||
print("Using meshtastic platform-custom.py, firmare version " + verObj['long'])
|
||||
print("Using meshtastic platformio-custom.py, firmare version " + verObj['long'])
|
||||
# print("path is" + ','.join(sys.path))
|
||||
|
||||
# General options that are passed to the C and C++ compilers
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img
|
||||
esptool.py --baud 115200 read_flash 0x1000 0xf000 system-info.img
|
||||
|
||||
@@ -1 +1 @@
|
||||
cd proto && ..\nanopb-0.4.5\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\proto *.proto
|
||||
cd protobufs && ..\nanopb-0.4.6\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.5 to be located in the"
|
||||
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.6 to be located in the"
|
||||
echo "meshtastic-device root directory if the following step fails, you should download the correct"
|
||||
echo "prebuilt binaries for your computer into nanopb-0.4.5"
|
||||
echo "prebuilt binaries for your computer into nanopb-0.4.6"
|
||||
|
||||
# the nanopb tool seems to require that the .options file be in the current directory!
|
||||
cd proto
|
||||
../nanopb-0.4.5/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../proto *.proto
|
||||
cd protobufs
|
||||
../nanopb-0.4.6/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
|
||||
|
||||
#echo "Regenerating protobuf documentation - if you see an error message"
|
||||
#echo "you can ignore it unless doing a new protobuf release to github."
|
||||
|
||||
1
design
1
design
Submodule design deleted from 73ba05ceef
@@ -20,6 +20,7 @@ default_envs = tbeam
|
||||
;default_envs = pca10059_diy_eink
|
||||
;default_envs = meshtastic-diy-v1
|
||||
;default_envs = meshtastic-diy-v1.1
|
||||
;default_envs = m5stack-coreink
|
||||
|
||||
extra_configs = variants/*/platformio.ini
|
||||
|
||||
@@ -35,24 +36,20 @@ build_flags = -Wno-missing-field-initializers
|
||||
-Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
|
||||
-DUSE_THREAD_NAMES
|
||||
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
-DPB_ENABLE_MALLOC=1
|
||||
|
||||
monitor_speed = 921600
|
||||
monitor_speed = 115200
|
||||
|
||||
lib_deps =
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||
https://github.com/meshtastic/arduino-fsm.git
|
||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
||||
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
|
||||
https://github.com/meshtastic/TinyGPSPlus.git
|
||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||
SPI
|
||||
https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
PubSubClient
|
||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
nanopb/Nanopb@^0.4.6
|
||||
meshtastic/json11@^1.0.2
|
||||
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
check_tool = cppcheck
|
||||
@@ -63,13 +60,24 @@ check_skip_packages = yes
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
; Portduino is using meshtastic fork for now
|
||||
https://github.com/jgromes/RadioLib.git
|
||||
|
||||
build_flags = ${env.build_flags} -Os
|
||||
# -DRADIOLIB_GODMODE
|
||||
src_filter = ${env.src_filter} -<portduino/>
|
||||
build_src_filter = ${env.build_src_filter} -<portduino/>
|
||||
|
||||
; Common libs for environmental measurements (not included in native / portduino)
|
||||
[environmental]
|
||||
; Common libs for communicating over TCP/IP networks such as MQTT
|
||||
[networking_base]
|
||||
lib_deps =
|
||||
PubSubClient
|
||||
meshtastic/json11@^1.0.2
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
; (not included in native / portduino)
|
||||
[environmental_base]
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.11.4
|
||||
adafruit/DHT sensor library@^1.4.1
|
||||
adafruit/Adafruit Unified Sensor@^1.1.4
|
||||
paulstoffregen/OneWire@^2.3.5
|
||||
@@ -77,15 +85,17 @@ lib_deps =
|
||||
adafruit/Adafruit BME280 Library@^2.2.2
|
||||
adafruit/Adafruit BME680 Library@^2.0.1
|
||||
adafruit/Adafruit MCP9808 Library@^2.0.0
|
||||
|
||||
adafruit/Adafruit INA260 Library@^1.5.0
|
||||
adafruit/Adafruit INA219@^1.2.0
|
||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||
[esp32_base]
|
||||
extends = arduino_base
|
||||
platform = espressif32@3.5.0
|
||||
src_filter =
|
||||
${arduino_base.src_filter} -<nrf52/>
|
||||
upload_speed = 921600
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<nrf52/>
|
||||
upload_speed = 115200
|
||||
debug_init_break = tbreak setup
|
||||
|
||||
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||
@@ -96,11 +106,14 @@ build_flags =
|
||||
-DAXP_DEBUG_PORT=Serial -DUSE_NEW_ESP32_BLUETOOTH
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git
|
||||
h2zero/NimBLE-Arduino@1.3.7
|
||||
arduino-libraries/NTPClient@^3.1.0
|
||||
lorol/LittleFS_esp32@^1.0.6
|
||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||
|
||||
lib_ignore =
|
||||
segger_rtt
|
||||
ESP32 BLE Arduino
|
||||
@@ -130,8 +143,8 @@ build_type = debug ; I'm debugging with ICE a lot now
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/nrf52
|
||||
src_filter =
|
||||
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
|
||||
@@ -140,7 +153,7 @@ extends = nrf52_base
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
|
||||
1
proto
1
proto
Submodule proto deleted from a578453b3c
1
protobufs
Submodule
1
protobufs
Submodule
Submodule protobufs added at c63a16c32f
@@ -1,10 +1,10 @@
|
||||
#include "configuration.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RadioLibInterface.h"
|
||||
#include "buzz.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "power.h"
|
||||
#include "buzz.h"
|
||||
#include <OneButton.h>
|
||||
|
||||
#ifndef NO_ESP32
|
||||
@@ -78,14 +78,9 @@ class ButtonThread : public concurrency::OSThread
|
||||
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
||||
#ifdef INPUT_PULLUP_SENSE
|
||||
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
||||
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
|
||||
#endif
|
||||
userButtonTouch.attachClick(touchPressed);
|
||||
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -114,16 +109,17 @@ class ButtonThread : public concurrency::OSThread
|
||||
|
||||
private:
|
||||
static void touchPressed()
|
||||
{
|
||||
{
|
||||
screen->forceDisplay();
|
||||
DEBUG_MSG("touch press!\n");
|
||||
DEBUG_MSG("touch press!\n");
|
||||
}
|
||||
|
||||
|
||||
static void userButtonPressed()
|
||||
{
|
||||
// DEBUG_MSG("press!\n");
|
||||
#ifdef BUTTON_PIN
|
||||
if ((BUTTON_PIN != radioConfig.preferences.inputbroker_pin_press) || !radioConfig.preferences.canned_message_module_enabled) {
|
||||
if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
}
|
||||
#endif
|
||||
@@ -135,7 +131,7 @@ class ButtonThread : public concurrency::OSThread
|
||||
screen->adjustBrightness();
|
||||
#endif
|
||||
// If user button is held down for 5 seconds, shutdown the device.
|
||||
if (millis() - longPressTime > 5 * 1000) {
|
||||
if ((millis() - longPressTime > 5 * 1000) && (longPressTime > 0)) {
|
||||
#ifdef TBEAM_V10
|
||||
if (axp192_found == true) {
|
||||
setLed(false);
|
||||
@@ -144,7 +140,7 @@ class ButtonThread : public concurrency::OSThread
|
||||
#elif NRF52_SERIES
|
||||
// Do actual shutdown when button released, otherwise the button release
|
||||
// may wake the board immediatedly.
|
||||
if (!shutdown_on_long_stop) {
|
||||
if ((!shutdown_on_long_stop) && (millis() > 30 * 1000)) {
|
||||
screen->startShutdownScreen();
|
||||
DEBUG_MSG("Shutdown from long press");
|
||||
playBeep();
|
||||
@@ -163,7 +159,7 @@ class ButtonThread : public concurrency::OSThread
|
||||
#ifndef NO_ESP32
|
||||
disablePin();
|
||||
#elif defined(HAS_EINK)
|
||||
digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW);
|
||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -177,23 +173,26 @@ class ButtonThread : public concurrency::OSThread
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void userButtonPressedLongStart()
|
||||
{
|
||||
DEBUG_MSG("Long press start!\n");
|
||||
longPressTime = millis();
|
||||
if (millis() > 30 * 1000) {
|
||||
DEBUG_MSG("Long press start!\n");
|
||||
longPressTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
static void userButtonPressedLongStop()
|
||||
{
|
||||
DEBUG_MSG("Long press stop!\n");
|
||||
longPressTime = 0;
|
||||
if (shutdown_on_long_stop) {
|
||||
playShutdownMelody();
|
||||
delay(3000);
|
||||
power->shutdown();
|
||||
if (millis() > 30 * 1000) {
|
||||
DEBUG_MSG("Long press stop!\n");
|
||||
longPressTime = 0;
|
||||
if (shutdown_on_long_stop) {
|
||||
playShutdownMelody();
|
||||
delay(3000);
|
||||
power->shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifdef CONSOLE_MAX_BAUD
|
||||
#define SERIAL_BAUD CONSOLE_MAX_BAUD
|
||||
#else
|
||||
#define SERIAL_BAUD 921600 // Serial debug baud rate
|
||||
#define SERIAL_BAUD 115200 // Serial debug baud rate
|
||||
#endif
|
||||
|
||||
#include "SerialConsole.h"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#include "FSCommon.h"
|
||||
|
||||
void listDir(const char * dirname, uint8_t levels)
|
||||
#ifdef FSCom
|
||||
{
|
||||
#ifdef FSCom
|
||||
File root = FSCom.open(dirname);
|
||||
if(!root){
|
||||
return;
|
||||
@@ -28,6 +28,46 @@ void listDir(const char * dirname, uint8_t levels)
|
||||
#endif
|
||||
}
|
||||
|
||||
void rmDir(const char * dirname)
|
||||
{
|
||||
#ifdef FSCom
|
||||
File file = FSCom.open(dirname);
|
||||
if(!file){
|
||||
return;
|
||||
}
|
||||
if(!file.isDirectory()){
|
||||
file.close();
|
||||
FSCom.remove(file.name());
|
||||
// DEBUG_MSG("Remove FILE %s\n", file.name());
|
||||
return;
|
||||
}
|
||||
|
||||
file.rewindDirectory();
|
||||
while (true) {
|
||||
File entry = file.openNextFile();
|
||||
if (!entry) {
|
||||
break;
|
||||
}
|
||||
char dirpath[100]; // array to hold the result.
|
||||
strcpy(dirpath, dirname); // copy string one into the result.
|
||||
strcat(dirpath,"/"); // append string two to the result.
|
||||
strcat(dirpath,entry.name()); // append string two to the result.
|
||||
if(entry.isDirectory() && !String(entry.name()).endsWith(".")) {
|
||||
entry.close();
|
||||
// DEBUG_MSG("Descend DIR %s\n", dirpath);
|
||||
rmDir(dirpath);
|
||||
} else {
|
||||
entry.close();
|
||||
// DEBUG_MSG("Remove FILE %s\n", entry.name());
|
||||
FSCom.remove(entry.name());
|
||||
}
|
||||
}
|
||||
FSCom.rmdir(dirname);
|
||||
// DEBUG_MSG("Remove DIR %s\n", dirname);
|
||||
file.close();
|
||||
#endif
|
||||
}
|
||||
|
||||
void fsInit()
|
||||
{
|
||||
#ifdef FSCom
|
||||
|
||||
@@ -26,4 +26,6 @@
|
||||
using namespace Adafruit_LittleFS_Namespace;
|
||||
#endif
|
||||
|
||||
void fsInit();
|
||||
void fsInit();
|
||||
void listDir(const char * dirname, uint8_t levels);
|
||||
void rmDir(const char * dirname);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "NodeDB.h"
|
||||
#include "Status.h"
|
||||
#include "configuration.h"
|
||||
#include "NodeDB.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
extern NodeDB nodeDB;
|
||||
@@ -17,8 +17,8 @@ class GPSStatus : public Status
|
||||
CallbackObserver<GPSStatus, const GPSStatus *> statusObserver =
|
||||
CallbackObserver<GPSStatus, const GPSStatus *>(this, &GPSStatus::updateStatus);
|
||||
|
||||
bool hasLock = false; // default to false, until we complete our first read
|
||||
bool isConnected = false; // Do we have a GPS we are talking to
|
||||
bool hasLock = false; // default to false, until we complete our first read
|
||||
bool isConnected = false; // Do we have a GPS we are talking to
|
||||
|
||||
Position p = Position_init_default;
|
||||
|
||||
@@ -42,8 +42,7 @@ class GPSStatus : public Status
|
||||
}
|
||||
|
||||
// preferred method
|
||||
GPSStatus(bool hasLock, bool isConnected, const Position& pos)
|
||||
: Status()
|
||||
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
|
||||
{
|
||||
this->hasLock = hasLock;
|
||||
this->isConnected = isConnected;
|
||||
@@ -61,8 +60,9 @@ class GPSStatus : public Status
|
||||
|
||||
bool getIsConnected() const { return isConnected; }
|
||||
|
||||
int32_t getLatitude() const {
|
||||
if (radioConfig.preferences.fixed_position){
|
||||
int32_t getLatitude() const
|
||||
{
|
||||
if (config.position.fixed_position) {
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("WARNING: Using fixed latitude\n");
|
||||
#endif
|
||||
@@ -73,8 +73,9 @@ class GPSStatus : public Status
|
||||
}
|
||||
}
|
||||
|
||||
int32_t getLongitude() const {
|
||||
if (radioConfig.preferences.fixed_position){
|
||||
int32_t getLongitude() const
|
||||
{
|
||||
if (config.position.fixed_position) {
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("WARNING: Using fixed longitude\n");
|
||||
#endif
|
||||
@@ -85,8 +86,9 @@ class GPSStatus : public Status
|
||||
}
|
||||
}
|
||||
|
||||
int32_t getAltitude() const {
|
||||
if (radioConfig.preferences.fixed_position){
|
||||
int32_t getAltitude() const
|
||||
{
|
||||
if (config.position.fixed_position) {
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("WARNING: Using fixed altitude\n");
|
||||
#endif
|
||||
@@ -106,17 +108,12 @@ class GPSStatus : public Status
|
||||
bool matches(const GPSStatus *newStatus) const
|
||||
{
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
|
||||
newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||
#endif
|
||||
return (newStatus->hasLock != hasLock ||
|
||||
newStatus->isConnected != isConnected ||
|
||||
newStatus->p.latitude_i != p.latitude_i ||
|
||||
newStatus->p.longitude_i != p.longitude_i ||
|
||||
newStatus->p.altitude != p.altitude ||
|
||||
newStatus->p.altitude_hae != p.altitude_hae ||
|
||||
newStatus->p.PDOP != p.PDOP ||
|
||||
newStatus->p.ground_track != p.ground_track ||
|
||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
||||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
|
||||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
|
||||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
|
||||
newStatus->p.sats_in_view != p.sats_in_view);
|
||||
}
|
||||
|
||||
@@ -125,8 +122,7 @@ class GPSStatus : public Status
|
||||
// Only update the status if values have actually changed
|
||||
bool isDirty = matches(newStatus);
|
||||
|
||||
if (isDirty && p.pos_timestamp &&
|
||||
(newStatus->p.pos_timestamp == p.pos_timestamp)) {
|
||||
if (isDirty && p.pos_timestamp && (newStatus->p.pos_timestamp == p.pos_timestamp)) {
|
||||
// We can NEVER be in two locations at the same time! (also PR #886)
|
||||
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n");
|
||||
}
|
||||
@@ -140,11 +136,9 @@ class GPSStatus : public Status
|
||||
if (isDirty) {
|
||||
if (hasLock) {
|
||||
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
|
||||
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n",
|
||||
p.pos_timestamp,
|
||||
p.latitude_i * 1e-7, p.longitude_i * 1e-7,
|
||||
p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
||||
p.sats_in_view);
|
||||
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", p.pos_timestamp,
|
||||
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
||||
p.sats_in_view);
|
||||
} else
|
||||
DEBUG_MSG("No GPS lock\n");
|
||||
onNewStatus.notifyObservers(this);
|
||||
|
||||
141
src/Power.cpp
141
src/Power.cpp
@@ -1,10 +1,11 @@
|
||||
#include "configuration.h"
|
||||
#include "power.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "sleep.h"
|
||||
#include "utils.h"
|
||||
#include "buzz/buzz.h"
|
||||
|
||||
#ifdef TBEAM_V10
|
||||
// FIXME. nasty hack cleanup how we load axp192
|
||||
@@ -13,27 +14,28 @@
|
||||
|
||||
AXP20X_Class axp;
|
||||
#else
|
||||
// Copy of the base class defined in axp20x.h.
|
||||
// Copy of the base class defined in axp20x.h.
|
||||
// I'd rather not inlude axp20x.h as it brings Wire dependency.
|
||||
class HasBatteryLevel {
|
||||
public:
|
||||
/**
|
||||
* Battery state of charge, from 0 to 100 or -1 for unknown
|
||||
*/
|
||||
virtual int getBattPercentage() { return -1; }
|
||||
class HasBatteryLevel
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Battery state of charge, from 0 to 100 or -1 for unknown
|
||||
*/
|
||||
virtual int getBattPercentage() { return -1; }
|
||||
|
||||
/**
|
||||
* The raw voltage of the battery or NAN if unknown
|
||||
*/
|
||||
virtual float getBattVoltage() { return NAN; }
|
||||
/**
|
||||
* The raw voltage of the battery or NAN if unknown
|
||||
*/
|
||||
virtual float getBattVoltage() { return NAN; }
|
||||
|
||||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
virtual bool isBatteryConnect() { return false; }
|
||||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
virtual bool isBatteryConnect() { return false; }
|
||||
|
||||
virtual bool isVBUSPlug() { return false; }
|
||||
virtual bool isChargeing() { return false; }
|
||||
virtual bool isVBUSPlug() { return false; }
|
||||
virtual bool isChargeing() { return false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -99,24 +101,24 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
|
||||
#ifndef ADC_MULTIPLIER
|
||||
#define ADC_MULTIPLIER 2.0
|
||||
#endif
|
||||
// Override variant or default ADC_MULTIPLIER if we have the override pref
|
||||
float operativeAdcMultiplier = radioConfig.preferences.adc_multiplier_override > 0 ?
|
||||
radioConfig.preferences.adc_multiplier_override :
|
||||
ADC_MULTIPLIER;
|
||||
#endif
|
||||
|
||||
#ifdef BATTERY_PIN
|
||||
// Do not call analogRead() often.
|
||||
// Override variant or default ADC_MULTIPLIER if we have the override pref
|
||||
float operativeAdcMultiplier = config.power.adc_multiplier_override > 0
|
||||
? config.power.adc_multiplier_override
|
||||
: ADC_MULTIPLIER;
|
||||
// Do not call analogRead() often.
|
||||
const uint32_t min_read_interval = 5000;
|
||||
if (millis() - last_read_time_ms > min_read_interval) {
|
||||
last_read_time_ms = millis();
|
||||
uint32_t raw = analogRead(BATTERY_PIN);
|
||||
float scaled;
|
||||
#ifndef VBAT_RAW_TO_SCALED
|
||||
#ifndef VBAT_RAW_TO_SCALED
|
||||
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
|
||||
#else
|
||||
scaled = VBAT_RAW_TO_SCALED(raw); //defined in variant.h
|
||||
#endif
|
||||
#else
|
||||
scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h
|
||||
#endif
|
||||
// DEBUG_MSG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
|
||||
last_read_value = scaled;
|
||||
return scaled;
|
||||
@@ -153,7 +155,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
|
||||
AnalogBatteryLevel analogLevel;
|
||||
|
||||
Power::Power() : OSThread("Power") {
|
||||
Power::Power() : OSThread("Power")
|
||||
{
|
||||
statusHandler = {};
|
||||
low_voltage_counter = 0;
|
||||
}
|
||||
@@ -172,7 +175,7 @@ bool Power::analogInit()
|
||||
#endif
|
||||
#ifdef NRF52_SERIES
|
||||
#ifdef VBAT_AR_INTERNAL
|
||||
analogReference(VBAT_AR_INTERNAL);
|
||||
analogReference(VBAT_AR_INTERNAL);
|
||||
#else
|
||||
analogReference(AR_INTERNAL); // 3.6V
|
||||
#endif
|
||||
@@ -181,9 +184,10 @@ bool Power::analogInit()
|
||||
#ifndef BATTERY_SENSE_RESOLUTION_BITS
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 10
|
||||
#endif
|
||||
|
||||
|
||||
// adcStart(BATTERY_PIN);
|
||||
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution.
|
||||
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11
|
||||
// depending on needed resolution.
|
||||
batteryLevel = &analogLevel;
|
||||
return true;
|
||||
#else
|
||||
@@ -208,8 +212,12 @@ void Power::shutdown()
|
||||
{
|
||||
#ifdef TBEAM_V10
|
||||
DEBUG_MSG("Shutting down\n");
|
||||
axp.setChgLEDMode(AXP20X_LED_OFF);
|
||||
axp.shutdown();
|
||||
#elif NRF52_SERIES
|
||||
playBeep();
|
||||
ledOff(PIN_LED1);
|
||||
ledOff(PIN_LED2);
|
||||
doDeepSleep(DELAY_FOREVER);
|
||||
#endif
|
||||
}
|
||||
@@ -246,24 +254,23 @@ void Power::readPowerStatus()
|
||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
|
||||
|
||||
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
|
||||
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
|
||||
#ifdef NRF52_SERIES
|
||||
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()){
|
||||
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){
|
||||
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
|
||||
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
|
||||
#ifdef NRF52_SERIES
|
||||
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
|
||||
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) {
|
||||
low_voltage_counter++;
|
||||
if (low_voltage_counter>3)
|
||||
if (low_voltage_counter > 3)
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
} else {
|
||||
low_voltage_counter = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#else
|
||||
// If we have a battery at all and it is less than 10% full, force deep sleep
|
||||
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
// No power sensing on this board - tell everyone else we have no idea what is happening
|
||||
const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
|
||||
@@ -355,40 +362,58 @@ bool Power::axp192Init()
|
||||
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
||||
|
||||
if (radioConfig.preferences.charge_current == ChargeCurrent_MAUnset) {
|
||||
switch (config.power.charge_current) {
|
||||
case Config_PowerConfig_ChargeCurrent_MAUnset:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA100) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA100:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_100MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA190) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA190:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_190MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA280) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA280:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_280MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA360) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA360:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_360MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA450) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA450:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA550) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA550:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA630) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA630:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_630MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA700) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA700:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_700MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA780) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA780:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_780MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA880) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA880:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_880MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA960) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA960:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_960MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1000) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1000:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1000MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1080) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1080:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1080MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1160) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1160:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1160MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1240) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1240:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1240MA);
|
||||
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1320) {
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1320:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA);
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -11,30 +11,30 @@
|
||||
/// Should we behave as if we have AC power now?
|
||||
static bool isPowered()
|
||||
{
|
||||
// Completely circumvents the battery / power sensing logic and assumes constant power source
|
||||
if (radioConfig.preferences.is_always_powered) {
|
||||
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
|
||||
#if !defined(BATTERY_PIN) && !defined(AXP192_SLAVE_ADDRESS)
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isRouter = (radioConfig.preferences.role == Role_Router ? 1 : 0);
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
|
||||
|
||||
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
||||
// We assume routers might be powered all the time, but from a low current (solar) source
|
||||
bool isLowPower = radioConfig.preferences.is_low_power || isRouter;
|
||||
bool isPowerSavingMode = config.power.is_power_saving || isRouter;
|
||||
|
||||
/* To determine if we're externally powered, assumptions
|
||||
1) If we're powered up and there's no battery, we must be getting power externally. (because we'd be dead otherwise)
|
||||
|
||||
2) If we detect USB power from the power management chip, we must be getting power externally.
|
||||
*/
|
||||
return !isLowPower && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
|
||||
return !isPowerSavingMode && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
|
||||
}
|
||||
|
||||
static void sdsEnter()
|
||||
{
|
||||
DEBUG_MSG("Enter state: SDS\n");
|
||||
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||
doDeepSleep(getPref_sds_secs() * 1000LL);
|
||||
doDeepSleep(config.power.sds_secs ? config.power.sds_secs : default_sds_secs * 1000LL);
|
||||
}
|
||||
|
||||
extern Power *power;
|
||||
@@ -51,7 +51,8 @@ static uint32_t secsSlept;
|
||||
|
||||
static void lsEnter()
|
||||
{
|
||||
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", getPref_ls_secs());
|
||||
DEBUG_MSG("lsEnter begin, ls_secs=%u\n",
|
||||
config.power.ls_secs ? config.power.ls_secs : default_ls_secs);
|
||||
screen->setOn(false);
|
||||
secsSlept = 0; // How long have we been sleeping this time
|
||||
|
||||
@@ -65,7 +66,7 @@ static void lsIdle()
|
||||
#ifndef NO_ESP32
|
||||
|
||||
// Do we have more sleeping to do?
|
||||
if (secsSlept < getPref_ls_secs()) {
|
||||
if (secsSlept < config.power.ls_secs ? config.power.ls_secs : default_ls_secs * 1000) {
|
||||
// Briefly come out of sleep long enough to blink the led once every few seconds
|
||||
uint32_t sleepTime = 30;
|
||||
|
||||
@@ -78,7 +79,7 @@ static void lsIdle()
|
||||
case ESP_SLEEP_WAKEUP_TIMER:
|
||||
// Normal case: timer expired, we should just go back to sleep ASAP
|
||||
|
||||
setLed(true); // briefly turn on led
|
||||
setLed(true); // briefly turn on led
|
||||
wakeCause2 = doLightSleep(1); // leave led on for 1ms
|
||||
|
||||
secsSlept += sleepTime;
|
||||
@@ -238,7 +239,7 @@ Fsm powerFSM(&stateBOOT);
|
||||
|
||||
void PowerFSM_setup()
|
||||
{
|
||||
bool isRouter = (radioConfig.preferences.role == Role_Router ? 1 : 0);
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
|
||||
bool hasPower = isPowered();
|
||||
|
||||
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower);
|
||||
@@ -332,7 +333,10 @@ void PowerFSM_setup()
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
|
||||
|
||||
powerFSM.add_timed_transition(&stateON, &stateDARK, getPref_screen_on_secs() * 1000, NULL, "Screen-on timeout");
|
||||
powerFSM.add_timed_transition(&stateON, &stateDARK,
|
||||
config.display.screen_on_secs ? config.display.screen_on_secs
|
||||
: 60 * 1000 * 10,
|
||||
NULL, "Screen-on timeout");
|
||||
|
||||
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
|
||||
State *lowPowerState = &stateLS;
|
||||
@@ -343,13 +347,18 @@ void PowerFSM_setup()
|
||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||
|
||||
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
|
||||
if (isRouter || radioConfig.preferences.is_power_saving) {
|
||||
|
||||
// I don't think this transition is correct, turning off for now - @geeksville
|
||||
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
|
||||
meshSds = getPref_mesh_sds_timeout_secs();
|
||||
if (isRouter || config.power.is_power_saving) {
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||
config.power.min_wake_secs ? config.power.min_wake_secs
|
||||
: default_min_wake_secs * 1000,
|
||||
NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS,
|
||||
config.power.wait_bluetooth_secs
|
||||
? config.power.wait_bluetooth_secs
|
||||
: default_wait_bluetooth_secs * 1000,
|
||||
NULL, "Bluetooth timeout");
|
||||
meshSds = config.power.mesh_sds_timeout_secs ? config.power.mesh_sds_timeout_secs
|
||||
: default_mesh_sds_timeout_secs;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "configuration.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "main.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "power.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "power.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
@@ -26,13 +26,16 @@ class PowerFSMThread : public OSThread
|
||||
|
||||
if (powerStatus->getHasUSB()) {
|
||||
timeLastPowered = millis();
|
||||
} else if (radioConfig.preferences.on_battery_shutdown_after_secs > 0 &&
|
||||
millis() > timeLastPowered + (1000 * radioConfig.preferences.on_battery_shutdown_after_secs)) { //shutdown after 30 minutes unpowered
|
||||
} else if (config.power.on_battery_shutdown_after_secs > 0 &&
|
||||
millis() >
|
||||
timeLastPowered +
|
||||
(1000 *
|
||||
config.power.on_battery_shutdown_after_secs)) { // shutdown after 30 minutes unpowered
|
||||
powerFSM.trigger(EVENT_SHUTDOWN);
|
||||
}
|
||||
|
||||
|
||||
return 10;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace concurrency
|
||||
@@ -72,7 +72,7 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
|
||||
|
||||
// If we are the first message on a report, include the header
|
||||
if (!isContinuationMessage) {
|
||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
|
||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
|
||||
if (rtc_sec > 0) {
|
||||
long hms = rtc_sec % SEC_PER_DAY;
|
||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "configuration.h"
|
||||
#include "SerialConsole.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#define Port Serial
|
||||
// Defaulting to the formerly removed phone_timeout_secs value of 15 minutes
|
||||
#define SERIAL_CONNECTION_TIMEOUT (15 * 60) * 1000UL
|
||||
|
||||
SerialConsole *console;
|
||||
|
||||
@@ -41,11 +43,12 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
|
||||
emitRebooted();
|
||||
}
|
||||
|
||||
|
||||
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
|
||||
bool SerialConsole::checkIsConnected()
|
||||
{
|
||||
uint32_t now = millis();
|
||||
return (now - lastContactMsec) < getPref_phone_timeout_secs() * 1000UL;
|
||||
return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,10 +58,9 @@ bool SerialConsole::checkIsConnected()
|
||||
bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
|
||||
{
|
||||
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
|
||||
if (!radioConfig.preferences.debug_log_enabled)
|
||||
if (!config.device.debug_log_enabled)
|
||||
setDestination(&noopPrint);
|
||||
canWrite = true;
|
||||
|
||||
return StreamAPI::handleToRadio(buf, len);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include "buzz.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef NRF52_SERIES
|
||||
#include "variant.h"
|
||||
#endif
|
||||
|
||||
#ifndef PIN_BUZZER
|
||||
|
||||
// Noop methods for boards w/o buzzer
|
||||
@@ -12,8 +8,13 @@ void playBeep(){};
|
||||
void playStartMelody(){};
|
||||
void playShutdownMelody(){};
|
||||
|
||||
#else
|
||||
#ifdef M5STACK
|
||||
#include "Speaker.h"
|
||||
TONE Tone;
|
||||
#else
|
||||
#include "Tone.h"
|
||||
#endif
|
||||
|
||||
extern "C" void delay(uint32_t dwMs);
|
||||
|
||||
@@ -42,13 +43,26 @@ const int DURATION_1_4 = 250; // 1/4 note
|
||||
void playTones(const ToneDuration *tone_durations, int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
const auto &tone_duration = tone_durations[i];
|
||||
#ifdef M5STACK
|
||||
Tone.tone(tone_duration.frequency_khz);
|
||||
delay(tone_duration.duration_ms);
|
||||
Tone.mute();
|
||||
#else
|
||||
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
|
||||
#endif
|
||||
// to distinguish the notes, set a minimum time between them.
|
||||
delay(1.3 * tone_duration.duration_ms);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef M5STACK
|
||||
void playBeep() {
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
#else
|
||||
void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); }
|
||||
#endif
|
||||
|
||||
void playStartMelody() {
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
|
||||
|
||||
@@ -25,6 +25,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef RV3028_RTC
|
||||
#include "Melopero_RV3028.h"
|
||||
#endif
|
||||
#ifdef PCF8563_RTC
|
||||
#include "pcf8563.h"
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Version
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -100,10 +108,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define GPS_TX_PIN 12
|
||||
#endif
|
||||
|
||||
#ifndef TTGO_T_ECHO
|
||||
#define GPS_UBLOX
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LoRa SPI
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -118,6 +122,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TTGO_T_ECHO
|
||||
#define GPS_UBLOX
|
||||
#endif
|
||||
|
||||
//
|
||||
// Standard definitions for !ESP32 targets
|
||||
//
|
||||
@@ -134,7 +142,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Disable use of the NTP library and related features
|
||||
//#define DISABLE_NTP
|
||||
// #define DISABLE_NTP
|
||||
|
||||
// Disable the welcome screen and allow
|
||||
// #define DISABLE_WELCOME_UNSET
|
||||
@@ -163,6 +171,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// The older M5 Faces I2C Keyboard
|
||||
#define FACESKB_ADDR 0x88
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SENSOR
|
||||
// -----------------------------------------------------------------------------
|
||||
#define BME_ADDR 0x76
|
||||
#define BME_ADDR_ALTERNATE 0x77
|
||||
#define MCP9808_ADDR 0x18
|
||||
#define INA_ADDR 0x40
|
||||
#define INA_ADDR_ALTERNATE 0x41
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -262,6 +279,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define HW_VENDOR HardwareModel_NRF52840_PCA10059
|
||||
|
||||
#elif defined(M5STACK)
|
||||
|
||||
#define HW_VENDOR HardwareModel_M5STACK
|
||||
|
||||
#elif NRF52_SERIES
|
||||
|
||||
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
|
||||
|
||||
@@ -1,8 +1,27 @@
|
||||
#include "../configuration.h"
|
||||
#include "../main.h"
|
||||
#include <Wire.h>
|
||||
#include "mesh/generated/telemetry.pb.h"
|
||||
|
||||
#ifndef NO_WIRE
|
||||
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
|
||||
uint16_t value = 0x00;
|
||||
Wire.beginTransmission(address);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission();
|
||||
delay(20);
|
||||
Wire.requestFrom(address, length);
|
||||
DEBUG_MSG("Wire.available() = %d\n", Wire.available());
|
||||
if (Wire.available() == 2) {
|
||||
// Read MSB, then LSB
|
||||
value = (uint16_t)Wire.read() << 8;
|
||||
value |= Wire.read();
|
||||
} else if (Wire.available()) {
|
||||
value = Wire.read();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint8_t oled_probe(byte addr)
|
||||
{
|
||||
uint8_t r = 0;
|
||||
@@ -34,6 +53,7 @@ uint8_t oled_probe(byte addr)
|
||||
void scanI2Cdevice(void)
|
||||
{
|
||||
byte err, addr;
|
||||
uint16_t registerValue = 0x00;
|
||||
int nDevices = 0;
|
||||
for (addr = 1; addr < 127; addr++) {
|
||||
Wire.beginTransmission(addr);
|
||||
@@ -54,10 +74,33 @@ void scanI2Cdevice(void)
|
||||
DEBUG_MSG("unknown display found\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RV3028_RTC
|
||||
if (addr == RV3028_RTC){
|
||||
rtc_found = addr;
|
||||
DEBUG_MSG("RV3028 RTC found\n");
|
||||
Melopero_RV3028 rtc;
|
||||
rtc.initI2C();
|
||||
rtc.writeToRegister(0x35,0x07); // no Clkout
|
||||
rtc.writeToRegister(0x37,0xB4);
|
||||
}
|
||||
#endif
|
||||
#ifdef PCF8563_RTC
|
||||
if (addr == PCF8563_RTC){
|
||||
rtc_found = addr;
|
||||
DEBUG_MSG("PCF8563 RTC found\n");
|
||||
}
|
||||
#endif
|
||||
if (addr == CARDKB_ADDR) {
|
||||
cardkb_found = addr;
|
||||
DEBUG_MSG("m5 cardKB found\n");
|
||||
// Do we have the RAK14006 instead?
|
||||
registerValue = getRegisterValue(addr, 0x04, 1);
|
||||
if (registerValue == 0x02) { // KEYPAD_VERSION
|
||||
DEBUG_MSG("RAK14004 found\n");
|
||||
kb_model = 0x02;
|
||||
} else {
|
||||
DEBUG_MSG("m5 cardKB found\n");
|
||||
kb_model = 0x00;
|
||||
}
|
||||
}
|
||||
if (addr == FACESKB_ADDR) {
|
||||
faceskb_found = addr;
|
||||
@@ -73,6 +116,31 @@ void scanI2Cdevice(void)
|
||||
DEBUG_MSG("axp192 PMU found\n");
|
||||
}
|
||||
#endif
|
||||
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
|
||||
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
|
||||
if (registerValue == 0x61) {
|
||||
DEBUG_MSG("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
|
||||
} else if (registerValue == 0x60) {
|
||||
DEBUG_MSG("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
|
||||
}
|
||||
}
|
||||
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
|
||||
registerValue = getRegisterValue(addr, 0xFE, 2);
|
||||
DEBUG_MSG("Register MFG_UID: 0x%x\n", registerValue);
|
||||
if (registerValue == 0x5449) {
|
||||
DEBUG_MSG("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
|
||||
} else { // Assume INA219 if INA260 ID is not found
|
||||
DEBUG_MSG("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
|
||||
}
|
||||
}
|
||||
if (addr == MCP9808_ADDR) {
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
|
||||
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
}
|
||||
} else if (err == 4) {
|
||||
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
|
||||
}
|
||||
@@ -81,7 +149,7 @@ void scanI2Cdevice(void)
|
||||
if (nDevices == 0)
|
||||
DEBUG_MSG("No I2C devices found\n");
|
||||
else
|
||||
DEBUG_MSG("done\n");
|
||||
DEBUG_MSG("%i I2C devices found\n",nDevices);
|
||||
}
|
||||
#else
|
||||
void scanI2Cdevice(void) {}
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
// proccess at once
|
||||
// static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)];
|
||||
static uint8_t fromRadioBytes[FromRadio_size];
|
||||
static uint8_t toRadioBytes[ToRadio_size];
|
||||
|
||||
static bool bleConnected;
|
||||
|
||||
NimBLECharacteristic *FromNumCharacteristic;
|
||||
NimBLEServer *bleServer;
|
||||
|
||||
@@ -54,7 +54,7 @@ class ESP32CryptoEngine : public CryptoEngine
|
||||
static uint8_t scratch[MAX_BLOCKSIZE];
|
||||
size_t nc_off = 0;
|
||||
|
||||
// DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
|
||||
DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
|
||||
initNonce(fromNode, packetId);
|
||||
assert(numBytes <= MAX_BLOCKSIZE);
|
||||
memcpy(scratch, bytes, numBytes);
|
||||
@@ -68,8 +68,6 @@ class ESP32CryptoEngine : public CryptoEngine
|
||||
|
||||
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
||||
{
|
||||
// DEBUG_MSG("ESP32 decrypt!\n");
|
||||
|
||||
// For CTR, the implementation is the same
|
||||
encrypt(fromNode, packetId, numBytes, bytes);
|
||||
}
|
||||
|
||||
173
src/gps/GPS.cpp
173
src/gps/GPS.cpp
@@ -1,7 +1,7 @@
|
||||
#include "configuration.h"
|
||||
#include "GPS.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
#include "sleep.h"
|
||||
#include <assert.h>
|
||||
|
||||
@@ -22,6 +22,43 @@ GPS *gps;
|
||||
/// only init that port once.
|
||||
static bool didSerialInit;
|
||||
|
||||
bool GPS::getACK(uint8_t c, uint8_t i) {
|
||||
uint8_t b;
|
||||
uint8_t ack = 0;
|
||||
const uint8_t ackP[2] = {c, i};
|
||||
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
unsigned long startTime = millis();
|
||||
|
||||
for (int j = 2; j < 6; j++) {
|
||||
buf[8] += buf[j];
|
||||
buf[9] += buf[8];
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
buf[6 + j] = ackP[j];
|
||||
buf[8] += buf[6 + j];
|
||||
buf[9] += buf[8];
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (ack > 9) {
|
||||
return true;
|
||||
}
|
||||
if (millis() - startTime > 1000) {
|
||||
return false;
|
||||
}
|
||||
if (_serial_gps->available()) {
|
||||
b = _serial_gps->read();
|
||||
if (b == buf[ack]) {
|
||||
ack++;
|
||||
}
|
||||
else {
|
||||
ack = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GPS::setupGPS()
|
||||
{
|
||||
if (_serial_gps && !didSerialInit) {
|
||||
@@ -37,13 +74,17 @@ bool GPS::setupGPS()
|
||||
_serial_gps->setRxBufferSize(2048); // the default is 256
|
||||
#endif
|
||||
#ifdef TTGO_T_ECHO
|
||||
// Switch to 4800 baud, then close and reopen port
|
||||
_serial_gps->write("$PCAS01,0*1C\r\n");
|
||||
delay(250);
|
||||
// Switch to 9600 baud, then close and reopen port
|
||||
_serial_gps->end();
|
||||
delay(250);
|
||||
_serial_gps->begin(4800);
|
||||
delay(250);
|
||||
_serial_gps->write("$PCAS01,1*1D\r\n");
|
||||
delay(250);
|
||||
_serial_gps->end();
|
||||
delay(250);
|
||||
_serial_gps->begin(9600);
|
||||
delay(250);
|
||||
// Initialize the L76K Chip, use GPS + GLONASS
|
||||
_serial_gps->write("$PCAS04,5*1C\r\n");
|
||||
delay(250);
|
||||
@@ -53,57 +94,62 @@ bool GPS::setupGPS()
|
||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||
_serial_gps->write("$PCAS11,3*1E\r\n");
|
||||
delay(250);
|
||||
|
||||
#endif
|
||||
#ifdef GPS_UBLOX
|
||||
// Set the UART port to output NMEA only
|
||||
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x91, 0xAF};
|
||||
_serial_gps->write(_message_nmea,sizeof(_message_nmea));
|
||||
delay(250);
|
||||
// Set the UART port to output NMEA only
|
||||
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
|
||||
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF};
|
||||
_serial_gps->write(_message_nmea, sizeof(_message_nmea));
|
||||
if (!getACK(0x06, 0x00)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GGL
|
||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||
0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x05,0x3A};
|
||||
_serial_gps->write(_message_GGL,sizeof(_message_GGL));
|
||||
delay(250);
|
||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
||||
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GSA
|
||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||
0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x06,0x41};
|
||||
_serial_gps->write(_message_GSA,sizeof(_message_GSA));
|
||||
delay(250);
|
||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
||||
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GSV
|
||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||
0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x07,0x48};
|
||||
_serial_gps->write(_message_GSV,sizeof(_message_GSV));
|
||||
delay(250);
|
||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
||||
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable VTG
|
||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||
0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x09,0x56};
|
||||
_serial_gps->write(_message_VTG,sizeof(_message_VTG));
|
||||
delay(250);
|
||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
||||
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable RMC
|
||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||
0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x09,0x54};
|
||||
_serial_gps->write(_message_RMC,sizeof(_message_RMC));
|
||||
delay(250);
|
||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
||||
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable GGA
|
||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
|
||||
0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x05, 0x38};
|
||||
_serial_gps->write(_message_GGA,sizeof(_message_GGA));
|
||||
delay(250);
|
||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
||||
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
||||
if (!getACK(0x06, 0x01)) DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -143,7 +189,15 @@ GPS::~GPS()
|
||||
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
||||
}
|
||||
|
||||
bool GPS::hasLock() { return hasValidLocation; }
|
||||
bool GPS::hasLock()
|
||||
{
|
||||
return hasValidLocation;
|
||||
}
|
||||
|
||||
bool GPS::hasFlow()
|
||||
{
|
||||
return hasGPS;
|
||||
}
|
||||
|
||||
// Allow defining the polarity of the WAKE output. default is active high
|
||||
#ifndef GPS_WAKE_ACTIVE
|
||||
@@ -213,14 +267,16 @@ void GPS::setAwake(bool on)
|
||||
*/
|
||||
uint32_t GPS::getWakeTime() const
|
||||
{
|
||||
uint32_t t = radioConfig.preferences.gps_attempt_time;
|
||||
uint32_t t = config.position.gps_attempt_time;
|
||||
|
||||
if (t == UINT32_MAX)
|
||||
return t; // already maxint
|
||||
|
||||
if (t == 0)
|
||||
t = (radioConfig.preferences.role == Role_Router) ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
|
||||
// less if we can find sats) or less if a router
|
||||
t = (config.device.role == Config_DeviceConfig_Role_Router)
|
||||
? 5 * 60
|
||||
: 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
|
||||
// less if we can find sats) or less if a router
|
||||
|
||||
t *= 1000; // msecs
|
||||
|
||||
@@ -231,18 +287,18 @@ uint32_t GPS::getWakeTime() const
|
||||
*/
|
||||
uint32_t GPS::getSleepTime() const
|
||||
{
|
||||
uint32_t t = radioConfig.preferences.gps_update_interval;
|
||||
bool gps_disabled = radioConfig.preferences.gps_disabled;
|
||||
bool loc_share_disabled = radioConfig.preferences.location_share_disabled;
|
||||
uint32_t t = config.position.gps_update_interval;
|
||||
bool gps_disabled = config.position.gps_disabled;
|
||||
|
||||
if (gps_disabled || loc_share_disabled)
|
||||
if (gps_disabled)
|
||||
t = UINT32_MAX; // Sleep forever now
|
||||
|
||||
if (t == UINT32_MAX)
|
||||
return t; // already maxint
|
||||
|
||||
if (t == 0) // default - unset in preferences
|
||||
t = (radioConfig.preferences.role == Role_Router) ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers
|
||||
if (t == 0) // default - unset in preferences
|
||||
t = (config.device.role == Config_DeviceConfig_Role_Router) ? 24 * 60 * 60
|
||||
: 2 * 60; // 2 mins or once per day for routers
|
||||
|
||||
t *= 1000;
|
||||
|
||||
@@ -255,12 +311,10 @@ void GPS::publishUpdate()
|
||||
shouldPublish = false;
|
||||
|
||||
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
|
||||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n",
|
||||
p.pos_timestamp, hasValidLocation, hasLock());
|
||||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.pos_timestamp, hasValidLocation, hasLock());
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const meshtastic::GPSStatus status =
|
||||
meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
|
||||
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
|
||||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
}
|
||||
@@ -270,6 +324,15 @@ int32_t GPS::runOnce()
|
||||
if (whileIdle()) {
|
||||
// if we have received valid NMEA claim we are connected
|
||||
setConnected();
|
||||
} else {
|
||||
#ifdef GPS_UBLOX
|
||||
// reset the GPS on next bootup
|
||||
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
devicestate.did_gps_reset = false;
|
||||
nodeDB.saveToDisk();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If we are overdue for an update, turn on the GPS and at least publish the current status
|
||||
@@ -379,7 +442,7 @@ GPS *createGps()
|
||||
#ifdef NO_GPS
|
||||
return nullptr;
|
||||
#else
|
||||
if (!radioConfig.preferences.gps_disabled){
|
||||
if (!config.position.gps_disabled) {
|
||||
#ifdef GPS_ALTITUDE_HAE
|
||||
DEBUG_MSG("Using HAE altitude model\n");
|
||||
#else
|
||||
|
||||
@@ -57,6 +57,9 @@ class GPS : private concurrency::OSThread
|
||||
/// Returns true if we have acquired GPS lock.
|
||||
virtual bool hasLock();
|
||||
|
||||
/// Returns true if there's valid data flow with the chip.
|
||||
virtual bool hasFlow();
|
||||
|
||||
/// Return true if we are connected to a GPS
|
||||
bool isConnected() const { return hasGPS; }
|
||||
|
||||
@@ -135,6 +138,8 @@ class GPS : private concurrency::OSThread
|
||||
*/
|
||||
uint32_t getSleepTime() const;
|
||||
|
||||
bool getACK(uint8_t c, uint8_t i);
|
||||
|
||||
/**
|
||||
* Tell users we have new GPS readings
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,19 @@ static int32_t toDegInt(RawDegrees d)
|
||||
return r;
|
||||
}
|
||||
|
||||
bool NMEAGPS::factoryReset()
|
||||
{
|
||||
#ifdef GPS_UBLOX
|
||||
// Factory Reset
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
|
||||
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
_serial_gps->write(_message_reset,sizeof(_message_reset));
|
||||
delay(1000);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NMEAGPS::setupGPS()
|
||||
{
|
||||
GPS::setupGPS();
|
||||
@@ -65,7 +78,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
||||
t.tm_year = d.year() - 1900;
|
||||
t.tm_isdst = false;
|
||||
if (t.tm_mon > -1){
|
||||
DEBUG_MSG("NMEA GPS time %d-%d-%d %d:%d:%d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
||||
DEBUG_MSG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
||||
perhapsSetRTC(RTCQualityGPS, t);
|
||||
return true;
|
||||
} else
|
||||
@@ -222,6 +235,10 @@ bool NMEAGPS::hasLock()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NMEAGPS::hasFlow()
|
||||
{
|
||||
return reader.passedChecksum() > 0;
|
||||
}
|
||||
|
||||
bool NMEAGPS::whileIdle()
|
||||
{
|
||||
|
||||
@@ -25,6 +25,8 @@ class NMEAGPS : public GPS
|
||||
public:
|
||||
virtual bool setupGPS() override;
|
||||
|
||||
virtual bool factoryReset() override;
|
||||
|
||||
protected:
|
||||
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
||||
*
|
||||
@@ -49,4 +51,6 @@ class NMEAGPS : public GPS
|
||||
virtual bool lookForLocation() override;
|
||||
|
||||
virtual bool hasLock() override;
|
||||
|
||||
virtual bool hasFlow() override;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -18,14 +19,57 @@ static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only upda
|
||||
void readFromRTC()
|
||||
{
|
||||
struct timeval tv; /* btw settimeofday() is helpfull here too*/
|
||||
|
||||
#ifdef RV3028_RTC
|
||||
if(rtc_found == RV3028_RTC) {
|
||||
uint32_t now = millis();
|
||||
Melopero_RV3028 rtc;
|
||||
rtc.initI2C();
|
||||
tm t;
|
||||
t.tm_year = rtc.getYear() - 1900;
|
||||
t.tm_mon = rtc.getMonth() - 1;
|
||||
t.tm_mday = rtc.getDate();
|
||||
t.tm_hour = rtc.getHour();
|
||||
t.tm_min = rtc.getMinute();
|
||||
t.tm_sec = rtc.getSecond();
|
||||
tv.tv_sec = mktime(&t);
|
||||
tv.tv_usec = 0;
|
||||
DEBUG_MSG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
if (currentQuality == RTCQualityNone) {
|
||||
currentQuality = RTCQualityDevice;
|
||||
}
|
||||
}
|
||||
#elif defined(PCF8563_RTC)
|
||||
if(rtc_found == PCF8563_RTC) {
|
||||
uint32_t now = millis();
|
||||
PCF8563_Class rtc;
|
||||
rtc.begin();
|
||||
auto tc = rtc.getDateTime();
|
||||
tm t;
|
||||
t.tm_year = tc.year;
|
||||
t.tm_mon = tc.month;
|
||||
t.tm_mday = tc.day;
|
||||
t.tm_hour = tc.hour;
|
||||
t.tm_min = tc.minute;
|
||||
t.tm_sec = tc.second;
|
||||
tv.tv_sec = mktime(&t);
|
||||
tv.tv_usec = 0;
|
||||
DEBUG_MSG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec);
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
if (currentQuality == RTCQualityNone) {
|
||||
currentQuality = RTCQualityDevice;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (!gettimeofday(&tv, NULL)) {
|
||||
uint32_t now = millis();
|
||||
|
||||
DEBUG_MSG("Read RTC time as %ld (cur millis %u) quality=%d\n", tv.tv_sec, now, currentQuality);
|
||||
DEBUG_MSG("Read RTC time as %ld\n", tv.tv_sec);
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||
@@ -55,12 +99,28 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
zeroOffsetSecs = tv->tv_sec;
|
||||
|
||||
// If this platform has a setable RTC, set it
|
||||
#ifndef NO_ESP32
|
||||
#ifdef RV3028_RTC
|
||||
if(rtc_found == RV3028_RTC) {
|
||||
Melopero_RV3028 rtc;
|
||||
rtc.initI2C();
|
||||
tm *t = localtime(&tv->tv_sec);
|
||||
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
DEBUG_MSG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
}
|
||||
#elif defined(PCF8563_RTC)
|
||||
if(rtc_found == PCF8563_RTC) {
|
||||
PCF8563_Class rtc;
|
||||
rtc.begin();
|
||||
tm *t = localtime(&tv->tv_sec);
|
||||
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
DEBUG_MSG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
}
|
||||
#elif !defined(NO_ESP32)
|
||||
settimeofday(tv, NULL);
|
||||
#endif
|
||||
|
||||
// nrf52 doesn't have a readable RTC (yet - software not written)
|
||||
#if defined(PORTDUINO) || !defined(NO_ESP32)
|
||||
#if defined(PORTDUINO) || !defined(NO_ESP32) || defined(RV3028_RTC) || defined(PCF8563_RTC)
|
||||
readFromRTC();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,17 +5,21 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
enum RTCQuality {
|
||||
|
||||
/// We haven't had our RTC set yet
|
||||
RTCQualityNone = 0,
|
||||
|
||||
/// We got time from an onboard peripheral after boot.
|
||||
RTCQualityDevice = 1,
|
||||
|
||||
/// Some other node gave us a time we can use
|
||||
RTCQualityFromNet = 1,
|
||||
RTCQualityFromNet = 2,
|
||||
|
||||
/// Our time is based on NTP
|
||||
RTCQualityNTP= 2,
|
||||
RTCQualityNTP= 3,
|
||||
|
||||
/// Our time is based on our own GPS
|
||||
RTCQualityGPS = 3
|
||||
RTCQualityGPS = 4
|
||||
};
|
||||
|
||||
RTCQuality getRTCQuality();
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
//4.2 inch 300x400 - GxEPD2_420_M01
|
||||
#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
|
||||
|
||||
#elif defined(M5_COREINK)
|
||||
//M5Stack CoreInk
|
||||
//1.54 inch 200x200 - GxEPD2_154_M09
|
||||
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
|
||||
|
||||
#endif
|
||||
|
||||
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
|
||||
@@ -58,6 +63,12 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
|
||||
//GxEPD2_420_M01
|
||||
setGeometry(GEOMETRY_RAWMODE, 300, 400);
|
||||
|
||||
#elif defined(M5_COREINK)
|
||||
|
||||
//M5Stack_CoreInk 200x200
|
||||
//1.54 inch 200x200 - GxEPD2_154_M09
|
||||
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
|
||||
|
||||
#endif
|
||||
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
|
||||
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
|
||||
@@ -108,7 +119,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
|
||||
// 4.2 inch 300x400 - GxEPD2_420_M01
|
||||
//adafruitDisplay->nextPage();
|
||||
|
||||
#elif defined(PCA10059)
|
||||
#elif defined(PCA10059) || defined(M5_COREINK)
|
||||
adafruitDisplay->nextPage();
|
||||
#endif
|
||||
|
||||
@@ -180,35 +191,10 @@ bool EInkDisplay::connect()
|
||||
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
|
||||
adafruitDisplay->setRotation(3);
|
||||
//For 1.54, 2.9 and 4.2
|
||||
//adafruitDisplay->setRotation(1);
|
||||
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
//adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
} else {
|
||||
(void)adafruitDisplay;
|
||||
}
|
||||
@@ -221,6 +207,12 @@ bool EInkDisplay::connect()
|
||||
adafruitDisplay->setRotation(3);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
}
|
||||
#elif defined(M5_COREINK)
|
||||
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
|
||||
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
||||
adafruitDisplay->init(115200, true, 40, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
adafruitDisplay->setRotation(0);
|
||||
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#include "configuration.h"
|
||||
#ifndef NO_SCREEN
|
||||
#include <OLEDDisplay.h>
|
||||
|
||||
#include "GPS.h"
|
||||
@@ -31,8 +32,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "graphics/images.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "mesh/generated/deviceonly.pb.h"
|
||||
#include "mesh/Channels.h"
|
||||
#include "mesh/generated/deviceonly.pb.h"
|
||||
#include "modules/TextMessageModule.h"
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
@@ -93,7 +94,7 @@ static uint16_t displayWidth, displayHeight;
|
||||
#define SCREEN_WIDTH displayWidth
|
||||
#define SCREEN_HEIGHT displayHeight
|
||||
|
||||
#ifdef HAS_EINK
|
||||
#if defined(HAS_EINK) || defined(ILI9341_DRIVER)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
@@ -162,21 +163,22 @@ static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDi
|
||||
// needs to be drawn relative to x and y
|
||||
|
||||
// draw centered icon left to right and centered above the one line of app text
|
||||
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2,
|
||||
oemStore.oem_icon_width, oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
|
||||
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2,
|
||||
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2, oemStore.oem_icon_width,
|
||||
oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
|
||||
|
||||
switch(oemStore.oem_font){
|
||||
case 0:
|
||||
display->setFont(FONT_SMALL);
|
||||
switch (oemStore.oem_font) {
|
||||
case 0:
|
||||
display->setFont(FONT_SMALL);
|
||||
break;
|
||||
case 2:
|
||||
display->setFont(FONT_LARGE);
|
||||
case 2:
|
||||
display->setFont(FONT_LARGE);
|
||||
break;
|
||||
default:
|
||||
display->setFont(FONT_MEDIUM);
|
||||
default:
|
||||
display->setFont(FONT_MEDIUM);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
const char *title = oemStore.oem_text;
|
||||
display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title);
|
||||
@@ -351,8 +353,8 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
|
||||
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
||||
static bool shouldDrawMessage(const MeshPacket *packet)
|
||||
{
|
||||
return packet->from != 0 && !radioConfig.preferences.range_test_module_enabled &&
|
||||
!radioConfig.preferences.store_forward_module_enabled;
|
||||
return packet->from != 0 && !moduleConfig.range_test.enabled &&
|
||||
!moduleConfig.store_forward.enabled;
|
||||
}
|
||||
|
||||
/// Draw the last text message we received
|
||||
@@ -466,7 +468,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *no
|
||||
// Draw GPS status summary
|
||||
static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||
{
|
||||
if (radioConfig.preferences.fixed_position) {
|
||||
if (config.position.fixed_position) {
|
||||
// GPS coordinates are currently fixed
|
||||
display->drawString(x - 1, y - 2, "Fixed GPS");
|
||||
return;
|
||||
@@ -505,10 +507,10 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
|
||||
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||
{
|
||||
String displayLine = "";
|
||||
if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) {
|
||||
if (!gps->getIsConnected() && !config.position.fixed_position) {
|
||||
// displayLine = "No GPS Module";
|
||||
// display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) {
|
||||
} else if (!gps->getHasLock() && !config.position.fixed_position) {
|
||||
// displayLine = "No GPS Lock";
|
||||
// display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else {
|
||||
@@ -521,32 +523,32 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
|
||||
// Draw GPS status coordinates
|
||||
static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||
{
|
||||
auto gpsFormat = radioConfig.preferences.gps_format;
|
||||
auto gpsFormat = config.display.gps_format;
|
||||
String displayLine = "";
|
||||
|
||||
if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) {
|
||||
if (!gps->getIsConnected() && !config.position.fixed_position) {
|
||||
displayLine = "No GPS Module";
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) {
|
||||
} else if (!gps->getHasLock() && !config.position.fixed_position) {
|
||||
displayLine = "No GPS Lock";
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else {
|
||||
|
||||
if (gpsFormat != GpsCoordinateFormat_GpsFormatDMS) {
|
||||
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) {
|
||||
char coordinateLine[22];
|
||||
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
|
||||
if (gpsFormat == GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
|
||||
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
|
||||
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
|
||||
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
|
||||
sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
|
||||
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
|
||||
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
|
||||
sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
|
||||
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
|
||||
geoCoord.getMGRSNorthing());
|
||||
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
|
||||
geoCoord.getOLCCode(coordinateLine);
|
||||
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
|
||||
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
|
||||
sprintf(coordinateLine, "%s", "Out of Boundary");
|
||||
else
|
||||
@@ -555,7 +557,7 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
|
||||
}
|
||||
|
||||
// If fixed position, display text "Fixed GPS" alternating with the coordinates.
|
||||
if (radioConfig.preferences.fixed_position) {
|
||||
if (config.position.fixed_position) {
|
||||
if ((millis() / 10000) % 2) {
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
|
||||
} else {
|
||||
@@ -816,7 +818,8 @@ void _screen_header()
|
||||
#endif
|
||||
|
||||
// #ifdef RAK4630
|
||||
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), dispdev_oled(address, sda, scl), ui(&dispdev)
|
||||
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl),
|
||||
// dispdev_oled(address, sda, scl), ui(&dispdev)
|
||||
// {
|
||||
// address_found = address;
|
||||
// cmdQueue.setReader(this);
|
||||
@@ -976,7 +979,7 @@ int32_t Screen::runOnce()
|
||||
}
|
||||
|
||||
// If we have an OEM Boot screen, toggle after 2,5 seconds
|
||||
if(strlen(oemStore.oem_text) > 0){
|
||||
if (strlen(oemStore.oem_text) > 0) {
|
||||
static bool showingOEMBootScreen = true;
|
||||
if (showingOEMBootScreen && (millis() > (2500 + serialSinceMsec))) {
|
||||
DEBUG_MSG("Switch to OEM screen...\n");
|
||||
@@ -991,7 +994,7 @@ int32_t Screen::runOnce()
|
||||
}
|
||||
|
||||
#ifndef DISABLE_WELCOME_UNSET
|
||||
if (showingNormalScreen && radioConfig.preferences.region == RegionCode_Unset) {
|
||||
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_Unset) {
|
||||
setWelcomeFrames();
|
||||
}
|
||||
#endif
|
||||
@@ -1064,8 +1067,8 @@ int32_t Screen::runOnce()
|
||||
// standard screen switching is stopped.
|
||||
if (showingNormalScreen) {
|
||||
// standard screen loop handling here
|
||||
if (radioConfig.preferences.auto_screen_carousel_secs > 0 &&
|
||||
(millis() - lastScreenTransition) > (radioConfig.preferences.auto_screen_carousel_secs * 1000)) {
|
||||
if (config.display.auto_screen_carousel_secs > 0 &&
|
||||
(millis() - lastScreenTransition) > (config.display.auto_screen_carousel_secs * 1000)) {
|
||||
DEBUG_MSG("LastScreenTransition exceeded %ums transitioning to next frame\n", (millis() - lastScreenTransition));
|
||||
handleOnPress();
|
||||
}
|
||||
@@ -1340,8 +1343,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
#ifdef HAS_WIFI
|
||||
const char *wifiName = radioConfig.preferences.wifi_ssid;
|
||||
const char *wifiPsw = radioConfig.preferences.wifi_password;
|
||||
const char *wifiName = config.wifi.ssid;
|
||||
const char *wifiPsw = config.wifi.psk;
|
||||
|
||||
displayedNodeNum = 0; // Not currently showing a node pane
|
||||
|
||||
@@ -1352,7 +1355,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
|
||||
if (isSoftAPForced()) {
|
||||
display->drawString(x, y, String("WiFi: Software AP (Admin)"));
|
||||
} else if (radioConfig.preferences.wifi_ap_mode) {
|
||||
} else if (config.wifi.ap_mode) {
|
||||
display->drawString(x, y, String("WiFi: Software AP"));
|
||||
} else if (WiFi.status() != WL_CONNECTED) {
|
||||
display->drawString(x, y, String("WiFi: Not Connected"));
|
||||
@@ -1375,8 +1378,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
- WL_NO_SHIELD: assigned when no WiFi shield is present;
|
||||
|
||||
*/
|
||||
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || radioConfig.preferences.wifi_ap_mode) {
|
||||
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
|
||||
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.wifi.ap_mode) {
|
||||
if (config.wifi.ap_mode || isSoftAPForced()) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
|
||||
|
||||
// Number of connections to the AP. Default max for the esp32 is 4
|
||||
@@ -1468,7 +1471,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
}
|
||||
|
||||
} else {
|
||||
if (radioConfig.preferences.wifi_ap_mode) {
|
||||
if (config.wifi.ap_mode) {
|
||||
if ((millis() / 10000) % 2) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||
} else {
|
||||
@@ -1515,22 +1518,31 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
|
||||
auto mode = "";
|
||||
|
||||
if (channels.getPrimary().modem_config == 0) {
|
||||
mode = "VLongSlow";
|
||||
} else if (channels.getPrimary().modem_config == 1) {
|
||||
mode = "LongSlow";
|
||||
} else if (channels.getPrimary().modem_config == 2) {
|
||||
mode = "LongFast";
|
||||
} else if (channels.getPrimary().modem_config == 3) {
|
||||
mode = "MidSlow";
|
||||
} else if (channels.getPrimary().modem_config == 4) {
|
||||
mode = "MidFast";
|
||||
} else if (channels.getPrimary().modem_config == 5) {
|
||||
mode = "ShortSlow";
|
||||
} else if (channels.getPrimary().modem_config == 6) {
|
||||
mode = "ShortFast";
|
||||
} else {
|
||||
switch (config.lora.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_ShortSlow:
|
||||
mode = "ShortS";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_ShortFast:
|
||||
mode = "ShortF";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedSlow:
|
||||
mode = "MedS";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedFast:
|
||||
mode = "MedF";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongSlow:
|
||||
mode = "LongS";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongFast:
|
||||
mode = "LongF";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_VLongSlow:
|
||||
mode = "VeryL";
|
||||
break;
|
||||
default:
|
||||
mode = "Custom";
|
||||
break;
|
||||
}
|
||||
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
|
||||
@@ -1557,7 +1569,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
else
|
||||
uptime += String(seconds) + "s ";
|
||||
|
||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
|
||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
|
||||
if (rtc_sec > 0) {
|
||||
long hms = rtc_sec % SEC_PER_DAY;
|
||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||
@@ -1583,7 +1595,8 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
||||
|
||||
// Line 3
|
||||
if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
|
||||
if (config.display.gps_format !=
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
|
||||
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
|
||||
// Line 4
|
||||
@@ -1652,3 +1665,4 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
||||
}
|
||||
|
||||
} // namespace graphics
|
||||
#endif // NO_SCREEN
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef NO_SCREEN
|
||||
#include "power.h"
|
||||
namespace graphics
|
||||
{
|
||||
// Noop class for boards without screen.
|
||||
@@ -15,6 +16,8 @@ class Screen
|
||||
void adjustBrightness(){}
|
||||
void doDeepSleep() {}
|
||||
void forceDisplay() {}
|
||||
void startBluetoothPinScreen(uint32_t pin) {}
|
||||
void stopBluetoothPinScreen() {}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -310,7 +313,7 @@ class Screen : public concurrency::OSThread
|
||||
SH1106Wire dispdev;
|
||||
#elif defined(USE_SSD1306)
|
||||
SSD1306Wire dispdev;
|
||||
#elif defined(ST7735_CS)
|
||||
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER)
|
||||
TFTDisplay dispdev;
|
||||
#elif defined(HAS_EINK)
|
||||
EInkDisplay dispdev;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef ST7735_CS
|
||||
#if defined(ST7735_CS) || defined(ILI9341_DRIVER)
|
||||
#include "SPILock.h"
|
||||
#include "TFTDisplay.h"
|
||||
#include <SPI.h>
|
||||
@@ -10,7 +10,11 @@ static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.
|
||||
|
||||
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl)
|
||||
{
|
||||
setGeometry(GEOMETRY_RAWMODE, 160, 80);
|
||||
#ifdef SCREEN_ROTATE
|
||||
setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH);
|
||||
#else
|
||||
setGeometry(GEOMETRY_RAWMODE, TFT_WIDTH, TFT_HEIGHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Write the buffer to the display memory
|
||||
@@ -20,12 +24,10 @@ void TFTDisplay::display(void)
|
||||
|
||||
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
|
||||
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
|
||||
for (uint8_t y = 0; y < displayHeight; y++) {
|
||||
for (uint8_t x = 0; x < displayWidth; x++) {
|
||||
|
||||
for (uint16_t y = 0; y < displayHeight; y++) {
|
||||
for (uint16_t x = 0; x < displayWidth; x++) {
|
||||
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
|
||||
auto b = buffer[x + (y / 8) * displayWidth];
|
||||
auto isset = b & (1 << (y & 7));
|
||||
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
||||
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
|
||||
}
|
||||
}
|
||||
@@ -38,21 +40,34 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
// Drop all commands to device (we just update the buffer)
|
||||
}
|
||||
|
||||
void TFTDisplay::setDetected(uint8_t detected)
|
||||
{
|
||||
(void)detected;
|
||||
}
|
||||
|
||||
// Connect to the display
|
||||
bool TFTDisplay::connect()
|
||||
{
|
||||
concurrency::LockGuard g(spiLock);
|
||||
DEBUG_MSG("Doing TFT init\n");
|
||||
|
||||
#ifdef TFT_BL
|
||||
digitalWrite(TFT_BL, HIGH);
|
||||
pinMode(TFT_BL, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifdef ST7735_BACKLIGHT_EN
|
||||
digitalWrite(ST7735_BACKLIGHT_EN, HIGH);
|
||||
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
|
||||
#endif
|
||||
|
||||
tft.init();
|
||||
#ifdef M5STACK
|
||||
tft.setRotation(1); // M5Stack has the TFT in landscape
|
||||
#else
|
||||
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
||||
#endif
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ class TFTDisplay : public OLEDDisplay
|
||||
|
||||
// Write the buffer to the display memory
|
||||
virtual void display(void) override;
|
||||
|
||||
/**
|
||||
* shim to make the abstraction happy
|
||||
*
|
||||
*/
|
||||
void setDetected(uint8_t detected);
|
||||
|
||||
protected:
|
||||
// the header size of the buffer used, e.g. for the SPI command header
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
#include "configuration.h"
|
||||
#include "RotaryEncoderInterruptBase.h"
|
||||
#include "configuration.h"
|
||||
|
||||
RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(
|
||||
const char *name) :
|
||||
concurrency::OSThread(name)
|
||||
RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(const char *name) : concurrency::OSThread(name)
|
||||
{
|
||||
this->_originName = name;
|
||||
}
|
||||
|
||||
void RotaryEncoderInterruptBase::init(
|
||||
uint8_t pinA, uint8_t pinB, uint8_t pinPress,
|
||||
char eventCw, char eventCcw, char eventPressed,
|
||||
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
|
||||
uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed,
|
||||
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
|
||||
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
|
||||
{
|
||||
this->_pinA = pinA;
|
||||
@@ -24,42 +21,34 @@ void RotaryEncoderInterruptBase::init(
|
||||
pinMode(this->_pinA, INPUT_PULLUP);
|
||||
pinMode(this->_pinB, INPUT_PULLUP);
|
||||
|
||||
// attachInterrupt(pinPress, onIntPress, RISING);
|
||||
// attachInterrupt(pinPress, onIntPress, RISING);
|
||||
attachInterrupt(pinPress, onIntPress, RISING);
|
||||
attachInterrupt(this->_pinA, onIntA, CHANGE);
|
||||
attachInterrupt(this->_pinB, onIntB, CHANGE);
|
||||
|
||||
this->rotaryLevelA = digitalRead(this->_pinA);
|
||||
this->rotaryLevelB = digitalRead(this->_pinB);
|
||||
DEBUG_MSG("Rotary initialized (%d, %d, %d)\n",
|
||||
this->_pinA, this->_pinB, pinPress);
|
||||
DEBUG_MSG("Rotary initialized (%d, %d, %d)\n", this->_pinA, this->_pinB, pinPress);
|
||||
}
|
||||
|
||||
|
||||
int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
{
|
||||
InputEvent e;
|
||||
e.inputEvent = InputEventChar_KEY_NONE;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
e.source = this->_originName;
|
||||
|
||||
if (this->action == ROTARY_ACTION_PRESSED)
|
||||
{
|
||||
if (this->action == ROTARY_ACTION_PRESSED) {
|
||||
DEBUG_MSG("Rotary event Press\n");
|
||||
e.inputEvent = this->_eventPressed;
|
||||
}
|
||||
else if (this->action == ROTARY_ACTION_CW)
|
||||
{
|
||||
} else if (this->action == ROTARY_ACTION_CW) {
|
||||
DEBUG_MSG("Rotary event CW\n");
|
||||
e.inputEvent = this->_eventCw;
|
||||
}
|
||||
else if (this->action == ROTARY_ACTION_CCW)
|
||||
{
|
||||
} else if (this->action == ROTARY_ACTION_CCW) {
|
||||
DEBUG_MSG("Rotary event CCW\n");
|
||||
e.inputEvent = this->_eventCcw;
|
||||
}
|
||||
|
||||
if (e.inputEvent != InputEventChar_KEY_NONE)
|
||||
{
|
||||
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
|
||||
@@ -68,7 +57,6 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
return 30000; // TODO: technically this can be MAX_INT
|
||||
}
|
||||
|
||||
|
||||
void RotaryEncoderInterruptBase::intPressHandler()
|
||||
{
|
||||
this->action = ROTARY_ACTION_PRESSED;
|
||||
@@ -79,66 +67,47 @@ void RotaryEncoderInterruptBase::intAHandler()
|
||||
{
|
||||
// CW rotation (at least on most common rotary encoders)
|
||||
int currentLevelA = digitalRead(this->_pinA);
|
||||
if (this->rotaryLevelA == currentLevelA)
|
||||
{
|
||||
if (this->rotaryLevelA == currentLevelA) {
|
||||
return;
|
||||
}
|
||||
this->rotaryLevelA = currentLevelA;
|
||||
this->rotaryStateCCW = intHandler(
|
||||
currentLevelA == HIGH,
|
||||
this->rotaryLevelB,
|
||||
ROTARY_ACTION_CCW,
|
||||
this->rotaryStateCCW);
|
||||
this->rotaryStateCCW = intHandler(currentLevelA == HIGH, this->rotaryLevelB, ROTARY_ACTION_CCW, this->rotaryStateCCW);
|
||||
}
|
||||
|
||||
void RotaryEncoderInterruptBase::intBHandler()
|
||||
{
|
||||
// CW rotation (at least on most common rotary encoders)
|
||||
int currentLevelB = digitalRead(this->_pinB);
|
||||
if (this->rotaryLevelB == currentLevelB)
|
||||
{
|
||||
if (this->rotaryLevelB == currentLevelB) {
|
||||
return;
|
||||
}
|
||||
this->rotaryLevelB = currentLevelB;
|
||||
this->rotaryStateCW = intHandler(
|
||||
currentLevelB == HIGH,
|
||||
this->rotaryLevelA,
|
||||
ROTARY_ACTION_CW,
|
||||
this->rotaryStateCW);
|
||||
this->rotaryStateCW = intHandler(currentLevelB == HIGH, this->rotaryLevelA, ROTARY_ACTION_CW, this->rotaryStateCW);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rotary action implementation.
|
||||
* We assume, the following pin setup:
|
||||
* A --||
|
||||
* GND --||]========
|
||||
* GND --||]========
|
||||
* B --||
|
||||
*
|
||||
*
|
||||
* @return The new state for rotary pin.
|
||||
*/
|
||||
RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(
|
||||
bool actualPinRaising,
|
||||
int otherPinLevel,
|
||||
RotaryEncoderInterruptBaseActionType action,
|
||||
RotaryEncoderInterruptBaseStateType state)
|
||||
RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(bool actualPinRaising, int otherPinLevel,
|
||||
RotaryEncoderInterruptBaseActionType action,
|
||||
RotaryEncoderInterruptBaseStateType state)
|
||||
{
|
||||
RotaryEncoderInterruptBaseStateType newState =
|
||||
state;
|
||||
if (actualPinRaising && (otherPinLevel == LOW))
|
||||
{
|
||||
if (state == ROTARY_EVENT_CLEARED)
|
||||
{
|
||||
RotaryEncoderInterruptBaseStateType newState = state;
|
||||
if (actualPinRaising && (otherPinLevel == LOW)) {
|
||||
if (state == ROTARY_EVENT_CLEARED) {
|
||||
newState = ROTARY_EVENT_OCCURRED;
|
||||
if ((this->action != ROTARY_ACTION_PRESSED)
|
||||
&& (this->action != action))
|
||||
{
|
||||
if ((this->action != ROTARY_ACTION_PRESSED) && (this->action != action)) {
|
||||
this->action = action;
|
||||
DEBUG_MSG("Rotary action\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!actualPinRaising && (otherPinLevel == HIGH))
|
||||
{
|
||||
} else if (!actualPinRaising && (otherPinLevel == HIGH)) {
|
||||
// Logic to prevent bouncing.
|
||||
newState = ROTARY_EVENT_CLEARED;
|
||||
}
|
||||
|
||||
@@ -1,45 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||
#include "InputBroker.h"
|
||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||
|
||||
enum RotaryEncoderInterruptBaseStateType
|
||||
{
|
||||
ROTARY_EVENT_OCCURRED,
|
||||
ROTARY_EVENT_CLEARED
|
||||
};
|
||||
enum RotaryEncoderInterruptBaseStateType { ROTARY_EVENT_OCCURRED, ROTARY_EVENT_CLEARED };
|
||||
|
||||
enum RotaryEncoderInterruptBaseActionType
|
||||
{
|
||||
ROTARY_ACTION_NONE,
|
||||
ROTARY_ACTION_PRESSED,
|
||||
ROTARY_ACTION_CW,
|
||||
ROTARY_ACTION_CCW
|
||||
};
|
||||
enum RotaryEncoderInterruptBaseActionType { ROTARY_ACTION_NONE, ROTARY_ACTION_PRESSED, ROTARY_ACTION_CW, ROTARY_ACTION_CCW };
|
||||
|
||||
class RotaryEncoderInterruptBase :
|
||||
public Observable<const InputEvent *>,
|
||||
private concurrency::OSThread
|
||||
class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, private concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
explicit RotaryEncoderInterruptBase(
|
||||
const char *name);
|
||||
void init(
|
||||
uint8_t pinA, uint8_t pinB, uint8_t pinPress,
|
||||
char eventCw, char eventCcw, char eventPressed,
|
||||
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
|
||||
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
|
||||
explicit RotaryEncoderInterruptBase(const char *name);
|
||||
void init(uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed,
|
||||
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
|
||||
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
|
||||
void intPressHandler();
|
||||
void intAHandler();
|
||||
void intBHandler();
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
RotaryEncoderInterruptBaseStateType intHandler(
|
||||
bool actualPinRaising,
|
||||
int otherPinLevel,
|
||||
RotaryEncoderInterruptBaseActionType action,
|
||||
RotaryEncoderInterruptBaseStateType state);
|
||||
RotaryEncoderInterruptBaseStateType intHandler(bool actualPinRaising, int otherPinLevel,
|
||||
RotaryEncoderInterruptBaseActionType action,
|
||||
RotaryEncoderInterruptBaseStateType state);
|
||||
|
||||
volatile RotaryEncoderInterruptBaseStateType rotaryStateCW = ROTARY_EVENT_CLEARED;
|
||||
volatile RotaryEncoderInterruptBaseStateType rotaryStateCCW = ROTARY_EVENT_CLEARED;
|
||||
@@ -50,8 +33,8 @@ class RotaryEncoderInterruptBase :
|
||||
private:
|
||||
uint8_t _pinA = 0;
|
||||
uint8_t _pinB = 0;
|
||||
char _eventCw = InputEventChar_KEY_NONE;
|
||||
char _eventCcw = InputEventChar_KEY_NONE;
|
||||
char _eventPressed = InputEventChar_KEY_NONE;
|
||||
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
const char *_originName;
|
||||
};
|
||||
|
||||
@@ -3,37 +3,26 @@
|
||||
|
||||
RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
|
||||
|
||||
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() :
|
||||
RotaryEncoderInterruptBase(
|
||||
"rotEnc1")
|
||||
{
|
||||
}
|
||||
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {}
|
||||
|
||||
void RotaryEncoderInterruptImpl1::init()
|
||||
{
|
||||
if (!radioConfig.preferences.rotary1_enabled)
|
||||
{
|
||||
if (!moduleConfig.canned_message.rotary1_enabled) {
|
||||
// Input device is disabled.
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t pinA = radioConfig.preferences.inputbroker_pin_a;
|
||||
uint8_t pinB = radioConfig.preferences.inputbroker_pin_b;
|
||||
uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press;
|
||||
char eventCw =
|
||||
static_cast<char>(radioConfig.preferences.inputbroker_event_cw);
|
||||
char eventCcw =
|
||||
static_cast<char>(radioConfig.preferences.inputbroker_event_ccw);
|
||||
char eventPressed =
|
||||
static_cast<char>(radioConfig.preferences.inputbroker_event_press);
|
||||
uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a;
|
||||
uint8_t pinB = moduleConfig.canned_message.inputbroker_pin_b;
|
||||
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
|
||||
char eventCw = static_cast<char>(moduleConfig.canned_message.inputbroker_event_cw);
|
||||
char eventCcw = static_cast<char>(moduleConfig.canned_message.inputbroker_event_ccw);
|
||||
char eventPressed = static_cast<char>(moduleConfig.canned_message.inputbroker_event_press);
|
||||
|
||||
//radioConfig.preferences.ext_notification_module_output
|
||||
RotaryEncoderInterruptBase::init(
|
||||
pinA, pinB, pinPress,
|
||||
eventCw, eventCcw, eventPressed,
|
||||
RotaryEncoderInterruptImpl1::handleIntA,
|
||||
RotaryEncoderInterruptImpl1::handleIntB,
|
||||
RotaryEncoderInterruptImpl1::handleIntPressed);
|
||||
// moduleConfig.canned_message.ext_notification_module_output
|
||||
RotaryEncoderInterruptBase::init(pinA, pinB, pinPress, eventCw, eventCcw, eventPressed,
|
||||
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
||||
RotaryEncoderInterruptImpl1::handleIntPressed);
|
||||
inputBroker->registerSource(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||
#include "InputBroker.h"
|
||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||
|
||||
class UpDownInterruptBase :
|
||||
public Observable<const InputEvent *>
|
||||
class UpDownInterruptBase : public Observable<const InputEvent *>
|
||||
{
|
||||
public:
|
||||
explicit UpDownInterruptBase(
|
||||
const char *name);
|
||||
void init(
|
||||
uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
|
||||
char eventDown, char eventUp, char eventPressed,
|
||||
void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)());
|
||||
explicit UpDownInterruptBase(const char *name);
|
||||
void init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, char eventDown, char eventUp, char eventPressed,
|
||||
void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)());
|
||||
void intPressHandler();
|
||||
void intDownHandler();
|
||||
void intUpHandler();
|
||||
@@ -20,8 +16,8 @@ class UpDownInterruptBase :
|
||||
private:
|
||||
uint8_t _pinDown = 0;
|
||||
uint8_t _pinUp = 0;
|
||||
char _eventDown = InputEventChar_KEY_NONE;
|
||||
char _eventUp = InputEventChar_KEY_NONE;
|
||||
char _eventPressed = InputEventChar_KEY_NONE;
|
||||
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
const char *_originName;
|
||||
};
|
||||
|
||||
@@ -3,38 +3,26 @@
|
||||
|
||||
UpDownInterruptImpl1 *upDownInterruptImpl1;
|
||||
|
||||
UpDownInterruptImpl1::UpDownInterruptImpl1() :
|
||||
UpDownInterruptBase(
|
||||
"upDown1")
|
||||
{
|
||||
}
|
||||
UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {}
|
||||
|
||||
void UpDownInterruptImpl1::init()
|
||||
{
|
||||
|
||||
if (!radioConfig.preferences.updown1_enabled)
|
||||
{
|
||||
if (!moduleConfig.canned_message.updown1_enabled) {
|
||||
// Input device is disabled.
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t pinUp = radioConfig.preferences.inputbroker_pin_a;
|
||||
uint8_t pinDown = radioConfig.preferences.inputbroker_pin_b;
|
||||
uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press;
|
||||
uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a;
|
||||
uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b;
|
||||
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
|
||||
|
||||
char eventDown =
|
||||
static_cast<char>(InputEventChar_KEY_DOWN);
|
||||
char eventUp =
|
||||
static_cast<char>(InputEventChar_KEY_UP);
|
||||
char eventPressed =
|
||||
static_cast<char>(InputEventChar_KEY_SELECT);
|
||||
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN);
|
||||
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP);
|
||||
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT);
|
||||
|
||||
UpDownInterruptBase::init(
|
||||
pinDown, pinUp, pinPress,
|
||||
eventDown, eventUp, eventPressed,
|
||||
UpDownInterruptImpl1::handleIntDown,
|
||||
UpDownInterruptImpl1::handleIntUp,
|
||||
UpDownInterruptImpl1::handleIntPressed);
|
||||
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
|
||||
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
|
||||
inputBroker->registerSource(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "configuration.h"
|
||||
#include "kbI2cBase.h"
|
||||
#include "configuration.h"
|
||||
#include <Wire.h>
|
||||
|
||||
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
|
||||
@@ -10,40 +10,39 @@ KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
|
||||
int32_t KbI2cBase::runOnce()
|
||||
{
|
||||
InputEvent e;
|
||||
e.inputEvent = InputEventChar_KEY_NONE;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
e.source = this->_originName;
|
||||
|
||||
Wire.requestFrom(CARDKB_ADDR, 1);
|
||||
|
||||
while(Wire.available()) {
|
||||
|
||||
while (Wire.available()) {
|
||||
char c = Wire.read();
|
||||
switch(c) {
|
||||
switch (c) {
|
||||
case 0x1b: // ESC
|
||||
e.inputEvent = InputEventChar_KEY_CANCEL;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL;
|
||||
break;
|
||||
case 0x08: // Back
|
||||
e.inputEvent = InputEventChar_KEY_BACK;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK;
|
||||
break;
|
||||
case 0xb5: // Up
|
||||
e.inputEvent = InputEventChar_KEY_UP;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP;
|
||||
break;
|
||||
case 0xb6: // Down
|
||||
e.inputEvent = InputEventChar_KEY_DOWN;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN;
|
||||
break;
|
||||
case 0xb4: // Left
|
||||
e.inputEvent = InputEventChar_KEY_LEFT;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT;
|
||||
break;
|
||||
case 0xb7: // Right
|
||||
e.inputEvent = InputEventChar_KEY_RIGHT;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT;
|
||||
break;
|
||||
case 0x0d: // Enter
|
||||
e.inputEvent = InputEventChar_KEY_SELECT;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.inputEvent != InputEventChar_KEY_NONE)
|
||||
{
|
||||
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
return 500;
|
||||
|
||||
68
src/main.cpp
68
src/main.cpp
@@ -1,4 +1,3 @@
|
||||
#include "configuration.h"
|
||||
#include "GPS.h"
|
||||
#include "MeshRadio.h"
|
||||
#include "MeshService.h"
|
||||
@@ -6,6 +5,7 @@
|
||||
#include "PowerFSM.h"
|
||||
#include "airtime.h"
|
||||
#include "buzz.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
#include "power.h"
|
||||
// #include "rom/rtc.h"
|
||||
@@ -17,28 +17,28 @@
|
||||
#include "SPILock.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "concurrency/Periodic.h"
|
||||
#include "debug/axpDebug.h"
|
||||
#include "debug/einkScan.h"
|
||||
#include "debug/i2cScan.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "main.h"
|
||||
#include "modules/Modules.h"
|
||||
#include "sleep.h"
|
||||
#include "shutdown.h"
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
#include "debug/i2cScan.h"
|
||||
#include "debug/einkScan.h"
|
||||
#include "debug/axpDebug.h"
|
||||
#include <Wire.h>
|
||||
// #include <driver/rtc_io.h>
|
||||
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
|
||||
#ifndef NO_ESP32
|
||||
#include "mesh/http/WebServer.h"
|
||||
#include "mesh/http/WebServer.h"
|
||||
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
#include "esp32/ESP32Bluetooth.h"
|
||||
#else
|
||||
#include "nimble/BluetoothUtil.h"
|
||||
#endif
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
#include "esp32/ESP32Bluetooth.h"
|
||||
#else
|
||||
#include "nimble/BluetoothUtil.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,10 +47,10 @@
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
|
||||
#include "LLCC68Interface.h"
|
||||
#include "RF95Interface.h"
|
||||
#include "SX1262Interface.h"
|
||||
#include "SX1268Interface.h"
|
||||
#include "LLCC68Interface.h"
|
||||
|
||||
#include "ButtonThread.h"
|
||||
#include "PowerFSMThread.h"
|
||||
@@ -75,16 +75,24 @@ uint8_t screen_model;
|
||||
|
||||
// The I2C address of the cardkb or RAK14004 (if found)
|
||||
uint8_t cardkb_found;
|
||||
// 0x02 for RAK14004 and 0x00 for cardkb
|
||||
uint8_t kb_model;
|
||||
|
||||
// The I2C address of the Faces Keyboard (if found)
|
||||
uint8_t faceskb_found;
|
||||
|
||||
// The I2C address of the RTC Module (if found)
|
||||
uint8_t rtc_found;
|
||||
|
||||
bool eink_found = true;
|
||||
|
||||
uint32_t serialSinceMsec;
|
||||
|
||||
bool axp192_found;
|
||||
|
||||
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
|
||||
uint8_t nodeTelemetrySensorsMap[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
||||
|
||||
const char *getDeviceName()
|
||||
@@ -93,9 +101,15 @@ const char *getDeviceName()
|
||||
|
||||
getMacAddr(dmac);
|
||||
|
||||
// Meshtastic_ab3c
|
||||
// Meshtastic_ab3c or Shortname_abcd
|
||||
static char name[20];
|
||||
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
|
||||
sprintf(name, "%02x%02x", dmac[4], dmac[5]);
|
||||
// if the shortname exists and is NOT the new default of ab3c, use it for BLE name.
|
||||
if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) {
|
||||
sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
|
||||
} else {
|
||||
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -123,7 +137,8 @@ RadioInterface *rIf = NULL;
|
||||
/**
|
||||
* Some platforms (nrf52) might provide an alterate version that supresses calling delay from sleep.
|
||||
*/
|
||||
__attribute__ ((weak, noinline)) bool loopCanSleep() {
|
||||
__attribute__((weak, noinline)) bool loopCanSleep()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,17 +157,23 @@ void setup()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_PORT
|
||||
if (!radioConfig.preferences.serial_disabled) {
|
||||
if (!config.device.serial_disabled) {
|
||||
consoleInit(); // Set serial baud rate and init our mesh console
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
serialSinceMsec = millis();
|
||||
|
||||
DEBUG_MSG("\n\n//\\ E S H T /\\ S T / C\n\n");
|
||||
|
||||
initDeepSleep();
|
||||
|
||||
// Testing this fix für erratic T-Echo boot behaviour
|
||||
#if defined(TTGO_T_ECHO) && defined(PIN_EINK_PWR_ON)
|
||||
pinMode(PIN_EINK_PWR_ON, OUTPUT);
|
||||
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef VEXT_ENABLE
|
||||
pinMode(VEXT_ENABLE, OUTPUT);
|
||||
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
||||
@@ -192,7 +213,7 @@ void setup()
|
||||
|
||||
fsInit();
|
||||
|
||||
//router = new DSRRouter();
|
||||
// router = new DSRRouter();
|
||||
router = new ReliableRouter();
|
||||
|
||||
#ifdef I2C_SDA
|
||||
@@ -285,7 +306,7 @@ void setup()
|
||||
|
||||
// Don't call screen setup until after nodedb is setup (because we need
|
||||
// the current region name)
|
||||
#if defined(ST7735_CS) || defined(HAS_EINK)
|
||||
#if defined(ST7735_CS) || defined(HAS_EINK) || defined(ILI9341_DRIVER)
|
||||
screen->setup();
|
||||
#else
|
||||
if (screen_found)
|
||||
@@ -298,6 +319,7 @@ void setup()
|
||||
|
||||
// ONCE we will factory reset the GPS for bug #327
|
||||
if (gps && !devicestate.did_gps_reset) {
|
||||
DEBUG_MSG("GPS FactoryReset requested\n");
|
||||
if (gps->factoryReset()) { // If we don't succeed try again next time
|
||||
devicestate.did_gps_reset = true;
|
||||
nodeDB.saveToDisk();
|
||||
@@ -398,14 +420,12 @@ void setup()
|
||||
|
||||
if (!rIf)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_NoRadio);
|
||||
else{
|
||||
else {
|
||||
router->addInterface(rIf);
|
||||
|
||||
// Calculate and save the bit rate to myNodeInfo
|
||||
// TODO: This needs to be added what ever method changes the channel from the phone.
|
||||
myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) /
|
||||
(float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))
|
||||
) * 1000;
|
||||
myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))) * 1000;
|
||||
DEBUG_MSG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
||||
}
|
||||
|
||||
@@ -417,7 +437,7 @@ void setup()
|
||||
setCPUFast(false); // 80MHz is fine for our slow peripherals
|
||||
}
|
||||
|
||||
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
|
||||
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
|
||||
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
|
||||
|
||||
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include "GPSStatus.h"
|
||||
#include "NodeStatus.h"
|
||||
#include "PowerStatus.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "mesh/generated/telemetry.pb.h"
|
||||
|
||||
extern uint8_t screen_found;
|
||||
extern uint8_t screen_model;
|
||||
extern uint8_t cardkb_found;
|
||||
extern uint8_t kb_model;
|
||||
extern uint8_t faceskb_found;
|
||||
extern uint8_t rtc_found;
|
||||
|
||||
extern bool eink_found;
|
||||
extern bool axp192_found;
|
||||
extern bool isCharging;
|
||||
extern bool isUSBPowered;
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[12];
|
||||
|
||||
// Global Screen singleton.
|
||||
extern graphics::Screen *screen;
|
||||
// extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "configuration.h"
|
||||
#include "Channels.h"
|
||||
#include "CryptoEngine.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -83,10 +83,11 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
||||
{
|
||||
Channel &ch = getByIndex(chIndex);
|
||||
ChannelSettings &channelSettings = ch.settings;
|
||||
Config_LoRaConfig &loraConfig = config.lora;
|
||||
|
||||
channelSettings.modem_config = ChannelSettings_ModemConfig_LongFast; // Default to Long Range & Fast
|
||||
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LongFast; // Default to Long Range & Fast
|
||||
|
||||
channelSettings.tx_power = 0; // default
|
||||
loraConfig.tx_power = 0; // default
|
||||
uint8_t defaultpskIndex = 1;
|
||||
channelSettings.psk.bytes[0] = defaultpskIndex;
|
||||
channelSettings.psk.size = 1;
|
||||
@@ -206,33 +207,33 @@ const char *Channels::getName(size_t chIndex)
|
||||
const ChannelSettings &channelSettings = getByIndex(chIndex).settings;
|
||||
const char *channelName = channelSettings.name;
|
||||
if (!*channelName) { // emptystring
|
||||
// Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case
|
||||
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
|
||||
// the app fucked up and forgot to set channelSettings.name
|
||||
|
||||
if (channelSettings.bandwidth != 0)
|
||||
channelName = "Unset";
|
||||
if (config.lora.bandwidth != 0)
|
||||
channelName = "Custom";
|
||||
else
|
||||
switch (channelSettings.modem_config) {
|
||||
case ChannelSettings_ModemConfig_ShortSlow:
|
||||
channelName = "ShortSlow";
|
||||
switch (config.lora.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_ShortSlow:
|
||||
channelName = "ShortS";
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_ShortFast:
|
||||
channelName = "ShortFast";
|
||||
case Config_LoRaConfig_ModemPreset_ShortFast:
|
||||
channelName = "ShortF";
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_MidSlow:
|
||||
channelName = "MediumSlow";
|
||||
case Config_LoRaConfig_ModemPreset_MedSlow:
|
||||
channelName = "MedS";
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_MidFast:
|
||||
channelName = "MediumFast";
|
||||
case Config_LoRaConfig_ModemPreset_MedFast:
|
||||
channelName = "MedF";
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_LongFast:
|
||||
channelName = "LongFast";
|
||||
case Config_LoRaConfig_ModemPreset_LongSlow:
|
||||
channelName = "LongS";
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_LongSlow:
|
||||
channelName = "LongSlow";
|
||||
case Config_LoRaConfig_ModemPreset_LongFast:
|
||||
channelName = "LongF";
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_VLongSlow:
|
||||
channelName = "VLongSlow";
|
||||
case Config_LoRaConfig_ModemPreset_VLongSlow:
|
||||
channelName = "VeryL";
|
||||
break;
|
||||
default:
|
||||
channelName = "Invalid";
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
|
||||
void CryptoEngine::setKey(const CryptoKey &k)
|
||||
{
|
||||
DEBUG_MSG("Installing AES%d key!\n", k.length * 8);
|
||||
/* for(uint8_t i = 0; i < k.length; i++)
|
||||
DEBUG_MSG("%02x ", k.bytes[i]);
|
||||
DEBUG_MSG("\n"); */
|
||||
|
||||
DEBUG_MSG("Using AES%d key!\n", k.length * 8);
|
||||
key = k;
|
||||
}
|
||||
|
||||
@@ -36,6 +32,4 @@ void CryptoEngine::initNonce(uint32_t fromNode, uint64_t packetId)
|
||||
// use memcpy to avoid breaking strict-aliasing
|
||||
memcpy(nonce, &packetId, sizeof(uint64_t));
|
||||
memcpy(nonce + sizeof(uint64_t), &fromNode, sizeof(uint32_t));
|
||||
//*((uint64_t *)&nonce[0]) = packetId;
|
||||
//*((uint32_t *)&nonce[8]) = fromNode;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
|
||||
if ((p->to == NODENUM_BROADCAST) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
||||
if (p->id != 0) {
|
||||
if (radioConfig.preferences.role != Role_ClientMute) {
|
||||
if (config.device.role != Config_DeviceConfig_Role_ClientMute) {
|
||||
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
||||
|
||||
tosend->hop_limit--; // bump down the hop count
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// Map from old region names to new region enums
|
||||
struct RegionInfo {
|
||||
RegionCode code;
|
||||
Config_LoRaConfig_RegionCode code;
|
||||
float freqStart;
|
||||
float freqEnd;
|
||||
float dutyCycle;
|
||||
|
||||
@@ -71,17 +71,7 @@ int MeshService::handleFromRadio(const MeshPacket *mp)
|
||||
printPacket("Forwarding to phone", mp);
|
||||
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
||||
|
||||
fromNum++;
|
||||
|
||||
if (toPhoneQueue.numFree() == 0) {
|
||||
DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n");
|
||||
MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
||||
if (d)
|
||||
releaseToPool(d);
|
||||
}
|
||||
|
||||
MeshPacket *copied = packetPool.allocCopy(*mp);
|
||||
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
|
||||
sendToPhone((MeshPacket *)mp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -161,12 +151,16 @@ bool MeshService::cancelSending(PacketId id)
|
||||
return router->cancelSending(nodeDB.getNodeNum(), id);
|
||||
}
|
||||
|
||||
void MeshService::sendToMesh(MeshPacket *p, RxSource src)
|
||||
void MeshService::sendToMesh(MeshPacket *p, RxSource src, bool ccToPhone)
|
||||
{
|
||||
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
|
||||
|
||||
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
|
||||
router->sendLocal(p, src);
|
||||
|
||||
if (ccToPhone) {
|
||||
sendToPhone(p);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
@@ -187,6 +181,21 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
}
|
||||
}
|
||||
|
||||
void MeshService::sendToPhone(MeshPacket *p)
|
||||
{
|
||||
if (toPhoneQueue.numFree() == 0) {
|
||||
DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n");
|
||||
MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
||||
if (d)
|
||||
releaseToPool(d);
|
||||
}
|
||||
|
||||
MeshPacket *copied = packetPool.allocCopy(*p);
|
||||
perhapsDecode(copied);
|
||||
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
|
||||
fromNum++;
|
||||
}
|
||||
|
||||
NodeInfo *MeshService::refreshMyNodeInfo()
|
||||
{
|
||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
@@ -227,7 +236,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("onGPSchanged() - lost validLocation\n");
|
||||
#endif
|
||||
if (radioConfig.preferences.fixed_position) {
|
||||
if (config.position.fixed_position) {
|
||||
DEBUG_MSG("WARNING: Using fixed position\n");
|
||||
pos = node->position;
|
||||
}
|
||||
@@ -239,8 +248,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
pos.time = getValidTime(RTCQualityGPS);
|
||||
|
||||
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
|
||||
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n",
|
||||
pos.pos_timestamp, pos.time, pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.pos_timestamp, pos.time, pos.latitude_i,
|
||||
pos.longitude_i, pos.altitude);
|
||||
|
||||
// Update our current position in the local DB
|
||||
nodeDB.updatePosition(nodeDB.getNodeNum(), pos, RX_SRC_LOCAL);
|
||||
|
||||
@@ -75,7 +75,7 @@ class MeshService
|
||||
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
||||
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
||||
/// cache
|
||||
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL);
|
||||
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL, bool ccToPhone = false);
|
||||
|
||||
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
|
||||
bool cancelSending(PacketId id);
|
||||
@@ -83,6 +83,9 @@ class MeshService
|
||||
/// Pull the latest power and time info into my nodeinfo
|
||||
NodeInfo *refreshMyNodeInfo();
|
||||
|
||||
/// Send a packet to the phone
|
||||
void sendToPhone(MeshPacket *p);
|
||||
|
||||
private:
|
||||
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
||||
/// returns 0 to allow futher processing
|
||||
|
||||
@@ -34,7 +34,8 @@ NodeDB nodeDB;
|
||||
// we have plenty of ram so statically alloc this tempbuf (for now)
|
||||
EXT_RAM_ATTR DeviceState devicestate;
|
||||
MyNodeInfo &myNodeInfo = devicestate.my_node;
|
||||
RadioConfig radioConfig;
|
||||
LocalConfig config;
|
||||
LocalModuleConfig moduleConfig;
|
||||
ChannelFile channelFile;
|
||||
|
||||
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
|
||||
@@ -47,7 +48,7 @@ DeviceState versions used to be defined in the .proto file but really only this
|
||||
#define here.
|
||||
*/
|
||||
|
||||
#define DEVICESTATE_CUR_VER 11
|
||||
#define DEVICESTATE_CUR_VER 13
|
||||
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
|
||||
|
||||
// FIXME - move this somewhere else
|
||||
@@ -86,21 +87,20 @@ bool NodeDB::resetRadioConfig()
|
||||
|
||||
radioGeneration++;
|
||||
|
||||
radioConfig.has_preferences = true;
|
||||
if (radioConfig.preferences.factory_reset) {
|
||||
// radioConfig.has_preferences = true;
|
||||
if (config.device.factory_reset) {
|
||||
DEBUG_MSG("Performing factory reset!\n");
|
||||
// first, remove the "/prefs" (this removes most prefs)
|
||||
rmDir("/prefs");
|
||||
// second, install default state (this will deal with the duplicate mac address issue)
|
||||
installDefaultDeviceState();
|
||||
// third, write to disk
|
||||
saveToDisk();
|
||||
#ifndef NO_ESP32
|
||||
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
|
||||
nvs_flash_erase();
|
||||
#endif
|
||||
#ifdef NRF52_SERIES
|
||||
// first, remove the "/prefs" (this removes most prefs)
|
||||
FSCom.rmdir_r("/prefs");
|
||||
// second, install default state (this will deal with the duplicate mac address issue)
|
||||
installDefaultDeviceState();
|
||||
// third, write to disk
|
||||
saveToDisk();
|
||||
Bluefruit.begin();
|
||||
DEBUG_MSG("Clearing bluetooth bonds!\n");
|
||||
bond_print_list(BLE_GAP_ROLE_PERIPH);
|
||||
@@ -125,11 +125,11 @@ bool NodeDB::resetRadioConfig()
|
||||
DEBUG_MSG("***** DEVELOPMENT MODE - DO NOT RELEASE *****\n");
|
||||
|
||||
// Sleep quite frequently to stress test the BLE comms, broadcast position every 6 mins
|
||||
radioConfig.preferences.screen_on_secs = 10;
|
||||
radioConfig.preferences.wait_bluetooth_secs = 10;
|
||||
radioConfig.preferences.position_broadcast_secs = 6 * 60;
|
||||
radioConfig.preferences.ls_secs = 60;
|
||||
radioConfig.preferences.region = RegionCode_TW;
|
||||
config.display.screen_on_secs = 10;
|
||||
config.power.wait_bluetooth_secs = 10;
|
||||
config.position.position_broadcast_secs = 6 * 60;
|
||||
config.power.ls_secs = 60;
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_TW;
|
||||
|
||||
// Enter super deep sleep soon and stay there not very long
|
||||
// radioConfig.preferences.mesh_sds_timeout_secs = 10;
|
||||
@@ -142,30 +142,48 @@ bool NodeDB::resetRadioConfig()
|
||||
return didFactoryReset;
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultRadioConfig()
|
||||
void NodeDB::installDefaultConfig()
|
||||
{
|
||||
memset(&radioConfig, 0, sizeof(radioConfig));
|
||||
radioConfig.has_preferences = true;
|
||||
memset(&config, 0, sizeof(LocalConfig));
|
||||
config.version = DEVICESTATE_CUR_VER;
|
||||
config.has_device = true;
|
||||
config.has_display = true;
|
||||
config.has_lora = true;
|
||||
config.has_position = true;
|
||||
config.has_power = true;
|
||||
config.has_wifi = true;
|
||||
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_Unset;
|
||||
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LongFast;
|
||||
resetRadioConfig();
|
||||
strncpy(config.device.ntp_server, "0.pool.ntp.org", 32);
|
||||
// for backward compat, default position flags are ALT+MSL
|
||||
config.position.position_flags =
|
||||
(Config_PositionConfig_PositionFlags_POS_ALTITUDE | Config_PositionConfig_PositionFlags_POS_ALT_MSL);
|
||||
}
|
||||
|
||||
// for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35)
|
||||
radioConfig.preferences.position_flags = (PositionFlags_POS_BATTERY |
|
||||
PositionFlags_POS_ALTITUDE | PositionFlags_POS_ALT_MSL);
|
||||
|
||||
void NodeDB::installDefaultModuleConfig()
|
||||
{
|
||||
memset(&moduleConfig, 0, sizeof(ModuleConfig));
|
||||
moduleConfig.version = DEVICESTATE_CUR_VER;
|
||||
moduleConfig.has_canned_message = true;
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.has_range_test = true;
|
||||
moduleConfig.has_serial = true;
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.has_telemetry = true;
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultChannels()
|
||||
{
|
||||
memset(&channelFile, 0, sizeof(channelFile));
|
||||
memset(&channelFile, 0, sizeof(ChannelFile));
|
||||
channelFile.version = DEVICESTATE_CUR_VER;
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultDeviceState()
|
||||
{
|
||||
// We try to preserve the region setting because it will really bum users out if we discard it
|
||||
String oldRegion = myNodeInfo.region;
|
||||
RegionCode oldRegionCode = radioConfig.preferences.region;
|
||||
|
||||
memset(&devicestate, 0, sizeof(devicestate));
|
||||
memset(&devicestate, 0, sizeof(DeviceState));
|
||||
|
||||
*numNodes = 0; // Forget node DB
|
||||
|
||||
@@ -186,20 +204,14 @@ void NodeDB::installDefaultDeviceState()
|
||||
|
||||
// Set default owner name
|
||||
pickNewNodeNum(); // based on macaddr now
|
||||
sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
||||
sprintf(owner.short_name, "?%02X", (unsigned)(myNodeInfo.my_node_num & 0xff));
|
||||
sprintf(owner.long_name, "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
||||
sprintf(owner.short_name, "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
||||
|
||||
sprintf(owner.id, "!%08x", getNodeNum()); // Default node ID now based on nodenum
|
||||
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
|
||||
|
||||
// Restore region if possible
|
||||
if (oldRegionCode != RegionCode_Unset)
|
||||
radioConfig.preferences.region = oldRegionCode;
|
||||
if (oldRegion.length()) // If the old style region was set, try to keep it up-to-date
|
||||
strcpy(myNodeInfo.region, oldRegion.c_str());
|
||||
|
||||
installDefaultChannels();
|
||||
installDefaultRadioConfig();
|
||||
installDefaultConfig();
|
||||
}
|
||||
|
||||
void NodeDB::init()
|
||||
@@ -241,14 +253,14 @@ void NodeDB::init()
|
||||
DEBUG_MSG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
|
||||
|
||||
/* The ESP32 has a wifi radio. This will need to be modified at some point so
|
||||
* the test isn't so simplistic.
|
||||
*/
|
||||
* the test isn't so simplistic.
|
||||
*/
|
||||
myNodeInfo.has_wifi = true;
|
||||
#endif
|
||||
|
||||
resetRadioConfig(); // If bogus settings got saved, then fix them
|
||||
|
||||
DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", radioConfig.preferences.region, myNodeInfo.my_node_num, *numNodes);
|
||||
DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numNodes);
|
||||
}
|
||||
|
||||
// We reserve a few nodenums for future use
|
||||
@@ -279,18 +291,19 @@ void NodeDB::pickNewNodeNum()
|
||||
}
|
||||
|
||||
static const char *preffile = "/prefs/db.proto";
|
||||
static const char *radiofile = "/prefs/radio.proto";
|
||||
static const char *configfile = "/prefs/config.proto";
|
||||
static const char *moduleConfigfile = "/prefs/module.proto";
|
||||
static const char *channelfile = "/prefs/channels.proto";
|
||||
|
||||
/** Load a protobuf from a file, return true for success */
|
||||
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||
{
|
||||
bool okay = false;
|
||||
#ifdef FSCom
|
||||
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
||||
|
||||
auto f = FSCom.open(filename);
|
||||
|
||||
bool okay = false;
|
||||
if (f) {
|
||||
DEBUG_MSG("Loading %s\n", filename);
|
||||
pb_istream_t stream = {&readcb, &f, protoSize};
|
||||
@@ -323,29 +336,66 @@ void NodeDB::loadFromDisk()
|
||||
if (devicestate.version < DEVICESTATE_MIN_VER) {
|
||||
DEBUG_MSG("Warn: devicestate %d is old, discarding\n", devicestate.version);
|
||||
installDefaultDeviceState();
|
||||
#ifndef NO_ESP32
|
||||
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
|
||||
nvs_flash_erase();
|
||||
#endif
|
||||
#ifdef NRF52_SERIES
|
||||
Bluefruit.begin();
|
||||
DEBUG_MSG("Clearing bluetooth bonds!\n");
|
||||
bond_print_list(BLE_GAP_ROLE_PERIPH);
|
||||
bond_print_list(BLE_GAP_ROLE_CENTRAL);
|
||||
Bluefruit.Periph.clearBonds();
|
||||
Bluefruit.Central.clearBonds();
|
||||
#endif
|
||||
} else {
|
||||
DEBUG_MSG("Loaded saved preferences version %d\n", devicestate.version);
|
||||
DEBUG_MSG("Loaded saved devicestate version %d\n", devicestate.version);
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig)) {
|
||||
installDefaultRadioConfig(); // Our in RAM copy might now be corrupt
|
||||
if (!loadProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config)) {
|
||||
installDefaultConfig(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (config.version < DEVICESTATE_MIN_VER) {
|
||||
DEBUG_MSG("Warn: config %d is old, discarding\n", config.version);
|
||||
installDefaultConfig();
|
||||
} else {
|
||||
DEBUG_MSG("Loaded saved config version %d\n", config.version);
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadProto(moduleConfigfile, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig)) {
|
||||
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
|
||||
DEBUG_MSG("Warn: moduleConfig %d is old, discarding\n", moduleConfig.version);
|
||||
installDefaultModuleConfig();
|
||||
} else {
|
||||
DEBUG_MSG("Loaded saved moduleConfig version %d\n", moduleConfig.version);
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadProto(channelfile, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile)) {
|
||||
installDefaultChannels(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (channelFile.version < DEVICESTATE_MIN_VER) {
|
||||
DEBUG_MSG("Warn: channelFile %d is old, discarding\n", channelFile.version);
|
||||
installDefaultChannels();
|
||||
} else {
|
||||
DEBUG_MSG("Loaded saved channelFile version %d\n", channelFile.version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Save a protobuf from a file, return true for success */
|
||||
bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct)
|
||||
{
|
||||
bool okay = false;
|
||||
#ifdef FSCom
|
||||
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
||||
String filenameTmp = filename;
|
||||
filenameTmp += ".tmp";
|
||||
auto f = FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
||||
bool okay = false;
|
||||
if (f) {
|
||||
DEBUG_MSG("Saving %s\n", filename);
|
||||
pb_ostream_t stream = {&writecb, &f, protoSize};
|
||||
@@ -359,7 +409,7 @@ bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_
|
||||
f.close();
|
||||
|
||||
// brief window of risk here ;-)
|
||||
if (!FSCom.remove(filename))
|
||||
if (FSCom.exists(filename) && !FSCom.remove(filename))
|
||||
DEBUG_MSG("Warning: Can't remove old pref file\n");
|
||||
if (!FSCom.rename(filenameTmp.c_str(), filename))
|
||||
DEBUG_MSG("Error: can't rename new pref file\n");
|
||||
@@ -389,7 +439,25 @@ void NodeDB::saveToDisk()
|
||||
FSCom.mkdir("/prefs");
|
||||
#endif
|
||||
saveProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate);
|
||||
saveProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig);
|
||||
|
||||
// save all config segments
|
||||
config.has_device = true;
|
||||
config.has_display = true;
|
||||
config.has_lora = true;
|
||||
config.has_position = true;
|
||||
config.has_power = true;
|
||||
config.has_wifi = true;
|
||||
saveProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config);
|
||||
|
||||
moduleConfig.has_canned_message = true;
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.has_range_test = true;
|
||||
moduleConfig.has_serial = true;
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.has_telemetry = true;
|
||||
saveProto(moduleConfigfile, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig);
|
||||
|
||||
saveChannelsToDisk();
|
||||
|
||||
} else {
|
||||
@@ -417,7 +485,7 @@ uint32_t sinceLastSeen(const NodeInfo *n)
|
||||
return delta;
|
||||
}
|
||||
|
||||
#define NUM_ONLINE_SECS (60 & 60 * 2) // 2 hrs to consider someone offline
|
||||
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
|
||||
|
||||
size_t NodeDB::getNumOnlineNodes()
|
||||
{
|
||||
@@ -444,12 +512,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
|
||||
if (src == RX_SRC_LOCAL) {
|
||||
// Local packet, fully authoritative
|
||||
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n",
|
||||
p.pos_timestamp, p.time, p.latitude_i, p.longitude_i, p.altitude);
|
||||
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.pos_timestamp, p.time, p.latitude_i,
|
||||
p.longitude_i, p.altitude);
|
||||
info->position = p;
|
||||
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp &&
|
||||
!p.location_source) {
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp && !p.location_source) {
|
||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||
// (stop-gap fix for issue #900)
|
||||
DEBUG_MSG("updatePosition SPECIAL time setting time=%u\n", p.time);
|
||||
@@ -461,8 +528,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
// recorded based on the packet rxTime
|
||||
//
|
||||
// FIXME perhaps handle RX_SRC_USER separately?
|
||||
DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n",
|
||||
nodeId, p.time, p.latitude_i, p.longitude_i);
|
||||
DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i);
|
||||
|
||||
// First, back up fields that we want to protect from overwrite
|
||||
uint32_t tmp_time = info->position.time;
|
||||
@@ -471,7 +537,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
info->position = p;
|
||||
|
||||
// Last, restore any fields that may have been overwritten
|
||||
if (! info->position.time)
|
||||
if (!info->position.time)
|
||||
info->position.time = tmp_time;
|
||||
}
|
||||
info->has_position = true;
|
||||
@@ -479,7 +545,6 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
notifyObservers(true); // Force an update whether or not our node counts have changed
|
||||
}
|
||||
|
||||
|
||||
/** Update telemetry info for this node based on received metrics
|
||||
* We only care about device telemetry here
|
||||
*/
|
||||
@@ -591,7 +656,7 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *f
|
||||
// Print error to screen and serial port
|
||||
String lcd = String("Critical error ") + code + "!\n";
|
||||
screen->print(lcd.c_str());
|
||||
if(filename)
|
||||
if (filename)
|
||||
DEBUG_MSG("NOTE! Recording critical error %d at %s:%lx\n", code, filename, address);
|
||||
else
|
||||
DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
extern DeviceState devicestate;
|
||||
extern ChannelFile channelFile;
|
||||
extern MyNodeInfo &myNodeInfo;
|
||||
extern RadioConfig radioConfig;
|
||||
extern LocalConfig config;
|
||||
extern LocalModuleConfig moduleConfig;
|
||||
extern User &owner;
|
||||
|
||||
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||
@@ -63,7 +64,7 @@ class NodeDB
|
||||
|
||||
/** Update telemetry info for this node based on received metrics
|
||||
*/
|
||||
void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO);
|
||||
void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO);
|
||||
|
||||
/** Update user info for this node based on received user data
|
||||
*/
|
||||
@@ -122,7 +123,8 @@ class NodeDB
|
||||
void loadFromDisk();
|
||||
|
||||
/// Reinit device state from scratch (not loading from disk)
|
||||
void installDefaultDeviceState(), installDefaultRadioConfig(), installDefaultChannels();
|
||||
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(),
|
||||
installDefaultModuleConfig();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -136,7 +138,7 @@ extern NodeDB nodeDB;
|
||||
/*
|
||||
If is_router is set, we use a number of different default values
|
||||
|
||||
# FIXME - after tuning, move these params into the on-device defaults based on is_router and is_low_power
|
||||
# FIXME - after tuning, move these params into the on-device defaults based on is_router and is_power_saving
|
||||
|
||||
# prefs.position_broadcast_secs = FIXME possibly broadcast only once an hr
|
||||
prefs.wait_bluetooth_secs = 1 # Don't stay in bluetooth mode
|
||||
@@ -146,11 +148,11 @@ extern NodeDB nodeDB;
|
||||
prefs.ls_secs = oneday
|
||||
|
||||
prefs.position_broadcast_secs = 12 hours # send either position or owner every 12hrs
|
||||
|
||||
|
||||
# get a new GPS position once per day
|
||||
prefs.gps_update_interval = oneday
|
||||
|
||||
prefs.is_low_power = True
|
||||
prefs.is_power_saving = True
|
||||
|
||||
# allow up to five minutes for each new GPS lock attempt
|
||||
prefs.gps_attempt_time = 300
|
||||
@@ -159,33 +161,26 @@ extern NodeDB nodeDB;
|
||||
// Our delay functions check for this for times that should never expire
|
||||
#define NODE_DELAY_FOREVER 0xffffffff
|
||||
|
||||
#define IF_ROUTER(routerVal, normalVal) ((radioConfig.preferences.role == Role_Router) ? (routerVal) : (normalVal))
|
||||
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_Router) ? (routerVal) : (normalVal))
|
||||
|
||||
#define PREF_GET(name, defaultVal) \
|
||||
inline uint32_t getPref_##name() { return radioConfig.preferences.name ? radioConfig.preferences.name : (defaultVal); }
|
||||
|
||||
PREF_GET(position_broadcast_secs, IF_ROUTER(12 * 60 * 60, 15 * 60))
|
||||
// Defaulting Telemetry to the same as position interval for now
|
||||
PREF_GET(telemetry_module_device_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60))
|
||||
PREF_GET(telemetry_module_environment_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60))
|
||||
#define default_broadcast_interval_secs IF_ROUTER(12 * 60 * 60, 15 * 60)
|
||||
#define default_wait_bluetooth_secs IF_ROUTER(1, 60)
|
||||
#define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60)
|
||||
#define default_sds_secs 365 * 24 * 60 * 60
|
||||
#define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60)
|
||||
#define default_min_wake_secs 10
|
||||
|
||||
|
||||
// Each time we wake into the DARK state allow 1 minute to send and receive BLE packets to the phone
|
||||
PREF_GET(wait_bluetooth_secs, IF_ROUTER(1, 60))
|
||||
inline uint32_t getIntervalOrDefaultMs(uint32_t interval)
|
||||
{
|
||||
if (interval > 0)
|
||||
return interval * 1000;
|
||||
return default_broadcast_interval_secs * 1000;
|
||||
}
|
||||
|
||||
PREF_GET(screen_on_secs, 60)
|
||||
PREF_GET(mesh_sds_timeout_secs, IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60))
|
||||
PREF_GET(sds_secs, 365 * 24 * 60 * 60)
|
||||
|
||||
// We default to sleeping (with bluetooth off for 5 minutes at a time). This seems to be a good tradeoff between
|
||||
// latency for the user sending messages and power savings because of not having to run (expensive) ESP32 bluetooth
|
||||
PREF_GET(ls_secs, IF_ROUTER(24 * 60 * 60, 5 * 60))
|
||||
|
||||
PREF_GET(phone_timeout_secs, 15 * 60)
|
||||
PREF_GET(min_wake_secs, 10)
|
||||
|
||||
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
|
||||
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
|
||||
* might have changed is incremented. Allows others to detect they might now be on a new channel.
|
||||
*/
|
||||
extern uint32_t radioGeneration;
|
||||
|
||||
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
@@ -112,7 +112,8 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
||||
*
|
||||
* Our sending states progress in the following sequence (the client app ASSUMES THIS SEQUENCE, DO NOT CHANGE IT):
|
||||
* STATE_SEND_MY_INFO, // send our my info record
|
||||
STATE_SEND_RADIO,
|
||||
* STATE_SEND_GROUPS
|
||||
STATE_SEND_CONFIG,
|
||||
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
|
||||
STATE_SEND_COMPLETE_ID,
|
||||
STATE_SEND_PACKETS // send packets or debug strings
|
||||
@@ -140,11 +141,89 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_my_info_tag;
|
||||
fromRadioScratch.my_info = myNodeInfo;
|
||||
state = STATE_SEND_NODEINFO;
|
||||
state = STATE_SEND_CONFIG;
|
||||
|
||||
service.refreshMyNodeInfo(); // Update my NodeInfo because the client will be asking for it soon.
|
||||
break;
|
||||
|
||||
case STATE_SEND_CONFIG:
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_config_tag;
|
||||
switch (config_state) {
|
||||
case Config_device_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_device_tag;
|
||||
fromRadioScratch.config.payloadVariant.device = config.device;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_position_tag;
|
||||
fromRadioScratch.config.payloadVariant.position = config.position;
|
||||
break;
|
||||
case Config_power_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_power_tag;
|
||||
fromRadioScratch.config.payloadVariant.power = config.power;
|
||||
fromRadioScratch.config.payloadVariant.power.ls_secs = default_ls_secs;
|
||||
break;
|
||||
case Config_wifi_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_wifi_tag;
|
||||
fromRadioScratch.config.payloadVariant.wifi = config.wifi;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_display_tag;
|
||||
fromRadioScratch.config.payloadVariant.display = config.display;
|
||||
break;
|
||||
case Config_lora_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_lora_tag;
|
||||
fromRadioScratch.config.payloadVariant.lora = config.lora;
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
||||
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
|
||||
// using to the app (so that even old phone apps work with new device loads).
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our config objects
|
||||
if (config_state > Config_lora_tag) {
|
||||
state = STATE_SEND_MODULECONFIG;
|
||||
config_state = ModuleConfig_mqtt_tag;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_moduleConfig_tag;
|
||||
switch (config_state) {
|
||||
case ModuleConfig_mqtt_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_mqtt_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.mqtt = moduleConfig.mqtt;
|
||||
break;
|
||||
case ModuleConfig_serial_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_serial_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.serial = moduleConfig.serial;
|
||||
break;
|
||||
case ModuleConfig_external_notification_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_external_notification_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.external_notification = moduleConfig.external_notification;
|
||||
break;
|
||||
case ModuleConfig_range_test_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_range_test_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.range_test = moduleConfig.range_test;
|
||||
break;
|
||||
case ModuleConfig_telemetry_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_telemetry_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.telemetry = moduleConfig.telemetry;
|
||||
break;
|
||||
case ModuleConfig_canned_message_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_canned_message_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
}
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our ModuleConfig objects
|
||||
if (config_state > ModuleConfig_canned_message_tag) {
|
||||
state = STATE_SEND_NODEINFO;
|
||||
config_state = Config_device_tag;
|
||||
}
|
||||
break;
|
||||
case STATE_SEND_NODEINFO: {
|
||||
const NodeInfo *info = nodeInfoForPhone;
|
||||
nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
|
||||
@@ -220,6 +299,12 @@ bool PhoneAPI::available()
|
||||
|
||||
case STATE_SEND_MY_INFO:
|
||||
return true;
|
||||
|
||||
case STATE_SEND_CONFIG:
|
||||
return true;
|
||||
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
return true;
|
||||
|
||||
case STATE_SEND_NODEINFO:
|
||||
if (!nodeInfoForPhone)
|
||||
@@ -269,4 +354,4 @@ int PhoneAPI::onNotify(uint32_t newValue)
|
||||
DEBUG_MSG("(Client not yet interested in packets)\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,11 @@ class PhoneAPI
|
||||
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
||||
{
|
||||
enum State {
|
||||
STATE_UNUSED, // (no longer used) old default state - until Android apps are all updated, uses the old BLE API
|
||||
STATE_SEND_NOTHING, // (Eventual) Initial state, don't send anything until the client starts asking for config
|
||||
// (disconnected)
|
||||
STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config
|
||||
STATE_SEND_MY_INFO, // send our my info record
|
||||
STATE_SEND_GROUPS,
|
||||
// STATE_SEND_RADIO, // in 1.2 we now send this as a regular mesh packet
|
||||
// STATE_SEND_OWNER, no need to send Owner specially, it is just part of the nodedb
|
||||
STATE_SEND_GROUPS, // new in 1.3?
|
||||
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
|
||||
STATE_SEND_MODULECONFIG, // Send Module specific config
|
||||
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
|
||||
STATE_SEND_COMPLETE_ID,
|
||||
STATE_SEND_PACKETS // send packets or debug strings
|
||||
@@ -34,6 +32,8 @@ class PhoneAPI
|
||||
|
||||
State state = STATE_SEND_NOTHING;
|
||||
|
||||
int8_t config_state = Config_device_tag;
|
||||
|
||||
/**
|
||||
* Each packet sent to the phone has an incrementing count
|
||||
*/
|
||||
|
||||
@@ -77,10 +77,13 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
T *decoded = NULL;
|
||||
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch))
|
||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
|
||||
decoded = &scratch;
|
||||
else
|
||||
} else {
|
||||
DEBUG_MSG("Error decoding protobuf module!\n");
|
||||
// if we can't decode it, nobody can process it!
|
||||
return ProcessMessage::STOP;
|
||||
}
|
||||
}
|
||||
|
||||
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;
|
||||
|
||||
@@ -70,19 +70,23 @@ bool RF95Interface::init()
|
||||
int res = lora->begin(getFreq(), bw, sf, cr, syncWord, power, currentLimit, preambleLength);
|
||||
DEBUG_MSG("RF95 init result %d\n", res);
|
||||
|
||||
DEBUG_MSG("Frequency set to %f\n", getFreq());
|
||||
DEBUG_MSG("Bandwidth set to %f\n", bw);
|
||||
DEBUG_MSG("Power output set to %d\n", power);
|
||||
|
||||
// current limit was removed from module' ctor
|
||||
// override default value (60 mA)
|
||||
res = lora->setCurrentLimit(currentLimit);
|
||||
DEBUG_MSG("Current limit set to %f\n", currentLimit);
|
||||
DEBUG_MSG("Current limit set result %d\n", res);
|
||||
|
||||
if (res == ERR_NONE)
|
||||
res = lora->setCRC(SX126X_LORA_CRC_ON);
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
|
||||
|
||||
if (res == ERR_NONE)
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
startReceive(); // start receiving
|
||||
|
||||
return res == ERR_NONE;
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
void INTERRUPT_ATTR RF95Interface::disableInterrupt()
|
||||
@@ -99,39 +103,39 @@ bool RF95Interface::reconfigure()
|
||||
|
||||
// configure publicly accessible settings
|
||||
int err = lora->setSpreadingFactor(sf);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
err = lora->setBandwidth(bw);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
err = lora->setCodingRate(cr);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
err = lora->setSyncWord(syncWord);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora->setCurrentLimit(currentLimit);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora->setPreambleLength(preambleLength);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora->setFrequency(getFreq());
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
if (power > MAX_POWER) // This chip has lower power limits than some
|
||||
power = MAX_POWER;
|
||||
err = lora->setOutputPower(power);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
startReceive(); // restart receiving
|
||||
|
||||
return ERR_NONE;
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,7 +151,7 @@ void RF95Interface::addReceiveMetadata(MeshPacket *mp)
|
||||
void RF95Interface::setStandby()
|
||||
{
|
||||
int err = lora->standby();
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = false; // If we were receiving, not any more
|
||||
disableInterrupt();
|
||||
@@ -168,7 +172,7 @@ void RF95Interface::startReceive()
|
||||
setTransmitEnable(false);
|
||||
setStandby();
|
||||
int err = lora->startReceive();
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = true;
|
||||
|
||||
@@ -184,12 +188,11 @@ bool RF95Interface::isChannelActive()
|
||||
setStandby(); // needed for smooth transition
|
||||
result = lora->scanChannel();
|
||||
|
||||
if (result == PREAMBLE_DETECTED) {
|
||||
if (result == RADIOLIB_PREAMBLE_DETECTED) {
|
||||
// DEBUG_MSG("Channel is busy!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(result != ERR_WRONG_MODEM);
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
// DEBUG_MSG("Channel is free!\n");
|
||||
return false;
|
||||
|
||||
@@ -13,8 +13,9 @@ class RF95Interface : public RadioLibInterface
|
||||
|
||||
public:
|
||||
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
|
||||
|
||||
bool isIRQPending() override { return lora->getPendingIRQ(); }
|
||||
|
||||
//TODO: Verify that this irq flag works with RFM95 / SX1276 radios the way it used to
|
||||
bool isIRQPending() override { return lora->getIRQFlags() & RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER; }
|
||||
|
||||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching) \
|
||||
{ \
|
||||
RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, #name \
|
||||
Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \
|
||||
frequency_switching, #name \
|
||||
}
|
||||
|
||||
const RegionInfo regions[] = {
|
||||
@@ -76,15 +77,15 @@ const RegionInfo regions[] = {
|
||||
*/
|
||||
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false),
|
||||
|
||||
/*
|
||||
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
|
||||
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
|
||||
*/
|
||||
/*
|
||||
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
|
||||
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
|
||||
*/
|
||||
RDEF(NZ865, 864.0f, 868.0f, 100, 0, 0, true, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false),
|
||||
|
||||
/*
|
||||
@@ -99,10 +100,10 @@ const RegionInfo *myRegion;
|
||||
void initRegion()
|
||||
{
|
||||
const RegionInfo *r = regions;
|
||||
for (; r->code != RegionCode_Unset && r->code != radioConfig.preferences.region; r++)
|
||||
for (; r->code != Config_LoRaConfig_RegionCode_Unset && r->code != config.lora.region; r++)
|
||||
;
|
||||
myRegion = r;
|
||||
DEBUG_MSG("Wanted region %d, using %s\n", radioConfig.preferences.region, r->name);
|
||||
DEBUG_MSG("Wanted region %d, using %s\n", config.lora.region, r->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,59 +159,53 @@ uint32_t RadioInterface::getPacketTime(MeshPacket *p)
|
||||
/** The delay to use for retransmitting dropped packets */
|
||||
uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p)
|
||||
{
|
||||
assert(shortPacketMsec); // Better be non zero
|
||||
|
||||
// was 20 and 22 secs respectively, but now with shortPacketMsec as 2269, this should give the same range
|
||||
return random(9 * shortPacketMsec, 10 * shortPacketMsec);
|
||||
assert(slotTimeMsec); // Better be non zero
|
||||
static uint8_t bytes[MAX_RHPACKETLEN];
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
|
||||
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
|
||||
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
|
||||
// DEBUG_MSG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
|
||||
float channelUtil = airTime->channelUtilizationPercent();
|
||||
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
|
||||
// Assuming we pick max. of CWsize and there will be a receiver with SNR at half the range
|
||||
return 2*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC;
|
||||
}
|
||||
|
||||
/** The delay to use when we want to send something but the ether is busy */
|
||||
/** The delay to use when we want to send something */
|
||||
uint32_t RadioInterface::getTxDelayMsec()
|
||||
{
|
||||
/** At the low end we want to pick a delay large enough that anyone who just completed sending (some other node)
|
||||
* has had enough time to switch their radio back into receive mode.
|
||||
*/
|
||||
const uint32_t MIN_TX_WAIT_MSEC = 100;
|
||||
|
||||
/**
|
||||
* At the high end, this value is used to spread node attempts across time so when they are replying to a packet
|
||||
* they don't both check that the airwaves are clear at the same moment. As long as they are off by some amount
|
||||
* one of the two will be first to start transmitting and the other will see that. I bet 500ms is more than enough
|
||||
* to guarantee this.
|
||||
*/
|
||||
// const uint32_t MAX_TX_WAIT_MSEC = 2000; // stress test would still fail occasionally with 1000
|
||||
|
||||
return random((MIN_TX_WAIT_MSEC), (MIN_TX_WAIT_MSEC + shortPacketMsec));
|
||||
/** We wait a random multiple of 'slotTimes' (see definition in header file) in order to avoid collisions.
|
||||
The pool to take a random multiple from is the contention window (CW), which size depends on the
|
||||
current channel utilization. */
|
||||
float channelUtil = airTime->channelUtilizationPercent();
|
||||
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
|
||||
// DEBUG_MSG("Current channel utilization is %f so setting CWsize to %d\n", channelUtil, CWsize);
|
||||
return random(0, pow(2, CWsize)) * slotTimeMsec;
|
||||
}
|
||||
|
||||
|
||||
/** The delay to use when we want to send something but the ether is busy */
|
||||
/** The delay to use when we want to flood a message */
|
||||
uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
||||
{
|
||||
/** At the low end we want to pick a delay large enough that anyone who just completed sending (some other node)
|
||||
* has had enough time to switch their radio back into receive mode.
|
||||
*/
|
||||
const uint32_t MIN_TX_WAIT_MSEC = 100;
|
||||
|
||||
// The minimum value for a LoRa SNR
|
||||
const uint32_t SNR_MIN = -20;
|
||||
|
||||
// The maximum value for a LoRa SNR
|
||||
const uint32_t SNR_MAX = 15;
|
||||
|
||||
// high SNR = Long Delay
|
||||
// low SNR = Short Delay
|
||||
// high SNR = large CW size (Long Delay)
|
||||
// low SNR = small CW size (Short Delay)
|
||||
uint32_t delay = 0;
|
||||
|
||||
if (radioConfig.preferences.role == Role_Router || radioConfig.preferences.role == Role_RouterClient) {
|
||||
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC, (MIN_TX_WAIT_MSEC + (shortPacketMsec / 2)));
|
||||
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
|
||||
// DEBUG_MSG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
|
||||
if (config.device.role == Config_DeviceConfig_Role_Router ||
|
||||
config.device.role == Config_DeviceConfig_Role_RouterClient) {
|
||||
delay = random(0, 2*CWsize) * slotTimeMsec;
|
||||
DEBUG_MSG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
|
||||
} else {
|
||||
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC + (shortPacketMsec / 2), (MIN_TX_WAIT_MSEC + shortPacketMsec * 2));
|
||||
delay = random(0, pow(2, CWsize)) * slotTimeMsec;
|
||||
DEBUG_MSG("rx_snr found in packet. Setting tx delay:%d\n", delay);
|
||||
}
|
||||
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
@@ -251,7 +246,7 @@ void printPacket(const char *prefix, const MeshPacket *p)
|
||||
DEBUG_MSG(" rxSNR=%g", p->rx_snr);
|
||||
}
|
||||
if (p->rx_rssi != 0) {
|
||||
DEBUG_MSG(" rxSNR=%g", p->rx_rssi);
|
||||
DEBUG_MSG(" rxRSSI=%g", p->rx_rssi);
|
||||
}
|
||||
if (p->priority != 0)
|
||||
DEBUG_MSG(" priority=%d", p->priority);
|
||||
@@ -351,41 +346,41 @@ void RadioInterface::applyModemConfig()
|
||||
{
|
||||
// Set up default configuration
|
||||
// No Sync Words in LORA mode
|
||||
|
||||
Config_LoRaConfig &loraConfig = config.lora;
|
||||
auto channelSettings = channels.getPrimary();
|
||||
if (channelSettings.spread_factor == 0) {
|
||||
switch (channelSettings.modem_config) {
|
||||
case ChannelSettings_ModemConfig_ShortFast:
|
||||
if (loraConfig.spread_factor == 0) {
|
||||
switch (loraConfig.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_ShortFast:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 7;
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_ShortSlow:
|
||||
case Config_LoRaConfig_ModemPreset_ShortSlow:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 8;
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_MidFast:
|
||||
case Config_LoRaConfig_ModemPreset_MedFast:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 9;
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_MidSlow:
|
||||
case Config_LoRaConfig_ModemPreset_MedSlow:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 10;
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_LongFast:
|
||||
case Config_LoRaConfig_ModemPreset_LongFast:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_LongSlow:
|
||||
case Config_LoRaConfig_ModemPreset_LongSlow:
|
||||
bw = 125;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
case ChannelSettings_ModemConfig_VLongSlow:
|
||||
case Config_LoRaConfig_ModemPreset_VLongSlow:
|
||||
bw = 31.25;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
@@ -394,9 +389,9 @@ void RadioInterface::applyModemConfig()
|
||||
assert(0); // Unknown enum
|
||||
}
|
||||
} else {
|
||||
sf = channelSettings.spread_factor;
|
||||
cr = channelSettings.coding_rate;
|
||||
bw = channelSettings.bandwidth;
|
||||
sf = loraConfig.spread_factor;
|
||||
cr = loraConfig.coding_rate;
|
||||
bw = loraConfig.bandwidth;
|
||||
|
||||
if (bw == 31) // This parameter is not an integer
|
||||
bw = 31.25;
|
||||
@@ -404,10 +399,15 @@ void RadioInterface::applyModemConfig()
|
||||
bw = 62.5;
|
||||
}
|
||||
|
||||
power = channelSettings.tx_power;
|
||||
shortPacketMsec = getPacketTime(sizeof(PacketHeader));
|
||||
power = loraConfig.tx_power;
|
||||
assert(myRegion); // Should have been found in init
|
||||
|
||||
if ((power == 0) || (power > myRegion->powerLimit))
|
||||
power = myRegion->powerLimit;
|
||||
|
||||
if (power == 0)
|
||||
power = 17; // Default to default power if we don't have a valid power
|
||||
|
||||
// Calculate the number of channels
|
||||
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000)));
|
||||
|
||||
@@ -419,13 +419,13 @@ void RadioInterface::applyModemConfig()
|
||||
saveChannelNum(channel_num);
|
||||
saveFreq(freq);
|
||||
|
||||
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power);
|
||||
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, loraConfig.modem_preset, channel_num, power);
|
||||
DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
|
||||
myRegion->freqEnd - myRegion->freqStart);
|
||||
DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels);
|
||||
DEBUG_MSG("Radio channel_num: %d\n", channel_num);
|
||||
DEBUG_MSG("Radio frequency: %f\n", getFreq());
|
||||
DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec);
|
||||
DEBUG_MSG("Slot time: %u msec\n", slotTimeMsec);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,8 +52,6 @@ class RadioInterface
|
||||
CallbackObserver<RadioInterface, void *> notifyDeepSleepObserver =
|
||||
CallbackObserver<RadioInterface, void *>(this, &RadioInterface::notifyDeepSleepCb);
|
||||
|
||||
/// Number of msecs we expect our shortest actual packet to be over the wire (used in retry timeout calcs)
|
||||
uint32_t shortPacketMsec;
|
||||
|
||||
protected:
|
||||
bool disabled = false;
|
||||
@@ -61,8 +59,16 @@ class RadioInterface
|
||||
float bw = 125;
|
||||
uint8_t sf = 9;
|
||||
uint8_t cr = 7;
|
||||
|
||||
/** Slottime is the minimum time to wait, consisting of:
|
||||
- CAD duration (maximum of SX126x and SX127x);
|
||||
- roundtrip air propagation time (assuming max. 30km between nodes);
|
||||
- Tx/Rx turnaround time (maximum of SX126x and SX127x);
|
||||
- MAC processing time (measured on T-beam) */
|
||||
uint32_t slotTimeMsec = 8.5 * pow(2, sf)/bw + 0.2 + 0.4 + 7;
|
||||
uint16_t preambleLength = 32; // 8 is default, but we use longer to increase the amount of sleep time when receiving
|
||||
const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined)
|
||||
const uint8_t CWmin = 2; // minimum CWsize
|
||||
const uint8_t CWmax = 8; // maximum CWsize
|
||||
|
||||
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
|
||||
uint32_t lastTxStart = 0L;
|
||||
@@ -126,10 +132,10 @@ class RadioInterface
|
||||
/** The delay to use for retransmitting dropped packets */
|
||||
uint32_t getRetransmissionMsec(const MeshPacket *p);
|
||||
|
||||
/** The delay to use when we want to send something but the ether is busy */
|
||||
/** The delay to use when we want to send something */
|
||||
uint32_t getTxDelayMsec();
|
||||
|
||||
/** The delay to use when we want to send something but the ether is busy. Use a weighted scale based on SNR */
|
||||
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
|
||||
uint32_t getTxDelayMsecWeighted(float snr);
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
|
||||
static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
||||
|
||||
#ifdef PORTDUINO
|
||||
|
||||
void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes)
|
||||
{
|
||||
concurrency::LockGuard g(spiLock);
|
||||
@@ -18,6 +20,24 @@ void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint
|
||||
Module::SPItransfer(cmd, reg, dataOut, dataIn, numBytes);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void LockingModule::SPIbeginTransaction()
|
||||
{
|
||||
spiLock->lock();
|
||||
|
||||
Module::SPIbeginTransaction();
|
||||
}
|
||||
|
||||
void LockingModule::SPIendTransaction()
|
||||
{
|
||||
spiLock->unlock();
|
||||
|
||||
Module::SPIendTransaction();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi, PhysicalLayer *_iface)
|
||||
: NotifiedWorkerThread("RadioIf"), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
|
||||
@@ -93,278 +113,291 @@ bool RadioLibInterface::canSendImmediately()
|
||||
/// bluetooth comms code. If the txmit queue is empty it might return an error
|
||||
ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
{
|
||||
if (radioConfig.preferences.region != RegionCode_Unset) {
|
||||
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
|
||||
DEBUG_MSG("send - lora_tx_disabled\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("send - lora_tx_disabled because RegionCode_Unset\n");
|
||||
#ifndef DISABLE_WELCOME_UNSET
|
||||
|
||||
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
|
||||
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
DEBUG_MSG("send - lora_tx_disabled\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("send - lora_tx_disabled because RegionCode_Unset\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
DEBUG_MSG("send - lora_tx_disabled\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
|
||||
// Sometimes when testing it is useful to be able to never turn on the xmitter
|
||||
#endif
|
||||
|
||||
// Sometimes when testing it is useful to be able to never turn on the xmitter
|
||||
#ifndef LORA_DISABLE_SENDING
|
||||
printPacket("enqueuing for send", p);
|
||||
printPacket("enqueuing for send", p);
|
||||
|
||||
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
|
||||
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
|
||||
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
|
||||
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
|
||||
|
||||
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
|
||||
packetPool.release(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
// set (random) transmit delay to let others reconfigure their radio,
|
||||
// to avoid collisions and implement timing-based flooding
|
||||
// DEBUG_MSG("Set random delay before transmitting.\n");
|
||||
setTransmitDelay();
|
||||
|
||||
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
|
||||
packetPool.release(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
// set (random) transmit delay to let others reconfigure their radio,
|
||||
// to avoid collisions and implement timing-based flooding
|
||||
// DEBUG_MSG("Set random delay before transmitting.\n");
|
||||
setTransmitDelay();
|
||||
|
||||
return res;
|
||||
#else
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool RadioLibInterface::canSleep()
|
||||
{
|
||||
bool res = txQueue.empty();
|
||||
if (!res) // only print debug messages if we are vetoing sleep
|
||||
DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", res);
|
||||
bool RadioLibInterface::canSleep()
|
||||
{
|
||||
bool res = txQueue.empty();
|
||||
if (!res) // only print debug messages if we are vetoing sleep
|
||||
DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", res);
|
||||
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
|
||||
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
|
||||
{
|
||||
auto p = txQueue.remove(from, id);
|
||||
if (p)
|
||||
packetPool.release(p); // free the packet we just removed
|
||||
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
|
||||
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
|
||||
{
|
||||
auto p = txQueue.remove(from, id);
|
||||
if (p)
|
||||
packetPool.release(p); // free the packet we just removed
|
||||
|
||||
bool result = (p != NULL);
|
||||
DEBUG_MSG("cancelSending id=0x%x, removed=%d\n", id, result);
|
||||
return result;
|
||||
}
|
||||
bool result = (p != NULL);
|
||||
DEBUG_MSG("cancelSending id=0x%x, removed=%d\n", id, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** radio helper thread callback.
|
||||
/** radio helper thread callback.
|
||||
We never immediately transmit after any operation (either Rx or Tx). Instead we should wait a random multiple of
|
||||
'slotTimes' (see definition in RadioInterface.h) taken from a contention window (CW) to lower the chance of collision.
|
||||
The CW size is determined by setTransmitDelay() and depends either on the current channel utilization or SNR in case
|
||||
of a flooding message. After this, we perform channel activity detection (CAD) and reset the transmit delay if it is
|
||||
currently active.
|
||||
*/
|
||||
void RadioLibInterface::onNotify(uint32_t notification)
|
||||
{
|
||||
switch (notification) {
|
||||
case ISR_TX:
|
||||
handleTransmitInterrupt();
|
||||
startReceive();
|
||||
// DEBUG_MSG("tx complete - starting timer\n");
|
||||
startTransmitTimer();
|
||||
break;
|
||||
case ISR_RX:
|
||||
handleReceiveInterrupt();
|
||||
startReceive();
|
||||
// DEBUG_MSG("rx complete - starting timer\n");
|
||||
startTransmitTimer();
|
||||
break;
|
||||
case TRANSMIT_DELAY_COMPLETED:
|
||||
// DEBUG_MSG("delay done\n");
|
||||
|
||||
We never immediately transmit after any operation (either rx or tx). Instead we should start receiving and
|
||||
wait a random delay of 100ms to 100ms+shortPacketMsec to make sure we are not stomping on someone else. The 100ms delay at the beginning ensures all
|
||||
possible listeners have had time to finish processing the previous packet and now have their radio in RX state. The up to 100ms+shortPacketMsec
|
||||
random delay gives a chance for all possible senders to have high odds of detecting that someone else started transmitting first
|
||||
and then they will wait until that packet finishes.
|
||||
|
||||
NOTE: the large flood rebroadcast delay might still be needed even with this approach. Because we might not be able to hear other
|
||||
transmitters that we are potentially stomping on. Requires further thought.
|
||||
|
||||
FIXME, the MIN_TX_WAIT_MSEC and MAX_TX_WAIT_MSEC values should be tuned via logic analyzer later.
|
||||
*/
|
||||
void RadioLibInterface::onNotify(uint32_t notification)
|
||||
{
|
||||
switch (notification) {
|
||||
case ISR_TX:
|
||||
handleTransmitInterrupt();
|
||||
startReceive();
|
||||
// DEBUG_MSG("tx complete - starting timer\n");
|
||||
startTransmitTimer();
|
||||
break;
|
||||
case ISR_RX:
|
||||
handleReceiveInterrupt();
|
||||
startReceive();
|
||||
// DEBUG_MSG("rx complete - starting timer\n");
|
||||
startTransmitTimer();
|
||||
break;
|
||||
case TRANSMIT_DELAY_COMPLETED:
|
||||
// DEBUG_MSG("delay done\n");
|
||||
|
||||
// If we are not currently in receive mode, then restart the random delay (this can happen if the main thread
|
||||
// has placed the unit into standby) FIXME, how will this work if the chipset is in sleep mode?
|
||||
if (!txQueue.empty()) {
|
||||
if (!canSendImmediately()) {
|
||||
// DEBUG_MSG("Currently Rx/Tx-ing: set random delay\n");
|
||||
setTransmitDelay(); // currently Rx/Tx-ing: reset random delay
|
||||
} else {
|
||||
if (isChannelActive()) { // check if there is currently a LoRa packet on the channel
|
||||
// DEBUG_MSG("Channel is active: set random delay\n");
|
||||
setTransmitDelay(); // reset random delay
|
||||
// If we are not currently in receive mode, then restart the random delay (this can happen if the main thread
|
||||
// has placed the unit into standby) FIXME, how will this work if the chipset is in sleep mode?
|
||||
if (!txQueue.empty()) {
|
||||
if (!canSendImmediately()) {
|
||||
// DEBUG_MSG("Currently Rx/Tx-ing: set random delay\n");
|
||||
setTransmitDelay(); // currently Rx/Tx-ing: reset random delay
|
||||
} else {
|
||||
// Send any outgoing packets we have ready
|
||||
MeshPacket *txp = txQueue.dequeue();
|
||||
assert(txp);
|
||||
startSend(txp);
|
||||
if (isChannelActive()) { // check if there is currently a LoRa packet on the channel
|
||||
// DEBUG_MSG("Channel is active: set random delay\n");
|
||||
setTransmitDelay(); // reset random delay
|
||||
} else {
|
||||
// Send any outgoing packets we have ready
|
||||
MeshPacket *txp = txQueue.dequeue();
|
||||
assert(txp);
|
||||
startSend(txp);
|
||||
|
||||
// Packet has been sent, count it toward our TX airtime utilization.
|
||||
uint32_t xmitMsec = getPacketTime(txp);
|
||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||
// Packet has been sent, count it toward our TX airtime utilization.
|
||||
uint32_t xmitMsec = getPacketTime(txp);
|
||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// DEBUG_MSG("done with txqueue\n");
|
||||
}
|
||||
} else {
|
||||
// DEBUG_MSG("done with txqueue\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0); // We expected to receive a valid notification from the ISR
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::setTransmitDelay()
|
||||
{
|
||||
MeshPacket *p = txQueue.getFront();
|
||||
// We want all sending/receiving to be done by our daemon thread.
|
||||
// We use a delay here because this packet might have been sent in response to a packet we just received.
|
||||
// So we want to make sure the other side has had a chance to reconfigure its radio.
|
||||
|
||||
/* 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
|
||||
* floor.
|
||||
*/
|
||||
if (p->rx_snr == 0 && p->rx_rssi == 0) {
|
||||
startTransmitTimer(true);
|
||||
} else {
|
||||
// If there is a SNR, start a timer scaled based on that SNR.
|
||||
DEBUG_MSG("rx_snr found. hop_limit:%d rx_snr:%f\n", p->hop_limit, p->rx_snr);
|
||||
startTransmitTimerSNR(p->rx_snr);
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::startTransmitTimer(bool withDelay)
|
||||
{
|
||||
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
||||
if (!txQueue.empty()) {
|
||||
uint32_t delay = !withDelay ? 1 : getTxDelayMsec();
|
||||
// DEBUG_MSG("xmit timer %d\n", delay);
|
||||
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::startTransmitTimerSNR(float snr)
|
||||
{
|
||||
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
||||
if (!txQueue.empty()) {
|
||||
uint32_t delay = getTxDelayMsecWeighted(snr);
|
||||
// DEBUG_MSG("xmit timer %d\n", delay);
|
||||
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::handleTransmitInterrupt()
|
||||
{
|
||||
// DEBUG_MSG("handling lora TX interrupt\n");
|
||||
// This can be null if we forced the device to enter standby mode. In that case
|
||||
// ignore the transmit interrupt
|
||||
if (sendingPacket)
|
||||
completeSending();
|
||||
}
|
||||
|
||||
void RadioLibInterface::completeSending()
|
||||
{
|
||||
// We are careful to clear sending packet before calling printPacket because
|
||||
// that can take a long time
|
||||
auto p = sendingPacket;
|
||||
sendingPacket = NULL;
|
||||
|
||||
if (p) {
|
||||
txGood++;
|
||||
printPacket("Completed sending", p);
|
||||
|
||||
// We are done sending that packet, release it
|
||||
packetPool.release(p);
|
||||
// DEBUG_MSG("Done with send\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::handleReceiveInterrupt()
|
||||
{
|
||||
uint32_t xmitMsec;
|
||||
assert(isReceiving);
|
||||
isReceiving = false;
|
||||
|
||||
// read the number of actually received bytes
|
||||
size_t length = iface->getPacketLength();
|
||||
|
||||
xmitMsec = getPacketTime(length);
|
||||
|
||||
int state = iface->readData(radiobuf, length);
|
||||
if (state != ERR_NONE) {
|
||||
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
|
||||
rxBad++;
|
||||
|
||||
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
|
||||
|
||||
} else {
|
||||
// Skip the 4 headers that are at the beginning of the rxBuf
|
||||
int32_t payloadLen = length - sizeof(PacketHeader);
|
||||
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
|
||||
|
||||
// check for short packets
|
||||
if (payloadLen < 0) {
|
||||
DEBUG_MSG("ignoring received packet too short\n");
|
||||
rxBad++;
|
||||
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
|
||||
} else {
|
||||
const PacketHeader *h = (PacketHeader *)radiobuf;
|
||||
|
||||
rxGood++;
|
||||
|
||||
// Note: we deliver _all_ packets to our router (i.e. our interface is intentionally promiscuous).
|
||||
// This allows the router and other apps on our node to sniff packets (usually routing) between other
|
||||
// nodes.
|
||||
MeshPacket *mp = packetPool.allocZeroed();
|
||||
|
||||
mp->from = h->from;
|
||||
mp->to = h->to;
|
||||
mp->id = h->id;
|
||||
mp->channel = h->channel;
|
||||
assert(HOP_MAX <= PACKET_FLAGS_HOP_MASK); // If hopmax changes, carefully check this code
|
||||
mp->hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
|
||||
mp->want_ack = !!(h->flags & PACKET_FLAGS_WANT_ACK_MASK);
|
||||
|
||||
addReceiveMetadata(mp);
|
||||
|
||||
mp->which_payloadVariant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
|
||||
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
|
||||
memcpy(mp->encrypted.bytes, payload, payloadLen);
|
||||
mp->encrypted.size = payloadLen;
|
||||
|
||||
printPacket("Lora RX", mp);
|
||||
|
||||
// xmitMsec = getPacketTime(mp);
|
||||
airTime->logAirtime(RX_LOG, xmitMsec);
|
||||
|
||||
deliverToReceiver(mp);
|
||||
break;
|
||||
default:
|
||||
assert(0); // We expected to receive a valid notification from the ISR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** start an immediate transmit */
|
||||
void RadioLibInterface::startSend(MeshPacket *txp)
|
||||
{
|
||||
printPacket("Starting low level send", txp);
|
||||
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
|
||||
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
|
||||
packetPool.release(txp);
|
||||
} else {
|
||||
setStandby(); // Cancel any already in process receives
|
||||
void RadioLibInterface::setTransmitDelay()
|
||||
{
|
||||
MeshPacket *p = txQueue.getFront();
|
||||
// We want all sending/receiving to be done by our daemon thread.
|
||||
// We use a delay here because this packet might have been sent in response to a packet we just received.
|
||||
// So we want to make sure the other side has had a chance to reconfigure its radio.
|
||||
|
||||
configHardwareForSend(); // must be after setStandby
|
||||
/* 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
|
||||
* floor.
|
||||
*/
|
||||
if (p->rx_snr == 0 && p->rx_rssi == 0) {
|
||||
startTransmitTimer(true);
|
||||
} else {
|
||||
// If there is a SNR, start a timer scaled based on that SNR.
|
||||
DEBUG_MSG("rx_snr found. hop_limit:%d rx_snr:%f\n", p->hop_limit, p->rx_snr);
|
||||
startTransmitTimerSNR(p->rx_snr);
|
||||
}
|
||||
}
|
||||
|
||||
size_t numbytes = beginSending(txp);
|
||||
void RadioLibInterface::startTransmitTimer(bool withDelay)
|
||||
{
|
||||
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
||||
if (!txQueue.empty()) {
|
||||
uint32_t delay = !withDelay ? 1 : getTxDelayMsec();
|
||||
// DEBUG_MSG("xmit timer %d\n", delay);
|
||||
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
|
||||
}
|
||||
}
|
||||
|
||||
int res = iface->startTransmit(radiobuf, numbytes);
|
||||
if (res != ERR_NONE) {
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
|
||||
void RadioLibInterface::startTransmitTimerSNR(float snr)
|
||||
{
|
||||
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
||||
if (!txQueue.empty()) {
|
||||
uint32_t delay = getTxDelayMsecWeighted(snr);
|
||||
// DEBUG_MSG("xmit timer %d\n", delay);
|
||||
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
|
||||
}
|
||||
}
|
||||
|
||||
// This send failed, but make sure to 'complete' it properly
|
||||
void RadioLibInterface::handleTransmitInterrupt()
|
||||
{
|
||||
// DEBUG_MSG("handling lora TX interrupt\n");
|
||||
// This can be null if we forced the device to enter standby mode. In that case
|
||||
// ignore the transmit interrupt
|
||||
if (sendingPacket)
|
||||
completeSending();
|
||||
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
|
||||
}
|
||||
|
||||
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
|
||||
enableInterrupt(isrTxLevel0);
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::completeSending()
|
||||
{
|
||||
// We are careful to clear sending packet before calling printPacket because
|
||||
// that can take a long time
|
||||
auto p = sendingPacket;
|
||||
sendingPacket = NULL;
|
||||
|
||||
if (p) {
|
||||
txGood++;
|
||||
printPacket("Completed sending", p);
|
||||
|
||||
// We are done sending that packet, release it
|
||||
packetPool.release(p);
|
||||
// DEBUG_MSG("Done with send\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::handleReceiveInterrupt()
|
||||
{
|
||||
uint32_t xmitMsec;
|
||||
assert(isReceiving);
|
||||
isReceiving = false;
|
||||
|
||||
// read the number of actually received bytes
|
||||
size_t length = iface->getPacketLength();
|
||||
|
||||
xmitMsec = getPacketTime(length);
|
||||
|
||||
int state = iface->readData(radiobuf, length);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
|
||||
rxBad++;
|
||||
|
||||
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
|
||||
|
||||
} else {
|
||||
// Skip the 4 headers that are at the beginning of the rxBuf
|
||||
int32_t payloadLen = length - sizeof(PacketHeader);
|
||||
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
|
||||
|
||||
// check for short packets
|
||||
if (payloadLen < 0) {
|
||||
DEBUG_MSG("ignoring received packet too short\n");
|
||||
rxBad++;
|
||||
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
|
||||
} else {
|
||||
const PacketHeader *h = (PacketHeader *)radiobuf;
|
||||
|
||||
rxGood++;
|
||||
|
||||
// Note: we deliver _all_ packets to our router (i.e. our interface is intentionally promiscuous).
|
||||
// This allows the router and other apps on our node to sniff packets (usually routing) between other
|
||||
// nodes.
|
||||
MeshPacket *mp = packetPool.allocZeroed();
|
||||
|
||||
mp->from = h->from;
|
||||
mp->to = h->to;
|
||||
mp->id = h->id;
|
||||
mp->channel = h->channel;
|
||||
assert(HOP_MAX <= PACKET_FLAGS_HOP_MASK); // If hopmax changes, carefully check this code
|
||||
mp->hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
|
||||
mp->want_ack = !!(h->flags & PACKET_FLAGS_WANT_ACK_MASK);
|
||||
|
||||
addReceiveMetadata(mp);
|
||||
|
||||
mp->which_payloadVariant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
|
||||
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
|
||||
memcpy(mp->encrypted.bytes, payload, payloadLen);
|
||||
mp->encrypted.size = payloadLen;
|
||||
|
||||
printPacket("Lora RX", mp);
|
||||
|
||||
// xmitMsec = getPacketTime(mp);
|
||||
airTime->logAirtime(RX_LOG, xmitMsec);
|
||||
|
||||
deliverToReceiver(mp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** start an immediate transmit */
|
||||
void RadioLibInterface::startSend(MeshPacket * txp)
|
||||
{
|
||||
printPacket("Starting low level send", txp);
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
|
||||
packetPool.release(txp);
|
||||
} else {
|
||||
setStandby(); // Cancel any already in process receives
|
||||
|
||||
configHardwareForSend(); // must be after setStandby
|
||||
|
||||
size_t numbytes = beginSending(txp);
|
||||
|
||||
int res = iface->startTransmit(radiobuf, numbytes);
|
||||
if (res != RADIOLIB_ERR_NONE) {
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
|
||||
|
||||
// This send failed, but make sure to 'complete' it properly
|
||||
completeSending();
|
||||
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
|
||||
}
|
||||
|
||||
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register
|
||||
// bits
|
||||
enableInterrupt(isrTxLevel0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,21 +40,13 @@ class LockingModule : public Module
|
||||
: Module(cs, irq, rst, gpio, spi, spiSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI single transfer method.
|
||||
|
||||
\param cmd SPI access command (read/write/burst/...).
|
||||
|
||||
\param reg Address of SPI register to transfer to/from.
|
||||
|
||||
\param dataOut Data that will be transfered from master to slave.
|
||||
|
||||
\param dataIn Data that was transfered from slave to master.
|
||||
|
||||
\param numBytes Number of bytes to transfer.
|
||||
*/
|
||||
virtual void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
|
||||
|
||||
#ifdef PORTDUINO
|
||||
void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
|
||||
#else
|
||||
void SPIbeginTransaction() override;
|
||||
void SPIendTransaction() override;
|
||||
#endif
|
||||
};
|
||||
|
||||
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
|
||||
|
||||
@@ -15,7 +15,7 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
|
||||
{
|
||||
// execute common part
|
||||
int16_t state = SX127x::begin(RF95_CHIP_VERSION, syncWord, preambleLength);
|
||||
if (state != ERR_NONE)
|
||||
if (state != RADIOLIB_ERR_NONE)
|
||||
state = SX127x::begin(RF95_ALT_VERSION, syncWord, preambleLength);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
@@ -30,7 +30,7 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
#ifdef RF95_TCXO
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_TCXO, 0x10 | _mod->SPIgetRegValue(SX127X_REG_TCXO));
|
||||
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_TCXO, 0x10 | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_TCXO));
|
||||
RADIOLIB_ASSERT(state);
|
||||
#endif
|
||||
|
||||
@@ -72,7 +72,7 @@ int16_t RadioLibRF95::setFrequency(float freq)
|
||||
bool RadioLibRF95::isReceiving()
|
||||
{
|
||||
// 0x0b == Look for header info valid, signal synchronized or signal detected
|
||||
uint8_t reg = readReg(SX127X_REG_MODEM_STAT);
|
||||
uint8_t reg = readReg(RADIOLIB_SX127X_REG_MODEM_STAT);
|
||||
// Serial.printf("reg %x\n", reg);
|
||||
return (reg & (RH_RF95_MODEM_STATUS_SIGNAL_DETECTED | RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED |
|
||||
RH_RF95_MODEM_STATUS_HEADER_INFO_VALID)) != 0;
|
||||
|
||||
@@ -43,7 +43,7 @@ class RadioLibRF95: public SX1278 {
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
|
||||
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
|
||||
|
||||
// configuration methods
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "configuration.h"
|
||||
#include "ReliableRouter.h"
|
||||
#include "MeshModule.h"
|
||||
#include "MeshTypes.h"
|
||||
#include "configuration.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
|
||||
// ReliableRouter::ReliableRouter() {}
|
||||
@@ -14,11 +14,11 @@ ErrorCode ReliableRouter::send(MeshPacket *p)
|
||||
{
|
||||
if (p->want_ack) {
|
||||
// If someone asks for acks on broadcast, we need the hop limit to be at least one, so that first node that receives our
|
||||
// message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop counts
|
||||
// and we want this message to get through the whole mesh, so use the default.
|
||||
// message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop
|
||||
// counts and we want this message to get through the whole mesh, so use the default.
|
||||
if (p->to == NODENUM_BROADCAST && p->hop_limit == 0) {
|
||||
if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) {
|
||||
p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit;
|
||||
if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) {
|
||||
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||
} else {
|
||||
p->hop_limit = HOP_RELIABLE;
|
||||
}
|
||||
@@ -41,9 +41,9 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
|
||||
// If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for
|
||||
// the original sending process.
|
||||
|
||||
// FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've heard one
|
||||
// one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those nodes to reach
|
||||
// our destination. Both of which might be incorrect.
|
||||
// FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've
|
||||
// heard one one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those
|
||||
// nodes to reach our destination. Both of which might be incorrect.
|
||||
auto key = GlobalPacketId(getFrom(p), p->id);
|
||||
auto old = findPendingPacket(key);
|
||||
if (old) {
|
||||
@@ -53,8 +53,7 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, old->packet->channel);
|
||||
|
||||
stopRetransmission(key);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DEBUG_MSG("didn't find pending packet\n");
|
||||
}
|
||||
}
|
||||
@@ -151,7 +150,7 @@ bool ReliableRouter::stopRetransmission(GlobalPacketId key)
|
||||
if (old) {
|
||||
auto numErased = pending.erase(key);
|
||||
assert(numErased == 1);
|
||||
packetPool.release(old->packet);
|
||||
cancelSending(getFrom(old->packet), old->packet->id);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
||||
@@ -118,8 +118,8 @@ MeshPacket *Router::allocForSending()
|
||||
p->which_payloadVariant = MeshPacket_decoded_tag; // Assume payload is decoded at start.
|
||||
p->from = nodeDB.getNodeNum();
|
||||
p->to = NODENUM_BROADCAST;
|
||||
if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) {
|
||||
p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit;
|
||||
if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) {
|
||||
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||
} else {
|
||||
p->hop_limit = HOP_RELIABLE;
|
||||
}
|
||||
@@ -227,7 +227,7 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
*/
|
||||
|
||||
bool shouldActuallyEncrypt = true;
|
||||
if (*radioConfig.preferences.mqtt_server && !radioConfig.preferences.mqtt_encryption_enabled) {
|
||||
if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) {
|
||||
shouldActuallyEncrypt = false;
|
||||
}
|
||||
|
||||
@@ -274,6 +274,9 @@ void Router::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
|
||||
bool perhapsDecode(MeshPacket *p)
|
||||
{
|
||||
|
||||
// DEBUG_MSG("\n\n** perhapsDecode payloadVariant - %d\n\n", p->which_payloadVariant);
|
||||
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag)
|
||||
return true; // If packet was already decoded just return
|
||||
|
||||
@@ -304,12 +307,32 @@ bool perhapsDecode(MeshPacket *p)
|
||||
p->which_payloadVariant = MeshPacket_decoded_tag; // change type to decoded
|
||||
p->channel = chIndex; // change to store the index instead of the hash
|
||||
|
||||
/*
|
||||
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_APP) {
|
||||
DEBUG_MSG("\n\n** TEXT_MESSAGE_APP\n");
|
||||
} else if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
DEBUG_MSG("\n\n** PortNum_TEXT_MESSAGE_COMPRESSED_APP\n");
|
||||
}
|
||||
*/
|
||||
|
||||
// Decompress if needed. jm
|
||||
if (p->decoded.which_payloadVariant == Data_payload_compressed_tag) {
|
||||
// Decompress the file
|
||||
}
|
||||
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
// Decompress the payload
|
||||
char compressed_in[Constants_DATA_PAYLOAD_LEN] = {};
|
||||
char decompressed_out[Constants_DATA_PAYLOAD_LEN] = {};
|
||||
int decompressed_len;
|
||||
|
||||
memcpy(compressed_in, p->decoded.payload.bytes, p->decoded.payload.size);
|
||||
|
||||
decompressed_len = unishox2_decompress_simple(compressed_in, p->decoded.payload.size, decompressed_out);
|
||||
|
||||
// DEBUG_MSG("\n\n**\n\nDecompressed length - %d \n", decompressed_len);
|
||||
|
||||
memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len);
|
||||
|
||||
// Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP
|
||||
p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
|
||||
}
|
||||
|
||||
printPacket("decoded message", p);
|
||||
return true;
|
||||
@@ -341,41 +364,28 @@ Routing_Error perhapsEncode(MeshPacket *p)
|
||||
char compressed_out[Constants_DATA_PAYLOAD_LEN] = {0};
|
||||
|
||||
int compressed_len;
|
||||
// compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
|
||||
compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
|
||||
|
||||
Serial.print("Original length - ");
|
||||
Serial.println(p->decoded.payload.size);
|
||||
|
||||
Serial.print("Compressed length - ");
|
||||
Serial.println(compressed_len);
|
||||
// Serial.println(compressed_out);
|
||||
DEBUG_MSG("Original length - %d \n", p->decoded.payload.size);
|
||||
DEBUG_MSG("Compressed length - %d \n", compressed_len);
|
||||
DEBUG_MSG("Original message - %s \n", p->decoded.payload.bytes);
|
||||
|
||||
// If the compressed length is greater than or equal to the original size, don't use the compressed form
|
||||
if (compressed_len >= p->decoded.payload.size) {
|
||||
|
||||
DEBUG_MSG("Not compressing message. Not enough benefit from doing so.\n");
|
||||
DEBUG_MSG("Not using compressing message.\n");
|
||||
// Set the uncompressed payload varient anyway. Shouldn't hurt?
|
||||
p->decoded.which_payloadVariant = Data_payload_tag;
|
||||
// p->decoded.which_payloadVariant = Data_payload_tag;
|
||||
|
||||
// Otherwise we use the compressor
|
||||
} else {
|
||||
DEBUG_MSG("Compressing message.\n");
|
||||
DEBUG_MSG("Using compressed message.\n");
|
||||
// Copy the compressed data into the meshpacket
|
||||
//p->decoded.payload_compressed.size = compressed_len;
|
||||
//memcpy(p->decoded.payload_compressed.bytes, compressed_out, compressed_len);
|
||||
|
||||
//p->decoded.which_payloadVariant = Data_payload_compressed_tag;
|
||||
}
|
||||
p->decoded.payload.size = compressed_len;
|
||||
memcpy(p->decoded.payload.bytes, compressed_out, compressed_len);
|
||||
|
||||
if (0) {
|
||||
char decompressed_out[Constants_DATA_PAYLOAD_LEN] = {};
|
||||
int decompressed_len;
|
||||
|
||||
// decompressed_len = unishox2_decompress_simple(compressed_out, compressed_len, decompressed_out);
|
||||
|
||||
Serial.print("Decompressed length - ");
|
||||
Serial.println(decompressed_len);
|
||||
Serial.println(decompressed_out);
|
||||
p->decoded.portnum = PortNum_TEXT_MESSAGE_COMPRESSED_APP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,8 +447,8 @@ void Router::handleReceived(MeshPacket *p, RxSource src)
|
||||
|
||||
void Router::perhapsHandleReceived(MeshPacket *p)
|
||||
{
|
||||
assert(radioConfig.has_preferences);
|
||||
bool ignore = is_in_repeated(radioConfig.preferences.ignore_incoming, p->from);
|
||||
// assert(radioConfig.has_preferences);
|
||||
bool ignore = is_in_repeated(config.lora.ignore_incoming, p->from);
|
||||
|
||||
if (ignore)
|
||||
DEBUG_MSG("Ignoring incoming message, 0x%x is in our ignore list\n", p->from);
|
||||
|
||||
@@ -56,6 +56,10 @@ bool SX126xInterface<T>::init()
|
||||
// \todo Display actual typename of the adapter, not just `SX126x`
|
||||
DEBUG_MSG("SX126x init result %d\n", res);
|
||||
|
||||
DEBUG_MSG("Frequency set to %f\n", getFreq());
|
||||
DEBUG_MSG("Bandwidth set to %f\n", bw);
|
||||
DEBUG_MSG("Power output set to %d\n", power);
|
||||
|
||||
// current limit was removed from module' ctor
|
||||
// override default value (60 mA)
|
||||
res = lora.setCurrentLimit(currentLimit);
|
||||
@@ -64,15 +68,15 @@ bool SX126xInterface<T>::init()
|
||||
|
||||
#ifdef SX126X_TXEN
|
||||
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
||||
if (res == ERR_NONE)
|
||||
res = lora.setDio2AsRfSwitch(false);
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setDio2AsRfSwitch(true);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// Read/write a register we are not using (only used for FSK mode) to test SPI comms
|
||||
uint8_t crcLSB = 0;
|
||||
int err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
|
||||
if(err != ERR_NONE)
|
||||
if(err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
|
||||
|
||||
//if(crcLSB != 0x0f)
|
||||
@@ -80,11 +84,11 @@ bool SX126xInterface<T>::init()
|
||||
|
||||
crcLSB = 0x5a;
|
||||
err = lora.writeRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
|
||||
if(err != ERR_NONE)
|
||||
if(err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
|
||||
|
||||
err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
|
||||
if(err != ERR_NONE)
|
||||
if(err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
|
||||
|
||||
if(crcLSB != 0x5a)
|
||||
@@ -92,13 +96,13 @@ bool SX126xInterface<T>::init()
|
||||
// If we got this far register accesses (and therefore SPI comms) are good
|
||||
#endif
|
||||
|
||||
if (res == ERR_NONE)
|
||||
res = lora.setCRC(SX126X_LORA_CRC_ON);
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
|
||||
|
||||
if (res == ERR_NONE)
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
startReceive(); // start receiving
|
||||
|
||||
return res == ERR_NONE;
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -111,42 +115,43 @@ bool SX126xInterface<T>::reconfigure()
|
||||
|
||||
// configure publicly accessible settings
|
||||
int err = lora.setSpreadingFactor(sf);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
err = lora.setBandwidth(bw);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
err = lora.setCodingRate(cr);
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
|
||||
err = lora.setRxGain(true);
|
||||
assert(err == ERR_NONE);
|
||||
// TODO: Confirm gain registers are okay now
|
||||
// err = lora.setRxGain(true);
|
||||
// assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setSyncWord(syncWord);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setCurrentLimit(currentLimit);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setPreambleLength(preambleLength);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setFrequency(getFreq());
|
||||
if (err != ERR_NONE)
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
|
||||
if (power > 22) // This chip has lower power limits than some
|
||||
power = 22;
|
||||
err = lora.setOutputPower(power);
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
startReceive(); // restart receiving
|
||||
|
||||
return ERR_NONE;
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -161,7 +166,7 @@ void SX126xInterface<T>::setStandby()
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
int err = lora.standby();
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn off RX and TX power
|
||||
digitalWrite(SX126X_RXEN, LOW);
|
||||
@@ -194,6 +199,9 @@ void SX126xInterface<T>::configHardwareForSend()
|
||||
#ifdef SX126X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX126X_TXEN, HIGH);
|
||||
#endif
|
||||
#ifdef SX126X_RXEN
|
||||
digitalWrite(SX126X_RXEN, LOW);
|
||||
#endif
|
||||
|
||||
RadioLibInterface::configHardwareForSend();
|
||||
}
|
||||
@@ -213,11 +221,14 @@ void SX126xInterface<T>::startReceive()
|
||||
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
|
||||
digitalWrite(SX126X_RXEN, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef SX126X_TXEN
|
||||
digitalWrite(SX126X_TXEN, LOW);
|
||||
#endif
|
||||
|
||||
// int err = lora.startReceive();
|
||||
int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
|
||||
// standby mostly.
|
||||
assert(err == ERR_NONE);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = true;
|
||||
|
||||
@@ -235,10 +246,10 @@ bool SX126xInterface<T>::isChannelActive()
|
||||
|
||||
setStandby();
|
||||
result = lora.scanChannel();
|
||||
if (result == PREAMBLE_DETECTED)
|
||||
if (result == RADIOLIB_PREAMBLE_DETECTED)
|
||||
return true;
|
||||
|
||||
assert(result != ERR_WRONG_MODEM);
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -253,7 +264,7 @@ bool SX126xInterface<T>::isActivelyReceiving()
|
||||
// never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
|
||||
|
||||
uint16_t irq = lora.getIrqStatus();
|
||||
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
|
||||
bool hasPreamble = (irq & RADIOLIB_SX126X_IRQ_HEADER_VALID);
|
||||
|
||||
// this is not correct - often always true - need to add an extra conditional
|
||||
// size_t bytesPending = lora.getPacketLength();
|
||||
@@ -283,4 +294,4 @@ bool SX126xInterface<T>::sleep()
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "admin.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(AdminMessage, AdminMessage, 2)
|
||||
PB_BIND(AdminMessage, AdminMessage, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,73 +1,153 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_ADMIN_PB_H_INCLUDED
|
||||
#define PB_ADMIN_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "channel.pb.h"
|
||||
#include "config.pb.h"
|
||||
#include "mesh.pb.h"
|
||||
#include "radioconfig.pb.h"
|
||||
#include "module_config.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _AdminMessage_ConfigType {
|
||||
AdminMessage_ConfigType_DEVICE_CONFIG = 0,
|
||||
AdminMessage_ConfigType_POSITION_CONFIG = 1,
|
||||
AdminMessage_ConfigType_POWER_CONFIG = 2,
|
||||
AdminMessage_ConfigType_WIFI_CONFIG = 3,
|
||||
AdminMessage_ConfigType_DISPLAY_CONFIG = 4,
|
||||
AdminMessage_ConfigType_LORA_CONFIG = 5
|
||||
} AdminMessage_ConfigType;
|
||||
|
||||
typedef enum _AdminMessage_ModuleConfigType {
|
||||
AdminMessage_ModuleConfigType_MQTT_CONFIG = 0,
|
||||
AdminMessage_ModuleConfigType_SERIAL_CONFIG = 1,
|
||||
AdminMessage_ModuleConfigType_EXTNOTIF_CONFIG = 2,
|
||||
AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG = 3,
|
||||
AdminMessage_ModuleConfigType_RANGETEST_CONFIG = 4,
|
||||
AdminMessage_ModuleConfigType_TELEMETRY_CONFIG = 5,
|
||||
AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6
|
||||
} AdminMessage_ModuleConfigType;
|
||||
|
||||
/* Struct definitions */
|
||||
/* This message is handled by the Admin module and is responsible for all settings/channel read/write operations.
|
||||
This message is used to do settings operations to both remote AND local nodes.
|
||||
(Prior to 1.2 these operations were done via special ToRadio operations) */
|
||||
typedef struct _AdminMessage {
|
||||
/* Set the radio provisioning for this node */
|
||||
pb_size_t which_variant;
|
||||
union {
|
||||
RadioConfig set_radio;
|
||||
/* Set the owner for this node */
|
||||
User set_owner;
|
||||
/* Set channels (using the new API).
|
||||
A special channel is the "primary channel".
|
||||
The other records are secondary channels.
|
||||
Note: only one channel can be marked as primary.
|
||||
If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. */
|
||||
Channel set_channel;
|
||||
bool get_radio_request;
|
||||
RadioConfig get_radio_response;
|
||||
/* Send the specified channel in the response to this message
|
||||
NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) */
|
||||
uint32_t get_channel_request;
|
||||
/* TODO: REPLACE */
|
||||
Channel get_channel_response;
|
||||
/* Send the current owner data in the response to this message. */
|
||||
bool get_owner_request;
|
||||
/* TODO: REPLACE */
|
||||
User get_owner_response;
|
||||
/* Ask for the following config data to be sent */
|
||||
AdminMessage_ConfigType get_config_request;
|
||||
/* Send the current Config in the response to this message. */
|
||||
Config get_config_response;
|
||||
/* Set the current Config */
|
||||
Config set_config;
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_config;
|
||||
/* Ask for the following config data to be sent */
|
||||
AdminMessage_ModuleConfigType get_module_config_request;
|
||||
/* Send the current Config in the response to this message. */
|
||||
ModuleConfig get_module_config_response;
|
||||
/* Set the current Config */
|
||||
ModuleConfig set_module_config;
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_module_config;
|
||||
/* Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again.
|
||||
Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes.
|
||||
If you fail to do so, the radio will assume loss of comms and revert your changes.
|
||||
These messages are optional when changing the local node. */
|
||||
bool confirm_set_channel;
|
||||
/* TODO: REPLACE */
|
||||
bool confirm_set_radio;
|
||||
/* This message is only supported for the simulator porduino build.
|
||||
If received the simulator will exit successfully. */
|
||||
bool exit_simulator;
|
||||
/* Tell the node to reboot in this many seconds (or <0 to cancel reboot) */
|
||||
int32_t reboot_seconds;
|
||||
/* Get the Canned Message Module message part1 in the response to this message. */
|
||||
bool get_canned_message_module_part1_request;
|
||||
/* TODO: REPLACE */
|
||||
char get_canned_message_module_part1_response[201];
|
||||
/* Get the Canned Message Module message part2 in the response to this message. */
|
||||
bool get_canned_message_module_part2_request;
|
||||
/* TODO: REPLACE */
|
||||
char get_canned_message_module_part2_response[201];
|
||||
/* Get the Canned Message Module message part3 in the response to this message. */
|
||||
bool get_canned_message_module_part3_request;
|
||||
/* TODO: REPLACE */
|
||||
char get_canned_message_module_part3_response[201];
|
||||
/* Get the Canned Message Module message part4 in the response to this message. */
|
||||
bool get_canned_message_module_part4_request;
|
||||
/* TODO: REPLACE */
|
||||
char get_canned_message_module_part4_response[201];
|
||||
/* Set the canned message module part 1 text. */
|
||||
char set_canned_message_module_part1[201];
|
||||
/* Set the canned message module part 2 text. */
|
||||
char set_canned_message_module_part2[201];
|
||||
/* Set the canned message module part 3 text. */
|
||||
char set_canned_message_module_part3[201];
|
||||
/* Set the canned message module part 4 text. */
|
||||
char set_canned_message_module_part4[201];
|
||||
/* Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) */
|
||||
int32_t shutdown_seconds;
|
||||
};
|
||||
};
|
||||
} AdminMessage;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _AdminMessage_ConfigType_MIN AdminMessage_ConfigType_DEVICE_CONFIG
|
||||
#define _AdminMessage_ConfigType_MAX AdminMessage_ConfigType_LORA_CONFIG
|
||||
#define _AdminMessage_ConfigType_ARRAYSIZE ((AdminMessage_ConfigType)(AdminMessage_ConfigType_LORA_CONFIG+1))
|
||||
|
||||
#define _AdminMessage_ModuleConfigType_MIN AdminMessage_ModuleConfigType_MQTT_CONFIG
|
||||
#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG
|
||||
#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define AdminMessage_init_default {0, {RadioConfig_init_default}}
|
||||
#define AdminMessage_init_zero {0, {RadioConfig_init_zero}}
|
||||
#define AdminMessage_init_default {0, {User_init_default}}
|
||||
#define AdminMessage_init_zero {0, {User_init_zero}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define AdminMessage_set_radio_tag 1
|
||||
#define AdminMessage_set_owner_tag 2
|
||||
#define AdminMessage_set_channel_tag 3
|
||||
#define AdminMessage_get_radio_request_tag 4
|
||||
#define AdminMessage_get_radio_response_tag 5
|
||||
#define AdminMessage_get_channel_request_tag 6
|
||||
#define AdminMessage_get_channel_response_tag 7
|
||||
#define AdminMessage_get_owner_request_tag 8
|
||||
#define AdminMessage_get_owner_response_tag 9
|
||||
#define AdminMessage_get_config_request_tag 10
|
||||
#define AdminMessage_get_config_response_tag 11
|
||||
#define AdminMessage_set_config_tag 12
|
||||
#define AdminMessage_confirm_set_config_tag 13
|
||||
#define AdminMessage_get_module_config_request_tag 14
|
||||
#define AdminMessage_get_module_config_response_tag 15
|
||||
#define AdminMessage_set_module_config_tag 16
|
||||
#define AdminMessage_confirm_set_module_config_tag 17
|
||||
#define AdminMessage_confirm_set_channel_tag 32
|
||||
#define AdminMessage_confirm_set_radio_tag 33
|
||||
#define AdminMessage_exit_simulator_tag 34
|
||||
@@ -88,15 +168,20 @@ extern "C" {
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define AdminMessage_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_radio,set_radio), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,set_owner), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_channel,set_channel), 3) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,get_radio_request,get_radio_request), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_radio_response,get_radio_response), 5) \
|
||||
X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,get_owner_request,get_owner_request), 8) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_owner_response,get_owner_response), 9) \
|
||||
X(a, STATIC, ONEOF, UENUM, (variant,get_config_request,get_config_request), 10) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_config_response,get_config_response), 11) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_config,set_config), 12) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_config,confirm_set_config), 13) \
|
||||
X(a, STATIC, ONEOF, UENUM, (variant,get_module_config_request,get_module_config_request), 14) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_module_config_response,get_module_config_response), 15) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_module_config,set_module_config), 16) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_module_config,confirm_set_module_config), 17) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
|
||||
@@ -116,12 +201,14 @@ X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part4,set_
|
||||
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
|
||||
#define AdminMessage_CALLBACK NULL
|
||||
#define AdminMessage_DEFAULT NULL
|
||||
#define AdminMessage_variant_set_radio_MSGTYPE RadioConfig
|
||||
#define AdminMessage_variant_set_owner_MSGTYPE User
|
||||
#define AdminMessage_variant_set_channel_MSGTYPE Channel
|
||||
#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig
|
||||
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel
|
||||
#define AdminMessage_variant_get_owner_response_MSGTYPE User
|
||||
#define AdminMessage_variant_get_config_response_MSGTYPE Config
|
||||
#define AdminMessage_variant_set_config_MSGTYPE Config
|
||||
#define AdminMessage_variant_get_module_config_response_MSGTYPE ModuleConfig
|
||||
#define AdminMessage_variant_set_module_config_MSGTYPE ModuleConfig
|
||||
|
||||
extern const pb_msgdesc_t AdminMessage_msg;
|
||||
|
||||
@@ -129,7 +216,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
|
||||
#define AdminMessage_fields &AdminMessage_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define AdminMessage_size 598
|
||||
#define AdminMessage_size 204
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "apponly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(ChannelSet, ChannelSet, AUTO)
|
||||
PB_BIND(ChannelSet, ChannelSet, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_APPONLY_PB_H_INCLUDED
|
||||
#define PB_APPONLY_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "channel.pb.h"
|
||||
#include "config.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
@@ -17,8 +18,12 @@
|
||||
No DISABLED channels are included.
|
||||
This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL */
|
||||
typedef struct _ChannelSet {
|
||||
/* TODO: REPLACE */
|
||||
pb_callback_t settings;
|
||||
/* Channel list with settings */
|
||||
pb_size_t settings_count;
|
||||
ChannelSettings settings[8];
|
||||
/* LoRa config */
|
||||
bool has_lora_config;
|
||||
Config_LoRaConfig lora_config;
|
||||
} ChannelSet;
|
||||
|
||||
|
||||
@@ -27,18 +32,21 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ChannelSet_init_default {{{NULL}, NULL}}
|
||||
#define ChannelSet_init_zero {{{NULL}, NULL}}
|
||||
#define ChannelSet_init_default {0, {ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default}, false, Config_LoRaConfig_init_default}
|
||||
#define ChannelSet_init_zero {0, {ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero}, false, Config_LoRaConfig_init_zero}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelSet_settings_tag 1
|
||||
#define ChannelSet_lora_config_tag 2
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ChannelSet_FIELDLIST(X, a) \
|
||||
X(a, CALLBACK, REPEATED, MESSAGE, settings, 1)
|
||||
#define ChannelSet_CALLBACK pb_default_field_callback
|
||||
X(a, STATIC, REPEATED, MESSAGE, settings, 1) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, lora_config, 2)
|
||||
#define ChannelSet_CALLBACK NULL
|
||||
#define ChannelSet_DEFAULT NULL
|
||||
#define ChannelSet_settings_MSGTYPE ChannelSettings
|
||||
#define ChannelSet_lora_config_MSGTYPE Config_LoRaConfig
|
||||
|
||||
extern const pb_msgdesc_t ChannelSet_msg;
|
||||
|
||||
@@ -46,7 +54,7 @@ extern const pb_msgdesc_t ChannelSet_msg;
|
||||
#define ChannelSet_fields &ChannelSet_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* ChannelSet_size depends on runtime parameters */
|
||||
#define ChannelSet_size 573
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "cannedmessages.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_CANNEDMESSAGES_PB_H_INCLUDED
|
||||
#define PB_CANNEDMESSAGES_PB_H_INCLUDED
|
||||
@@ -13,13 +13,13 @@
|
||||
/* Canned message module configuration. */
|
||||
typedef struct _CannedMessageModuleConfig {
|
||||
/* Predefined messages for canned message module separated by '|' characters. */
|
||||
char messagesPart1[201];
|
||||
char messagesPart1[201];
|
||||
/* TODO: REPLACE */
|
||||
char messagesPart2[201];
|
||||
char messagesPart2[201];
|
||||
/* TODO: REPLACE */
|
||||
char messagesPart3[201];
|
||||
char messagesPart3[201];
|
||||
/* TODO: REPLACE */
|
||||
char messagesPart4[201];
|
||||
char messagesPart4[201];
|
||||
} CannedMessageModuleConfig;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "channel.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
@@ -14,4 +14,3 @@ PB_BIND(Channel, Channel, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_CHANNEL_PB_H_INCLUDED
|
||||
#define PB_CHANNEL_PB_H_INCLUDED
|
||||
@@ -10,16 +10,6 @@
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _ChannelSettings_ModemConfig {
|
||||
ChannelSettings_ModemConfig_VLongSlow = 0,
|
||||
ChannelSettings_ModemConfig_LongSlow = 1,
|
||||
ChannelSettings_ModemConfig_LongFast = 2,
|
||||
ChannelSettings_ModemConfig_MidSlow = 3,
|
||||
ChannelSettings_ModemConfig_MidFast = 4,
|
||||
ChannelSettings_ModemConfig_ShortSlow = 5,
|
||||
ChannelSettings_ModemConfig_ShortFast = 6
|
||||
} ChannelSettings_ModemConfig;
|
||||
|
||||
typedef enum _Channel_Role {
|
||||
Channel_Role_DISABLED = 0,
|
||||
Channel_Role_PRIMARY = 1,
|
||||
@@ -48,28 +38,26 @@ typedef PB_BYTES_ARRAY_T(32) ChannelSettings_psk_t;
|
||||
FIXME: explain how apps use channels for security.
|
||||
explain how remote settings and remote gpio are managed as an example */
|
||||
typedef struct _ChannelSettings {
|
||||
/* If zero then, use default max legal continuous power (ie. something that won't
|
||||
burn out the radio hardware)
|
||||
In most cases you should use zero here.
|
||||
Units are in dBm. */
|
||||
int8_t tx_power;
|
||||
/* Note: This is the 'old' mechanism for specifying channel parameters.
|
||||
Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH.
|
||||
As a heuristic: If bandwidth is specified, do not use modem_config.
|
||||
Because protobufs take ZERO space when the value is zero this works out nicely.
|
||||
This value is replaced by bandwidth/spread_factor/coding_rate.
|
||||
If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. */
|
||||
ChannelSettings_ModemConfig modem_config;
|
||||
/* Bandwidth in MHz
|
||||
Certain bandwidth numbers are 'special' and will be converted to the
|
||||
appropriate floating point value: 31 -> 31.25MHz */
|
||||
ChannelSettings_psk_t psk;
|
||||
/* A number from 7 to 12.
|
||||
Indicates number of chirps per symbol as 1<<spread_factor. */
|
||||
char name[12];
|
||||
/* The denominator of the coding rate.
|
||||
ie for 4/8, the value is 8. 5/8 the value is 5. */
|
||||
uint16_t bandwidth;
|
||||
/* A simple pre-shared key for now for crypto.
|
||||
Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256).
|
||||
A special shorthand is used for 1 byte long psks.
|
||||
These psks should be treated as only minimally secure,
|
||||
because they are listed in this source code.
|
||||
Those bytes are mapped using the following scheme:
|
||||
`0` = No crypto
|
||||
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf}
|
||||
`2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
|
||||
Shown to user as simple1 through 10 */
|
||||
ChannelSettings_psk_t psk;
|
||||
/* A SHORT name that will be packed into the URL.
|
||||
Less than 12 bytes.
|
||||
Something for end users to call the channel
|
||||
If this is the empty string it is assumed that this channel
|
||||
is the special (minimally secure) "Default"channel.
|
||||
In user interfaces it should be rendered as a local language translation of "X".
|
||||
For channel_num hashing empty string will be treated as "X".
|
||||
Where "X" is selected based on the English words listed above for ModemPreset */
|
||||
char name[12];
|
||||
/* NOTE: this field is _independent_ and unrelated to the concepts in channel.proto.
|
||||
this is controlling the actual hardware frequency the radio is transmitting on.
|
||||
In a perfect world we would have called it something else (band?) but I forgot to make this change during the big 1.2 renaming.
|
||||
@@ -88,27 +76,7 @@ typedef struct _ChannelSettings {
|
||||
hash = ((hash << 5) + hash) + (unsigned char) c;
|
||||
return hash;
|
||||
} */
|
||||
uint32_t spread_factor;
|
||||
/* A simple pre-shared key for now for crypto.
|
||||
Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256).
|
||||
A special shorthand is used for 1 byte long psks.
|
||||
These psks should be treated as only minimally secure,
|
||||
because they are listed in this source code.
|
||||
Those bytes are mapped using the following scheme:
|
||||
`0` = No crypto
|
||||
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf}
|
||||
`2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
|
||||
Shown to user as simple1 through 10 */
|
||||
uint8_t coding_rate;
|
||||
/* A SHORT name that will be packed into the URL.
|
||||
Less than 12 bytes.
|
||||
Something for end users to call the channel
|
||||
If this is the empty string it is assumed that this channel
|
||||
is the special (minimally secure) "Default"channel.
|
||||
In user interfaces it should be rendered as a local language translation of "X".
|
||||
For channel_num hashing empty string will be treated as "X".
|
||||
Where "X" is selected based on the English words listed above for ModemConfig */
|
||||
uint8_t channel_num;
|
||||
uint8_t channel_num;
|
||||
/* Used to construct a globally unique channel ID.
|
||||
The full globally unique ID will be: "name.id" where ID is shown as base36.
|
||||
Assuming that the number of meshtastic users is below 20K (true for a long time)
|
||||
@@ -120,11 +88,11 @@ typedef struct _ChannelSettings {
|
||||
Those channels do not have a numeric id included in the settings, but instead it is pulled from
|
||||
a table of well known IDs.
|
||||
(see Well Known Channels FIXME) */
|
||||
uint32_t id;
|
||||
uint32_t id;
|
||||
/* If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe */
|
||||
bool uplink_enabled;
|
||||
bool uplink_enabled;
|
||||
/* If true, messages seen on the internet will be forwarded to the local mesh. */
|
||||
bool downlink_enabled;
|
||||
bool downlink_enabled;
|
||||
} ChannelSettings;
|
||||
|
||||
/* A pair of a channel number, mode and the (sharable) settings for that channel */
|
||||
@@ -132,20 +100,16 @@ typedef struct _Channel {
|
||||
/* The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1)
|
||||
(Someday - not currently implemented) An index of -1 could be used to mean "set by name",
|
||||
in which case the target node will find and set the channel by settings.name. */
|
||||
int8_t index;
|
||||
int8_t index;
|
||||
/* The new settings, or NULL to disable that channel */
|
||||
bool has_settings;
|
||||
ChannelSettings settings;
|
||||
ChannelSettings settings;
|
||||
/* TODO: REPLACE */
|
||||
Channel_Role role;
|
||||
Channel_Role role;
|
||||
} Channel;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _ChannelSettings_ModemConfig_MIN ChannelSettings_ModemConfig_VLongSlow
|
||||
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_ShortFast
|
||||
#define _ChannelSettings_ModemConfig_ARRAYSIZE ((ChannelSettings_ModemConfig)(ChannelSettings_ModemConfig_ShortFast+1))
|
||||
|
||||
#define _Channel_Role_MIN Channel_Role_DISABLED
|
||||
#define _Channel_Role_MAX Channel_Role_SECONDARY
|
||||
#define _Channel_Role_ARRAYSIZE ((Channel_Role)(Channel_Role_SECONDARY+1))
|
||||
@@ -156,19 +120,14 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
||||
#define ChannelSettings_init_default {{0, {0}}, "", 0, 0, 0, 0}
|
||||
#define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
|
||||
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
|
||||
#define ChannelSettings_init_zero {{0, {0}}, "", 0, 0, 0, 0}
|
||||
#define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelSettings_tx_power_tag 1
|
||||
#define ChannelSettings_modem_config_tag 3
|
||||
#define ChannelSettings_psk_tag 4
|
||||
#define ChannelSettings_name_tag 5
|
||||
#define ChannelSettings_bandwidth_tag 6
|
||||
#define ChannelSettings_spread_factor_tag 7
|
||||
#define ChannelSettings_coding_rate_tag 8
|
||||
#define ChannelSettings_channel_num_tag 9
|
||||
#define ChannelSettings_id_tag 10
|
||||
#define ChannelSettings_uplink_enabled_tag 16
|
||||
@@ -179,13 +138,8 @@ extern "C" {
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ChannelSettings_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, modem_config, 3) \
|
||||
X(a, STATIC, SINGULAR, BYTES, psk, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, bandwidth, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, spread_factor, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, coding_rate, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, channel_num, 9) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, id, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 16) \
|
||||
@@ -209,8 +163,8 @@ extern const pb_msgdesc_t Channel_msg;
|
||||
#define Channel_fields &Channel_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelSettings_size 87
|
||||
#define Channel_size 102
|
||||
#define ChannelSettings_size 61
|
||||
#define Channel_size 76
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
36
src/mesh/generated/config.pb.c
Normal file
36
src/mesh/generated/config.pb.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "config.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(Config, Config, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_DeviceConfig, Config_DeviceConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_PositionConfig, Config_PositionConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_PowerConfig, Config_PowerConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_WiFiConfig, Config_WiFiConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_LoRaConfig, Config_LoRaConfig, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
361
src/mesh/generated/config.pb.h
Normal file
361
src/mesh/generated/config.pb.h
Normal file
@@ -0,0 +1,361 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_CONFIG_PB_H_INCLUDED
|
||||
#define PB_CONFIG_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _Config_DeviceConfig_Role {
|
||||
Config_DeviceConfig_Role_Client = 0,
|
||||
Config_DeviceConfig_Role_ClientMute = 1,
|
||||
Config_DeviceConfig_Role_Router = 2,
|
||||
Config_DeviceConfig_Role_RouterClient = 3
|
||||
} Config_DeviceConfig_Role;
|
||||
|
||||
typedef enum _Config_PositionConfig_PositionFlags {
|
||||
Config_PositionConfig_PositionFlags_POS_UNDEFINED = 0,
|
||||
Config_PositionConfig_PositionFlags_POS_ALTITUDE = 1,
|
||||
Config_PositionConfig_PositionFlags_POS_ALT_MSL = 2,
|
||||
Config_PositionConfig_PositionFlags_POS_GEO_SEP = 4,
|
||||
Config_PositionConfig_PositionFlags_POS_DOP = 8,
|
||||
Config_PositionConfig_PositionFlags_POS_HVDOP = 16,
|
||||
Config_PositionConfig_PositionFlags_POS_SATINVIEW = 32,
|
||||
Config_PositionConfig_PositionFlags_POS_SEQ_NOS = 64,
|
||||
Config_PositionConfig_PositionFlags_POS_TIMESTAMP = 128,
|
||||
Config_PositionConfig_PositionFlags_POS_HEADING = 256,
|
||||
Config_PositionConfig_PositionFlags_POS_SPEED = 512
|
||||
} Config_PositionConfig_PositionFlags;
|
||||
|
||||
typedef enum _Config_PowerConfig_ChargeCurrent {
|
||||
Config_PowerConfig_ChargeCurrent_MAUnset = 0,
|
||||
Config_PowerConfig_ChargeCurrent_MA100 = 1,
|
||||
Config_PowerConfig_ChargeCurrent_MA190 = 2,
|
||||
Config_PowerConfig_ChargeCurrent_MA280 = 3,
|
||||
Config_PowerConfig_ChargeCurrent_MA360 = 4,
|
||||
Config_PowerConfig_ChargeCurrent_MA450 = 5,
|
||||
Config_PowerConfig_ChargeCurrent_MA550 = 6,
|
||||
Config_PowerConfig_ChargeCurrent_MA630 = 7,
|
||||
Config_PowerConfig_ChargeCurrent_MA700 = 8,
|
||||
Config_PowerConfig_ChargeCurrent_MA780 = 9,
|
||||
Config_PowerConfig_ChargeCurrent_MA880 = 10,
|
||||
Config_PowerConfig_ChargeCurrent_MA960 = 11,
|
||||
Config_PowerConfig_ChargeCurrent_MA1000 = 12,
|
||||
Config_PowerConfig_ChargeCurrent_MA1080 = 13,
|
||||
Config_PowerConfig_ChargeCurrent_MA1160 = 14,
|
||||
Config_PowerConfig_ChargeCurrent_MA1240 = 15,
|
||||
Config_PowerConfig_ChargeCurrent_MA1320 = 16
|
||||
} Config_PowerConfig_ChargeCurrent;
|
||||
|
||||
typedef enum _Config_DisplayConfig_GpsCoordinateFormat {
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec = 0,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS = 1,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM = 2,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS = 3,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC = 4,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR = 5
|
||||
} Config_DisplayConfig_GpsCoordinateFormat;
|
||||
|
||||
typedef enum _Config_LoRaConfig_RegionCode {
|
||||
Config_LoRaConfig_RegionCode_Unset = 0,
|
||||
Config_LoRaConfig_RegionCode_US = 1,
|
||||
Config_LoRaConfig_RegionCode_EU433 = 2,
|
||||
Config_LoRaConfig_RegionCode_EU868 = 3,
|
||||
Config_LoRaConfig_RegionCode_CN = 4,
|
||||
Config_LoRaConfig_RegionCode_JP = 5,
|
||||
Config_LoRaConfig_RegionCode_ANZ = 6,
|
||||
Config_LoRaConfig_RegionCode_KR = 7,
|
||||
Config_LoRaConfig_RegionCode_TW = 8,
|
||||
Config_LoRaConfig_RegionCode_RU = 9,
|
||||
Config_LoRaConfig_RegionCode_IN = 10,
|
||||
Config_LoRaConfig_RegionCode_NZ865 = 11,
|
||||
Config_LoRaConfig_RegionCode_TH = 12
|
||||
} Config_LoRaConfig_RegionCode;
|
||||
|
||||
typedef enum _Config_LoRaConfig_ModemPreset {
|
||||
Config_LoRaConfig_ModemPreset_LongFast = 0,
|
||||
Config_LoRaConfig_ModemPreset_LongSlow = 1,
|
||||
Config_LoRaConfig_ModemPreset_VLongSlow = 2,
|
||||
Config_LoRaConfig_ModemPreset_MedSlow = 3,
|
||||
Config_LoRaConfig_ModemPreset_MedFast = 4,
|
||||
Config_LoRaConfig_ModemPreset_ShortSlow = 5,
|
||||
Config_LoRaConfig_ModemPreset_ShortFast = 6
|
||||
} Config_LoRaConfig_ModemPreset;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _Config_DeviceConfig {
|
||||
Config_DeviceConfig_Role role;
|
||||
bool serial_disabled;
|
||||
bool factory_reset;
|
||||
bool debug_log_enabled;
|
||||
char ntp_server[33];
|
||||
} Config_DeviceConfig;
|
||||
|
||||
typedef struct _Config_DisplayConfig {
|
||||
uint32_t screen_on_secs;
|
||||
Config_DisplayConfig_GpsCoordinateFormat gps_format;
|
||||
uint32_t auto_screen_carousel_secs;
|
||||
} Config_DisplayConfig;
|
||||
|
||||
typedef struct _Config_LoRaConfig {
|
||||
int32_t tx_power;
|
||||
Config_LoRaConfig_ModemPreset modem_preset;
|
||||
uint32_t bandwidth;
|
||||
uint32_t spread_factor;
|
||||
uint32_t coding_rate;
|
||||
float frequency_offset;
|
||||
Config_LoRaConfig_RegionCode region;
|
||||
uint32_t hop_limit;
|
||||
bool tx_disabled;
|
||||
pb_size_t ignore_incoming_count;
|
||||
uint32_t ignore_incoming[3];
|
||||
} Config_LoRaConfig;
|
||||
|
||||
typedef struct _Config_PositionConfig {
|
||||
uint32_t position_broadcast_secs;
|
||||
bool position_broadcast_smart_disabled;
|
||||
bool fixed_position;
|
||||
bool gps_disabled;
|
||||
uint32_t gps_update_interval;
|
||||
uint32_t gps_attempt_time;
|
||||
uint32_t position_flags;
|
||||
} Config_PositionConfig;
|
||||
|
||||
typedef struct _Config_PowerConfig {
|
||||
Config_PowerConfig_ChargeCurrent charge_current;
|
||||
bool is_power_saving;
|
||||
uint32_t on_battery_shutdown_after_secs;
|
||||
float adc_multiplier_override;
|
||||
uint32_t wait_bluetooth_secs;
|
||||
uint32_t mesh_sds_timeout_secs;
|
||||
uint32_t sds_secs;
|
||||
uint32_t ls_secs;
|
||||
uint32_t min_wake_secs;
|
||||
} Config_PowerConfig;
|
||||
|
||||
typedef struct _Config_WiFiConfig {
|
||||
char ssid[33];
|
||||
char psk[64];
|
||||
bool ap_mode;
|
||||
bool ap_hidden;
|
||||
} Config_WiFiConfig;
|
||||
|
||||
typedef struct _Config {
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
Config_DeviceConfig device;
|
||||
Config_PositionConfig position;
|
||||
Config_PowerConfig power;
|
||||
Config_WiFiConfig wifi;
|
||||
Config_DisplayConfig display;
|
||||
Config_LoRaConfig lora;
|
||||
} payloadVariant;
|
||||
} Config;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _Config_DeviceConfig_Role_MIN Config_DeviceConfig_Role_Client
|
||||
#define _Config_DeviceConfig_Role_MAX Config_DeviceConfig_Role_RouterClient
|
||||
#define _Config_DeviceConfig_Role_ARRAYSIZE ((Config_DeviceConfig_Role)(Config_DeviceConfig_Role_RouterClient+1))
|
||||
|
||||
#define _Config_PositionConfig_PositionFlags_MIN Config_PositionConfig_PositionFlags_POS_UNDEFINED
|
||||
#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_POS_SPEED
|
||||
#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_POS_SPEED+1))
|
||||
|
||||
#define _Config_PowerConfig_ChargeCurrent_MIN Config_PowerConfig_ChargeCurrent_MAUnset
|
||||
#define _Config_PowerConfig_ChargeCurrent_MAX Config_PowerConfig_ChargeCurrent_MA1320
|
||||
#define _Config_PowerConfig_ChargeCurrent_ARRAYSIZE ((Config_PowerConfig_ChargeCurrent)(Config_PowerConfig_ChargeCurrent_MA1320+1))
|
||||
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR+1))
|
||||
|
||||
#define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_Unset
|
||||
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_TH
|
||||
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_TH+1))
|
||||
|
||||
#define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LongFast
|
||||
#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_ShortFast
|
||||
#define _Config_LoRaConfig_ModemPreset_ARRAYSIZE ((Config_LoRaConfig_ModemPreset)(Config_LoRaConfig_ModemPreset_ShortFast+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define Config_init_default {0, {Config_DeviceConfig_init_default}}
|
||||
#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
|
||||
#define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_PowerConfig_init_default {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_WiFiConfig_init_default {"", "", 0, 0}
|
||||
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0}
|
||||
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}}
|
||||
#define Config_init_zero {0, {Config_DeviceConfig_init_zero}}
|
||||
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
|
||||
#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_PowerConfig_init_zero {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_WiFiConfig_init_zero {"", "", 0, 0}
|
||||
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0}
|
||||
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, {0, 0, 0}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define Config_DeviceConfig_role_tag 1
|
||||
#define Config_DeviceConfig_serial_disabled_tag 2
|
||||
#define Config_DeviceConfig_factory_reset_tag 3
|
||||
#define Config_DeviceConfig_debug_log_enabled_tag 4
|
||||
#define Config_DeviceConfig_ntp_server_tag 5
|
||||
#define Config_DisplayConfig_screen_on_secs_tag 1
|
||||
#define Config_DisplayConfig_gps_format_tag 2
|
||||
#define Config_DisplayConfig_auto_screen_carousel_secs_tag 3
|
||||
#define Config_LoRaConfig_tx_power_tag 1
|
||||
#define Config_LoRaConfig_modem_preset_tag 2
|
||||
#define Config_LoRaConfig_bandwidth_tag 3
|
||||
#define Config_LoRaConfig_spread_factor_tag 4
|
||||
#define Config_LoRaConfig_coding_rate_tag 5
|
||||
#define Config_LoRaConfig_frequency_offset_tag 6
|
||||
#define Config_LoRaConfig_region_tag 7
|
||||
#define Config_LoRaConfig_hop_limit_tag 8
|
||||
#define Config_LoRaConfig_tx_disabled_tag 9
|
||||
#define Config_LoRaConfig_ignore_incoming_tag 103
|
||||
#define Config_PositionConfig_position_broadcast_secs_tag 1
|
||||
#define Config_PositionConfig_position_broadcast_smart_disabled_tag 2
|
||||
#define Config_PositionConfig_fixed_position_tag 3
|
||||
#define Config_PositionConfig_gps_disabled_tag 5
|
||||
#define Config_PositionConfig_gps_update_interval_tag 6
|
||||
#define Config_PositionConfig_gps_attempt_time_tag 7
|
||||
#define Config_PositionConfig_position_flags_tag 10
|
||||
#define Config_PowerConfig_charge_current_tag 1
|
||||
#define Config_PowerConfig_is_power_saving_tag 2
|
||||
#define Config_PowerConfig_on_battery_shutdown_after_secs_tag 4
|
||||
#define Config_PowerConfig_adc_multiplier_override_tag 6
|
||||
#define Config_PowerConfig_wait_bluetooth_secs_tag 7
|
||||
#define Config_PowerConfig_mesh_sds_timeout_secs_tag 9
|
||||
#define Config_PowerConfig_sds_secs_tag 10
|
||||
#define Config_PowerConfig_ls_secs_tag 11
|
||||
#define Config_PowerConfig_min_wake_secs_tag 12
|
||||
#define Config_WiFiConfig_ssid_tag 1
|
||||
#define Config_WiFiConfig_psk_tag 2
|
||||
#define Config_WiFiConfig_ap_mode_tag 3
|
||||
#define Config_WiFiConfig_ap_hidden_tag 4
|
||||
#define Config_device_tag 1
|
||||
#define Config_position_tag 2
|
||||
#define Config_power_tag 3
|
||||
#define Config_wifi_tag 4
|
||||
#define Config_display_tag 5
|
||||
#define Config_lora_tag 6
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define Config_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,device,payloadVariant.device), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,position,payloadVariant.position), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,power,payloadVariant.power), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,wifi,payloadVariant.wifi), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,display,payloadVariant.display), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,lora,payloadVariant.lora), 6)
|
||||
#define Config_CALLBACK NULL
|
||||
#define Config_DEFAULT NULL
|
||||
#define Config_payloadVariant_device_MSGTYPE Config_DeviceConfig
|
||||
#define Config_payloadVariant_position_MSGTYPE Config_PositionConfig
|
||||
#define Config_payloadVariant_power_MSGTYPE Config_PowerConfig
|
||||
#define Config_payloadVariant_wifi_MSGTYPE Config_WiFiConfig
|
||||
#define Config_payloadVariant_display_MSGTYPE Config_DisplayConfig
|
||||
#define Config_payloadVariant_lora_MSGTYPE Config_LoRaConfig
|
||||
|
||||
#define Config_DeviceConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_disabled, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, factory_reset, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, ntp_server, 5)
|
||||
#define Config_DeviceConfig_CALLBACK NULL
|
||||
#define Config_DeviceConfig_DEFAULT NULL
|
||||
|
||||
#define Config_PositionConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, gps_disabled, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_flags, 10)
|
||||
#define Config_PositionConfig_CALLBACK NULL
|
||||
#define Config_PositionConfig_DEFAULT NULL
|
||||
|
||||
#define Config_PowerConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, charge_current, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 4) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sds_secs, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ls_secs, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 12)
|
||||
#define Config_PowerConfig_CALLBACK NULL
|
||||
#define Config_PowerConfig_DEFAULT NULL
|
||||
|
||||
#define Config_WiFiConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, ssid, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, psk, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ap_mode, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ap_hidden, 4)
|
||||
#define Config_WiFiConfig_CALLBACK NULL
|
||||
#define Config_WiFiConfig_DEFAULT NULL
|
||||
|
||||
#define Config_DisplayConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3)
|
||||
#define Config_DisplayConfig_CALLBACK NULL
|
||||
#define Config_DisplayConfig_DEFAULT NULL
|
||||
|
||||
#define Config_LoRaConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, modem_preset, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, bandwidth, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, spread_factor, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, coding_rate, 5) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, region, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 8) \
|
||||
X(a, STATIC, SINGULAR, BOOL, tx_disabled, 9) \
|
||||
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)
|
||||
#define Config_LoRaConfig_CALLBACK NULL
|
||||
#define Config_LoRaConfig_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t Config_msg;
|
||||
extern const pb_msgdesc_t Config_DeviceConfig_msg;
|
||||
extern const pb_msgdesc_t Config_PositionConfig_msg;
|
||||
extern const pb_msgdesc_t Config_PowerConfig_msg;
|
||||
extern const pb_msgdesc_t Config_WiFiConfig_msg;
|
||||
extern const pb_msgdesc_t Config_DisplayConfig_msg;
|
||||
extern const pb_msgdesc_t Config_LoRaConfig_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define Config_fields &Config_msg
|
||||
#define Config_DeviceConfig_fields &Config_DeviceConfig_msg
|
||||
#define Config_PositionConfig_fields &Config_PositionConfig_msg
|
||||
#define Config_PowerConfig_fields &Config_PowerConfig_msg
|
||||
#define Config_WiFiConfig_fields &Config_WiFiConfig_msg
|
||||
#define Config_DisplayConfig_fields &Config_DisplayConfig_msg
|
||||
#define Config_LoRaConfig_fields &Config_LoRaConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Config_DeviceConfig_size 42
|
||||
#define Config_DisplayConfig_size 14
|
||||
#define Config_LoRaConfig_size 67
|
||||
#define Config_PositionConfig_size 30
|
||||
#define Config_PowerConfig_size 45
|
||||
#define Config_WiFiConfig_size 103
|
||||
#define Config_size 105
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "deviceonly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_DEVICEONLY_PB_H_INCLUDED
|
||||
#define PB_DEVICEONLY_PB_H_INCLUDED
|
||||
@@ -27,7 +27,11 @@ typedef enum _ScreenFonts {
|
||||
typedef struct _ChannelFile {
|
||||
/* The channels our node knows about */
|
||||
pb_size_t channels_count;
|
||||
Channel channels[8];
|
||||
Channel channels[8];
|
||||
/* A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code. */
|
||||
uint32_t version;
|
||||
} ChannelFile;
|
||||
|
||||
/* This message is never sent over the wire, but it is used for serializing DB
|
||||
@@ -38,30 +42,30 @@ typedef struct _ChannelFile {
|
||||
typedef struct _DeviceState {
|
||||
/* Read only settings/info about this node */
|
||||
bool has_my_node;
|
||||
MyNodeInfo my_node;
|
||||
MyNodeInfo my_node;
|
||||
/* My owner info */
|
||||
bool has_owner;
|
||||
User owner;
|
||||
User owner;
|
||||
/* TODO: REPLACE */
|
||||
pb_size_t node_db_count;
|
||||
NodeInfo node_db[64];
|
||||
NodeInfo node_db[80];
|
||||
/* Received packets saved for delivery to the phone */
|
||||
pb_size_t receive_queue_count;
|
||||
MeshPacket receive_queue[1];
|
||||
/* A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code. */
|
||||
bool has_rx_text_message;
|
||||
MeshPacket rx_text_message;
|
||||
MeshPacket receive_queue[1];
|
||||
/* We keep the last received text message (only) stored in the device flash,
|
||||
so we can show it on the screen.
|
||||
Might be null */
|
||||
uint32_t version;
|
||||
bool has_rx_text_message;
|
||||
MeshPacket rx_text_message;
|
||||
/* A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code. */
|
||||
uint32_t version;
|
||||
/* Used only during development.
|
||||
Indicates developer is testing and changes should never be saved to flash. */
|
||||
bool no_save;
|
||||
bool no_save;
|
||||
/* Some GPSes seem to have bogus settings from the factory, so we always do one factory reset. */
|
||||
bool did_gps_reset;
|
||||
bool did_gps_reset;
|
||||
} DeviceState;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
|
||||
@@ -69,15 +73,15 @@ typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
|
||||
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
|
||||
typedef struct _OEMStore {
|
||||
/* The Logo width in Px */
|
||||
uint32_t oem_icon_width;
|
||||
uint32_t oem_icon_width;
|
||||
/* The Logo height in Px */
|
||||
uint32_t oem_icon_height;
|
||||
uint32_t oem_icon_height;
|
||||
/* The Logo in xbm bytechar format */
|
||||
OEMStore_oem_icon_bits_t oem_icon_bits;
|
||||
OEMStore_oem_icon_bits_t oem_icon_bits;
|
||||
/* Use this font for the OEM text. */
|
||||
ScreenFonts oem_font;
|
||||
ScreenFonts oem_font;
|
||||
/* Use this font for the OEM text. */
|
||||
char oem_text[40];
|
||||
char oem_text[40];
|
||||
} OEMStore;
|
||||
|
||||
|
||||
@@ -92,15 +96,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
|
||||
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}, 0}
|
||||
#define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
|
||||
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
|
||||
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}, 0}
|
||||
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelFile_channels_tag 1
|
||||
#define ChannelFile_version_tag 2
|
||||
#define DeviceState_my_node_tag 2
|
||||
#define DeviceState_owner_tag 3
|
||||
#define DeviceState_node_db_tag 4
|
||||
@@ -134,7 +139,8 @@ X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
|
||||
#define DeviceState_rx_text_message_MSGTYPE MeshPacket
|
||||
|
||||
#define ChannelFile_FIELDLIST(X, a) \
|
||||
X(a, STATIC, REPEATED, MESSAGE, channels, 1)
|
||||
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 2)
|
||||
#define ChannelFile_CALLBACK NULL
|
||||
#define ChannelFile_DEFAULT NULL
|
||||
#define ChannelFile_channels_MSGTYPE Channel
|
||||
@@ -158,8 +164,8 @@ extern const pb_msgdesc_t OEMStore_msg;
|
||||
#define OEMStore_fields &OEMStore_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelFile_size 832
|
||||
#define DeviceState_size 19327
|
||||
#define ChannelFile_size 630
|
||||
#define DeviceState_size 23728
|
||||
#define OEMStore_size 2106
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "radioconfig.pb.h"
|
||||
#include "localonly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(RadioConfig, RadioConfig, 2)
|
||||
|
||||
|
||||
PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PB_BIND(LocalConfig, LocalConfig, 2)
|
||||
|
||||
|
||||
PB_BIND(LocalModuleConfig, LocalModuleConfig, 2)
|
||||
|
||||
|
||||
|
||||
148
src/mesh/generated/localonly.pb.h
Normal file
148
src/mesh/generated/localonly.pb.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_LOCALONLY_PB_H_INCLUDED
|
||||
#define PB_LOCALONLY_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "config.pb.h"
|
||||
#include "module_config.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _LocalConfig {
|
||||
/* The part of the config that is specific to the Device */
|
||||
bool has_device;
|
||||
Config_DeviceConfig device;
|
||||
/* The part of the config that is specific to the GPS Position */
|
||||
bool has_position;
|
||||
Config_PositionConfig position;
|
||||
/* The part of the config that is specific to the Power settings */
|
||||
bool has_power;
|
||||
Config_PowerConfig power;
|
||||
/* The part of the config that is specific to the Wifi Settings */
|
||||
bool has_wifi;
|
||||
Config_WiFiConfig wifi;
|
||||
/* The part of the config that is specific to the Display */
|
||||
bool has_display;
|
||||
Config_DisplayConfig display;
|
||||
/* The part of the config that is specific to the Lora Radio */
|
||||
bool has_lora;
|
||||
Config_LoRaConfig lora;
|
||||
/* A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code. */
|
||||
uint32_t version;
|
||||
} LocalConfig;
|
||||
|
||||
typedef struct _LocalModuleConfig {
|
||||
/* The part of the config that is specific to the MQTT module */
|
||||
bool has_mqtt;
|
||||
ModuleConfig_MQTTConfig mqtt;
|
||||
/* The part of the config that is specific to the Serial module */
|
||||
bool has_serial;
|
||||
ModuleConfig_SerialConfig serial;
|
||||
/* The part of the config that is specific to the ExternalNotification module */
|
||||
bool has_external_notification;
|
||||
ModuleConfig_ExternalNotificationConfig external_notification;
|
||||
/* The part of the config that is specific to the Store & Forward module */
|
||||
bool has_store_forward;
|
||||
ModuleConfig_StoreForwardConfig store_forward;
|
||||
/* The part of the config that is specific to the RangeTest module */
|
||||
bool has_range_test;
|
||||
ModuleConfig_RangeTestConfig range_test;
|
||||
/* The part of the config that is specific to the Telemetry module */
|
||||
bool has_telemetry;
|
||||
ModuleConfig_TelemetryConfig telemetry;
|
||||
/* The part of the config that is specific to the Canned Message module */
|
||||
bool has_canned_message;
|
||||
ModuleConfig_CannedMessageConfig canned_message;
|
||||
/* A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code. */
|
||||
uint32_t version;
|
||||
} LocalModuleConfig;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define LocalConfig_init_default {false, Config_DeviceConfig_init_default, false, Config_PositionConfig_init_default, false, Config_PowerConfig_init_default, false, Config_WiFiConfig_init_default, false, Config_DisplayConfig_init_default, false, Config_LoRaConfig_init_default, 0}
|
||||
#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default, 0}
|
||||
#define LocalConfig_init_zero {false, Config_DeviceConfig_init_zero, false, Config_PositionConfig_init_zero, false, Config_PowerConfig_init_zero, false, Config_WiFiConfig_init_zero, false, Config_DisplayConfig_init_zero, false, Config_LoRaConfig_init_zero, 0}
|
||||
#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define LocalConfig_device_tag 1
|
||||
#define LocalConfig_position_tag 2
|
||||
#define LocalConfig_power_tag 3
|
||||
#define LocalConfig_wifi_tag 4
|
||||
#define LocalConfig_display_tag 5
|
||||
#define LocalConfig_lora_tag 6
|
||||
#define LocalConfig_version_tag 7
|
||||
#define LocalModuleConfig_mqtt_tag 1
|
||||
#define LocalModuleConfig_serial_tag 2
|
||||
#define LocalModuleConfig_external_notification_tag 3
|
||||
#define LocalModuleConfig_store_forward_tag 4
|
||||
#define LocalModuleConfig_range_test_tag 5
|
||||
#define LocalModuleConfig_telemetry_tag 6
|
||||
#define LocalModuleConfig_canned_message_tag 7
|
||||
#define LocalModuleConfig_version_tag 8
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define LocalConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, device, 1) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, position, 2) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, power, 3) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, wifi, 4) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, display, 5) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, lora, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 7)
|
||||
#define LocalConfig_CALLBACK NULL
|
||||
#define LocalConfig_DEFAULT NULL
|
||||
#define LocalConfig_device_MSGTYPE Config_DeviceConfig
|
||||
#define LocalConfig_position_MSGTYPE Config_PositionConfig
|
||||
#define LocalConfig_power_MSGTYPE Config_PowerConfig
|
||||
#define LocalConfig_wifi_MSGTYPE Config_WiFiConfig
|
||||
#define LocalConfig_display_MSGTYPE Config_DisplayConfig
|
||||
#define LocalConfig_lora_MSGTYPE Config_LoRaConfig
|
||||
|
||||
#define LocalModuleConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, mqtt, 1) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, serial, 2) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, external_notification, 3) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 8)
|
||||
#define LocalModuleConfig_CALLBACK NULL
|
||||
#define LocalModuleConfig_DEFAULT NULL
|
||||
#define LocalModuleConfig_mqtt_MSGTYPE ModuleConfig_MQTTConfig
|
||||
#define LocalModuleConfig_serial_MSGTYPE ModuleConfig_SerialConfig
|
||||
#define LocalModuleConfig_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig
|
||||
#define LocalModuleConfig_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig
|
||||
#define LocalModuleConfig_range_test_MSGTYPE ModuleConfig_RangeTestConfig
|
||||
#define LocalModuleConfig_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
|
||||
#define LocalModuleConfig_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
|
||||
|
||||
extern const pb_msgdesc_t LocalConfig_msg;
|
||||
extern const pb_msgdesc_t LocalModuleConfig_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define LocalConfig_fields &LocalConfig_msg
|
||||
#define LocalModuleConfig_fields &LocalModuleConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define LocalConfig_size 319
|
||||
#define LocalModuleConfig_size 288
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "mesh.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
@@ -45,6 +45,8 @@ PB_BIND(ToRadio, ToRadio, 2)
|
||||
PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Compressed, Compressed, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_MESH_PB_H_INCLUDED
|
||||
#define PB_MESH_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "config.pb.h"
|
||||
#include "module_config.pb.h"
|
||||
#include "portnums.pb.h"
|
||||
#include "telemetry.pb.h"
|
||||
|
||||
@@ -65,45 +67,14 @@ typedef enum _HardwareModel {
|
||||
HardwareModel_NANO_G1 = 41,
|
||||
/* nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ */
|
||||
HardwareModel_NRF52840_PCA10059 = 42,
|
||||
/* Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 */
|
||||
HardwareModel_DR_DEV = 43,
|
||||
/* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */
|
||||
HardwareModel_M5STACK = 44,
|
||||
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
|
||||
HardwareModel_PRIVATE_HW = 255
|
||||
} HardwareModel;
|
||||
|
||||
/* The team colors are based on the names of "friendly teams" in ATAK:
|
||||
https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */
|
||||
typedef enum _Team {
|
||||
/* the default (unset) is "achromatic" (unaffiliated) */
|
||||
Team_CLEAR = 0,
|
||||
/* TODO: REPLACE */
|
||||
Team_CYAN = 1,
|
||||
/* TODO: REPLACE */
|
||||
Team_WHITE = 2,
|
||||
/* TODO: REPLACE */
|
||||
Team_YELLOW = 3,
|
||||
/* TODO: REPLACE */
|
||||
Team_ORANGE = 4,
|
||||
/* TODO: REPLACE */
|
||||
Team_MAGENTA = 5,
|
||||
/* TODO: REPLACE */
|
||||
Team_RED = 6,
|
||||
/* TODO: REPLACE */
|
||||
Team_MAROON = 7,
|
||||
/* TODO: REPLACE */
|
||||
Team_PURPLE = 8,
|
||||
/* TODO: REPLACE */
|
||||
Team_DARK_BLUE = 9,
|
||||
/* TODO: REPLACE */
|
||||
Team_BLUE = 10,
|
||||
/* TODO: REPLACE */
|
||||
Team_TEAL = 11,
|
||||
/* TODO: REPLACE */
|
||||
Team_GREEN = 12,
|
||||
/* TODO: REPLACE */
|
||||
Team_DARK_GREEN = 13,
|
||||
/* TODO: REPLACE */
|
||||
Team_BROWN = 14
|
||||
} Team;
|
||||
|
||||
/* Shared constants between device and phone */
|
||||
typedef enum _Constants {
|
||||
/* First enum must be zero, and we are just using this enum to
|
||||
@@ -164,18 +135,17 @@ typedef enum _Position_LocSource {
|
||||
Position_LocSource_LOCSRC_GPS_EXTERNAL = 3
|
||||
} Position_LocSource;
|
||||
|
||||
/* The team colors are based on the names of "friendly teams" in ATAK:
|
||||
https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */
|
||||
/* Shared constants between device and phone */
|
||||
typedef enum _Position_AltSource {
|
||||
/* the default (unset) is "achromatic" (unaffiliated) */
|
||||
/* First enum must be zero, and we are just using this enum to
|
||||
pass int constants between two very different environments */
|
||||
Position_AltSource_ALTSRC_UNSPECIFIED = 0,
|
||||
/* TODO: REPLACE */
|
||||
/* From mesh.options
|
||||
note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
|
||||
outside of this envelope */
|
||||
Position_AltSource_ALTSRC_MANUAL_ENTRY = 1,
|
||||
/* TODO: REPLACE */
|
||||
Position_AltSource_ALTSRC_GPS_INTERNAL = 2,
|
||||
/* TODO: REPLACE */
|
||||
Position_AltSource_ALTSRC_GPS_EXTERNAL = 3,
|
||||
/* TODO: REPLACE */
|
||||
Position_AltSource_ALTSRC_BAROMETRIC = 4
|
||||
} Position_AltSource;
|
||||
|
||||
@@ -232,14 +202,15 @@ typedef enum _MeshPacket_Priority {
|
||||
MeshPacket_Priority_MAX = 127
|
||||
} MeshPacket_Priority;
|
||||
|
||||
/* The team colors are based on the names of "friendly teams" in ATAK:
|
||||
https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */
|
||||
/* Shared constants between device and phone */
|
||||
typedef enum _MeshPacket_Delayed {
|
||||
/* the default (unset) is "achromatic" (unaffiliated) */
|
||||
/* First enum must be zero, and we are just using this enum to
|
||||
pass int constants between two very different environments */
|
||||
MeshPacket_Delayed_NO_DELAY = 0,
|
||||
/* TODO: REPLACE */
|
||||
/* From mesh.options
|
||||
note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
|
||||
outside of this envelope */
|
||||
MeshPacket_Delayed_DELAYED_BROADCAST = 1,
|
||||
/* TODO: REPLACE */
|
||||
MeshPacket_Delayed_DELAYED_DIRECT = 2
|
||||
} MeshPacket_Delayed;
|
||||
|
||||
@@ -266,18 +237,24 @@ typedef enum _LogRecord_Level {
|
||||
} LogRecord_Level;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
|
||||
typedef struct _Compressed {
|
||||
PortNum portnum;
|
||||
Compressed_data_t data;
|
||||
} Compressed;
|
||||
|
||||
/* Location of a waypoint to associate with a message */
|
||||
typedef struct _Location {
|
||||
/* Id of the location */
|
||||
uint32_t id;
|
||||
uint32_t id;
|
||||
/* latitude_i */
|
||||
int32_t latitude_i;
|
||||
int32_t latitude_i;
|
||||
/* longitude_i */
|
||||
int32_t longitude_i;
|
||||
int32_t longitude_i;
|
||||
/* Time the location is to expire (epoch) */
|
||||
uint32_t expire;
|
||||
uint32_t expire;
|
||||
/* If true, only allow the original sender to update the location. */
|
||||
bool locked;
|
||||
bool locked;
|
||||
} Location;
|
||||
|
||||
/* Debug output from the device.
|
||||
@@ -287,13 +264,13 @@ typedef struct _Location {
|
||||
and then extend as needed by emitting multiple records. */
|
||||
typedef struct _LogRecord {
|
||||
/* Log levels, chosen to match python logging conventions. */
|
||||
char message[64];
|
||||
char message[64];
|
||||
/* Seconds since 1970 - or 0 for unknown/unset */
|
||||
uint32_t time;
|
||||
uint32_t time;
|
||||
/* Usually based on thread name - if known */
|
||||
char source[8];
|
||||
char source[8];
|
||||
/* Not yet set */
|
||||
LogRecord_Level level;
|
||||
LogRecord_Level level;
|
||||
} LogRecord;
|
||||
|
||||
/* Unique local debugging info for this node
|
||||
@@ -302,139 +279,134 @@ typedef struct _LogRecord {
|
||||
typedef struct _MyNodeInfo {
|
||||
/* Tells the phone what our node number is, default starting value is
|
||||
lowbyte of macaddr, but it will be fixed if that is already in use */
|
||||
uint32_t my_node_num;
|
||||
uint32_t my_node_num;
|
||||
/* Note: This flag merely means we detected a hardware GPS in our node.
|
||||
Not the same as UserPreferences.location_sharing */
|
||||
bool has_gps;
|
||||
/* The maximum number of 'software' channels that can be set on this node. */
|
||||
char region[12];
|
||||
/* Deprecated! ONLY USED IN DEVICE CODE (for upgrading old 1.0 firmwares) DO NOT READ ELSEWHERE.
|
||||
The region code for my radio (US, CN, etc...)
|
||||
Note: This string is deprecated.
|
||||
The 1.0 builds populate it based on the flashed firmware name.
|
||||
But for newer builds this string will be unpopulated (missing/null).
|
||||
For those builds you should instead look at the new read/write region enum in UserSettings
|
||||
The format of this string was 1.0-US or 1.0-CN etc.. Or empty string if unset. */
|
||||
char firmware_version[18];
|
||||
bool has_gps;
|
||||
/* 0.0.5 etc... */
|
||||
CriticalErrorCode error_code;
|
||||
char firmware_version[18];
|
||||
/* An error message we'd like to report back to the mothership through analytics.
|
||||
It indicates a serious bug occurred on the device, the device coped with it,
|
||||
but we still want to tell the devs about the bug.
|
||||
This field will be cleared after the phone reads MyNodeInfo
|
||||
(i.e. it will only be reported once)
|
||||
a numeric error code to go with error message, zero means no error */
|
||||
uint32_t error_address;
|
||||
CriticalErrorCode error_code;
|
||||
/* A numeric error address (nonzero if available) */
|
||||
uint32_t error_count;
|
||||
uint32_t error_address;
|
||||
/* The total number of errors this node has ever encountered
|
||||
(well - since the last time we discarded preferences) */
|
||||
uint32_t reboot_count;
|
||||
uint32_t error_count;
|
||||
/* The total number of reboots this node has ever encountered
|
||||
(well - since the last time we discarded preferences) */
|
||||
float bitrate;
|
||||
uint32_t reboot_count;
|
||||
/* Calculated bitrate of the current channel (in Bytes Per Second) */
|
||||
uint32_t message_timeout_msec;
|
||||
float bitrate;
|
||||
/* How long before we consider a message abandoned and we can clear our
|
||||
caches of any messages in flight Normally quite large to handle the worst case
|
||||
message delivery time, 5 minutes.
|
||||
Formerly called FLOOD_EXPIRE_TIME in the device code */
|
||||
uint32_t min_app_version;
|
||||
uint32_t message_timeout_msec;
|
||||
/* The minimum app version that can talk to this device.
|
||||
Phone/PC apps should compare this to their build number and if too low tell the user they must update their app */
|
||||
uint32_t max_channels;
|
||||
uint32_t min_app_version;
|
||||
/* The maximum number of 'software' channels that can be set on this node. */
|
||||
uint32_t max_channels;
|
||||
/* 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
|
||||
pb_size_t air_period_tx_count;
|
||||
uint32_t air_period_tx[8];
|
||||
uint32_t air_period_tx[8];
|
||||
/* 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
|
||||
pb_size_t air_period_rx_count;
|
||||
uint32_t air_period_rx[8];
|
||||
uint32_t air_period_rx[8];
|
||||
/* Is the device wifi capable? */
|
||||
bool has_wifi;
|
||||
bool has_wifi;
|
||||
/* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
|
||||
float channel_utilization;
|
||||
float channel_utilization;
|
||||
/* Percent of airtime for transmission used within the last hour. */
|
||||
float air_util_tx;
|
||||
float air_util_tx;
|
||||
} MyNodeInfo;
|
||||
|
||||
/* a gps position */
|
||||
typedef struct _Position {
|
||||
/* The new preferred location encoding, divide by 1e-7 to get degrees
|
||||
in floating point */
|
||||
int32_t latitude_i;
|
||||
int32_t latitude_i;
|
||||
/* TODO: REPLACE */
|
||||
int32_t longitude_i;
|
||||
int32_t longitude_i;
|
||||
/* In meters above MSL (but see issue #359) */
|
||||
int32_t altitude;
|
||||
int32_t altitude;
|
||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
||||
from the phone so that the local device can set its RTC If it is sent over
|
||||
the mesh (because there are devices on the mesh without GPS), it will only
|
||||
be sent by devices which has a hardware GPS clock.
|
||||
seconds since 1970 */
|
||||
uint32_t time;
|
||||
uint32_t time;
|
||||
/* TODO: REPLACE */
|
||||
Position_LocSource location_source;
|
||||
Position_LocSource location_source;
|
||||
/* TODO: REPLACE */
|
||||
Position_AltSource altitude_source;
|
||||
Position_AltSource altitude_source;
|
||||
/* Positional timestamp (actual timestamp of GPS solution) in integer epoch seconds */
|
||||
uint32_t pos_timestamp;
|
||||
uint32_t pos_timestamp;
|
||||
/* Pos. timestamp milliseconds adjustment (rarely available or required) */
|
||||
int32_t pos_time_millis;
|
||||
int32_t pos_time_millis;
|
||||
/* HAE altitude in meters - can be used instead of MSL altitude */
|
||||
int32_t altitude_hae;
|
||||
int32_t altitude_hae;
|
||||
/* Geoidal separation in meters */
|
||||
int32_t alt_geoid_sep;
|
||||
int32_t alt_geoid_sep;
|
||||
/* Horizontal, Vertical and Position Dilution of Precision, in 1/100 units
|
||||
- PDOP is sufficient for most cases
|
||||
- for higher precision scenarios, HDOP and VDOP can be used instead,
|
||||
in which case PDOP becomes redundant (PDOP=sqrt(HDOP^2 + VDOP^2))
|
||||
TODO: REMOVE/INTEGRATE */
|
||||
uint32_t PDOP;
|
||||
uint32_t PDOP;
|
||||
/* TODO: REPLACE */
|
||||
uint32_t HDOP;
|
||||
uint32_t HDOP;
|
||||
/* TODO: REPLACE */
|
||||
uint32_t VDOP;
|
||||
uint32_t VDOP;
|
||||
/* GPS accuracy (a hardware specific constant) in mm
|
||||
multiplied with DOP to calculate positional accuracy
|
||||
Default: "'bout three meters-ish" :) */
|
||||
uint32_t gps_accuracy;
|
||||
uint32_t gps_accuracy;
|
||||
/* Ground speed in m/s and True North TRACK in 1/100 degrees
|
||||
Clarification of terms:
|
||||
- "track" is the direction of motion (measured in horizontal plane)
|
||||
- "heading" is where the fuselage points (measured in horizontal plane)
|
||||
- "yaw" indicates a relative rotation about the vertical axis
|
||||
TODO: REMOVE/INTEGRATE */
|
||||
uint32_t ground_speed;
|
||||
uint32_t ground_speed;
|
||||
/* TODO: REPLACE */
|
||||
uint32_t ground_track;
|
||||
uint32_t ground_track;
|
||||
/* GPS fix quality (from NMEA GxGGA statement or similar) */
|
||||
uint32_t fix_quality;
|
||||
uint32_t fix_quality;
|
||||
/* GPS fix type 2D/3D (from NMEA GxGSA statement) */
|
||||
uint32_t fix_type;
|
||||
uint32_t fix_type;
|
||||
/* GPS "Satellites in View" number */
|
||||
uint32_t sats_in_view;
|
||||
uint32_t sats_in_view;
|
||||
/* Sensor ID - in case multiple positioning sensors are being used */
|
||||
uint32_t sensor_id;
|
||||
uint32_t sensor_id;
|
||||
/* Estimated/expected time (in seconds) until next update:
|
||||
- if we update at fixed intervals of X seconds, use X
|
||||
- if we update at dynamic intervals (based on relative movement etc),
|
||||
but "AT LEAST every Y seconds", use Y */
|
||||
uint32_t pos_next_update;
|
||||
uint32_t pos_next_update;
|
||||
/* A sequence number, incremented with each Position message to help
|
||||
detect lost updates if needed */
|
||||
uint32_t pos_seq_number;
|
||||
uint32_t pos_seq_number;
|
||||
} Position;
|
||||
|
||||
/* A message used in our Dynamic Source Routing protocol (RFC 4728 based) */
|
||||
typedef struct _RouteDiscovery {
|
||||
/* The list of nodenums this packet has visited so far */
|
||||
pb_size_t route_count;
|
||||
uint32_t route[8];
|
||||
uint32_t route[8];
|
||||
} RouteDiscovery;
|
||||
|
||||
/* Compressed message payload */
|
||||
typedef struct _ToRadio_PeerInfo {
|
||||
uint32_t app_version;
|
||||
bool mqtt_gateway;
|
||||
/* PortNum to determine the how to handle the compressed payload. */
|
||||
uint32_t app_version;
|
||||
/* Compressed data. */
|
||||
bool mqtt_gateway;
|
||||
} ToRadio_PeerInfo;
|
||||
|
||||
/* Broadcast when a newly powered mesh node wants to find a node num it can use
|
||||
@@ -462,82 +434,71 @@ typedef struct _User {
|
||||
In the case of Signal that would mean +16504442323, for the default macaddr derived id it would be !<8 hexidecimal bytes>.
|
||||
Note: app developers are encouraged to also use the following standard
|
||||
node IDs "^all" (for broadcast), "^local" (for the locally connected node) */
|
||||
char id[16];
|
||||
char id[16];
|
||||
/* A full name for this user, i.e. "Kevin Hester" */
|
||||
char long_name[40];
|
||||
char long_name[40];
|
||||
/* A VERY short name, ideally two characters.
|
||||
Suitable for a tiny OLED screen */
|
||||
char short_name[5];
|
||||
char short_name[5];
|
||||
/* This is the addr of the radio.
|
||||
Not populated by the phone, but added by the esp32 when broadcasting */
|
||||
pb_byte_t macaddr[6];
|
||||
pb_byte_t macaddr[6];
|
||||
/* TBEAM, HELTEC, etc...
|
||||
Starting in 1.2.11 moved to hw_model enum in the NodeInfo object.
|
||||
Apps will still need the string here for older builds
|
||||
(so OTA update can find the right image), but if the enum is available it will be used instead. */
|
||||
HardwareModel hw_model;
|
||||
HardwareModel hw_model;
|
||||
/* In some regions Ham radio operators have different bandwidth limitations than others.
|
||||
If this user is a licensed operator, set this flag.
|
||||
Also, "long_name" should be their licence number. */
|
||||
bool is_licensed;
|
||||
/* Participants in the same network can self-group into different teams.
|
||||
Short-term this can be used to visually differentiate them on the map;
|
||||
in the longer term it could also help users to semi-automatically
|
||||
select or ignore messages according to team affiliation.
|
||||
In total, 14 teams are defined (encoded in 4 bits) */
|
||||
Team team;
|
||||
bool is_licensed;
|
||||
/* Transmit power at antenna connector, in decibel-milliwatt
|
||||
An optional self-reported value useful in network planning, discovery
|
||||
and positioning - along with ant_gain_dbi and ant_azimuth below */
|
||||
uint32_t tx_power_dbm;
|
||||
uint32_t tx_power_dbm;
|
||||
/* Antenna gain (applicable to both Tx and Rx), in decibel-isotropic */
|
||||
uint32_t ant_gain_dbi;
|
||||
uint32_t ant_gain_dbi;
|
||||
/* Directional antenna true azimuth *if applicable*, in degrees (0-360)
|
||||
Only applicable in case of stationary nodes with a directional antenna
|
||||
Zero = not applicable (mobile or omni) or not specified
|
||||
(use a value of 360 to indicate an antenna azimuth of zero degrees) */
|
||||
uint32_t ant_azimuth;
|
||||
uint32_t ant_azimuth;
|
||||
} User;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(237) Data_payload_t;
|
||||
typedef PB_BYTES_ARRAY_T(237) Data_payload_compressed_t;
|
||||
/* (Formerly called SubPacket)
|
||||
The payload portion fo a packet, this is the actual bytes that are sent
|
||||
inside a radio packet (because from/to are broken out by the comms library) */
|
||||
typedef struct _Data {
|
||||
/* Formerly named typ and of type Type */
|
||||
PortNum portnum;
|
||||
PortNum portnum;
|
||||
/* TODO: REPLACE */
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
Data_payload_t payload;
|
||||
Data_payload_compressed_t payload_compressed;
|
||||
};
|
||||
/* TODO: REPLACE */
|
||||
bool want_response;
|
||||
Data_payload_t payload;
|
||||
/* Not normally used, but for testing a sender can request that recipient
|
||||
responds in kind (i.e. if it received a position, it should unicast back it's position).
|
||||
Note: that if you set this on a broadcast you will receive many replies. */
|
||||
uint32_t dest;
|
||||
bool want_response;
|
||||
/* The address of the destination node.
|
||||
This field is is filled in by the mesh radio device software, application
|
||||
layer software should never need it.
|
||||
RouteDiscovery messages _must_ populate this.
|
||||
Other message types might need to if they are doing multihop routing. */
|
||||
uint32_t source;
|
||||
uint32_t dest;
|
||||
/* The address of the original sender for this message.
|
||||
This field should _only_ be populated for reliable multihop packets (to keep
|
||||
packets small). */
|
||||
uint32_t request_id;
|
||||
uint32_t source;
|
||||
/* Only used in routing or response messages.
|
||||
Indicates the original message ID that this message is reporting failure on. (formerly called original_id) */
|
||||
uint32_t reply_id;
|
||||
uint32_t request_id;
|
||||
/* If set, this message is intened to be a reply to a previously sent message with the defined id. */
|
||||
uint32_t emoji;
|
||||
uint32_t reply_id;
|
||||
/* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving
|
||||
a message a heart or poop emoji. */
|
||||
uint32_t emoji;
|
||||
/* Location structure */
|
||||
bool has_location;
|
||||
Location location;
|
||||
Location location;
|
||||
} Data;
|
||||
|
||||
/* The bluetooth to device link:
|
||||
@@ -558,33 +519,36 @@ typedef struct _Data {
|
||||
Full information about a node on the mesh */
|
||||
typedef struct _NodeInfo {
|
||||
/* The node number */
|
||||
uint32_t num;
|
||||
uint32_t num;
|
||||
/* The user info for this node */
|
||||
bool has_user;
|
||||
User user;
|
||||
User user;
|
||||
/* This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
|
||||
Position.time now indicates the last time we received a POSITION from that node. */
|
||||
bool has_position;
|
||||
Position position;
|
||||
Position position;
|
||||
/* Returns the Signal-to-noise ratio (SNR) of the last received message,
|
||||
as measured by the receiver. Return SNR of the last received message in dB */
|
||||
float snr;
|
||||
float snr;
|
||||
/* Set to indicate the last time we received a packet from this node */
|
||||
uint32_t last_heard;
|
||||
uint32_t last_heard;
|
||||
/* The latest device metrics for the node. */
|
||||
bool has_device_metrics;
|
||||
DeviceMetrics device_metrics;
|
||||
DeviceMetrics device_metrics;
|
||||
} NodeInfo;
|
||||
|
||||
/* A Routing control Data packet handled by the routing module */
|
||||
typedef struct _Routing {
|
||||
/* A route request going from the requester */
|
||||
pb_size_t which_variant;
|
||||
union {
|
||||
/* A route request going from the requester */
|
||||
RouteDiscovery route_request;
|
||||
/* A route reply */
|
||||
RouteDiscovery route_reply;
|
||||
/* A failure in delivering a message (usually used for routing control messages, but might be provided
|
||||
in addition to ack.fail_id to provide details on the type of failure). */
|
||||
Routing_Error error_reason;
|
||||
};
|
||||
};
|
||||
} Routing;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
||||
@@ -596,10 +560,10 @@ typedef struct _MeshPacket {
|
||||
Note: Our crypto implementation uses this field as well.
|
||||
See [crypto](/docs/developers/firmware/encryption) for details.
|
||||
FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. */
|
||||
uint32_t from;
|
||||
uint32_t from;
|
||||
/* The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only
|
||||
hurts the ble link though. */
|
||||
uint32_t to;
|
||||
uint32_t to;
|
||||
/* (Usually) If set, this indicates the index in the secondary_channels table that this packet was sent/received on.
|
||||
If unset, packet was on the primary channel.
|
||||
A particular node might know only a subset of channels in use on the mesh.
|
||||
@@ -607,15 +571,14 @@ typedef struct _MeshPacket {
|
||||
Very briefly, while sending and receiving deep inside the device Router code, this field instead
|
||||
contains the 'channel hash' instead of the index.
|
||||
This 'trick' is only used while the payloadVariant is an 'encrypted'. */
|
||||
uint8_t channel;
|
||||
/* TODO: REPLACE */
|
||||
uint8_t channel;
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
/* TODO: REPLACE */
|
||||
Data decoded;
|
||||
/* TODO: REPLACE */
|
||||
MeshPacket_encrypted_t encrypted;
|
||||
};
|
||||
/* TODO: REPLACE */
|
||||
uint32_t id;
|
||||
};
|
||||
/* A unique ID for this packet.
|
||||
Always 0 for no-ack packets or non broadcast packets (and therefore take zero bytes of space).
|
||||
Otherwise a unique ID for this packet, useful for flooding algorithms.
|
||||
@@ -626,21 +589,21 @@ typedef struct _MeshPacket {
|
||||
See [crypto](/docs/developers/firmware/encryption) for details.
|
||||
FIXME - really should be fixed32 instead, this encoding only
|
||||
hurts the ble link though. */
|
||||
uint32_t rx_time;
|
||||
uint32_t id;
|
||||
/* The time this message was received by the esp32 (secs since 1970).
|
||||
Note: this field is _never_ sent on the radio link itself (to save space) Times
|
||||
are typically not sent over the mesh, but they will be added to any Packet
|
||||
(chain of SubPacket) sent to the phone (so the phone can know exact time of reception) */
|
||||
float rx_snr;
|
||||
uint32_t rx_time;
|
||||
/* *Never* sent over the radio links.
|
||||
Set during reception to indicate the SNR of this packet.
|
||||
Used to collect statistics on current link quality. */
|
||||
uint8_t hop_limit;
|
||||
float rx_snr;
|
||||
/* If unset treated as zero (no forwarding, send to adjacent nodes only)
|
||||
if 1, allow hopping through one node, etc...
|
||||
For our usecase real world topologies probably have a max of about 3.
|
||||
This field is normally placed into a few of bits in the header. */
|
||||
bool want_ack;
|
||||
uint8_t hop_limit;
|
||||
/* This packet is being sent as a reliable message, we would prefer it to arrive at the destination.
|
||||
We would like to receive a ack packet in response.
|
||||
Broadcasts messages treat this flag specially: Since acks for broadcasts would
|
||||
@@ -650,12 +613,14 @@ typedef struct _MeshPacket {
|
||||
So FloodingRouter.cpp generates an implicit ack which is delivered to the original sender.
|
||||
If after some time we don't hear anyone rebroadcast our packet, we will timeout and retransmit, using the regular resend logic.
|
||||
Note: This flag is normally sent in a flag bit in the header when sent over the wire */
|
||||
MeshPacket_Priority priority;
|
||||
bool want_ack;
|
||||
/* The priority of this message for sending.
|
||||
See MeshPacket.Priority description for more details. */
|
||||
int32_t rx_rssi;
|
||||
MeshPacket_Priority priority;
|
||||
/* rssi of received packet. Only sent to phone for dispay purposes. */
|
||||
MeshPacket_Delayed delayed;
|
||||
int32_t rx_rssi;
|
||||
/* Describe if this message is delayed */
|
||||
MeshPacket_Delayed delayed;
|
||||
} MeshPacket;
|
||||
|
||||
/* Packets from the radio to the phone will appear on the fromRadio characteristic.
|
||||
@@ -665,30 +630,60 @@ typedef struct _MeshPacket {
|
||||
typedef struct _FromRadio {
|
||||
/* The packet id, used to allow the phone to request missing read packets from the FIFO,
|
||||
see our bluetooth docs */
|
||||
uint32_t id;
|
||||
/* Log levels, chosen to match python logging conventions. */
|
||||
uint32_t id;
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
/* Tells the phone what our node number is, can be -1 if we've not yet joined a mesh.
|
||||
NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. */
|
||||
MyNodeInfo my_info;
|
||||
/* One packet is sent for each node in the on radio DB
|
||||
starts over with the first node in our DB */
|
||||
NodeInfo node_info;
|
||||
/* Include a part of the config (was: RadioConfig radio) */
|
||||
Config config;
|
||||
/* Set to send debug console output over our protobuf stream */
|
||||
LogRecord log_record;
|
||||
/* Sent as true once the device has finished sending all of the responses to want_config
|
||||
recipient should check if this ID matches our original request nonce, if
|
||||
not, it means your config responses haven't started yet.
|
||||
NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. */
|
||||
uint32_t config_complete_id;
|
||||
/* Sent to tell clients the radio has just rebooted.
|
||||
Set to true if present.
|
||||
Not used on all transports, currently just used for the serial console.
|
||||
NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. */
|
||||
bool rebooted;
|
||||
/* Include module config */
|
||||
ModuleConfig moduleConfig;
|
||||
/* Log levels, chosen to match python logging conventions. */
|
||||
MeshPacket packet;
|
||||
};
|
||||
};
|
||||
} FromRadio;
|
||||
|
||||
/* Packets/commands to the radio will be written (reliably) to the toRadio characteristic.
|
||||
Once the write completes the phone can assume it is handled. */
|
||||
typedef struct _ToRadio {
|
||||
/* Send this packet on the mesh */
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
/* Send this packet on the mesh */
|
||||
MeshPacket packet;
|
||||
/* Information about the peer, sent after the phone sneds want_config_id.
|
||||
Old clients do not send this, which is fine. */
|
||||
ToRadio_PeerInfo peer_info;
|
||||
/* Phone wants radio to send full node db to the phone, This is
|
||||
typically the first packet sent to the radio when the phone gets a
|
||||
bluetooth connection. The radio will respond by sending back a
|
||||
MyNodeInfo, a owner, a radio config and a series of
|
||||
FromRadio.node_infos, and config_complete
|
||||
the integer you write into this field will be reported back in the
|
||||
config_complete_id response this allows clients to never be confused by
|
||||
a stale old partially sent config. */
|
||||
uint32_t want_config_id;
|
||||
/* Tell API server we are disconnecting now.
|
||||
This is useful for serial links where there is no hardware/protocol based notification that the client has dropped the link.
|
||||
(Sending this message is optional for clients) */
|
||||
bool disconnect;
|
||||
};
|
||||
};
|
||||
} ToRadio;
|
||||
|
||||
|
||||
@@ -697,10 +692,6 @@ typedef struct _ToRadio {
|
||||
#define _HardwareModel_MAX HardwareModel_PRIVATE_HW
|
||||
#define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_PRIVATE_HW+1))
|
||||
|
||||
#define _Team_MIN Team_CLEAR
|
||||
#define _Team_MAX Team_BROWN
|
||||
#define _Team_ARRAYSIZE ((Team)(Team_BROWN+1))
|
||||
|
||||
#define _Constants_MIN Constants_Unused
|
||||
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
|
||||
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
|
||||
@@ -740,33 +731,37 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define Position_init_default {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
|
||||
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, 0, 0, 0}
|
||||
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define Routing_init_default {0, {RouteDiscovery_init_default}}
|
||||
#define Data_init_default {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_default}
|
||||
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, Location_init_default}
|
||||
#define Location_init_default {0, 0, 0, 0, 0}
|
||||
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
|
||||
#define MyNodeInfo_init_default {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define MyNodeInfo_init_default {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
||||
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
|
||||
#define ToRadio_init_default {0, {MeshPacket_init_default}}
|
||||
#define ToRadio_PeerInfo_init_default {0, 0}
|
||||
#define Compressed_init_default {_PortNum_MIN, {0, {0}}}
|
||||
#define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
|
||||
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, 0, 0, 0}
|
||||
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
|
||||
#define Data_init_zero {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero}
|
||||
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero}
|
||||
#define Location_init_zero {0, 0, 0, 0, 0}
|
||||
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
|
||||
#define MyNodeInfo_init_zero {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define MyNodeInfo_init_zero {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
||||
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
|
||||
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
|
||||
#define ToRadio_PeerInfo_init_zero {0, 0}
|
||||
#define Compressed_init_zero {_PortNum_MIN, {0, {0}}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define Compressed_portnum_tag 1
|
||||
#define Compressed_data_tag 2
|
||||
#define Location_id_tag 1
|
||||
#define Location_latitude_i_tag 2
|
||||
#define Location_longitude_i_tag 3
|
||||
@@ -778,7 +773,6 @@ extern "C" {
|
||||
#define LogRecord_level_tag 4
|
||||
#define MyNodeInfo_my_node_num_tag 1
|
||||
#define MyNodeInfo_has_gps_tag 2
|
||||
#define MyNodeInfo_region_tag 4
|
||||
#define MyNodeInfo_firmware_version_tag 6
|
||||
#define MyNodeInfo_error_code_tag 7
|
||||
#define MyNodeInfo_error_address_tag 8
|
||||
@@ -824,13 +818,11 @@ extern "C" {
|
||||
#define User_macaddr_tag 4
|
||||
#define User_hw_model_tag 6
|
||||
#define User_is_licensed_tag 7
|
||||
#define User_team_tag 8
|
||||
#define User_tx_power_dbm_tag 10
|
||||
#define User_ant_gain_dbi_tag 11
|
||||
#define User_ant_azimuth_tag 12
|
||||
#define Data_portnum_tag 1
|
||||
#define Data_payload_tag 2
|
||||
#define Data_payload_compressed_tag 10
|
||||
#define Data_want_response_tag 3
|
||||
#define Data_dest_tag 4
|
||||
#define Data_source_tag 5
|
||||
@@ -863,9 +855,11 @@ extern "C" {
|
||||
#define FromRadio_id_tag 1
|
||||
#define FromRadio_my_info_tag 3
|
||||
#define FromRadio_node_info_tag 4
|
||||
#define FromRadio_config_tag 6
|
||||
#define FromRadio_log_record_tag 7
|
||||
#define FromRadio_config_complete_id_tag 8
|
||||
#define FromRadio_rebooted_tag 9
|
||||
#define FromRadio_moduleConfig_tag 10
|
||||
#define FromRadio_packet_tag 11
|
||||
#define ToRadio_packet_tag 2
|
||||
#define ToRadio_peer_info_tag 3
|
||||
@@ -906,7 +900,6 @@ X(a, STATIC, SINGULAR, STRING, short_name, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, hw_model, 6) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_licensed, 7) \
|
||||
X(a, STATIC, SINGULAR, UENUM, team, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, tx_power_dbm, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ant_gain_dbi, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ant_azimuth, 12)
|
||||
@@ -929,15 +922,14 @@ X(a, STATIC, ONEOF, UENUM, (variant,error_reason,error_reason), 3)
|
||||
|
||||
#define Data_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payloadVariant,payload,payload), 2) \
|
||||
X(a, STATIC, SINGULAR, BYTES, payload, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, want_response, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, location, 9) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payloadVariant,payload_compressed,payload_compressed), 10)
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, location, 9)
|
||||
#define Data_CALLBACK NULL
|
||||
#define Data_DEFAULT NULL
|
||||
#define Data_location_MSGTYPE Location
|
||||
@@ -985,7 +977,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6)
|
||||
#define MyNodeInfo_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, region, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, firmware_version, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, error_code, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, error_address, 8) \
|
||||
@@ -1015,15 +1006,19 @@ X(a, STATIC, SINGULAR, UENUM, level, 4)
|
||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,my_info,my_info), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,node_info,node_info), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,config,config), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,log_record,log_record), 7) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payloadVariant,config_complete_id,config_complete_id), 8) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payloadVariant,rebooted,rebooted), 9) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,moduleConfig,moduleConfig), 10) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
|
||||
#define FromRadio_CALLBACK NULL
|
||||
#define FromRadio_DEFAULT NULL
|
||||
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
|
||||
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
|
||||
#define FromRadio_payloadVariant_config_MSGTYPE Config
|
||||
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
|
||||
#define FromRadio_payloadVariant_moduleConfig_MSGTYPE ModuleConfig
|
||||
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
|
||||
|
||||
#define ToRadio_FIELDLIST(X, a) \
|
||||
@@ -1042,6 +1037,12 @@ X(a, STATIC, SINGULAR, BOOL, mqtt_gateway, 2)
|
||||
#define ToRadio_PeerInfo_CALLBACK NULL
|
||||
#define ToRadio_PeerInfo_DEFAULT NULL
|
||||
|
||||
#define Compressed_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
||||
X(a, STATIC, SINGULAR, BYTES, data, 2)
|
||||
#define Compressed_CALLBACK NULL
|
||||
#define Compressed_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t Position_msg;
|
||||
extern const pb_msgdesc_t User_msg;
|
||||
extern const pb_msgdesc_t RouteDiscovery_msg;
|
||||
@@ -1055,6 +1056,7 @@ extern const pb_msgdesc_t LogRecord_msg;
|
||||
extern const pb_msgdesc_t FromRadio_msg;
|
||||
extern const pb_msgdesc_t ToRadio_msg;
|
||||
extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
|
||||
extern const pb_msgdesc_t Compressed_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define Position_fields &Position_msg
|
||||
@@ -1070,21 +1072,23 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
|
||||
#define FromRadio_fields &FromRadio_msg
|
||||
#define ToRadio_fields &ToRadio_msg
|
||||
#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
|
||||
#define Compressed_fields &Compressed_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Compressed_size 243
|
||||
#define Data_size 296
|
||||
#define FromRadio_size 356
|
||||
#define Location_size 24
|
||||
#define LogRecord_size 81
|
||||
#define MeshPacket_size 347
|
||||
#define MyNodeInfo_size 210
|
||||
#define NodeInfo_size 283
|
||||
#define MyNodeInfo_size 197
|
||||
#define NodeInfo_size 281
|
||||
#define Position_size 142
|
||||
#define RouteDiscovery_size 40
|
||||
#define Routing_size 42
|
||||
#define ToRadio_PeerInfo_size 8
|
||||
#define ToRadio_size 350
|
||||
#define User_size 97
|
||||
#define User_size 95
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
36
src/mesh/generated/module_config.pb.c
Normal file
36
src/mesh/generated/module_config.pb.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "module_config.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(ModuleConfig, ModuleConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_MQTTConfig, ModuleConfig_MQTTConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_SerialConfig, ModuleConfig_SerialConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_ExternalNotificationConfig, ModuleConfig_ExternalNotificationConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_StoreForwardConfig, ModuleConfig_StoreForwardConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_RangeTestConfig, ModuleConfig_RangeTestConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_TelemetryConfig, ModuleConfig_TelemetryConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_CannedMessageConfig, ModuleConfig_CannedMessageConfig, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
357
src/mesh/generated/module_config.pb.h
Normal file
357
src/mesh/generated/module_config.pb.h
Normal file
@@ -0,0 +1,357 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_MODULE_CONFIG_PB_H_INCLUDED
|
||||
#define PB_MODULE_CONFIG_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "telemetry.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _ModuleConfig_SerialConfig_Serial_Baud {
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 1,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_300 = 2,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_600 = 3,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200 = 4,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_2400 = 5,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_4800 = 6,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_9600 = 7,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_19200 = 8,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_38400 = 9,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_57600 = 10,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_115200 = 11,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_230400 = 12,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_460800 = 13,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_576000 = 14,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600 = 15
|
||||
} ModuleConfig_SerialConfig_Serial_Baud;
|
||||
|
||||
typedef enum _ModuleConfig_SerialConfig_Serial_Mode {
|
||||
ModuleConfig_SerialConfig_Serial_Mode_MODE_Default = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_MODE_SIMPLE = 1,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO = 2
|
||||
} ModuleConfig_SerialConfig_Serial_Mode;
|
||||
|
||||
typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE = 0,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP = 17,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN = 18,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT = 19,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT = 20,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT = 10,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK = 27,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL = 24
|
||||
} ModuleConfig_CannedMessageConfig_InputEventChar;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _ModuleConfig_CannedMessageConfig {
|
||||
bool rotary1_enabled;
|
||||
uint32_t inputbroker_pin_a;
|
||||
uint32_t inputbroker_pin_b;
|
||||
uint32_t inputbroker_pin_press;
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_cw;
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_ccw;
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_press;
|
||||
bool updown1_enabled;
|
||||
bool enabled;
|
||||
char allow_input_source[16];
|
||||
bool send_bell;
|
||||
} ModuleConfig_CannedMessageConfig;
|
||||
|
||||
typedef struct _ModuleConfig_ExternalNotificationConfig {
|
||||
bool enabled;
|
||||
uint32_t output_ms;
|
||||
uint32_t output;
|
||||
bool active;
|
||||
bool alert_message;
|
||||
bool alert_bell;
|
||||
} ModuleConfig_ExternalNotificationConfig;
|
||||
|
||||
typedef struct _ModuleConfig_MQTTConfig {
|
||||
bool disabled;
|
||||
char address[32];
|
||||
char username[32];
|
||||
char password[32];
|
||||
bool encryption_enabled;
|
||||
} ModuleConfig_MQTTConfig;
|
||||
|
||||
typedef struct _ModuleConfig_RangeTestConfig {
|
||||
bool enabled;
|
||||
uint32_t sender;
|
||||
bool save;
|
||||
} ModuleConfig_RangeTestConfig;
|
||||
|
||||
typedef struct _ModuleConfig_SerialConfig {
|
||||
bool enabled;
|
||||
bool echo;
|
||||
uint32_t rxd;
|
||||
uint32_t txd;
|
||||
ModuleConfig_SerialConfig_Serial_Baud baud;
|
||||
uint32_t timeout;
|
||||
ModuleConfig_SerialConfig_Serial_Mode mode;
|
||||
} ModuleConfig_SerialConfig;
|
||||
|
||||
typedef struct _ModuleConfig_StoreForwardConfig {
|
||||
bool enabled;
|
||||
bool heartbeat;
|
||||
uint32_t records;
|
||||
uint32_t history_return_max;
|
||||
uint32_t history_return_window;
|
||||
} ModuleConfig_StoreForwardConfig;
|
||||
|
||||
typedef struct _ModuleConfig_TelemetryConfig {
|
||||
uint32_t device_update_interval;
|
||||
uint32_t environment_update_interval;
|
||||
bool environment_measurement_enabled;
|
||||
bool environment_screen_enabled;
|
||||
uint32_t environment_read_error_count_threshold;
|
||||
uint32_t environment_recovery_interval;
|
||||
bool environment_display_fahrenheit;
|
||||
TelemetrySensorType environment_sensor_type;
|
||||
uint32_t environment_sensor_pin;
|
||||
} ModuleConfig_TelemetryConfig;
|
||||
|
||||
/* Module Config */
|
||||
typedef struct _ModuleConfig {
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_MQTTConfig mqtt;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_SerialConfig serial;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_ExternalNotificationConfig external_notification;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_StoreForwardConfig store_forward;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_RangeTestConfig range_test;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_TelemetryConfig telemetry;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_CannedMessageConfig canned_message;
|
||||
} payloadVariant;
|
||||
} ModuleConfig;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MAX ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
|
||||
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_MODE_Default
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO+1))
|
||||
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((ModuleConfig_CannedMessageConfig_InputEventChar)(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ModuleConfig_init_default {0, {ModuleConfig_MQTTConfig_init_default}}
|
||||
#define ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0}
|
||||
#define ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
|
||||
#define ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, _TelemetrySensorType_MIN, 0}
|
||||
#define ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||
#define ModuleConfig_init_zero {0, {ModuleConfig_MQTTConfig_init_zero}}
|
||||
#define ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0}
|
||||
#define ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
|
||||
#define ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, _TelemetrySensorType_MIN, 0}
|
||||
#define ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_press_tag 4
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_event_cw_tag 5
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_tag 6
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_event_press_tag 7
|
||||
#define ModuleConfig_CannedMessageConfig_updown1_enabled_tag 8
|
||||
#define ModuleConfig_CannedMessageConfig_enabled_tag 9
|
||||
#define ModuleConfig_CannedMessageConfig_allow_input_source_tag 10
|
||||
#define ModuleConfig_CannedMessageConfig_send_bell_tag 11
|
||||
#define ModuleConfig_ExternalNotificationConfig_enabled_tag 1
|
||||
#define ModuleConfig_ExternalNotificationConfig_output_ms_tag 2
|
||||
#define ModuleConfig_ExternalNotificationConfig_output_tag 3
|
||||
#define ModuleConfig_ExternalNotificationConfig_active_tag 4
|
||||
#define ModuleConfig_ExternalNotificationConfig_alert_message_tag 5
|
||||
#define ModuleConfig_ExternalNotificationConfig_alert_bell_tag 6
|
||||
#define ModuleConfig_MQTTConfig_disabled_tag 1
|
||||
#define ModuleConfig_MQTTConfig_address_tag 2
|
||||
#define ModuleConfig_MQTTConfig_username_tag 3
|
||||
#define ModuleConfig_MQTTConfig_password_tag 4
|
||||
#define ModuleConfig_MQTTConfig_encryption_enabled_tag 5
|
||||
#define ModuleConfig_RangeTestConfig_enabled_tag 1
|
||||
#define ModuleConfig_RangeTestConfig_sender_tag 2
|
||||
#define ModuleConfig_RangeTestConfig_save_tag 3
|
||||
#define ModuleConfig_SerialConfig_enabled_tag 1
|
||||
#define ModuleConfig_SerialConfig_echo_tag 2
|
||||
#define ModuleConfig_SerialConfig_rxd_tag 3
|
||||
#define ModuleConfig_SerialConfig_txd_tag 4
|
||||
#define ModuleConfig_SerialConfig_baud_tag 5
|
||||
#define ModuleConfig_SerialConfig_timeout_tag 6
|
||||
#define ModuleConfig_SerialConfig_mode_tag 7
|
||||
#define ModuleConfig_StoreForwardConfig_enabled_tag 1
|
||||
#define ModuleConfig_StoreForwardConfig_heartbeat_tag 2
|
||||
#define ModuleConfig_StoreForwardConfig_records_tag 3
|
||||
#define ModuleConfig_StoreForwardConfig_history_return_max_tag 4
|
||||
#define ModuleConfig_StoreForwardConfig_history_return_window_tag 5
|
||||
#define ModuleConfig_TelemetryConfig_device_update_interval_tag 1
|
||||
#define ModuleConfig_TelemetryConfig_environment_update_interval_tag 2
|
||||
#define ModuleConfig_TelemetryConfig_environment_measurement_enabled_tag 3
|
||||
#define ModuleConfig_TelemetryConfig_environment_screen_enabled_tag 4
|
||||
#define ModuleConfig_TelemetryConfig_environment_read_error_count_threshold_tag 5
|
||||
#define ModuleConfig_TelemetryConfig_environment_recovery_interval_tag 6
|
||||
#define ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 7
|
||||
#define ModuleConfig_TelemetryConfig_environment_sensor_type_tag 8
|
||||
#define ModuleConfig_TelemetryConfig_environment_sensor_pin_tag 9
|
||||
#define ModuleConfig_mqtt_tag 1
|
||||
#define ModuleConfig_serial_tag 2
|
||||
#define ModuleConfig_external_notification_tag 3
|
||||
#define ModuleConfig_store_forward_tag 4
|
||||
#define ModuleConfig_range_test_tag 5
|
||||
#define ModuleConfig_telemetry_tag 6
|
||||
#define ModuleConfig_canned_message_tag 7
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ModuleConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,mqtt,payloadVariant.mqtt), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,serial,payloadVariant.serial), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,external_notification,payloadVariant.external_notification), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,store_forward,payloadVariant.store_forward), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,range_test,payloadVariant.range_test), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,telemetry,payloadVariant.telemetry), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,canned_message,payloadVariant.canned_message), 7)
|
||||
#define ModuleConfig_CALLBACK NULL
|
||||
#define ModuleConfig_DEFAULT NULL
|
||||
#define ModuleConfig_payloadVariant_mqtt_MSGTYPE ModuleConfig_MQTTConfig
|
||||
#define ModuleConfig_payloadVariant_serial_MSGTYPE ModuleConfig_SerialConfig
|
||||
#define ModuleConfig_payloadVariant_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig
|
||||
#define ModuleConfig_payloadVariant_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig
|
||||
#define ModuleConfig_payloadVariant_range_test_MSGTYPE ModuleConfig_RangeTestConfig
|
||||
#define ModuleConfig_payloadVariant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
|
||||
#define ModuleConfig_payloadVariant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
|
||||
|
||||
#define ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, disabled, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, address, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, username, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, password, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5)
|
||||
#define ModuleConfig_MQTTConfig_CALLBACK NULL
|
||||
#define ModuleConfig_MQTTConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_SerialConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, echo, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, rxd, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, txd, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, baud, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, timeout, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, mode, 7)
|
||||
#define ModuleConfig_SerialConfig_CALLBACK NULL
|
||||
#define ModuleConfig_SerialConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_ExternalNotificationConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, output_ms, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, output, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, active, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_message, 5) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_bell, 6)
|
||||
#define ModuleConfig_ExternalNotificationConfig_CALLBACK NULL
|
||||
#define ModuleConfig_ExternalNotificationConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_StoreForwardConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, heartbeat, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, records, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, history_return_max, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, history_return_window, 5)
|
||||
#define ModuleConfig_StoreForwardConfig_CALLBACK NULL
|
||||
#define ModuleConfig_StoreForwardConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_RangeTestConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sender, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, save, 3)
|
||||
#define ModuleConfig_RangeTestConfig_CALLBACK NULL
|
||||
#define ModuleConfig_RangeTestConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_TelemetryConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, device_update_interval, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, environment_update_interval, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, environment_read_error_count_threshold, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, environment_recovery_interval, 6) \
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 7) \
|
||||
X(a, STATIC, SINGULAR, UENUM, environment_sensor_type, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, environment_sensor_pin, 9)
|
||||
#define ModuleConfig_TelemetryConfig_CALLBACK NULL
|
||||
#define ModuleConfig_TelemetryConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_CannedMessageConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 5) \
|
||||
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 7) \
|
||||
X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 8) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 9) \
|
||||
X(a, STATIC, SINGULAR, STRING, allow_input_source, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, send_bell, 11)
|
||||
#define ModuleConfig_CannedMessageConfig_CALLBACK NULL
|
||||
#define ModuleConfig_CannedMessageConfig_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t ModuleConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_MQTTConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_SerialConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_ExternalNotificationConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_StoreForwardConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_RangeTestConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_TelemetryConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define ModuleConfig_fields &ModuleConfig_msg
|
||||
#define ModuleConfig_MQTTConfig_fields &ModuleConfig_MQTTConfig_msg
|
||||
#define ModuleConfig_SerialConfig_fields &ModuleConfig_SerialConfig_msg
|
||||
#define ModuleConfig_ExternalNotificationConfig_fields &ModuleConfig_ExternalNotificationConfig_msg
|
||||
#define ModuleConfig_StoreForwardConfig_fields &ModuleConfig_StoreForwardConfig_msg
|
||||
#define ModuleConfig_RangeTestConfig_fields &ModuleConfig_RangeTestConfig_msg
|
||||
#define ModuleConfig_TelemetryConfig_fields &ModuleConfig_TelemetryConfig_msg
|
||||
#define ModuleConfig_CannedMessageConfig_fields &ModuleConfig_CannedMessageConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ModuleConfig_CannedMessageConfig_size 49
|
||||
#define ModuleConfig_ExternalNotificationConfig_size 20
|
||||
#define ModuleConfig_MQTTConfig_size 103
|
||||
#define ModuleConfig_RangeTestConfig_size 10
|
||||
#define ModuleConfig_SerialConfig_size 26
|
||||
#define ModuleConfig_StoreForwardConfig_size 22
|
||||
#define ModuleConfig_TelemetryConfig_size 38
|
||||
#define ModuleConfig_size 105
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "mqtt.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_MQTT_PB_H_INCLUDED
|
||||
#define PB_MQTT_PB_H_INCLUDED
|
||||
@@ -14,13 +14,13 @@
|
||||
/* This message wraps a MeshPacket with extra metadata about the sender and how it arrived. */
|
||||
typedef struct _ServiceEnvelope {
|
||||
/* The (probably encrypted) packet */
|
||||
struct _MeshPacket *packet;
|
||||
struct _MeshPacket *packet;
|
||||
/* The global channel ID it was sent on */
|
||||
char *channel_id;
|
||||
char *channel_id;
|
||||
/* The sending gateway node ID. Can we use this to authenticate/prevent fake
|
||||
nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as
|
||||
the globally trusted nodenum */
|
||||
char *gateway_id;
|
||||
char *gateway_id;
|
||||
} ServiceEnvelope;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#include "portnums.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
/* Generated by nanopb-0.4.6 */
|
||||
|
||||
#ifndef PB_PORTNUMS_PB_H_INCLUDED
|
||||
#define PB_PORTNUMS_PB_H_INCLUDED
|
||||
@@ -29,8 +29,7 @@ typedef enum _PortNum {
|
||||
PortNum_UNKNOWN_APP = 0,
|
||||
/* A simple UTF-8 text message, which even the little micros in the mesh
|
||||
can understand and show on their screen eventually in some circumstances
|
||||
even signal might send messages in this form (see below)
|
||||
Formerly called CLEAR_TEXT */
|
||||
even signal might send messages in this form (see below) */
|
||||
PortNum_TEXT_MESSAGE_APP = 1,
|
||||
/* Reserved for built-in GPIO/example app.
|
||||
See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number */
|
||||
@@ -47,6 +46,10 @@ typedef enum _PortNum {
|
||||
/* Admin control packets.
|
||||
Payload is a [AdminMessage](/docs/developers/protobufs/api#adminmessage) message */
|
||||
PortNum_ADMIN_APP = 6,
|
||||
/* Compressed TEXT_MESSAGE payloads. */
|
||||
PortNum_TEXT_MESSAGE_COMPRESSED_APP = 7,
|
||||
/* Waypoint payloads. */
|
||||
PortNum_WAYPOINT_APP = 8,
|
||||
/* Provides a 'ping' service that replies to any packet it receives.
|
||||
Also serves as a small example module. */
|
||||
PortNum_REPLY_APP = 32,
|
||||
|
||||
@@ -1,606 +0,0 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5 */
|
||||
|
||||
#ifndef PB_RADIOCONFIG_PB_H_INCLUDED
|
||||
#define PB_RADIOCONFIG_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
/* The frequency/regulatory region the user has selected.
|
||||
Note: In 1.0 builds (which must still be supported by the android app for a
|
||||
long time) this field will be unpopulated.
|
||||
If firmware is ever upgraded from an old 1.0ish build, the old
|
||||
MyNodeInfo.region string will be used to set UserPreferences.region and the
|
||||
old value will be no longer set. */
|
||||
typedef enum _RegionCode {
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_Unset = 0,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_US = 1,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_EU433 = 2,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_EU868 = 3,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_CN = 4,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_JP = 5,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_ANZ = 6,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_KR = 7,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_TW = 8,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_RU = 9,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_IN = 10,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_NZ865 = 11,
|
||||
/* TODO: REPLACE */
|
||||
RegionCode_TH = 12
|
||||
} RegionCode;
|
||||
|
||||
/* Defines the device's role on the Mesh network
|
||||
unset
|
||||
Behave normally.
|
||||
Router
|
||||
Functions as a router */
|
||||
typedef enum _Role {
|
||||
/* Client device role */
|
||||
Role_Client = 0,
|
||||
/* ClientMute device role
|
||||
This is like the client but packets will not hop over this node. Would be
|
||||
useful if you want to save power by not contributing to the mesh. */
|
||||
Role_ClientMute = 1,
|
||||
/* Router device role.
|
||||
Uses an agressive algirithem for the flood networking so packets will
|
||||
prefer to be routed over this node. Also assume that this will be generally
|
||||
unattended and so will turn off the wifi/ble radio as well as the oled screen. */
|
||||
Role_Router = 2,
|
||||
/* RouterClient device role
|
||||
Uses an agressive algirithem for the flood networking so packets will
|
||||
prefer to be routed over this node. Similiar power management as a regular
|
||||
client, so the RouterClient can be used as both a Router and a Client. Useful
|
||||
as a well placed base station that you could also use to send messages. */
|
||||
Role_RouterClient = 3
|
||||
} Role;
|
||||
|
||||
/* Sets the charge control current of devices with a battery charger that can be
|
||||
configured. This is passed into the axp power management chip like on the tbeam. */
|
||||
typedef enum _ChargeCurrent {
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MAUnset = 0,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA100 = 1,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA190 = 2,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA280 = 3,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA360 = 4,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA450 = 5,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA550 = 6,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA630 = 7,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA700 = 8,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA780 = 9,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA880 = 10,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA960 = 11,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA1000 = 12,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA1080 = 13,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA1160 = 14,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA1240 = 15,
|
||||
/* TODO: REPLACE */
|
||||
ChargeCurrent_MA1320 = 16
|
||||
} ChargeCurrent;
|
||||
|
||||
/* How the GPS coordinates are displayed on the OLED screen. */
|
||||
typedef enum _GpsCoordinateFormat {
|
||||
/* GPS coordinates are displayed in the normal decimal degrees format:
|
||||
DD.DDDDDD DDD.DDDDDD */
|
||||
GpsCoordinateFormat_GpsFormatDec = 0,
|
||||
/* GPS coordinates are displayed in the degrees minutes seconds format:
|
||||
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant */
|
||||
GpsCoordinateFormat_GpsFormatDMS = 1,
|
||||
/* GPS coordinates are displayed in Universal Transverse Mercator format:
|
||||
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing */
|
||||
GpsCoordinateFormat_GpsFormatUTM = 2,
|
||||
/* GPS coordinates are displayed in Military Grid Reference System format:
|
||||
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
|
||||
E is easting, N is northing */
|
||||
GpsCoordinateFormat_GpsFormatMGRS = 3,
|
||||
/* GPS coordinates are displayed in Open Location Code (aka Plus Codes). */
|
||||
GpsCoordinateFormat_GpsFormatOLC = 4,
|
||||
/* GPS coordinates are displayed in Ordnance Survey Grid Reference (the National Grid System of the UK).
|
||||
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, E is the easting,
|
||||
N is the northing */
|
||||
GpsCoordinateFormat_GpsFormatOSGR = 5
|
||||
} GpsCoordinateFormat;
|
||||
|
||||
/* Bit field of boolean configuration options, indicating which optional
|
||||
fields to include when assembling POSITION messages
|
||||
Longitude and latitude are always included (also time if GPS-synced)
|
||||
NOTE: the more fields are included, the larger the message will be -
|
||||
leading to longer airtime and a higher risk of packet loss */
|
||||
typedef enum _PositionFlags {
|
||||
/* Required for compilation */
|
||||
PositionFlags_POS_UNDEFINED = 0,
|
||||
/* Include an altitude value (if available) */
|
||||
PositionFlags_POS_ALTITUDE = 1,
|
||||
/* Altitude value is MSL */
|
||||
PositionFlags_POS_ALT_MSL = 2,
|
||||
/* Include geoidal separation */
|
||||
PositionFlags_POS_GEO_SEP = 4,
|
||||
/* Include the DOP value ; PDOP used by default, see below */
|
||||
PositionFlags_POS_DOP = 8,
|
||||
/* If POS_DOP set, send separate HDOP / VDOP values instead of PDOP */
|
||||
PositionFlags_POS_HVDOP = 16,
|
||||
/* Include battery level */
|
||||
PositionFlags_POS_BATTERY = 32,
|
||||
/* Include number of "satellites in view" */
|
||||
PositionFlags_POS_SATINVIEW = 64,
|
||||
/* Include a sequence number incremented per packet */
|
||||
PositionFlags_POS_SEQ_NOS = 128,
|
||||
/* Include positional timestamp (from GPS solution) */
|
||||
PositionFlags_POS_TIMESTAMP = 256
|
||||
} PositionFlags;
|
||||
|
||||
/* TODO: REPLACE */
|
||||
typedef enum _InputEventChar {
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_NONE = 0,
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_UP = 17,
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_DOWN = 18,
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_LEFT = 19,
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_RIGHT = 20,
|
||||
/* '\n' */
|
||||
InputEventChar_KEY_SELECT = 10,
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_BACK = 27,
|
||||
/* TODO: REPLACE */
|
||||
InputEventChar_KEY_CANCEL = 24
|
||||
} InputEventChar;
|
||||
|
||||
/* The frequency/regulatory region the user has selected.
|
||||
Note: In 1.0 builds (which must still be supported by the android app for a
|
||||
long time) this field will be unpopulated.
|
||||
If firmware is ever upgraded from an old 1.0ish build, the old
|
||||
MyNodeInfo.region string will be used to set UserPreferences.region and the
|
||||
old value will be no longer set. */
|
||||
typedef enum _RadioConfig_UserPreferences_Serial_Baud {
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_Default = 0,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_2400 = 1,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_4800 = 2,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_9600 = 3,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_19200 = 4,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_38400 = 5,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_57600 = 6,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_115200 = 7,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_230400 = 8,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_460800 = 9,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_576000 = 10,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_921600 = 11,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_110 = 12,
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_300 = 13,
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_600 = 14,
|
||||
RadioConfig_UserPreferences_Serial_Baud_BAUD_1200 = 15
|
||||
} RadioConfig_UserPreferences_Serial_Baud;
|
||||
|
||||
/* Defines the device's role on the Mesh network
|
||||
unset
|
||||
Behave normally.
|
||||
Router
|
||||
Functions as a router */
|
||||
typedef enum _RadioConfig_UserPreferences_Serial_Mode {
|
||||
/* Client device role */
|
||||
RadioConfig_UserPreferences_Serial_Mode_MODE_Default = 0,
|
||||
/* ClientMute device role
|
||||
This is like the client but packets will not hop over this node. Would be
|
||||
useful if you want to save power by not contributing to the mesh. */
|
||||
RadioConfig_UserPreferences_Serial_Mode_MODE_SIMPLE = 1,
|
||||
/* Router device role.
|
||||
Uses an agressive algirithem for the flood networking so packets will
|
||||
prefer to be routed over this node. Also assume that this will be generally
|
||||
unattended and so will turn off the wifi/ble radio as well as the oled screen. */
|
||||
RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO = 2
|
||||
} RadioConfig_UserPreferences_Serial_Mode;
|
||||
|
||||
/* Sets the charge control current of devices with a battery charger that can be
|
||||
configured. This is passed into the axp power management chip like on the tbeam. */
|
||||
typedef enum _RadioConfig_UserPreferences_TelemetrySensorType {
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_None = 0,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_DHT11 = 1,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_DS18B20 = 2,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_DHT12 = 3,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_DHT21 = 4,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_DHT22 = 5,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_BME280 = 6,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_BME680 = 7,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_MCP9808 = 8,
|
||||
/* TODO: REPLACE */
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 = 9
|
||||
} RadioConfig_UserPreferences_TelemetrySensorType;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _RadioConfig_UserPreferences {
|
||||
uint32_t position_broadcast_secs;
|
||||
uint32_t wait_bluetooth_secs;
|
||||
uint32_t screen_on_secs;
|
||||
uint32_t phone_timeout_secs;
|
||||
uint32_t mesh_sds_timeout_secs;
|
||||
uint32_t sds_secs;
|
||||
uint32_t ls_secs;
|
||||
uint32_t min_wake_secs;
|
||||
char wifi_ssid[33];
|
||||
char wifi_password[64];
|
||||
bool wifi_ap_mode;
|
||||
RegionCode region;
|
||||
ChargeCurrent charge_current;
|
||||
bool position_broadcast_smart_disabled;
|
||||
Role role;
|
||||
bool location_share_disabled;
|
||||
bool gps_disabled;
|
||||
uint32_t gps_update_interval;
|
||||
uint32_t gps_attempt_time;
|
||||
bool is_low_power;
|
||||
bool fixed_position;
|
||||
bool serial_disabled;
|
||||
float frequency_offset;
|
||||
char mqtt_server[32];
|
||||
bool mqtt_disabled;
|
||||
GpsCoordinateFormat gps_format;
|
||||
bool gps_accept_2d;
|
||||
uint32_t gps_max_dop;
|
||||
bool factory_reset;
|
||||
bool debug_log_enabled;
|
||||
pb_size_t ignore_incoming_count;
|
||||
uint32_t ignore_incoming[3];
|
||||
bool serial_module_enabled;
|
||||
bool serial_module_echo;
|
||||
uint32_t serial_module_rxd;
|
||||
uint32_t serial_module_txd;
|
||||
uint32_t serial_module_timeout;
|
||||
RadioConfig_UserPreferences_Serial_Mode serial_module_mode;
|
||||
bool ext_notification_module_enabled;
|
||||
uint32_t ext_notification_module_output_ms;
|
||||
uint32_t ext_notification_module_output;
|
||||
bool ext_notification_module_active;
|
||||
bool ext_notification_module_alert_message;
|
||||
bool ext_notification_module_alert_bell;
|
||||
bool range_test_module_enabled;
|
||||
uint32_t range_test_module_sender;
|
||||
bool range_test_module_save;
|
||||
uint32_t store_forward_module_records;
|
||||
uint32_t store_forward_module_history_return_max;
|
||||
uint32_t store_forward_module_history_return_window;
|
||||
bool telemetry_module_environment_measurement_enabled;
|
||||
bool telemetry_module_environment_screen_enabled;
|
||||
uint32_t telemetry_module_environment_read_error_count_threshold;
|
||||
uint32_t telemetry_module_device_update_interval;
|
||||
uint32_t telemetry_module_environment_recovery_interval;
|
||||
bool telemetry_module_environment_display_fahrenheit;
|
||||
RadioConfig_UserPreferences_TelemetrySensorType telemetry_module_environment_sensor_type;
|
||||
uint32_t telemetry_module_environment_sensor_pin;
|
||||
bool store_forward_module_enabled;
|
||||
bool store_forward_module_heartbeat;
|
||||
uint32_t position_flags;
|
||||
bool is_always_powered;
|
||||
uint32_t auto_screen_carousel_secs;
|
||||
uint32_t on_battery_shutdown_after_secs;
|
||||
uint32_t hop_limit;
|
||||
char mqtt_username[32];
|
||||
char mqtt_password[32];
|
||||
bool is_lora_tx_disabled;
|
||||
bool is_power_saving;
|
||||
bool rotary1_enabled;
|
||||
uint32_t inputbroker_pin_a;
|
||||
uint32_t inputbroker_pin_b;
|
||||
uint32_t inputbroker_pin_press;
|
||||
InputEventChar inputbroker_event_cw;
|
||||
InputEventChar inputbroker_event_ccw;
|
||||
InputEventChar inputbroker_event_press;
|
||||
bool updown1_enabled;
|
||||
bool canned_message_module_enabled;
|
||||
char canned_message_module_allow_input_source[16];
|
||||
bool canned_message_module_send_bell;
|
||||
bool mqtt_encryption_enabled;
|
||||
float adc_multiplier_override;
|
||||
RadioConfig_UserPreferences_Serial_Baud serial_module_baud;
|
||||
uint32_t telemetry_module_environment_update_interval;
|
||||
} RadioConfig_UserPreferences;
|
||||
|
||||
/* The entire set of user settable/readable settings for our radio device.
|
||||
Includes both the current channel settings and any preferences the user has
|
||||
set for behavior of their node */
|
||||
typedef struct _RadioConfig {
|
||||
/* TODO: REPLACE */
|
||||
bool has_preferences;
|
||||
RadioConfig_UserPreferences preferences;
|
||||
} RadioConfig;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _RegionCode_MIN RegionCode_Unset
|
||||
#define _RegionCode_MAX RegionCode_TH
|
||||
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TH+1))
|
||||
|
||||
#define _Role_MIN Role_Client
|
||||
#define _Role_MAX Role_RouterClient
|
||||
#define _Role_ARRAYSIZE ((Role)(Role_RouterClient+1))
|
||||
|
||||
#define _ChargeCurrent_MIN ChargeCurrent_MAUnset
|
||||
#define _ChargeCurrent_MAX ChargeCurrent_MA1320
|
||||
#define _ChargeCurrent_ARRAYSIZE ((ChargeCurrent)(ChargeCurrent_MA1320+1))
|
||||
|
||||
#define _GpsCoordinateFormat_MIN GpsCoordinateFormat_GpsFormatDec
|
||||
#define _GpsCoordinateFormat_MAX GpsCoordinateFormat_GpsFormatOSGR
|
||||
#define _GpsCoordinateFormat_ARRAYSIZE ((GpsCoordinateFormat)(GpsCoordinateFormat_GpsFormatOSGR+1))
|
||||
|
||||
#define _PositionFlags_MIN PositionFlags_POS_UNDEFINED
|
||||
#define _PositionFlags_MAX PositionFlags_POS_TIMESTAMP
|
||||
#define _PositionFlags_ARRAYSIZE ((PositionFlags)(PositionFlags_POS_TIMESTAMP+1))
|
||||
|
||||
#define _InputEventChar_MIN InputEventChar_KEY_NONE
|
||||
#define _InputEventChar_MAX InputEventChar_KEY_BACK
|
||||
#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1))
|
||||
|
||||
#define _RadioConfig_UserPreferences_Serial_Baud_MIN RadioConfig_UserPreferences_Serial_Baud_BAUD_Default
|
||||
#define _RadioConfig_UserPreferences_Serial_Baud_MAX RadioConfig_UserPreferences_Serial_Baud_BAUD_1200
|
||||
#define _RadioConfig_UserPreferences_Serial_Baud_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Baud)(RadioConfig_UserPreferences_Serial_Baud_BAUD_1200+1))
|
||||
|
||||
#define _RadioConfig_UserPreferences_Serial_Mode_MIN RadioConfig_UserPreferences_Serial_Mode_MODE_Default
|
||||
#define _RadioConfig_UserPreferences_Serial_Mode_MAX RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO
|
||||
#define _RadioConfig_UserPreferences_Serial_Mode_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Mode)(RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO+1))
|
||||
|
||||
#define _RadioConfig_UserPreferences_TelemetrySensorType_MIN RadioConfig_UserPreferences_TelemetrySensorType_None
|
||||
#define _RadioConfig_UserPreferences_TelemetrySensorType_MAX RadioConfig_UserPreferences_TelemetrySensorType_SHTC3
|
||||
#define _RadioConfig_UserPreferences_TelemetrySensorType_ARRAYSIZE ((RadioConfig_UserPreferences_TelemetrySensorType)(RadioConfig_UserPreferences_TelemetrySensorType_SHTC3+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0}
|
||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
|
||||
#define RadioConfig_UserPreferences_wait_bluetooth_secs_tag 4
|
||||
#define RadioConfig_UserPreferences_screen_on_secs_tag 5
|
||||
#define RadioConfig_UserPreferences_phone_timeout_secs_tag 6
|
||||
#define RadioConfig_UserPreferences_mesh_sds_timeout_secs_tag 8
|
||||
#define RadioConfig_UserPreferences_sds_secs_tag 9
|
||||
#define RadioConfig_UserPreferences_ls_secs_tag 10
|
||||
#define RadioConfig_UserPreferences_min_wake_secs_tag 11
|
||||
#define RadioConfig_UserPreferences_wifi_ssid_tag 12
|
||||
#define RadioConfig_UserPreferences_wifi_password_tag 13
|
||||
#define RadioConfig_UserPreferences_wifi_ap_mode_tag 14
|
||||
#define RadioConfig_UserPreferences_region_tag 15
|
||||
#define RadioConfig_UserPreferences_charge_current_tag 16
|
||||
#define RadioConfig_UserPreferences_position_broadcast_smart_disabled_tag 17
|
||||
#define RadioConfig_UserPreferences_role_tag 18
|
||||
#define RadioConfig_UserPreferences_location_share_disabled_tag 32
|
||||
#define RadioConfig_UserPreferences_gps_disabled_tag 33
|
||||
#define RadioConfig_UserPreferences_gps_update_interval_tag 34
|
||||
#define RadioConfig_UserPreferences_gps_attempt_time_tag 36
|
||||
#define RadioConfig_UserPreferences_is_low_power_tag 38
|
||||
#define RadioConfig_UserPreferences_fixed_position_tag 39
|
||||
#define RadioConfig_UserPreferences_serial_disabled_tag 40
|
||||
#define RadioConfig_UserPreferences_frequency_offset_tag 41
|
||||
#define RadioConfig_UserPreferences_mqtt_server_tag 42
|
||||
#define RadioConfig_UserPreferences_mqtt_disabled_tag 43
|
||||
#define RadioConfig_UserPreferences_gps_format_tag 44
|
||||
#define RadioConfig_UserPreferences_gps_accept_2d_tag 45
|
||||
#define RadioConfig_UserPreferences_gps_max_dop_tag 46
|
||||
#define RadioConfig_UserPreferences_factory_reset_tag 100
|
||||
#define RadioConfig_UserPreferences_debug_log_enabled_tag 101
|
||||
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
|
||||
#define RadioConfig_UserPreferences_serial_module_enabled_tag 120
|
||||
#define RadioConfig_UserPreferences_serial_module_echo_tag 121
|
||||
#define RadioConfig_UserPreferences_serial_module_rxd_tag 122
|
||||
#define RadioConfig_UserPreferences_serial_module_txd_tag 123
|
||||
#define RadioConfig_UserPreferences_serial_module_timeout_tag 124
|
||||
#define RadioConfig_UserPreferences_serial_module_mode_tag 125
|
||||
#define RadioConfig_UserPreferences_ext_notification_module_enabled_tag 126
|
||||
#define RadioConfig_UserPreferences_ext_notification_module_output_ms_tag 127
|
||||
#define RadioConfig_UserPreferences_ext_notification_module_output_tag 128
|
||||
#define RadioConfig_UserPreferences_ext_notification_module_active_tag 129
|
||||
#define RadioConfig_UserPreferences_ext_notification_module_alert_message_tag 130
|
||||
#define RadioConfig_UserPreferences_ext_notification_module_alert_bell_tag 131
|
||||
#define RadioConfig_UserPreferences_range_test_module_enabled_tag 132
|
||||
#define RadioConfig_UserPreferences_range_test_module_sender_tag 133
|
||||
#define RadioConfig_UserPreferences_range_test_module_save_tag 134
|
||||
#define RadioConfig_UserPreferences_store_forward_module_records_tag 137
|
||||
#define RadioConfig_UserPreferences_store_forward_module_history_return_max_tag 138
|
||||
#define RadioConfig_UserPreferences_store_forward_module_history_return_window_tag 139
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_measurement_enabled_tag 140
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_screen_enabled_tag 141
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_read_error_count_threshold_tag 142
|
||||
#define RadioConfig_UserPreferences_telemetry_module_device_update_interval_tag 143
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_recovery_interval_tag 144
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_display_fahrenheit_tag 145
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_type_tag 146
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_pin_tag 147
|
||||
#define RadioConfig_UserPreferences_store_forward_module_enabled_tag 148
|
||||
#define RadioConfig_UserPreferences_store_forward_module_heartbeat_tag 149
|
||||
#define RadioConfig_UserPreferences_position_flags_tag 150
|
||||
#define RadioConfig_UserPreferences_is_always_powered_tag 151
|
||||
#define RadioConfig_UserPreferences_auto_screen_carousel_secs_tag 152
|
||||
#define RadioConfig_UserPreferences_on_battery_shutdown_after_secs_tag 153
|
||||
#define RadioConfig_UserPreferences_hop_limit_tag 154
|
||||
#define RadioConfig_UserPreferences_mqtt_username_tag 155
|
||||
#define RadioConfig_UserPreferences_mqtt_password_tag 156
|
||||
#define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157
|
||||
#define RadioConfig_UserPreferences_is_power_saving_tag 158
|
||||
#define RadioConfig_UserPreferences_rotary1_enabled_tag 160
|
||||
#define RadioConfig_UserPreferences_inputbroker_pin_a_tag 161
|
||||
#define RadioConfig_UserPreferences_inputbroker_pin_b_tag 162
|
||||
#define RadioConfig_UserPreferences_inputbroker_pin_press_tag 163
|
||||
#define RadioConfig_UserPreferences_inputbroker_event_cw_tag 164
|
||||
#define RadioConfig_UserPreferences_inputbroker_event_ccw_tag 165
|
||||
#define RadioConfig_UserPreferences_inputbroker_event_press_tag 166
|
||||
#define RadioConfig_UserPreferences_updown1_enabled_tag 167
|
||||
#define RadioConfig_UserPreferences_canned_message_module_enabled_tag 170
|
||||
#define RadioConfig_UserPreferences_canned_message_module_allow_input_source_tag 171
|
||||
#define RadioConfig_UserPreferences_canned_message_module_send_bell_tag 173
|
||||
#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174
|
||||
#define RadioConfig_UserPreferences_adc_multiplier_override_tag 175
|
||||
#define RadioConfig_UserPreferences_serial_module_baud_tag 176
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_update_interval_tag 177
|
||||
#define RadioConfig_preferences_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define RadioConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, preferences, 1)
|
||||
#define RadioConfig_CALLBACK NULL
|
||||
#define RadioConfig_DEFAULT NULL
|
||||
#define RadioConfig_preferences_MSGTYPE RadioConfig_UserPreferences
|
||||
|
||||
#define RadioConfig_UserPreferences_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sds_secs, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ls_secs, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 11) \
|
||||
X(a, STATIC, SINGULAR, STRING, wifi_ssid, 12) \
|
||||
X(a, STATIC, SINGULAR, STRING, wifi_password, 13) \
|
||||
X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
|
||||
X(a, STATIC, SINGULAR, UENUM, region, 15) \
|
||||
X(a, STATIC, SINGULAR, UENUM, charge_current, 16) \
|
||||
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 17) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 18) \
|
||||
X(a, STATIC, SINGULAR, BOOL, location_share_disabled, 32) \
|
||||
X(a, STATIC, SINGULAR, BOOL, gps_disabled, 33) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_low_power, 38) \
|
||||
X(a, STATIC, SINGULAR, BOOL, fixed_position, 39) \
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_disabled, 40) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 41) \
|
||||
X(a, STATIC, SINGULAR, STRING, mqtt_server, 42) \
|
||||
X(a, STATIC, SINGULAR, BOOL, mqtt_disabled, 43) \
|
||||
X(a, STATIC, SINGULAR, UENUM, gps_format, 44) \
|
||||
X(a, STATIC, SINGULAR, BOOL, gps_accept_2d, 45) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 46) \
|
||||
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
|
||||
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 101) \
|
||||
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_module_enabled, 120) \
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_module_echo, 121) \
|
||||
X(a, STATIC, SINGULAR, UINT32, serial_module_rxd, 122) \
|
||||
X(a, STATIC, SINGULAR, UINT32, serial_module_txd, 123) \
|
||||
X(a, STATIC, SINGULAR, UINT32, serial_module_timeout, 124) \
|
||||
X(a, STATIC, SINGULAR, UENUM, serial_module_mode, 125) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_enabled, 126) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output_ms, 127) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output, 128) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_active, 129) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_message, 130) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_bell, 131) \
|
||||
X(a, STATIC, SINGULAR, BOOL, range_test_module_enabled, 132) \
|
||||
X(a, STATIC, SINGULAR, UINT32, range_test_module_sender, 133) \
|
||||
X(a, STATIC, SINGULAR, BOOL, range_test_module_save, 134) \
|
||||
X(a, STATIC, SINGULAR, UINT32, store_forward_module_records, 137) \
|
||||
X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_max, 138) \
|
||||
X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_window, 139) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_measurement_enabled, 140) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_screen_enabled, 141) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_read_error_count_threshold, 142) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_device_update_interval, 143) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_recovery_interval, 144) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_display_fahrenheit, 145) \
|
||||
X(a, STATIC, SINGULAR, UENUM, telemetry_module_environment_sensor_type, 146) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_sensor_pin, 147) \
|
||||
X(a, STATIC, SINGULAR, BOOL, store_forward_module_enabled, 148) \
|
||||
X(a, STATIC, SINGULAR, BOOL, store_forward_module_heartbeat, 149) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_always_powered, 151) \
|
||||
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) \
|
||||
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 153) \
|
||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \
|
||||
X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \
|
||||
X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) \
|
||||
X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 160) \
|
||||
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 161) \
|
||||
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 162) \
|
||||
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 163) \
|
||||
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 164) \
|
||||
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 165) \
|
||||
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 166) \
|
||||
X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 167) \
|
||||
X(a, STATIC, SINGULAR, BOOL, canned_message_module_enabled, 170) \
|
||||
X(a, STATIC, SINGULAR, STRING, canned_message_module_allow_input_source, 171) \
|
||||
X(a, STATIC, SINGULAR, BOOL, canned_message_module_send_bell, 173) \
|
||||
X(a, STATIC, SINGULAR, BOOL, mqtt_encryption_enabled, 174) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 175) \
|
||||
X(a, STATIC, SINGULAR, UENUM, serial_module_baud, 176) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_update_interval, 177)
|
||||
#define RadioConfig_UserPreferences_CALLBACK NULL
|
||||
#define RadioConfig_UserPreferences_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t RadioConfig_msg;
|
||||
extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define RadioConfig_fields &RadioConfig_msg
|
||||
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define RadioConfig_UserPreferences_size 592
|
||||
#define RadioConfig_size 595
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user