mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-17 08:12:32 +00:00
Compare commits
266 Commits
apollo
...
native-dfu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96a119cdd8 | ||
|
|
4c97351187 | ||
|
|
3298df953a | ||
|
|
d1f7739bbe | ||
|
|
0d860882a8 | ||
|
|
3b40fe9805 | ||
|
|
8e8b22edb0 | ||
|
|
01892cbd1e | ||
|
|
7fb22cf678 | ||
|
|
fdc87d492c | ||
|
|
0fdbf70452 | ||
|
|
71591fb06a | ||
|
|
9041af365d | ||
|
|
f87c370123 | ||
|
|
c4fcbad372 | ||
|
|
0f981153eb | ||
|
|
c1beb44678 | ||
|
|
973b453d43 | ||
|
|
950341d1f9 | ||
|
|
b353bcc04a | ||
|
|
c4051c1a7b | ||
|
|
2262d77be4 | ||
|
|
9566d6ffd4 | ||
|
|
e466bf2475 | ||
|
|
b0fe5ef8ba | ||
|
|
f132158c3e | ||
|
|
8179e61fdc | ||
|
|
a085614aaa | ||
|
|
7acd72ede1 | ||
|
|
7ba593432e | ||
|
|
a48df91737 | ||
|
|
262f1d25a2 | ||
|
|
4cd2ba5479 | ||
|
|
f9876cfe9c | ||
|
|
85de193845 | ||
|
|
fb2c008c89 | ||
|
|
dd9ab7f0e1 | ||
|
|
729c39fb86 | ||
|
|
038430db23 | ||
|
|
d5cd6f87a0 | ||
|
|
de42d96adf | ||
|
|
e2dd845051 | ||
|
|
6366633cd4 | ||
|
|
1c0f43c8e2 | ||
|
|
89a9e0b99d | ||
|
|
4dc8d6e400 | ||
|
|
e0f97c9306 | ||
|
|
6b1c01ce02 | ||
|
|
70296b47bc | ||
|
|
0cf4a2951a | ||
|
|
124936b6cf | ||
|
|
fd60c9b3be | ||
|
|
a0a4c5bc79 | ||
|
|
0fe8d4ccc7 | ||
|
|
00fdf2c9aa | ||
|
|
253ab458ef | ||
|
|
b4a4d2db4e | ||
|
|
6b8cf164e9 | ||
|
|
812aa35f09 | ||
|
|
e7802d960f | ||
|
|
077ee02426 | ||
|
|
46ea39af45 | ||
|
|
25a5f178e1 | ||
|
|
c144ee77a7 | ||
|
|
b62bdbc46a | ||
|
|
f18a92e8c5 | ||
|
|
2e44de262e | ||
|
|
1d756ae574 | ||
|
|
8aac9f2e8e | ||
|
|
33e5a04508 | ||
|
|
6cf3485d07 | ||
|
|
9421eba027 | ||
|
|
27fbfd03d6 | ||
|
|
353740623f | ||
|
|
cdcbf4c615 | ||
|
|
395469d20a | ||
|
|
86170171a7 | ||
|
|
57766d47a8 | ||
|
|
e5dbcf5bce | ||
|
|
4c3a3ca47d | ||
|
|
78371dfdb7 | ||
|
|
ca32889893 | ||
|
|
35cd600c54 | ||
|
|
70076a4b27 | ||
|
|
f1a8900288 | ||
|
|
16bc89ea57 | ||
|
|
6edf74e8f1 | ||
|
|
7f280dd556 | ||
|
|
2396aa77ca | ||
|
|
d3cbbfd345 | ||
|
|
c003ab0eee | ||
|
|
4fcf7fe027 | ||
|
|
9cc79b1d1e | ||
|
|
403fa15a3f | ||
|
|
b0087fd328 | ||
|
|
fb74e1d182 | ||
|
|
29a7866fc1 | ||
|
|
2f552d15e5 | ||
|
|
892e0922ff | ||
|
|
d21d6c1301 | ||
|
|
031aecac66 | ||
|
|
7c10caa78b | ||
|
|
5196ee39cb | ||
|
|
02a5a91da0 | ||
|
|
b2a89b8136 | ||
|
|
15019e8663 | ||
|
|
35814fd4bc | ||
|
|
6aabbedc00 | ||
|
|
eb72ee0fc1 | ||
|
|
7480378aed | ||
|
|
7c21d7761c | ||
|
|
2c654454cf | ||
|
|
9afadde2f4 | ||
|
|
66a961cb75 | ||
|
|
e1aaafb77a | ||
|
|
9d710041c4 | ||
|
|
b41efc17ba | ||
|
|
9bda080e3d | ||
|
|
9f7cbf1b4f | ||
|
|
93e2bc7058 | ||
|
|
7a1c32b89a | ||
|
|
88d8ab53c8 | ||
|
|
183f68ba00 | ||
|
|
9f32995d7f | ||
|
|
c2c06ed0ad | ||
|
|
9abd07bb05 | ||
|
|
fdcc0e12aa | ||
|
|
8b34c4ff05 | ||
|
|
9af8c58c40 | ||
|
|
58ebd5bcdb | ||
|
|
d1e5be515a | ||
|
|
f9e71c3fb9 | ||
|
|
bfcfca2e46 | ||
|
|
a2a6b236b7 | ||
|
|
3c7053c66a | ||
|
|
e45c0e4d40 | ||
|
|
57a9a5ca21 | ||
|
|
6749367a73 | ||
|
|
a8e2446f00 | ||
|
|
89ebafc8b8 | ||
|
|
43d6b31603 | ||
|
|
31a5b9c122 | ||
|
|
ad726ad684 | ||
|
|
b2808063d0 | ||
|
|
2b33be2fea | ||
|
|
5133117936 | ||
|
|
e5accf4e1d | ||
|
|
26a4d6c87a | ||
|
|
ae93f3fa3f | ||
|
|
ed39d14c85 | ||
|
|
8f8e304216 | ||
|
|
cd198fcf3f | ||
|
|
b1d25ac7b7 | ||
|
|
b12ac6d564 | ||
|
|
33d2f78d21 | ||
|
|
b12aa3f360 | ||
|
|
d87b7e49e4 | ||
|
|
cc357df489 | ||
|
|
1281da627e | ||
|
|
835344074c | ||
|
|
13960874ae | ||
|
|
a7d9e8107a | ||
|
|
fbdd6e7223 | ||
|
|
175ff218f1 | ||
|
|
57af51cc18 | ||
|
|
b4b2fd6122 | ||
|
|
143e1d1a0d | ||
|
|
32719f69c9 | ||
|
|
6a2a4ffa2a | ||
|
|
80fc0f2bda | ||
|
|
fa1a1fd869 | ||
|
|
2fd5a4848a | ||
|
|
f4cff33450 | ||
|
|
1c8b165408 | ||
|
|
8e6ef4ea04 | ||
|
|
fb7866fca7 | ||
|
|
d9b287880f | ||
|
|
f39a9c5083 | ||
|
|
398d29064e | ||
|
|
df63423cdc | ||
|
|
9a10907a2d | ||
|
|
5fed679d33 | ||
|
|
58d80b8557 | ||
|
|
960626e498 | ||
|
|
658459aaf3 | ||
|
|
e1de439a7f | ||
|
|
827553f4c7 | ||
|
|
445c641004 | ||
|
|
7075a05bcd | ||
|
|
63091b7838 | ||
|
|
8c6eec52f2 | ||
|
|
68413486e3 | ||
|
|
af79970ad7 | ||
|
|
4edeca5f84 | ||
|
|
b0e3039732 | ||
|
|
92511ab10b | ||
|
|
b0a4087a0c | ||
|
|
1b2fc00b99 | ||
|
|
69d01a8088 | ||
|
|
09c082fd00 | ||
|
|
020e9102a8 | ||
|
|
2d45afafe5 | ||
|
|
56002155c6 | ||
|
|
547a57256d | ||
|
|
ea72abff22 | ||
|
|
4024bfdeeb | ||
|
|
6d8be13266 | ||
|
|
4a1239f811 | ||
|
|
44cf6d388e | ||
|
|
c3f89a6db8 | ||
|
|
332dbaf573 | ||
|
|
92225eb6c3 | ||
|
|
03770b799f | ||
|
|
1790407078 | ||
|
|
7dd3629501 | ||
|
|
cabeb40c30 | ||
|
|
761a99d241 | ||
|
|
cf46e675ca | ||
|
|
438f627e9b | ||
|
|
0e3dae4fec | ||
|
|
d0e3427ec7 | ||
|
|
f3850ee73b | ||
|
|
3ae85e2c82 | ||
|
|
f81d3b045d | ||
|
|
59ed5c9049 | ||
|
|
4a34bf648f | ||
|
|
b99e57a6fa | ||
|
|
46eab20a90 | ||
|
|
39b5fb041e | ||
|
|
fc16d93421 | ||
|
|
bac9fec17f | ||
|
|
de774188c9 | ||
|
|
c3d60342f4 | ||
|
|
d3e3985e39 | ||
|
|
8eca6a2df8 | ||
|
|
e4f53677fc | ||
|
|
10e10450cf | ||
|
|
f846503cbf | ||
|
|
85b2bad275 | ||
|
|
7ad137b56a | ||
|
|
57ea6a265e | ||
|
|
d00e0f6911 | ||
|
|
594af0cacd | ||
|
|
9f4c8a2804 | ||
|
|
43b8972171 | ||
|
|
fe8e0713cc | ||
|
|
ac6b6c8d83 | ||
|
|
79da2365f0 | ||
|
|
b5777beb7d | ||
|
|
5ad30a55ea | ||
|
|
060a3bde4d | ||
|
|
8df7a035e2 | ||
|
|
b00c05012d | ||
|
|
0832388482 | ||
|
|
601d912c6f | ||
|
|
502a83bb8a | ||
|
|
474f9b5bfb | ||
|
|
fe86c40145 | ||
|
|
09286a3beb | ||
|
|
ae4f54224e | ||
|
|
d5af8f0a97 | ||
|
|
58c957f2c7 | ||
|
|
7c2b6778cb | ||
|
|
0048e3cdcb | ||
|
|
6018c0a830 | ||
|
|
37da78919a |
52
.clusterfuzzlite/Dockerfile
Normal file
52
.clusterfuzzlite/Dockerfile
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# This container is used to build Meshtastic with the libraries required by the fuzzer.
|
||||||
|
# ClusterFuzzLite starts the container, runs the build.sh script, and then exits.
|
||||||
|
|
||||||
|
# As this is not a long running service, health-checks are not required. ClusterFuzzLite
|
||||||
|
# also only works if the user remains unchanged from the base image (it expects to run
|
||||||
|
# as root).
|
||||||
|
# trunk-ignore-all(trivy/DS026): No healthcheck is needed for this builder container
|
||||||
|
# trunk-ignore-all(checkov/CKV_DOCKER_2): No healthcheck is needed for this builder container
|
||||||
|
# trunk-ignore-all(checkov/CKV_DOCKER_3): We must run as root for this container
|
||||||
|
# trunk-ignore-all(trivy/DS002): We must run as root for this container
|
||||||
|
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
|
||||||
|
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||||
|
|
||||||
|
FROM gcr.io/oss-fuzz-base/base-builder:v1
|
||||||
|
|
||||||
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
|
|
||||||
|
# trunk-ignore(hadolint/DL3008): apt packages are not pinned.
|
||||||
|
# trunk-ignore(terrascan/AC_DOCKER_0002): apt packages are not pinned.
|
||||||
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
|
cmake git zip libgpiod-dev libbluetooth-dev libi2c-dev \
|
||||||
|
libunistring-dev libmicrohttpd-dev libgnutls28-dev libgcrypt20-dev \
|
||||||
|
libusb-1.0-0-dev libssl-dev pkg-config && \
|
||||||
|
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
||||||
|
pip install --no-cache-dir -U \
|
||||||
|
platformio==6.1.16 \
|
||||||
|
grpcio-tools==1.68.1 \
|
||||||
|
meshtastic==2.5.9
|
||||||
|
|
||||||
|
# Ugly hack to avoid clang detecting a conflict between the math "log" function and the "log" function in framework-portduino/cores/portduino/logging.h
|
||||||
|
RUN sed -i -e 's/__MATHCALL_VEC (log,, (_Mdouble_ __x));//' /usr/include/x86_64-linux-gnu/bits/mathcalls.h
|
||||||
|
|
||||||
|
# A few dependencies are too old on the base-builder image. More recent versions are built from source.
|
||||||
|
WORKDIR $SRC
|
||||||
|
RUN git config --global advice.detachedHead false && \
|
||||||
|
git clone --depth 1 --branch 0.8.0 https://github.com/jbeder/yaml-cpp.git && \
|
||||||
|
git clone --depth 1 --branch v2.3.3 https://github.com/babelouest/orcania.git && \
|
||||||
|
git clone --depth 1 --branch v1.4.20 https://github.com/babelouest/yder.git && \
|
||||||
|
git clone --depth 1 --branch v2.7.15 https://github.com/babelouest/ulfius.git
|
||||||
|
|
||||||
|
COPY ./.clusterfuzzlite/build.sh $SRC/
|
||||||
|
|
||||||
|
WORKDIR $SRC/firmware
|
||||||
|
COPY . $SRC/firmware/
|
||||||
|
|
||||||
|
# https://docs.platformio.org/en/latest/envvars.html
|
||||||
|
ENV PLATFORMIO_CORE_DIR=$SRC/pio/core \
|
||||||
|
PLATFORMIO_LIBDEPS_DIR=$SRC/pio/libdeps \
|
||||||
|
PLATFORMIO_PACKAGES_DIR=$SRC/pio/packages \
|
||||||
|
PLATFORMIO_SETTING_ENABLE_CACHE=No \
|
||||||
|
PIO_ENV=buildroot
|
||||||
|
RUN platformio pkg install --environment $PIO_ENV
|
||||||
59
.clusterfuzzlite/README.md
Normal file
59
.clusterfuzzlite/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# ClusterFuzzLite for Meshtastic
|
||||||
|
|
||||||
|
This directory contains the fuzzer implementation for Meshtastic using the ClusterFuzzLite framework.
|
||||||
|
See the [ClusterFuzzLite documentation](https://google.github.io/clusterfuzzlite/) for more details.
|
||||||
|
|
||||||
|
## Running locally
|
||||||
|
|
||||||
|
ClusterFuzzLite uses the OSS-Fuzz toolchain. To build the fuzzer manually, first grab a copy of OSS-Fuzz.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/google/oss-fuzz.git
|
||||||
|
cd oss-fuzz
|
||||||
|
```
|
||||||
|
|
||||||
|
To build the fuzzer, run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
python3 infra/helper.py build_image --external $PATH_TO_MESHTASTIC_FIRMWARE_DIRECTORY
|
||||||
|
python3 infra/helper.py build_fuzzers --external $PATH_TO_MESHTASTIC_FIRMWARE_DIRECTORY --sanitizer address
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the fuzzer, run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
python3 infra/helper.py run_fuzzer --external --corpus-dir=<path-to-temp-corpus-dir> $PATH_TO_MESHTASTIC_FIRMWARE_DIRECTORY router_fuzzer
|
||||||
|
```
|
||||||
|
|
||||||
|
More background on these commands can be found in the
|
||||||
|
[ClusterFuzzLite documentation](https://google.github.io/clusterfuzzlite/build-integration/#testing-locally).
|
||||||
|
|
||||||
|
## router_fuzzer.cpp
|
||||||
|
|
||||||
|
This fuzzer submits MeshPacket protos to the `Router::enqueueReceivedMessage` method. It takes the binary
|
||||||
|
data from the fuzzer and decodes that data to a MeshPacket using nanopb. A few fields in
|
||||||
|
the MeshPacket are modified by the fuzzer.
|
||||||
|
|
||||||
|
- If the `to` field is 0, it will be replaced with the NodeID of the running node.
|
||||||
|
- If the `from` field is 0, it will be replaced with the NodeID of the running node.
|
||||||
|
- If the `id` field is 0, it will be replaced with an incrementing counter value.
|
||||||
|
- If the `pki_encrypted` field is true, the `public_key` field will be populated with the first admin key.
|
||||||
|
|
||||||
|
The `router_fuzzer_seed_corpus.py` file contains a list of MeshPackets. It is run from inside build.sh and
|
||||||
|
writes the binary MeshPacket protos to files. These files are use used by the fuzzer as its initial seed data,
|
||||||
|
helping the fuzzer to start off with a few known inputs.
|
||||||
|
|
||||||
|
### Interpreting a fuzzer crash
|
||||||
|
|
||||||
|
If the fuzzer crashes, it'll write the input bytes used for the test case to a file and notify about the
|
||||||
|
location of that file. The contents of the file are a binary serialized MeshPacket protobuf. The following
|
||||||
|
snippet of Python code can be used to parse the file into a human readable form.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from meshtastic.protobuf import mesh_pb2
|
||||||
|
|
||||||
|
mesh_pb2.MeshPacket.FromString(open("crash-XXXX-file", "rb").read())
|
||||||
|
```
|
||||||
|
|
||||||
|
Consider adding any such crash results to the `router_fuzzer_seed_corpus.py` file to ensure there a isn't
|
||||||
|
a future regression for that crash test case.
|
||||||
71
.clusterfuzzlite/build.sh
Normal file
71
.clusterfuzzlite/build.sh
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
# Build Meshtastic and a few needed dependencies using clang++
|
||||||
|
# and the OSS-Fuzz required build flags.
|
||||||
|
|
||||||
|
env
|
||||||
|
|
||||||
|
cd "$SRC"
|
||||||
|
NPROC=$(nproc || echo 1)
|
||||||
|
|
||||||
|
LDFLAGS=-lpthread cmake -S "$SRC/yaml-cpp" -B "$WORK/yaml-cpp/$SANITIZER" \
|
||||||
|
-DBUILD_SHARED_LIBS=OFF
|
||||||
|
cmake --build "$WORK/yaml-cpp/$SANITIZER" -j "$NPROC"
|
||||||
|
cmake --install "$WORK/yaml-cpp/$SANITIZER" --prefix /usr
|
||||||
|
|
||||||
|
cmake -S "$SRC/orcania" -B "$WORK/orcania/$SANITIZER" \
|
||||||
|
-DBUILD_STATIC=ON
|
||||||
|
cmake --build "$WORK/orcania/$SANITIZER" -j "$NPROC"
|
||||||
|
cmake --install "$WORK/orcania/$SANITIZER" --prefix /usr
|
||||||
|
|
||||||
|
cmake -S "$SRC/yder" -B "$WORK/yder/$SANITIZER" \
|
||||||
|
-DBUILD_STATIC=ON -DWITH_JOURNALD=OFF
|
||||||
|
cmake --build "$WORK/yder/$SANITIZER" -j "$NPROC"
|
||||||
|
cmake --install "$WORK/yder/$SANITIZER" --prefix /usr
|
||||||
|
|
||||||
|
cmake -S "$SRC/ulfius" -B "$WORK/ulfius/$SANITIZER" \
|
||||||
|
-DBUILD_STATIC=ON -DWITH_JANSSON=OFF -DWITH_CURL=OFF -DWITH_WEBSOCKET=OFF
|
||||||
|
cmake --build "$WORK/ulfius/$SANITIZER" -j "$NPROC"
|
||||||
|
cmake --install "$WORK/ulfius/$SANITIZER" --prefix /usr
|
||||||
|
|
||||||
|
cd "$SRC/firmware"
|
||||||
|
|
||||||
|
PLATFORMIO_EXTRA_SCRIPTS=$(echo -e "pre:.clusterfuzzlite/platformio-clusterfuzzlite-pre.py\npost:.clusterfuzzlite/platformio-clusterfuzzlite-post.py")
|
||||||
|
STATIC_LIBS=$(pkg-config --libs --static libulfius openssl libgpiod yaml-cpp bluez --silence-errors)
|
||||||
|
export PLATFORMIO_EXTRA_SCRIPTS
|
||||||
|
export STATIC_LIBS
|
||||||
|
export PLATFORMIO_WORKSPACE_DIR="$WORK/pio/$SANITIZER"
|
||||||
|
export TARGET_CC=$CC
|
||||||
|
export TARGET_CXX=$CXX
|
||||||
|
export TARGET_LD=$CXX
|
||||||
|
export TARGET_AR=llvm-ar
|
||||||
|
export TARGET_AS=llvm-as
|
||||||
|
export TARGET_OBJCOPY=llvm-objcopy
|
||||||
|
export TARGET_RANLIB=llvm-ranlib
|
||||||
|
|
||||||
|
mkdir -p "$OUT/lib"
|
||||||
|
|
||||||
|
cp .clusterfuzzlite/*_fuzzer.options "$OUT/"
|
||||||
|
|
||||||
|
for f in .clusterfuzzlite/*_fuzzer.cpp; do
|
||||||
|
fuzzer=$(basename "$f" .cpp)
|
||||||
|
cp -f "$f" src/fuzzer.cpp
|
||||||
|
pio run -vvv --environment "$PIO_ENV"
|
||||||
|
program="$PLATFORMIO_WORKSPACE_DIR/build/$PIO_ENV/program"
|
||||||
|
cp "$program" "$OUT/$fuzzer"
|
||||||
|
|
||||||
|
# Copy shared libraries used by the fuzzer.
|
||||||
|
read -d '' -ra shared_libs < <(ldd "$program" | sed -n 's/[^=]\+=> \([^ ]\+\).*/\1/p') || true
|
||||||
|
cp -f "${shared_libs[@]}" "$OUT/lib/"
|
||||||
|
|
||||||
|
# Build the initial fuzzer seed corpus.
|
||||||
|
corpus_name="${fuzzer}_seed_corpus"
|
||||||
|
corpus_generator="$PWD/.clusterfuzzlite/${corpus_name}.py"
|
||||||
|
if [[ -f $corpus_generator ]]; then
|
||||||
|
mkdir "$corpus_name"
|
||||||
|
pushd "$corpus_name"
|
||||||
|
python3 "$corpus_generator"
|
||||||
|
popd
|
||||||
|
zip -D "$OUT/${corpus_name}.zip" "$corpus_name"/*
|
||||||
|
fi
|
||||||
|
done
|
||||||
35
.clusterfuzzlite/platformio-clusterfuzzlite-post.py
Normal file
35
.clusterfuzzlite/platformio-clusterfuzzlite-post.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
"""PlatformIO build script (post: runs after other Meshtastic scripts)."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
from SCons.Script import DefaultEnvironment
|
||||||
|
|
||||||
|
env = DefaultEnvironment()
|
||||||
|
|
||||||
|
# Remove any static libraries from the LIBS environment. Static libraries are
|
||||||
|
# handled in platformio-clusterfuzzlite-pre.py.
|
||||||
|
static_libs = set(lib[2:] for lib in shlex.split(os.getenv("STATIC_LIBS")))
|
||||||
|
env.Replace(
|
||||||
|
LIBS=[
|
||||||
|
lib for lib in env["LIBS"] if not (isinstance(lib, str) and lib in static_libs)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# FrameworkArduino/portduino/main.cpp contains the "main" function the binary.
|
||||||
|
# The fuzzing framework also provides a "main" function and needs to be run
|
||||||
|
# before Meshtastic is started. We rename the "main" function for Meshtastic to
|
||||||
|
# "portduino_main" here so that it can be called inside the fuzzer.
|
||||||
|
env.AddPostAction(
|
||||||
|
"$BUILD_DIR/FrameworkArduino/portduino/main.cpp.o",
|
||||||
|
env.VerboseAction(
|
||||||
|
" ".join(
|
||||||
|
[
|
||||||
|
"$OBJCOPY",
|
||||||
|
"--redefine-sym=main=portduino_main",
|
||||||
|
"$BUILD_DIR/FrameworkArduino/portduino/main.cpp.o",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
"Renaming main symbol to portduino_main",
|
||||||
|
),
|
||||||
|
)
|
||||||
52
.clusterfuzzlite/platformio-clusterfuzzlite-pre.py
Normal file
52
.clusterfuzzlite/platformio-clusterfuzzlite-pre.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
"""PlatformIO build script (pre: runs before other Meshtastic scripts).
|
||||||
|
|
||||||
|
ClusterFuzzLite executes in a different container from the build. During the build,
|
||||||
|
attempt to link statically to as many dependencies as possible. For dependencies that
|
||||||
|
do not have static libraries, the shared library files are copied to the output
|
||||||
|
directory by the build.sh script.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
from SCons.Script import DefaultEnvironment, Literal
|
||||||
|
|
||||||
|
env = DefaultEnvironment()
|
||||||
|
|
||||||
|
cxxflags = shlex.split(os.getenv("CXXFLAGS"))
|
||||||
|
sanitizer_flags = shlex.split(os.getenv("SANITIZER_FLAGS"))
|
||||||
|
lib_fuzzing_engine = shlex.split(os.getenv("LIB_FUZZING_ENGINE"))
|
||||||
|
statics = glob.glob("/usr/lib/lib*.a") + glob.glob("/usr/lib/*/lib*.a")
|
||||||
|
no_static = set(("-ldl",))
|
||||||
|
|
||||||
|
|
||||||
|
def replaceStatic(lib):
|
||||||
|
"""Replace -l<libname> with the static .a file for the library."""
|
||||||
|
if not lib.startswith("-l") or lib in no_static:
|
||||||
|
return lib
|
||||||
|
static_name = f"/lib{lib[2:]}.a"
|
||||||
|
static = [s for s in statics if s.endswith(static_name)]
|
||||||
|
if len(static) == 1:
|
||||||
|
return static[0]
|
||||||
|
return lib
|
||||||
|
|
||||||
|
|
||||||
|
# Setup the environment for building with Clang and the OSS-Fuzz required build flags.
|
||||||
|
env.Append(
|
||||||
|
CFLAGS=os.getenv("CFLAGS"),
|
||||||
|
CXXFLAGS=cxxflags,
|
||||||
|
LIBSOURCE_DIRS=["/usr/lib/x86_64-linux-gnu"],
|
||||||
|
LINKFLAGS=cxxflags
|
||||||
|
+ sanitizer_flags
|
||||||
|
+ lib_fuzzing_engine
|
||||||
|
+ ["-stdlib=libc++", "-std=c++17"],
|
||||||
|
_LIBFLAGS=[replaceStatic(s) for s in shlex.split(os.getenv("STATIC_LIBS"))]
|
||||||
|
+ [
|
||||||
|
"/usr/lib/x86_64-linux-gnu/libunistring.a", # Needs to be at the end.
|
||||||
|
# Find the shared libraries in a subdirectory named lib
|
||||||
|
# within the same directory as the binary.
|
||||||
|
Literal("-Wl,-rpath,$ORIGIN/lib"),
|
||||||
|
"-Wl,-z,origin",
|
||||||
|
],
|
||||||
|
)
|
||||||
1
.clusterfuzzlite/project.yaml
Normal file
1
.clusterfuzzlite/project.yaml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
language: c++
|
||||||
206
.clusterfuzzlite/router_fuzzer.cpp
Normal file
206
.clusterfuzzlite/router_fuzzer.cpp
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
// Fuzzer implementation that sends MeshPackets to Router::enqueueReceivedMessage.
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <mutex>
|
||||||
|
#include <pb_decode.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "PortduinoGPIO.h"
|
||||||
|
#include "PortduinoGlue.h"
|
||||||
|
#include "PowerFSM.h"
|
||||||
|
#include "mesh/MeshTypes.h"
|
||||||
|
#include "mesh/NodeDB.h"
|
||||||
|
#include "mesh/Router.h"
|
||||||
|
#include "mesh/TypeConversions.h"
|
||||||
|
#include "mesh/mesh-pb-constants.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr uint32_t nodeId = 0x12345678;
|
||||||
|
// Set to true when lateInitVariant finishes. Used to ensure lateInitVariant was called during startup.
|
||||||
|
bool hasBeenConfigured = false;
|
||||||
|
|
||||||
|
// These are used to block the Arduino loop() function until a fuzzer input is ready. This is
|
||||||
|
// an optimization that prevents a sleep from happening before the loop is run. The Arduino loop
|
||||||
|
// function calls loopCanSleep() before sleeping. loopCanSleep is implemented here in the fuzzer
|
||||||
|
// and blocks until runLoopOnce() is called to signal for the loop to run.
|
||||||
|
bool fuzzerRunning = false; // Set to true once LLVMFuzzerTestOneInput has started running.
|
||||||
|
bool loopCanRun = true; // The main Arduino loop() can run when this is true.
|
||||||
|
bool loopIsWaiting = false; // The main Arduino loop() is waiting to be signaled to run.
|
||||||
|
bool loopShouldExit = false; // Indicates that the main Arduino thread should exit by throwing ShouldExitException.
|
||||||
|
std::mutex loopLock;
|
||||||
|
std::condition_variable loopCV;
|
||||||
|
std::thread meshtasticThread;
|
||||||
|
|
||||||
|
// This exception is thrown when the portuino main thread should exit.
|
||||||
|
class ShouldExitException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start the loop for one test case and wait till the loop has completed. This ensures fuzz
|
||||||
|
// test cases do not overlap with one another. This helps the fuzzer attribute a crash to the
|
||||||
|
// single, currently running, test case.
|
||||||
|
void runLoopOnce()
|
||||||
|
{
|
||||||
|
realHardware = true; // Avoids delay(100) within portduino/main.cpp
|
||||||
|
std::unique_lock<std::mutex> lck(loopLock);
|
||||||
|
fuzzerRunning = true;
|
||||||
|
loopCanRun = true;
|
||||||
|
loopCV.notify_one();
|
||||||
|
loopCV.wait(lck, [] { return !loopCanRun && loopIsWaiting; });
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Called in the main Arduino loop function to determine if the loop can delay/sleep before running again.
|
||||||
|
// We use this as a way to block the loop from sleeping and to start the loop function immediately when a
|
||||||
|
// fuzzer input is ready.
|
||||||
|
bool loopCanSleep()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(loopLock);
|
||||||
|
loopIsWaiting = true;
|
||||||
|
loopCV.notify_one();
|
||||||
|
loopCV.wait(lck, [] { return loopCanRun || loopShouldExit; });
|
||||||
|
loopIsWaiting = false;
|
||||||
|
if (loopShouldExit)
|
||||||
|
throw ShouldExitException("exit");
|
||||||
|
if (!fuzzerRunning)
|
||||||
|
return true; // The loop can sleep before the fuzzer starts.
|
||||||
|
loopCanRun = false; // Only run the loop once before waiting again.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called just prior to starting Meshtastic. Allows for setting config values before startup.
|
||||||
|
void lateInitVariant()
|
||||||
|
{
|
||||||
|
settingsMap[logoutputlevel] = level_error;
|
||||||
|
channelFile.channels[0] = meshtastic_Channel{
|
||||||
|
.has_settings = true,
|
||||||
|
.settings =
|
||||||
|
meshtastic_ChannelSettings{
|
||||||
|
.psk = {.size = 1, .bytes = {/*defaultpskIndex=*/1}},
|
||||||
|
.name = "LongFast",
|
||||||
|
.uplink_enabled = true,
|
||||||
|
.has_module_settings = true,
|
||||||
|
.module_settings = {.position_precision = 16},
|
||||||
|
},
|
||||||
|
.role = meshtastic_Channel_Role_PRIMARY,
|
||||||
|
};
|
||||||
|
config.security.admin_key[0] = {
|
||||||
|
.size = 32,
|
||||||
|
.bytes = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a,
|
||||||
|
0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c},
|
||||||
|
};
|
||||||
|
config.security.admin_key_count = 1;
|
||||||
|
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_US;
|
||||||
|
moduleConfig.has_mqtt = true;
|
||||||
|
moduleConfig.mqtt = meshtastic_ModuleConfig_MQTTConfig{
|
||||||
|
.enabled = true,
|
||||||
|
.proxy_to_client_enabled = true,
|
||||||
|
};
|
||||||
|
moduleConfig.has_store_forward = true;
|
||||||
|
moduleConfig.store_forward = meshtastic_ModuleConfig_StoreForwardConfig{
|
||||||
|
.enabled = true,
|
||||||
|
.history_return_max = 4,
|
||||||
|
.history_return_window = 600,
|
||||||
|
.is_server = true,
|
||||||
|
};
|
||||||
|
meshtastic_Position fixedGPS = meshtastic_Position{
|
||||||
|
.has_latitude_i = true,
|
||||||
|
.latitude_i = static_cast<uint32_t>(1 * 1e7),
|
||||||
|
.has_longitude_i = true,
|
||||||
|
.longitude_i = static_cast<uint32_t>(3 * 1e7),
|
||||||
|
.has_altitude = true,
|
||||||
|
.altitude = 64,
|
||||||
|
.location_source = meshtastic_Position_LocSource_LOC_MANUAL,
|
||||||
|
};
|
||||||
|
nodeDB->setLocalPosition(fixedGPS);
|
||||||
|
config.has_position = true;
|
||||||
|
config.position.fixed_position = true;
|
||||||
|
meshtastic_NodeInfoLite *info = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||||
|
info->has_position = true;
|
||||||
|
info->position = TypeConversions::ConvertToPositionLite(fixedGPS);
|
||||||
|
hasBeenConfigured = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
int portduino_main(int argc, char **argv); // Renamed "main" function from Meshtastic binary.
|
||||||
|
|
||||||
|
// Start Meshtastic in a thread and wait till it has reached the ON state.
|
||||||
|
int LLVMFuzzerInitialize(int *argc, char ***argv)
|
||||||
|
{
|
||||||
|
settingsMap[maxtophone] = 5;
|
||||||
|
|
||||||
|
meshtasticThread = std::thread([program = *argv[0]]() {
|
||||||
|
char nodeIdStr[12];
|
||||||
|
strcpy(nodeIdStr, std::to_string(nodeId).c_str());
|
||||||
|
int argc = 7;
|
||||||
|
char *argv[] = {program, "-d", "/tmp/meshtastic", "-h", nodeIdStr, "-p", "0", nullptr};
|
||||||
|
try {
|
||||||
|
portduino_main(argc, argv);
|
||||||
|
} catch (const ShouldExitException &) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
std::atexit([] {
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lck(loopLock);
|
||||||
|
loopShouldExit = true;
|
||||||
|
loopCV.notify_one();
|
||||||
|
}
|
||||||
|
meshtasticThread.join();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for startup.
|
||||||
|
for (int i = 1; i < 20; ++i) {
|
||||||
|
if (powerFSM.getState() == &stateON) {
|
||||||
|
assert(hasBeenConfigured);
|
||||||
|
assert(router);
|
||||||
|
assert(nodeDB);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the main entrypoint for the fuzzer (the fuzz target). The fuzzer will provide an array of bytes to be
|
||||||
|
// interpreted by this method. To keep things simple, the bytes are interpreted as a binary serialized MeshPacket
|
||||||
|
// proto. Any crashes discovered by the fuzzer will be written to a file. Unserialize that file to print the MeshPacket
|
||||||
|
// that caused the failure.
|
||||||
|
//
|
||||||
|
// This guide provides best practices for writing a fuzzer target.
|
||||||
|
// https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
meshtastic_MeshPacket p = meshtastic_MeshPacket_init_default;
|
||||||
|
pb_istream_t stream = pb_istream_from_buffer(data, length);
|
||||||
|
// Ignore any inputs that fail to decode or have fields set that are not transmitted over LoRa.
|
||||||
|
if (!pb_decode(&stream, &meshtastic_MeshPacket_msg, &p) || p.rx_time || p.rx_snr || p.priority || p.rx_rssi || p.delayed ||
|
||||||
|
p.public_key.size || p.next_hop || p.relay_node || p.tx_after)
|
||||||
|
return -1; // Reject: The input will not be added to the corpus.
|
||||||
|
if (p.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
|
meshtastic_Data d;
|
||||||
|
stream = pb_istream_from_buffer(p.decoded.payload.bytes, p.decoded.payload.size);
|
||||||
|
if (!pb_decode(&stream, &meshtastic_Data_msg, &d))
|
||||||
|
return -1; // Reject: The input will not be added to the corpus.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide default values for a few fields so the fuzzer doesn't need to guess them.
|
||||||
|
if (p.from == 0)
|
||||||
|
p.from = nodeDB->getNodeNum();
|
||||||
|
if (p.to == 0)
|
||||||
|
p.to = nodeDB->getNodeNum();
|
||||||
|
static uint32_t packetId = 0;
|
||||||
|
if (p.id == 0)
|
||||||
|
p.id == ++packetId;
|
||||||
|
if (p.pki_encrypted && config.security.admin_key_count)
|
||||||
|
memcpy(&p.public_key, &config.security.admin_key[0], sizeof(p.public_key));
|
||||||
|
|
||||||
|
router->enqueueReceivedMessage(packetPool.allocCopy(p));
|
||||||
|
runLoopOnce();
|
||||||
|
return 0; // Accept: The input may be added to the corpus.
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.clusterfuzzlite/router_fuzzer.options
Normal file
2
.clusterfuzzlite/router_fuzzer.options
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[libfuzzer]
|
||||||
|
max_len=256
|
||||||
168
.clusterfuzzlite/router_fuzzer_seed_corpus.py
Normal file
168
.clusterfuzzlite/router_fuzzer_seed_corpus.py
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
"""Generate an initial set of MeshPackets.
|
||||||
|
|
||||||
|
The fuzzer uses these MeshPackets as an initial seed of test candidates.
|
||||||
|
|
||||||
|
It's also good to add any previously discovered crash test cases to this list
|
||||||
|
to avoid future regressions.
|
||||||
|
|
||||||
|
If left unset, the following values will be automatically set by the fuzzer.
|
||||||
|
- to: automatically set to the running node's NodeID
|
||||||
|
- from: automatically set to the running node's NodeID
|
||||||
|
- id: automatically set to the value of an incrementing counter
|
||||||
|
|
||||||
|
Additionally, if `pki_encrypted` is populated in the packet, the first admin key
|
||||||
|
will be copied into the `public_key` field.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from meshtastic import BROADCAST_NUM
|
||||||
|
from meshtastic.protobuf import (
|
||||||
|
admin_pb2,
|
||||||
|
atak_pb2,
|
||||||
|
mesh_pb2,
|
||||||
|
portnums_pb2,
|
||||||
|
telemetry_pb2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def From(node: int = 9):
|
||||||
|
"""Return a dict suitable for **kwargs for populating the 'from' field.
|
||||||
|
|
||||||
|
'from' is a reserved keyword in Python. It can't be used directly as an
|
||||||
|
argument to the MeshPacket constructor. Rather **From() can be used as
|
||||||
|
the final argument to provide the from node as a **kwarg.
|
||||||
|
|
||||||
|
Defaults to 9 if no value is provided.
|
||||||
|
"""
|
||||||
|
return {"from": node}
|
||||||
|
|
||||||
|
|
||||||
|
packets = (
|
||||||
|
(
|
||||||
|
"position",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.POSITION_APP,
|
||||||
|
payload=mesh_pb2.Position(
|
||||||
|
latitude_i=int(1 * 1e7),
|
||||||
|
longitude_i=int(2 * 1e7),
|
||||||
|
altitude=5,
|
||||||
|
precision_bits=32,
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
to=BROADCAST_NUM,
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"telemetry",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.TELEMETRY_APP,
|
||||||
|
payload=telemetry_pb2.Telemetry(
|
||||||
|
time=1736192207,
|
||||||
|
device_metrics=telemetry_pb2.DeviceMetrics(
|
||||||
|
battery_level=101,
|
||||||
|
channel_utilization=8,
|
||||||
|
air_util_tx=2,
|
||||||
|
uptime_seconds=42,
|
||||||
|
),
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
to=BROADCAST_NUM,
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"text",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.TEXT_MESSAGE_APP,
|
||||||
|
payload=b"Hello world",
|
||||||
|
),
|
||||||
|
to=BROADCAST_NUM,
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.NODEINFO_APP,
|
||||||
|
payload=mesh_pb2.User(
|
||||||
|
id="!00000009",
|
||||||
|
long_name="Node 9",
|
||||||
|
short_name="N9",
|
||||||
|
macaddr=b"\x00\x00\x00\x00\x00\x09",
|
||||||
|
hw_model=mesh_pb2.HardwareModel.RAK4631,
|
||||||
|
public_key=base64.b64decode(
|
||||||
|
"L0ih/6F41itofdE8mYyHk1SdfOJ/QRM1KQ+pO4vEEjQ="
|
||||||
|
),
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"traceroute",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.TRACEROUTE_APP,
|
||||||
|
payload=mesh_pb2.RouteDiscovery(
|
||||||
|
route=[10],
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"routing",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.ROUTING_APP,
|
||||||
|
payload=mesh_pb2.Routing(
|
||||||
|
error_reason=mesh_pb2.Routing.NO_RESPONSE,
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"admin",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.ADMIN_APP,
|
||||||
|
payload=admin_pb2.AdminMessage(
|
||||||
|
get_owner_request=True,
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
pki_encrypted=True,
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"atak",
|
||||||
|
mesh_pb2.MeshPacket(
|
||||||
|
decoded=mesh_pb2.Data(
|
||||||
|
portnum=portnums_pb2.PortNum.ATAK_PLUGIN,
|
||||||
|
payload=atak_pb2.TAKPacket(
|
||||||
|
is_compressed=True,
|
||||||
|
# Note, the strings are not valid for a compressed message, but will
|
||||||
|
# give the fuzzer a starting point.
|
||||||
|
contact=atak_pb2.Contact(
|
||||||
|
callsign="callsign", device_callsign="device_callsign"
|
||||||
|
),
|
||||||
|
chat=atak_pb2.GeoChat(
|
||||||
|
message="message", to="to", to_callsign="to_callsign"
|
||||||
|
),
|
||||||
|
).SerializeToString(),
|
||||||
|
),
|
||||||
|
**From(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for name, packet in packets:
|
||||||
|
with open(f"{name}.MeshPacket", "wb") as f:
|
||||||
|
f.write(packet.SerializeToString())
|
||||||
183
.devcontainer/99-platformio-udev.rules
Normal file
183
.devcontainer/99-platformio-udev.rules
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
#
|
||||||
|
# INSTALLATION
|
||||||
|
#
|
||||||
|
# Please visit > https://docs.platformio.org/en/latest/core/installation/udev-rules.html
|
||||||
|
#
|
||||||
|
#####################################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Boards
|
||||||
|
#
|
||||||
|
|
||||||
|
# CP210X USB UART
|
||||||
|
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea[67][013]", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="80a9", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# FT231XS USB UART
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Prolific Technology, Inc. PL2303 Serial Port
|
||||||
|
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# QinHeng Electronics HL-340 USB-Serial adapter
|
||||||
|
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
# QinHeng Electronics CH343 USB-Serial adapter
|
||||||
|
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d3", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
# QinHeng Electronics CH9102 USB-Serial adapter
|
||||||
|
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Arduino boards
|
||||||
|
ATTRS{idVendor}=="2341", ATTRS{idProduct}=="[08][023]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="[08][02]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Arduino SAM-BA
|
||||||
|
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="6124", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{MTP_NO_PROBE}="1"
|
||||||
|
|
||||||
|
# Digistump boards
|
||||||
|
ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Maple with DFU
|
||||||
|
ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="000[34]", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# USBtiny
|
||||||
|
ATTRS{idProduct}=="0c9f", ATTRS{idVendor}=="1781", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# USBasp V2.0
|
||||||
|
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Teensy boards
|
||||||
|
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
|
||||||
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666"
|
||||||
|
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666"
|
||||||
|
|
||||||
|
# TI Stellaris Launchpad
|
||||||
|
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# TI MSP430 Launchpad
|
||||||
|
ATTRS{idVendor}=="0451", ATTRS{idProduct}=="f432", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# GD32V DFU Bootloader
|
||||||
|
ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# FireBeetle-ESP32
|
||||||
|
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7522", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Wio Terminal
|
||||||
|
ATTRS{idVendor}=="2886", ATTRS{idProduct}=="[08]02d", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Raspberry Pi Pico
|
||||||
|
ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="[01]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# AIR32F103
|
||||||
|
ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# STM32 virtual COM port
|
||||||
|
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Debuggers
|
||||||
|
#
|
||||||
|
|
||||||
|
# Black Magic Probe
|
||||||
|
SUBSYSTEM=="tty", ATTRS{interface}=="Black Magic GDB Server", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
SUBSYSTEM=="tty", ATTRS{interface}=="Black Magic UART Port", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# opendous and estick
|
||||||
|
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204f", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Original FT232/FT245/FT2232/FT232H/FT4232
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="60[01][104]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# DISTORTEC JTAG-lock-pick Tiny 2
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8220", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# TUMPA, TUMPA Lite
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a9[89]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# XDS100v2
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a6d0", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE)
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca[01]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# TI/Luminary Stellaris Evaluation Board FTDI (several)
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd[9a]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# egnite Turtelizer 2
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bdc8", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Section5 ICEbear
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c14[01]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Amontec JTAGkey and JTAGkey-tiny
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="cff8", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# TI ICDI
|
||||||
|
ATTRS{idVendor}=="0451", ATTRS{idProduct}=="c32a", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# STLink probes
|
||||||
|
ATTRS{idVendor}=="0483", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Hilscher NXHX Boards
|
||||||
|
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="0028", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Hitex probes
|
||||||
|
ATTRS{idVendor}=="0640", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Altera USB Blaster
|
||||||
|
ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Amontec JTAGkey-HiSpeed
|
||||||
|
ATTRS{idVendor}=="0fbb", ATTRS{idProduct}=="1000", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# SEGGER J-Link
|
||||||
|
ATTRS{idVendor}=="1366", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Raisonance RLink
|
||||||
|
ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Debug Board for Neo1973
|
||||||
|
ATTRS{idVendor}=="1457", ATTRS{idProduct}=="5118", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Olimex probes
|
||||||
|
ATTRS{idVendor}=="15ba", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# USBprog with OpenOCD firmware
|
||||||
|
ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
|
||||||
|
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Marvell Sheevaplug
|
||||||
|
ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Keil Software, Inc. ULink
|
||||||
|
ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2710", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# CMSIS-DAP compatible adapters
|
||||||
|
ATTRS{product}=="*CMSIS-DAP*", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Atmel AVR Dragon
|
||||||
|
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2107", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Espressif USB JTAG/serial debug unit
|
||||||
|
ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
|
|
||||||
|
# Zephyr framework USB CDC-ACM
|
||||||
|
ATTRS{idVendor}=="2fe3", ATTRS{idProduct}=="0100", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
||||||
|
|
||||||
# [Optional] Uncomment this section to install additional packages.
|
USER root
|
||||||
|
|
||||||
|
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||||
|
# trunk-ignore(hadolint/DL3008): Use latest version of packages
|
||||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
&& apt-get -y install --no-install-recommends \
|
&& apt-get -y install --no-install-recommends \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
@@ -20,6 +23,16 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
|||||||
python3-wheel \
|
python3-wheel \
|
||||||
wget \
|
wget \
|
||||||
zip \
|
zip \
|
||||||
|
usbutils \
|
||||||
|
hwdata \
|
||||||
|
gpg \
|
||||||
|
gnupg2 \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN pipx install platformio==6.1.15
|
RUN pipx install platformio==6.1.15
|
||||||
|
|
||||||
|
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
||||||
|
|
||||||
|
USER vscode
|
||||||
|
|
||||||
|
HEALTHCHECK NONE
|
||||||
@@ -13,13 +13,24 @@
|
|||||||
},
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": ["ms-vscode.cpptools", "platformio.platformio-ide"]
|
"extensions": [
|
||||||
|
"ms-vscode.cpptools",
|
||||||
|
"platformio.platformio-ide",
|
||||||
|
"Trunk.io"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": ["ms-azuretools.vscode-docker"],
|
||||||
|
"settings": {
|
||||||
|
"extensions.ignoreRecommendations": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
"forwardPorts": [4403],
|
"forwardPorts": [4403],
|
||||||
|
|
||||||
|
// Use "--device=" to make a local device available inside the container.
|
||||||
|
// "runArgs": ["--device=/dev/ttyACM0"],
|
||||||
|
|
||||||
// Run commands to prepare the container for use
|
// Run commands to prepare the container for use
|
||||||
"postCreateCommand": ".devcontainer/setup.sh"
|
"postCreateCommand": ".devcontainer/setup.sh"
|
||||||
}
|
}
|
||||||
|
|||||||
1
.dockerignore
Symbolic link
1
.dockerignore
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
.gitignore
|
||||||
4
.env.example
Normal file
4
.env.example
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Absolute path to the local meshtastic config.yaml file
|
||||||
|
CONFIG_PATH=/path/to/meshtastic/config.yaml
|
||||||
|
# USB device to passthrough (`lsusb -t`: look for `ch341`)
|
||||||
|
USB_DEVICE=/dev/bus/usb/001/037
|
||||||
10
.github/actions/build-variant/action.yml
vendored
10
.github/actions/build-variant/action.yml
vendored
@@ -68,6 +68,12 @@ runs:
|
|||||||
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
|
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
|
||||||
done
|
done
|
||||||
|
|
||||||
|
- name: PlatformIO ${{ inputs.arch }} download cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.platformio/.cache
|
||||||
|
key: pio-cache-${{ inputs.arch }}-${{ hashFiles('.github/actions/**', '**.ini') }}
|
||||||
|
|
||||||
- name: Build ${{ inputs.board }}
|
- name: Build ${{ inputs.board }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
|
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
|
||||||
@@ -83,13 +89,13 @@ runs:
|
|||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
${{ inputs.artifact-paths }}
|
${{ inputs.artifact-paths }}
|
||||||
|
|||||||
13
.github/actions/setup-base/action.yml
vendored
13
.github/actions/setup-base/action.yml
vendored
@@ -20,19 +20,16 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update --fix-missing
|
sudo apt-get -y update --fix-missing
|
||||||
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev
|
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
cache: pip
|
||||||
# - name: Cache python libs
|
cache-dependency-path: |
|
||||||
# uses: actions/cache@v4
|
.github/actions/**
|
||||||
# id: cache-pip # needed in if test
|
**.ini
|
||||||
# with:
|
|
||||||
# path: ~/.cache/pip
|
|
||||||
# key: ${{ runner.os }}-pip
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
- name: Upgrade python tools
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
14
.github/actions/setup-native/action.yml
vendored
Normal file
14
.github/actions/setup-native/action.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
name: Setup native build
|
||||||
|
description: Install libraries needed for building the Native/Portduino build
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Setup base
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
|
- name: Install libs needed for native build
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
||||||
72
.github/workflows/build_debian_src.yml
vendored
Normal file
72
.github/workflows/build_debian_src.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
name: Build Debian Source Package
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
PPA_GPG_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
series:
|
||||||
|
description: Ubuntu/Debian series to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
build_location:
|
||||||
|
description: Location where build will execute
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-debian-src:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: meshtasticd
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y software-properties-common build-essential devscripts equivs
|
||||||
|
sudo add-apt-repository ppa:meshtastic/build-tools -y
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
|
||||||
|
|
||||||
|
- name: Import GPG key
|
||||||
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||||
|
id: gpg
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: ${{ inputs.build_location }}
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Fetch libdeps, package debian source
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: debian/ci_pack_sdeb.sh
|
||||||
|
env:
|
||||||
|
SERIES: ${{ inputs.series }}
|
||||||
|
GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }}
|
||||||
|
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||||
|
|
||||||
|
- name: Store binaries as an artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
|
overwrite: true
|
||||||
|
path: |
|
||||||
|
meshtasticd_${{ steps.version.outputs.deb }}*
|
||||||
57
.github/workflows/build_native.yml
vendored
57
.github/workflows/build_native.yml
vendored
@@ -10,12 +10,6 @@ jobs:
|
|||||||
build-native:
|
build-native:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install libs needed for native build
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get update --fix-missing
|
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -23,63 +17,22 @@ jobs:
|
|||||||
ref: ${{github.event.pull_request.head.ref}}
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- name: Upgrade python tools
|
- name: Setup native build
|
||||||
shell: bash
|
id: base
|
||||||
run: |
|
uses: ./.github/actions/setup-native
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -U platformio adafruit-nrfutil
|
|
||||||
pip install -U meshtastic --pre
|
|
||||||
|
|
||||||
- name: Upgrade platformio
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
pio upgrade
|
|
||||||
|
|
||||||
- name: Build Native
|
- name: Build Native
|
||||||
run: bin/build-native.sh
|
run: bin/build-native.sh
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
name: firmware-native-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
release/meshtasticd_linux_x86_64
|
release/meshtasticd_linux_x86_64
|
||||||
bin/config-dist.yaml
|
bin/config-dist.yaml
|
||||||
|
|
||||||
- name: Docker login
|
|
||||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
continue-on-error: true # FIXME: Failing docker login auth
|
|
||||||
with:
|
|
||||||
username: meshtastic
|
|
||||||
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
|
|
||||||
|
|
||||||
- name: Docker setup
|
|
||||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
|
||||||
continue-on-error: true # FIXME: Failing docker login auth
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Docker build and push tagged versions
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
|
||||||
continue-on-error: true # FIXME: Failing docker login auth
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
push: true
|
|
||||||
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
|
|
||||||
|
|
||||||
- name: Docker build and push
|
|
||||||
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
|
||||||
continue-on-error: true # FIXME: Failing docker login auth
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
push: true
|
|
||||||
tags: meshtastic/device-simulator:latest
|
|
||||||
|
|||||||
6
.github/workflows/build_raspbian.yml
vendored
6
.github/workflows/build_raspbian.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -y --fix-missing
|
sudo apt-get update -y --fix-missing
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -39,13 +39,13 @@ jobs:
|
|||||||
run: bin/build-native.sh
|
run: bin/build-native.sh
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
release/meshtasticd_linux_aarch64
|
release/meshtasticd_linux_aarch64
|
||||||
|
|||||||
6
.github/workflows/build_raspbian_armv7l.yml
vendored
6
.github/workflows/build_raspbian_armv7l.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -y --fix-missing
|
sudo apt-get update -y --fix-missing
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -39,13 +39,13 @@ jobs:
|
|||||||
run: bin/build-native.sh
|
run: bin/build-native.sh
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-armv7l-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
release/meshtasticd_linux_armv7l
|
release/meshtasticd_linux_armv7l
|
||||||
|
|||||||
51
.github/workflows/daily_packaging.yml
vendored
Normal file
51
.github/workflows/daily_packaging.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: Daily Packaging
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: 0 9 * * *
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- debian/**
|
||||||
|
- "*.rpkg"
|
||||||
|
- .github/workflows/nightly_packaging.yml
|
||||||
|
- .github/workflows/build_debian_src.yml
|
||||||
|
- .github/workflows/package_ppa.yml
|
||||||
|
- .github/workflows/package_obs.yml
|
||||||
|
- .github/workflows/hook_copr.yml
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker-multiarch:
|
||||||
|
uses: ./.github/workflows/docker_manifest.yml
|
||||||
|
with:
|
||||||
|
release_channel: daily
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
package-ppa:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
series: [plucky, oracular, noble, jammy]
|
||||||
|
uses: ./.github/workflows/package_ppa.yml
|
||||||
|
with:
|
||||||
|
ppa_repo: ppa:meshtastic/daily
|
||||||
|
series: ${{ matrix.series }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
package-obs:
|
||||||
|
uses: ./.github/workflows/package_obs.yml
|
||||||
|
with:
|
||||||
|
obs_project: network:Meshtastic:daily
|
||||||
|
series: unstable
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
hook-copr:
|
||||||
|
uses: ./.github/workflows/hook_copr.yml
|
||||||
|
with:
|
||||||
|
copr_project: daily
|
||||||
|
secrets: inherit
|
||||||
92
.github/workflows/docker_build.yml
vendored
Normal file
92
.github/workflows/docker_build.yml
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
name: Build Docker
|
||||||
|
|
||||||
|
# Build Docker image, push untagged (digest-only)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
DOCKER_FIRMWARE_TOKEN:
|
||||||
|
required: false # Only required for push
|
||||||
|
inputs:
|
||||||
|
distro:
|
||||||
|
description: Distro to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
# choices: [debian, alpine]
|
||||||
|
platform:
|
||||||
|
description: Platform to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
runs-on:
|
||||||
|
description: Runner to use
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
push:
|
||||||
|
description: Push images to registry
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
outputs:
|
||||||
|
digest:
|
||||||
|
description: Digest of built image
|
||||||
|
value: ${{ jobs.docker-build.outputs.digest }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker-build:
|
||||||
|
outputs:
|
||||||
|
digest: ${{ steps.docker_variant.outputs.digest }}
|
||||||
|
runs-on: ${{ inputs.runs-on }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: |
|
||||||
|
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Docker login
|
||||||
|
if: ${{ inputs.push }}
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: meshtastic
|
||||||
|
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Docker setup
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Sanitize platform string
|
||||||
|
id: sanitize_platform
|
||||||
|
# Replace slashes with underscores
|
||||||
|
run: echo "cleaned_platform=${{ inputs.platform }}" | sed 's/\//_/g' >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Docker tag
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: meshtastic/meshtasticd
|
||||||
|
tags: |
|
||||||
|
GHA-${{ steps.version.outputs.long }}-${{ inputs.distro }}-${{ steps.sanitize_platform.outputs.cleaned_platform }}
|
||||||
|
flavor: latest=false
|
||||||
|
|
||||||
|
- name: Docker build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
id: docker_variant
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: |
|
||||||
|
${{ contains(inputs.distro, 'debian') && './Dockerfile' || contains(inputs.distro, 'alpine') && './alpine.Dockerfile' }}
|
||||||
|
push: ${{ inputs.push }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }} # Tag is only meant to be consumed by the "manifest" job
|
||||||
|
platforms: ${{ inputs.platform }}
|
||||||
186
.github/workflows/docker_manifest.yml
vendored
Normal file
186
.github/workflows/docker_manifest.yml
vendored
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
name: Build Docker Multi-Arch Manifest
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
DOCKER_FIRMWARE_TOKEN:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
release_channel:
|
||||||
|
description: Release channel to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker-debian-amd64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: true
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
docker-debian-arm64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/arm64
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: true
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
docker-debian-armv7:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/arm/v7
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: true
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
docker-alpine-amd64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: alpine
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: true
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
docker-alpine-arm64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: alpine
|
||||||
|
platform: linux/arm64
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: true
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
docker-alpine-armv7:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: alpine
|
||||||
|
platform: linux/arm/v7
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: true
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
docker-manifest:
|
||||||
|
needs:
|
||||||
|
# Debian
|
||||||
|
- docker-debian-amd64
|
||||||
|
- docker-debian-arm64
|
||||||
|
- docker-debian-armv7
|
||||||
|
# Alpine
|
||||||
|
- docker-alpine-amd64
|
||||||
|
- docker-alpine-arm64
|
||||||
|
- docker-alpine-armv7
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: |
|
||||||
|
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Enumerate tags
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
import os
|
||||||
|
|
||||||
|
short = "${{ steps.version.outputs.short }}"
|
||||||
|
long = "${{ steps.version.outputs.long }}"
|
||||||
|
release_channel = "${{ inputs.release_channel }}"
|
||||||
|
tags = {
|
||||||
|
"beta": {
|
||||||
|
"debian": [
|
||||||
|
f"{short}", f"{long}", f"{short}-beta", f"{long}-beta", "beta", "latest",
|
||||||
|
f"{short}-debian", f"{long}-debian", f"{short}-beta-debian", f"{long}-beta-debian", "beta-debian"
|
||||||
|
],
|
||||||
|
"alpine": [
|
||||||
|
f"{short}-alpine", f"{long}-alpine", f"{short}-beta-alpine", f"{long}-beta-alpine", "beta-alpine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"alpha": {
|
||||||
|
"debian": [
|
||||||
|
f"{short}-alpha", f"{long}-alpha", "alpha",
|
||||||
|
f"{short}-alpha-debian", f"{long}-alpha-debian", "alpha-debian"
|
||||||
|
],
|
||||||
|
"alpine": [
|
||||||
|
f"{short}-alpha-alpine", f"{long}-alpha-alpine", "alpha-alpine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"daily": {
|
||||||
|
"debian": ["daily", "daily-debian"],
|
||||||
|
"alpine": ["daily-alpine"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(os.environ["GITHUB_OUTPUT"], "a") as fh:
|
||||||
|
fh.write("debian<<EOF\n")
|
||||||
|
fh.write("\n".join(tags[release_channel]["debian"]))
|
||||||
|
fh.write("\nEOF\n")
|
||||||
|
|
||||||
|
fh.write("alpine<<EOF\n")
|
||||||
|
fh.write("\n".join(tags[release_channel]["alpine"]))
|
||||||
|
fh.write("\nEOF\n")
|
||||||
|
id: tags
|
||||||
|
|
||||||
|
- name: Docker login
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: meshtastic
|
||||||
|
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
|
||||||
|
|
||||||
|
- name: Docker meta (Debian)
|
||||||
|
id: meta_debian
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: meshtastic/meshtasticd
|
||||||
|
tags: |
|
||||||
|
${{ steps.tags.outputs.debian }}
|
||||||
|
flavor: latest=false
|
||||||
|
|
||||||
|
- name: Create Docker manifest (Debian)
|
||||||
|
id: manifest_debian
|
||||||
|
uses: int128/docker-manifest-create-action@v2
|
||||||
|
with:
|
||||||
|
tags: |
|
||||||
|
${{ steps.meta_debian.outputs.tags }}
|
||||||
|
push: true
|
||||||
|
sources: |
|
||||||
|
meshtastic/meshtasticd@${{ needs.docker-debian-amd64.outputs.digest }}
|
||||||
|
meshtastic/meshtasticd@${{ needs.docker-debian-arm64.outputs.digest }}
|
||||||
|
meshtastic/meshtasticd@${{ needs.docker-debian-armv7.outputs.digest }}
|
||||||
|
|
||||||
|
- name: Docker meta (Alpine)
|
||||||
|
id: meta_alpine
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: meshtastic/meshtasticd
|
||||||
|
tags: |
|
||||||
|
${{ steps.tags.outputs.alpine }}
|
||||||
|
|
||||||
|
- name: Create Docker manifest (Alpine)
|
||||||
|
id: manifest_alpine
|
||||||
|
uses: int128/docker-manifest-create-action@v2
|
||||||
|
with:
|
||||||
|
tags: |
|
||||||
|
${{ steps.meta_alpine.outputs.tags }}
|
||||||
|
push: true
|
||||||
|
sources: |
|
||||||
|
meshtastic/meshtasticd@${{ needs.docker-alpine-amd64.outputs.digest }}
|
||||||
|
meshtastic/meshtasticd@${{ needs.docker-alpine-arm64.outputs.digest }}
|
||||||
|
meshtastic/meshtasticd@${{ needs.docker-alpine-armv7.outputs.digest }}
|
||||||
38
.github/workflows/hook_copr.yml
vendored
Normal file
38
.github/workflows/hook_copr.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Trigger COPR build
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
COPR_API_CONFIG:
|
||||||
|
inputs:
|
||||||
|
copr_project:
|
||||||
|
description: COPR project to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-copr-hook:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
ref: ${{ github.ref }}
|
||||||
|
repository: ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Trigger COPR build
|
||||||
|
uses: vidplace7/copr-build@main
|
||||||
|
id: copr_build
|
||||||
|
env:
|
||||||
|
COPR_API_TOKEN_CONFIG: ${{ secrets.COPR_API_CONFIG }}
|
||||||
|
with:
|
||||||
|
owner: "@meshtastic"
|
||||||
|
package-name: meshtasticd
|
||||||
|
project-name: ${{ inputs.copr_project }}
|
||||||
|
git-remote: "${{ github.server_url }}/${{ github.repository }}.git"
|
||||||
|
committish: ${{ github.sha }}
|
||||||
161
.github/workflows/main_matrix.yml
vendored
161
.github/workflows/main_matrix.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
|||||||
else
|
else
|
||||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
|
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
|
||||||
fi
|
fi
|
||||||
echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} Head: ${{ github.head_ref }} Ref: ${{ github.ref }} Targets: $TARGETS"
|
echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} } Ref: ${{ github.ref }} Targets: $TARGETS"
|
||||||
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
|
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
|
||||||
outputs:
|
outputs:
|
||||||
esp32: ${{ steps.jsonStep.outputs.esp32 }}
|
esp32: ${{ steps.jsonStep.outputs.esp32 }}
|
||||||
@@ -137,6 +137,48 @@ jobs:
|
|||||||
package-native:
|
package-native:
|
||||||
uses: ./.github/workflows/package_amd64.yml
|
uses: ./.github/workflows/package_amd64.yml
|
||||||
|
|
||||||
|
build-debian-src:
|
||||||
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
with:
|
||||||
|
series: UNRELEASED
|
||||||
|
build_location: local
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
test-native:
|
||||||
|
uses: ./.github/workflows/test_native.yml
|
||||||
|
|
||||||
|
docker-debian-amd64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: false
|
||||||
|
|
||||||
|
docker-alpine-amd64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: false
|
||||||
|
|
||||||
|
docker-debian-arm64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/arm64
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: false
|
||||||
|
|
||||||
|
docker-debian-armv7:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/arm/v7
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: false
|
||||||
|
|
||||||
after-checks:
|
after-checks:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||||
@@ -184,7 +226,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
@@ -193,7 +235,7 @@ jobs:
|
|||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./firmware-*.bin
|
./firmware-*.bin
|
||||||
@@ -210,7 +252,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -224,12 +266,12 @@ jobs:
|
|||||||
chmod +x ./output/device-update.sh
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: ./*.elf
|
path: ./*.elf
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
@@ -237,8 +279,8 @@ jobs:
|
|||||||
- uses: scruplelesswizard/comment-artifact@main
|
- uses: scruplelesswizard/comment-artifact@main
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation"
|
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
release-artifacts:
|
release-artifacts:
|
||||||
@@ -252,6 +294,7 @@ jobs:
|
|||||||
package-raspbian,
|
package-raspbian,
|
||||||
package-raspbian-armv7l,
|
package-raspbian-armv7l,
|
||||||
package-native,
|
package-native,
|
||||||
|
build-debian-src,
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -263,73 +306,70 @@ jobs:
|
|||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: |
|
||||||
|
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: local
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: actions/create-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
id: create_release
|
id: create_release
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }} Alpha
|
name: Meshtastic Firmware ${{ steps.version.outputs.long }} Alpha
|
||||||
tag_name: v${{ steps.version.outputs.version }}
|
tag_name: v${{ steps.version.outputs.long }}
|
||||||
body: |
|
body: |
|
||||||
Autogenerated by github action, developer should edit as required before publishing...
|
Autogenerated by github action, developer should edit as required before publishing...
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
|
|
||||||
- name: Download deb files
|
- name: Download deb files
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
pattern: meshtasticd_${{ steps.version.outputs.long }}_*.deb
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
|
- name: Download source deb
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: firmware-debian-${{ steps.version.outputs.deb }}~UNRELEASED-src
|
||||||
|
merge-multiple: true
|
||||||
|
path: ./output/debian-src
|
||||||
|
|
||||||
|
- name: Zip source deb
|
||||||
|
working-directory: output
|
||||||
|
run: zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
|
||||||
|
|
||||||
# For diagnostics
|
# For diagnostics
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -lR
|
run: ls -lR
|
||||||
|
|
||||||
- name: Add raspbian aarch64 .deb
|
- name: Add deb files to release
|
||||||
uses: actions/upload-release-asset@v1
|
run: |
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd_${{ steps.version.outputs.long }}_arm64.deb
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd_${{ steps.version.outputs.long }}_armhf.deb
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd_${{ steps.version.outputs.long }}_amd64.deb
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
|
||||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
|
||||||
asset_content_type: application/vnd.debian.binary-package
|
|
||||||
|
|
||||||
- name: Add raspbian armv7l .deb
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
|
||||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
|
||||||
asset_content_type: application/vnd.debian.binary-package
|
|
||||||
|
|
||||||
- name: Add raspbian amd64 .deb
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
|
||||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
|
||||||
asset_content_type: application/vnd.debian.binary-package
|
|
||||||
|
|
||||||
- name: Bump version.properties
|
- name: Bump version.properties
|
||||||
run: >-
|
run: >-
|
||||||
bin/bump_version.py
|
bin/bump_version.py
|
||||||
|
|
||||||
|
- name: Update debian changelog
|
||||||
|
run: >-
|
||||||
|
debian/ci_changelog.sh
|
||||||
|
|
||||||
- name: Create version.properties pull request
|
- name: Create version.properties pull request
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v7
|
||||||
with:
|
with:
|
||||||
title: Bump version.properties
|
title: Bump version.properties
|
||||||
add-paths: |
|
add-paths: |
|
||||||
version.properties
|
version.properties
|
||||||
|
debian/changelog
|
||||||
|
|
||||||
release-firmware:
|
release-firmware:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -349,12 +389,12 @@ jobs:
|
|||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -367,37 +407,24 @@ jobs:
|
|||||||
chmod +x ./output/device-update.sh
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./elfs
|
path: ./elfs
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip debug elfs
|
||||||
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./elfs
|
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./elfs
|
||||||
|
|
||||||
# For diagnostics
|
# For diagnostics
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -lR
|
run: ls -lR
|
||||||
|
|
||||||
- name: Add bins to release
|
- name: Add bins and debug elfs to release
|
||||||
uses: actions/upload-release-asset@v1
|
run: |
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
|
||||||
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
|
|
||||||
asset_path: ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_content_type: application/zip
|
|
||||||
|
|
||||||
- name: Add debug elfs to release
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
|
|
||||||
asset_path: ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_content_type: application/zip
|
|
||||||
|
|||||||
29
.github/workflows/package_amd64.yml
vendored
29
.github/workflows/package_amd64.yml
vendored
@@ -32,13 +32,13 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
name: firmware-native-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -47,39 +47,44 @@ jobs:
|
|||||||
- name: build .debpkg
|
- name: build .debpkg
|
||||||
run: |
|
run: |
|
||||||
mkdir -p .debpkg/DEBIAN
|
mkdir -p .debpkg/DEBIAN
|
||||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
mkdir -p .debpkg/usr/share/meshtasticd/web
|
||||||
mkdir -p .debpkg/usr/sbin
|
mkdir -p .debpkg/usr/sbin
|
||||||
mkdir -p .debpkg/etc/meshtasticd
|
mkdir -p .debpkg/etc/meshtasticd
|
||||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
mkdir -p .debpkg/etc/meshtasticd/config.d
|
||||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
mkdir -p .debpkg/etc/meshtasticd/available.d
|
||||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||||
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web
|
||||||
shopt -s dotglob nullglob
|
shopt -s dotglob nullglob
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then mv .debpkg/usr/share/meshtasticd/web/build/* .debpkg/usr/share/meshtasticd/web/; fi
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; fi
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/meshtasticd/web/.DS_Store; fi
|
||||||
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
gunzip .debpkg/usr/share/meshtasticd/web/ -r
|
||||||
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
|
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
|
||||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
|
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ -r
|
||||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||||
chmod +x .debpkg/DEBIAN/conffiles
|
chmod +x .debpkg/DEBIAN/conffiles
|
||||||
|
# Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd
|
||||||
|
echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst
|
||||||
|
chmod +x .debpkg/DEBIAN/preinst
|
||||||
|
echo "ln -sf /usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/postinst
|
||||||
|
chmod +x .debpkg/DEBIAN/postinst
|
||||||
|
|
||||||
- uses: jiro4989/build-deb-action@v3
|
- uses: jiro4989/build-deb-action@v3
|
||||||
with:
|
with:
|
||||||
package: meshtasticd
|
package: meshtasticd
|
||||||
package_root: .debpkg
|
package_root: .debpkg
|
||||||
maintainer: Jonathan Bennett
|
maintainer: Jonathan Bennett
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
version: ${{ steps.version.outputs.long }} # refs/tags/v*.*.*
|
||||||
arch: amd64
|
arch: amd64
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7
|
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
||||||
desc: Native Linux Meshtastic binary.
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
name: meshtasticd_${{ steps.version.outputs.long }}_amd64.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
110
.github/workflows/package_obs.yml
vendored
Normal file
110
.github/workflows/package_obs.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
name: Package for OpenSUSE Build Service
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
OBS_PASSWORD:
|
||||||
|
required: true
|
||||||
|
PPA_GPG_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
obs_project:
|
||||||
|
description: Meshtastic OBS project to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
series:
|
||||||
|
description: Debian series to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-debian-src:
|
||||||
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
series: ${{ inputs.series }}
|
||||||
|
build_location: obs
|
||||||
|
|
||||||
|
package-obs:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: build-debian-src
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: meshtasticd
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Install OpenSUSE Build Service deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo 'deb http://download.opensuse.org/repositories/openSUSE:/Tools/xUbuntu_24.04/ /' | sudo tee /etc/apt/sources.list.d/openSUSE:Tools.list
|
||||||
|
curl -fsSL https://download.opensuse.org/repositories/openSUSE:Tools/xUbuntu_24.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/openSUSE_Tools.gpg > /dev/null
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y osc
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: obs
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -lah
|
||||||
|
|
||||||
|
- name: Configure osc
|
||||||
|
env:
|
||||||
|
OBS_USERNAME: meshtastic
|
||||||
|
run: |
|
||||||
|
# Setup OpenSUSE Build Service credentials
|
||||||
|
mkdir -p ~/.config/osc
|
||||||
|
echo "[general]" > ~/.config/osc/oscrc
|
||||||
|
echo "apiurl=https://api.opensuse.org" >> ~/.config/osc/oscrc
|
||||||
|
echo "[https://api.opensuse.org]" >> ~/.config/osc/oscrc
|
||||||
|
echo "user=${{ env.OBS_USERNAME }}" >> ~/.config/osc/oscrc
|
||||||
|
echo "pass=${{ secrets.OBS_PASSWORD }}" >> ~/.config/osc/oscrc
|
||||||
|
echo "credentials_mgr_class=osc.credentials.PlaintextConfigFileCredentialsManager" >> ~/.config/osc/oscrc
|
||||||
|
# Create a temporary directory for osc checkout
|
||||||
|
mkdir -p osc
|
||||||
|
|
||||||
|
# Intentionally fail if credentials are invalid
|
||||||
|
# Update secrets if this returns `401`
|
||||||
|
- name: Verify OBS authentication
|
||||||
|
run: osc token
|
||||||
|
|
||||||
|
- name: Upload package to OBS
|
||||||
|
shell: bash
|
||||||
|
working-directory: osc
|
||||||
|
env:
|
||||||
|
OBS_PROJECT: ${{ inputs.obs_project }}
|
||||||
|
OBS_PACKAGE: meshtasticd
|
||||||
|
run: |
|
||||||
|
# Initialize the package in the current directory
|
||||||
|
osc checkout --output-dir . $OBS_PROJECT $OBS_PACKAGE
|
||||||
|
|
||||||
|
# Remove the existing package files
|
||||||
|
rm -rf *.dsc *.tar.xz
|
||||||
|
|
||||||
|
# Copy new package files to the directory
|
||||||
|
cp $GITHUB_WORKSPACE/*.dsc .
|
||||||
|
cp $GITHUB_WORKSPACE/*.tar.xz .
|
||||||
|
|
||||||
|
# Add/Remove the files
|
||||||
|
osc addremove
|
||||||
|
|
||||||
|
# Commit changes and push to OpenSUSE Build Service
|
||||||
|
osc commit -m "GitHub Actions: ${{ steps.version.outputs.deb }}~${{ inputs.series }}"
|
||||||
74
.github/workflows/package_ppa.yml
vendored
Normal file
74
.github/workflows/package_ppa.yml
vendored
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
name: Package for Launchpad PPA
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
PPA_GPG_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
inputs:
|
||||||
|
ppa_repo:
|
||||||
|
description: Meshtastic PPA to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
series:
|
||||||
|
description: Ubuntu series to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-debian-src:
|
||||||
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
series: ${{ inputs.series }}
|
||||||
|
build_location: ppa
|
||||||
|
|
||||||
|
package-ppa:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: build-debian-src
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: meshtasticd
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y dput
|
||||||
|
|
||||||
|
- name: Import GPG key
|
||||||
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||||
|
id: gpg
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
working-directory: meshtasticd
|
||||||
|
run: |
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: ppa
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -lah
|
||||||
|
|
||||||
|
- name: Publish with dput
|
||||||
|
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||||
|
run: |
|
||||||
|
dput ${{ inputs.ppa_repo }} meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes
|
||||||
29
.github/workflows/package_raspbian.yml
vendored
29
.github/workflows/package_raspbian.yml
vendored
@@ -32,13 +32,13 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -47,39 +47,44 @@ jobs:
|
|||||||
- name: build .debpkg
|
- name: build .debpkg
|
||||||
run: |
|
run: |
|
||||||
mkdir -p .debpkg/DEBIAN
|
mkdir -p .debpkg/DEBIAN
|
||||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
mkdir -p .debpkg/usr/share/meshtasticd/web
|
||||||
mkdir -p .debpkg/usr/sbin
|
mkdir -p .debpkg/usr/sbin
|
||||||
mkdir -p .debpkg/etc/meshtasticd
|
mkdir -p .debpkg/etc/meshtasticd
|
||||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
mkdir -p .debpkg/etc/meshtasticd/config.d
|
||||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
mkdir -p .debpkg/etc/meshtasticd/available.d
|
||||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||||
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web
|
||||||
shopt -s dotglob nullglob
|
shopt -s dotglob nullglob
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then mv .debpkg/usr/share/meshtasticd/web/build/* .debpkg/usr/share/meshtasticd/web/; fi
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; fi
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/meshtasticd/web/.DS_Store; fi
|
||||||
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
gunzip .debpkg/usr/share/meshtasticd/web/ -r
|
||||||
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
|
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
|
||||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
|
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ -r
|
||||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||||
chmod +x .debpkg/DEBIAN/conffiles
|
chmod +x .debpkg/DEBIAN/conffiles
|
||||||
|
# Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd
|
||||||
|
echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst
|
||||||
|
chmod +x .debpkg/DEBIAN/preinst
|
||||||
|
echo "ln -sf /usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/postinst
|
||||||
|
chmod +x .debpkg/DEBIAN/postinst
|
||||||
|
|
||||||
- uses: jiro4989/build-deb-action@v3
|
- uses: jiro4989/build-deb-action@v3
|
||||||
with:
|
with:
|
||||||
package: meshtasticd
|
package: meshtasticd
|
||||||
package_root: .debpkg
|
package_root: .debpkg
|
||||||
maintainer: Jonathan Bennett
|
maintainer: Jonathan Bennett
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
version: ${{ steps.version.outputs.long }} # refs/tags/v*.*.*
|
||||||
arch: arm64
|
arch: arm64
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7
|
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
||||||
desc: Native Linux Meshtastic binary.
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
name: meshtasticd_${{ steps.version.outputs.long }}_arm64.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
29
.github/workflows/package_raspbian_armv7l.yml
vendored
29
.github/workflows/package_raspbian_armv7l.yml
vendored
@@ -32,13 +32,13 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
name: firmware-raspbian-armv7l-${{ steps.version.outputs.long }}.zip
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -47,39 +47,44 @@ jobs:
|
|||||||
- name: build .debpkg
|
- name: build .debpkg
|
||||||
run: |
|
run: |
|
||||||
mkdir -p .debpkg/DEBIAN
|
mkdir -p .debpkg/DEBIAN
|
||||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
mkdir -p .debpkg/usr/share/meshtasticd/web
|
||||||
mkdir -p .debpkg/usr/sbin
|
mkdir -p .debpkg/usr/sbin
|
||||||
mkdir -p .debpkg/etc/meshtasticd
|
mkdir -p .debpkg/etc/meshtasticd
|
||||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
mkdir -p .debpkg/etc/meshtasticd/config.d
|
||||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
mkdir -p .debpkg/etc/meshtasticd/available.d
|
||||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||||
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web
|
||||||
shopt -s dotglob nullglob
|
shopt -s dotglob nullglob
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then mv .debpkg/usr/share/meshtasticd/web/build/* .debpkg/usr/share/meshtasticd/web/; fi
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; fi
|
||||||
if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi
|
if [ -d .debpkg/usr/share/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/meshtasticd/web/.DS_Store; fi
|
||||||
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
gunzip .debpkg/usr/share/meshtasticd/web/ -r
|
||||||
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
|
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
|
||||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
|
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ -r
|
||||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||||
chmod +x .debpkg/DEBIAN/conffiles
|
chmod +x .debpkg/DEBIAN/conffiles
|
||||||
|
# Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd
|
||||||
|
echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst
|
||||||
|
chmod +x .debpkg/DEBIAN/preinst
|
||||||
|
echo "ln -sf /usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/postinst
|
||||||
|
chmod +x .debpkg/DEBIAN/postinst
|
||||||
|
|
||||||
- uses: jiro4989/build-deb-action@v3
|
- uses: jiro4989/build-deb-action@v3
|
||||||
with:
|
with:
|
||||||
package: meshtasticd
|
package: meshtasticd
|
||||||
package_root: .debpkg
|
package_root: .debpkg
|
||||||
maintainer: Jonathan Bennett
|
maintainer: Jonathan Bennett
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
version: ${{ steps.version.outputs.long }} # refs/tags/v*.*.*
|
||||||
arch: armhf
|
arch: armhf
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7
|
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
||||||
desc: Native Linux Meshtastic binary.
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
name: meshtasticd_${{ steps.version.outputs.long }}_armhf.deb
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./*.deb
|
./*.deb
|
||||||
|
|||||||
45
.github/workflows/release_channels.yml
vendored
Normal file
45
.github/workflows/release_channels.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
name: Trigger release workflows upon Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published, released]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-docker:
|
||||||
|
uses: ./.github/workflows/docker_manifest.yml
|
||||||
|
with:
|
||||||
|
release_channel: |-
|
||||||
|
${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
package-ppa:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
series: [plucky, oracular, noble, jammy]
|
||||||
|
uses: ./.github/workflows/package_ppa.yml
|
||||||
|
with:
|
||||||
|
ppa_repo: |-
|
||||||
|
ppa:meshtastic/${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
series: ${{ matrix.series }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
package-obs:
|
||||||
|
uses: ./.github/workflows/package_obs.yml
|
||||||
|
with:
|
||||||
|
obs_project: |-
|
||||||
|
network:Meshtastic:${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
series: |-
|
||||||
|
${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
# hook-copr:
|
||||||
|
# uses: ./.github/workflows/hook_copr.yml
|
||||||
|
# with:
|
||||||
|
# copr_project: |-
|
||||||
|
# ${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
|
# secrets: inherit
|
||||||
169
.github/workflows/test_native.yml
vendored
Normal file
169
.github/workflows/test_native.yml
vendored
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
name: Run Tests on Native platform
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
env:
|
||||||
|
LCOV_CAPTURE_FLAGS: --quiet --capture --include "${PWD}/src/*" --exclude '*/src/mesh/generated/*' --directory .pio/build/coverage/src --base-directory "${PWD}"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
simulator-tests:
|
||||||
|
name: Native Simulator Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Setup native build
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-native
|
||||||
|
|
||||||
|
- name: Install simulator dependencies
|
||||||
|
run: pip install -U dotmap
|
||||||
|
|
||||||
|
# We now run integration test before other build steps (to quickly see runtime failures)
|
||||||
|
- name: Build for native/coverage
|
||||||
|
run: platformio run -e coverage
|
||||||
|
|
||||||
|
- name: Capture initial coverage information
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --initial --output-file coverage_base.info
|
||||||
|
sed -i -e "s#${PWD}#.#" coverage_base.info # Make paths relative.
|
||||||
|
|
||||||
|
- name: Integration test
|
||||||
|
run: |
|
||||||
|
.pio/build/coverage/program &
|
||||||
|
PID=$!
|
||||||
|
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
|
||||||
|
echo "Simulator started, launching python test..."
|
||||||
|
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||||
|
wait
|
||||||
|
|
||||||
|
- name: Capture coverage information
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
run: |
|
||||||
|
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name integration --output-file coverage_integration.info
|
||||||
|
sed -i -e "s#${PWD}#.#" coverage_integration.info # Make paths relative.
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Save coverage information
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
with:
|
||||||
|
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: ./coverage_*.info
|
||||||
|
|
||||||
|
platformio-tests:
|
||||||
|
name: Native PlatformIO Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Setup native build
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-native
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
# Disable (comment-out) BUILD_EPOCH. It causes a full rebuild between tests and resets the
|
||||||
|
# coverage information each time.
|
||||||
|
- name: Disable BUILD_EPOCH
|
||||||
|
run: sed -i 's/-DBUILD_EPOCH=$UNIX_TIME/#-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
|
||||||
|
|
||||||
|
- name: PlatformIO Tests
|
||||||
|
run: platformio test -e coverage -v --junit-output-path testreport.xml
|
||||||
|
|
||||||
|
- name: Save test results
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: ./testreport.xml
|
||||||
|
|
||||||
|
- name: Capture coverage information
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name tests --output-file coverage_tests.info
|
||||||
|
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||||
|
|
||||||
|
- name: Save coverage information
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always() # run this step even if previous step failed
|
||||||
|
with:
|
||||||
|
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}.zip
|
||||||
|
overwrite: true
|
||||||
|
path: ./coverage_*.info
|
||||||
|
|
||||||
|
generate-reports:
|
||||||
|
name: Generate Test Reports
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions: # Needed for dorny/test-reporter.
|
||||||
|
contents: read
|
||||||
|
actions: read
|
||||||
|
checks: write
|
||||||
|
needs:
|
||||||
|
- simulator-tests
|
||||||
|
- platformio-tests
|
||||||
|
if: always()
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download test artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Test Report
|
||||||
|
uses: dorny/test-reporter@v1.9.1
|
||||||
|
with:
|
||||||
|
name: PlatformIO Tests
|
||||||
|
path: testreport.xml
|
||||||
|
reporter: java-junit
|
||||||
|
|
||||||
|
- name: Download coverage artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}.zip
|
||||||
|
path: code-coverage-report
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Generate Code Coverage Report
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
lcov --quiet --add-tracefile code-coverage-report/coverage_base.info --add-tracefile code-coverage-report/coverage_integration.info --add-tracefile code-coverage-report/coverage_tests.info --output-file code-coverage-report/coverage_src.info
|
||||||
|
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
|
||||||
|
|
||||||
|
- name: Save Code Coverage Report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: code-coverage-report-${{ steps.version.outputs.long }}.zip
|
||||||
|
path: code-coverage-report
|
||||||
51
.github/workflows/tests.yml
vendored
51
.github/workflows/tests.yml
vendored
@@ -6,55 +6,8 @@ on:
|
|||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-simulator:
|
native-tests:
|
||||||
runs-on: ubuntu-latest
|
uses: ./.github/workflows/test_native.yml
|
||||||
steps:
|
|
||||||
- name: Install libbluetooth
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get update --fix-missing
|
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
|
||||||
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -U platformio adafruit-nrfutil
|
|
||||||
pip install -U meshtastic --pre
|
|
||||||
|
|
||||||
- name: Upgrade platformio
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
pio upgrade
|
|
||||||
|
|
||||||
- name: Build Native
|
|
||||||
run: bin/build-native.sh
|
|
||||||
|
|
||||||
# We now run integration test before other build steps (to quickly see runtime failures)
|
|
||||||
- name: Build for native
|
|
||||||
run: platformio run -e native
|
|
||||||
|
|
||||||
- name: Integration test
|
|
||||||
run: |
|
|
||||||
.pio/build/native/program & sleep 10 # 5 seconds was not enough
|
|
||||||
echo "Simulator started, launching python test..."
|
|
||||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
|
||||||
|
|
||||||
- name: PlatformIO Tests
|
|
||||||
run: platformio test -e native --junit-output-path testreport.xml
|
|
||||||
|
|
||||||
- name: Test Report
|
|
||||||
uses: dorny/test-reporter@v1.9.1
|
|
||||||
if: success() || failure() # run this step even if previous step failed
|
|
||||||
with:
|
|
||||||
name: PlatformIO Tests
|
|
||||||
path: testreport.xml
|
|
||||||
reporter: java-junit
|
|
||||||
|
|
||||||
hardware-tests:
|
hardware-tests:
|
||||||
runs-on: test-runner
|
runs-on: test-runner
|
||||||
|
|||||||
6
.github/workflows/trunk_format_pr.yml
vendored
6
.github/workflows/trunk_format_pr.yml
vendored
@@ -22,12 +22,16 @@ jobs:
|
|||||||
- name: Run Trunk Fmt
|
- name: Run Trunk Fmt
|
||||||
run: trunk fmt
|
run: trunk fmt
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
- name: Commit and push changes
|
- name: Commit and push changes
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name "github-actions[bot]"
|
git config --global user.name "github-actions[bot]"
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git add .
|
git add .
|
||||||
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
|
git commit -m "Add firmware version ${{ steps.version.outputs.long }}"
|
||||||
git push
|
git push
|
||||||
|
|
||||||
- name: Comment on PR
|
- name: Comment on PR
|
||||||
|
|||||||
7
.github/workflows/update_protobufs.yml
vendored
7
.github/workflows/update_protobufs.yml
vendored
@@ -12,14 +12,15 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Update submodule
|
- name: Update submodule
|
||||||
|
if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
run: |
|
run: |
|
||||||
git submodule update --remote protobufs
|
git submodule update --remote protobufs
|
||||||
|
|
||||||
- name: Download nanopb
|
- name: Download nanopb
|
||||||
run: |
|
run: |
|
||||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9-linux-x86.tar.gz
|
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9.1-linux-x86.tar.gz
|
||||||
tar xvzf nanopb-0.4.9-linux-x86.tar.gz
|
tar xvzf nanopb-0.4.9.1-linux-x86.tar.gz
|
||||||
mv nanopb-0.4.9-linux-x86 nanopb-0.4.9
|
mv nanopb-0.4.9.1-linux-x86 nanopb-0.4.9
|
||||||
|
|
||||||
- name: Re-generate protocol buffers
|
- name: Re-generate protocol buffers
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,4 +1,8 @@
|
|||||||
.pio
|
.pio
|
||||||
|
pio
|
||||||
|
pio.tar
|
||||||
|
web
|
||||||
|
web.tar
|
||||||
|
|
||||||
# ignore vscode IDE settings files
|
# ignore vscode IDE settings files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
@@ -8,6 +12,9 @@
|
|||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
|
.platformio
|
||||||
|
.local
|
||||||
|
.cache
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|||||||
@@ -4,33 +4,34 @@ cli:
|
|||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v1.6.4
|
ref: v1.6.6
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- trufflehog@3.83.6
|
- prettier@3.4.2
|
||||||
|
- trufflehog@3.86.1
|
||||||
- yamllint@1.35.1
|
- yamllint@1.35.1
|
||||||
- bandit@1.7.10
|
- bandit@1.8.0
|
||||||
- checkov@3.2.287
|
- checkov@3.2.334
|
||||||
- terrascan@1.19.9
|
- terrascan@1.19.9
|
||||||
- trivy@0.56.2
|
- trivy@0.58.0
|
||||||
#- trufflehog@3.63.2-rc0
|
#- trufflehog@3.63.2-rc0
|
||||||
- taplo@0.9.3
|
- taplo@0.9.3
|
||||||
- ruff@0.7.3
|
- ruff@0.8.3
|
||||||
- isort@5.13.2
|
- isort@5.13.2
|
||||||
- markdownlint@0.42.0
|
- markdownlint@0.43.0
|
||||||
- oxipng@9.1.2
|
- oxipng@9.1.3
|
||||||
- svgo@3.3.2
|
- svgo@3.3.2
|
||||||
- actionlint@1.7.4
|
- actionlint@1.7.4
|
||||||
- flake8@7.1.1
|
- flake8@7.1.1
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.1-beta
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.10.0
|
- shellcheck@0.10.0
|
||||||
- black@24.10.0
|
- black@24.10.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.21.1
|
- gitleaks@8.21.2
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
- prettier@3.3.3
|
#- prettier@3.3.3
|
||||||
ignore:
|
ignore:
|
||||||
- linters: [ALL]
|
- linters: [ALL]
|
||||||
paths:
|
paths:
|
||||||
@@ -39,7 +40,7 @@ runtimes:
|
|||||||
enabled:
|
enabled:
|
||||||
- python@3.10.8
|
- python@3.10.8
|
||||||
- go@1.21.0
|
- go@1.21.0
|
||||||
- node@18.12.1
|
- node@18.20.5
|
||||||
actions:
|
actions:
|
||||||
disabled:
|
disabled:
|
||||||
- trunk-announce
|
- trunk-announce
|
||||||
|
|||||||
70
Dockerfile
70
Dockerfile
@@ -1,32 +1,29 @@
|
|||||||
FROM debian:bookworm-slim AS builder
|
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||||
|
# trunk-ignore-all(hadolint/DL3008): Use latest version of apt packages for buildchain
|
||||||
|
# trunk-ignore-all(trivy/DS002): We must run as root for this container
|
||||||
|
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
|
||||||
|
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||||
|
|
||||||
|
FROM python:3.12-bookworm AS builder
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Etc/UTC
|
ENV TZ=Etc/UTC
|
||||||
|
|
||||||
# http://bugs.python.org/issue19846
|
# Install Dependencies
|
||||||
# > At the moment, setting "LANG=C" on a Linux system *fundamentally breaks Python 3*, and that's not OK.
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
ENV LANG C.UTF-8
|
RUN apt-get update && apt-get install --no-install-recommends -y wget g++ zip git ca-certificates \
|
||||||
|
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
|
||||||
# Install build deps
|
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config && \
|
||||||
USER root
|
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
||||||
|
pip install --no-cache-dir -U platformio==6.1.16 && \
|
||||||
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
mkdir /tmp/firmware
|
||||||
# trunk-ignore(hadolint/DL3008): Use latest version of packages for buildchain
|
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y wget python3 python3-pip python3-wheel python3-venv g++ zip git \
|
|
||||||
ca-certificates libgpiod-dev libyaml-cpp-dev libbluetooth-dev \
|
|
||||||
libulfius-dev liborcania-dev libssl-dev pkg-config && \
|
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/* && mkdir /tmp/firmware
|
|
||||||
|
|
||||||
RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh && chown mesh:mesh /tmp/firmware
|
|
||||||
USER mesh
|
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
WORKDIR /tmp/firmware
|
WORKDIR /tmp/firmware
|
||||||
RUN python3 -m venv /tmp/firmware
|
COPY . /tmp/firmware
|
||||||
RUN bash -o pipefail -c "source bin/activate; pip3 install --no-cache-dir -U platformio==6.1.15"
|
|
||||||
# trunk-ignore(terrascan/AC_DOCKER_00024): We would actually like these files to be owned by mesh tyvm
|
# Build
|
||||||
COPY --chown=mesh:mesh . /tmp/firmware
|
RUN bash ./bin/build-native.sh && \
|
||||||
RUN bash -o pipefail -c "source ./bin/activate && bash ./bin/build-native.sh"
|
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
||||||
RUN cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
|
||||||
|
|
||||||
|
|
||||||
##### PRODUCTION BUILD #############
|
##### PRODUCTION BUILD #############
|
||||||
@@ -35,20 +32,25 @@ FROM debian:bookworm-slim
|
|||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Etc/UTC
|
ENV TZ=Etc/UTC
|
||||||
|
|
||||||
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
||||||
# trunk-ignore(hadolint/DL3008): Use latest version of packages for buildchain
|
USER root
|
||||||
RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libulfius2.7 liborcania2.3 libssl3 && \
|
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh
|
RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 && \
|
||||||
USER mesh
|
apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& mkdir -p /var/lib/meshtasticd \
|
||||||
|
&& mkdir -p /etc/meshtasticd/config.d
|
||||||
|
|
||||||
WORKDIR /home/mesh
|
# Fetch compiled binary from the builder
|
||||||
COPY --from=builder /tmp/firmware/release/meshtasticd /home/mesh/
|
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
|
||||||
|
# Copy config templates
|
||||||
|
COPY ./bin/config.d /etc/meshtasticd/available.d
|
||||||
|
|
||||||
RUN mkdir data
|
WORKDIR /var/lib/meshtasticd
|
||||||
VOLUME /home/mesh/data
|
VOLUME /var/lib/meshtasticd
|
||||||
|
|
||||||
CMD [ "sh", "-cx", "./meshtasticd -d /home/mesh/data --hwid=${HWID:-$RANDOM}" ]
|
# Expose Meshtastic TCP API port from the host
|
||||||
|
EXPOSE 4403
|
||||||
|
|
||||||
|
CMD [ "sh", "-cx", "meshtasticd -d /var/lib/meshtasticd" ]
|
||||||
|
|
||||||
HEALTHCHECK NONE
|
HEALTHCHECK NONE
|
||||||
42
alpine.Dockerfile
Normal file
42
alpine.Dockerfile
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# trunk-ignore-all(trivy/DS002): We must run as root for this container
|
||||||
|
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
|
||||||
|
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||||
|
|
||||||
|
FROM python:3.12-alpine3.21 AS builder
|
||||||
|
|
||||||
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
|
RUN apk add bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||||
|
libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone && \
|
||||||
|
pip install --no-cache-dir -U platformio==6.1.16 && \
|
||||||
|
mkdir /tmp/firmware
|
||||||
|
|
||||||
|
WORKDIR /tmp/firmware
|
||||||
|
COPY . /tmp/firmware
|
||||||
|
|
||||||
|
# Create small package (no debugging symbols)
|
||||||
|
# Add `argp` for musl
|
||||||
|
ENV PLATFORMIO_BUILD_FLAGS="-Os -ffunction-sections -fdata-sections -Wl,--gc-sections -largp"
|
||||||
|
|
||||||
|
RUN bash ./bin/build-native.sh && \
|
||||||
|
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
||||||
|
|
||||||
|
# ##### PRODUCTION BUILD #############
|
||||||
|
|
||||||
|
FROM alpine:3.21
|
||||||
|
|
||||||
|
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
||||||
|
USER root
|
||||||
|
|
||||||
|
RUN apk add libstdc++ libgpiod yaml-cpp libusb i2c-tools \
|
||||||
|
&& mkdir -p /var/lib/meshtasticd \
|
||||||
|
&& mkdir -p /etc/meshtasticd/config.d
|
||||||
|
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
|
||||||
|
|
||||||
|
WORKDIR /var/lib/meshtasticd
|
||||||
|
VOLUME /var/lib/meshtasticd
|
||||||
|
|
||||||
|
EXPOSE 4403
|
||||||
|
|
||||||
|
CMD [ "sh", "-cx", "meshtasticd --fsdir=/var/lib/meshtasticd" ]
|
||||||
|
|
||||||
|
HEALTHCHECK NONE
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
[nrf52_base]
|
[nrf52_base]
|
||||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||||
platform = platformio/nordicnrf52@^10.5.0
|
platform = platformio/nordicnrf52@^10.7.0
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages =
|
platform_packages =
|
||||||
; our custom Git version until they merge our PR
|
; our custom Git version until they merge our PR
|
||||||
framework-arduinoadafruitnrf52 @ https://github.com/geeksville/Adafruit_nRF52_Arduino.git
|
framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
||||||
|
toolchain-gccarmnoneeabi@~1.90301.0
|
||||||
|
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags =
|
build_flags =
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated).
|
||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform = https://github.com/meshtastic/platform-native.git#bcd02436cfca91f7d28ad0f7dab977c6aaa781af
|
platform = https://github.com/meshtastic/platform-native.git#562d189828f09fbf4c4093b3c0104bae9d8e9ff9
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
@@ -25,7 +25,8 @@ lib_deps =
|
|||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
|
https://github.com/pine64/libch341-spi-userspace#a9b17e3452f7fb747000d9b4ad4409155b39f6ef
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
@@ -33,7 +34,10 @@ build_flags =
|
|||||||
-Isrc/platform/portduino
|
-Isrc/platform/portduino
|
||||||
-DRADIOLIB_EEPROM_UNSUPPORTED
|
-DRADIOLIB_EEPROM_UNSUPPORTED
|
||||||
-DPORTDUINO_LINUX_HARDWARE
|
-DPORTDUINO_LINUX_HARDWARE
|
||||||
|
-lpthread
|
||||||
-lstdc++fs
|
-lstdc++fs
|
||||||
-lbluetooth
|
-lbluetooth
|
||||||
-lgpiod
|
-lgpiod
|
||||||
-lyaml-cpp
|
-lyaml-cpp
|
||||||
|
-li2c
|
||||||
|
-std=c++17
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2040_base]
|
[rp2040_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico >=4.2.1
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#996c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2350_base]
|
[rp2350_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico >=4.2.1
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#96c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags} -Wno-unused-variable
|
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
|
||||||
-Isrc/platform/rp2xx0
|
-Isrc/platform/rp2xx0
|
||||||
-D__PLAT_RP2040__
|
-D__PLAT_RP2350__
|
||||||
# -D _POSIX_THREADS
|
# -D _POSIX_THREADS
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp> -<platform/rp2xx0/pico_sleep> -<platform/rp2xx0/hardware_rosc>
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
|||||||
1
bin/.gitignore
vendored
Normal file
1
bin/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
config.yaml
|
||||||
@@ -24,7 +24,7 @@ def write_macros_to_json(macros, output_file):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
header_file = 'userPrefs.h'
|
header_file = 'userPrefs.h'
|
||||||
output_file = 'userPrefs.json'
|
output_file = 'userPrefs.jsonc'
|
||||||
# Uncomment all macros in the header file
|
# Uncomment all macros in the header file
|
||||||
with open(header_file, 'r') as file:
|
with open(header_file, 'r') as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
|
|||||||
@@ -12,19 +12,6 @@ Lora:
|
|||||||
# IRQ: 17
|
# IRQ: 17
|
||||||
# Reset: 22
|
# Reset: 22
|
||||||
|
|
||||||
# Module: sx1262 # pinedio
|
|
||||||
# CS: 0
|
|
||||||
# IRQ: 10
|
|
||||||
# Busy: 11
|
|
||||||
# DIO2_AS_RF_SWITCH: true
|
|
||||||
# spidev: spidev0.1
|
|
||||||
|
|
||||||
# Module: RF95 # Adafruit RFM9x
|
|
||||||
# Reset: 25
|
|
||||||
# CS: 7
|
|
||||||
# IRQ: 22
|
|
||||||
# Busy: 23
|
|
||||||
|
|
||||||
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
|
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
|
||||||
# Reset: 22
|
# Reset: 22
|
||||||
# CS: 7
|
# CS: 7
|
||||||
@@ -36,6 +23,47 @@ Lora:
|
|||||||
# Busy: 20
|
# Busy: 20
|
||||||
# Reset: 18
|
# Reset: 18
|
||||||
|
|
||||||
|
### The Radxa Zero 3E/W employs multiple gpio chips.
|
||||||
|
### Each gpio pin must be unique, but can be assigned to a specific gpio chip and line.
|
||||||
|
### In case solely a no. is given, the default gpio chip and pin == line will be employed.
|
||||||
|
###
|
||||||
|
# Module: sx1262 # Radxa Zero 3E/W + Ebyte E22-900M30S
|
||||||
|
# DIO2_AS_RF_SWITCH: true
|
||||||
|
# DIO3_TCXO_VOLTAGE: 1.8
|
||||||
|
# CS: # NSS PIN_24 -> chip 4, line 22
|
||||||
|
# pin: 24
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 22
|
||||||
|
# SCK: # SCK PIN_23 -> chip 4, line 18
|
||||||
|
# pin: 23
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 18
|
||||||
|
# Busy: # BUSY PIN_29 -> chip 3!, line 11
|
||||||
|
# pin: 29
|
||||||
|
# gpiochip: 3
|
||||||
|
# line: 11
|
||||||
|
# MOSI: # MOSI PIN_19 -> chip 4, line 19
|
||||||
|
# pin: 19
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 19
|
||||||
|
# MISO: # MISO PIN_21 -> chip 4, line 21
|
||||||
|
# pin: 21
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 21
|
||||||
|
# Reset: # NRST PIN_27 -> chip 4, line 10
|
||||||
|
# pin: 27
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 10
|
||||||
|
# IRQ: # DIO1 PIN_28 -> chip 4, line 11
|
||||||
|
# pin: 28
|
||||||
|
# gpiochip: 4
|
||||||
|
# line: 11
|
||||||
|
# RXen: # RXEN PIN_22 -> chip 3!, line 17
|
||||||
|
# pin: 22
|
||||||
|
# gpiochip: 3
|
||||||
|
# line: 17
|
||||||
|
# TXen: RADIOLIB_NC # TXEN no PIN, no line, fallback to default gpio chip
|
||||||
|
|
||||||
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
|
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
|
||||||
# CS: 21
|
# CS: 21
|
||||||
# IRQ: 16
|
# IRQ: 16
|
||||||
@@ -50,11 +78,9 @@ Lora:
|
|||||||
# TXen: x # TX and RX enable pins
|
# TXen: x # TX and RX enable pins
|
||||||
# RXen: x
|
# RXen: x
|
||||||
|
|
||||||
# ch341_quirk: true # Uncomment this to use the chunked SPI transfer that seems to fix the ch341
|
|
||||||
|
|
||||||
# spiSpeed: 2000000
|
# spiSpeed: 2000000
|
||||||
|
|
||||||
### Set gpio chip to use in /dev/. Defaults to 0.
|
### Set default/fallback gpio chip to use in /dev/. Defaults to 0.
|
||||||
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
|
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
|
||||||
# gpiochip: 4
|
# gpiochip: 4
|
||||||
|
|
||||||
@@ -155,9 +181,11 @@ Logging:
|
|||||||
|
|
||||||
Webserver:
|
Webserver:
|
||||||
# Port: 443 # Port for Webserver & Webservices
|
# Port: 443 # Port for Webserver & Webservices
|
||||||
# RootPath: /usr/share/doc/meshtasticd/web # Root Dir of WebServer
|
# RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer
|
||||||
|
|
||||||
General:
|
General:
|
||||||
MaxNodes: 200
|
MaxNodes: 200
|
||||||
MaxMessageQueue: 100
|
MaxMessageQueue: 100
|
||||||
ConfigDirectory: /etc/meshtasticd/config.d/
|
ConfigDirectory: /etc/meshtasticd/config.d/
|
||||||
|
# MACAddress: AA:BB:CC:DD:EE:FF
|
||||||
|
# MACAddressSource: eth0
|
||||||
|
|||||||
9
bin/config.d/OpenWRT/BananaPi-BPI-R4-sx1262.yaml
Normal file
9
bin/config.d/OpenWRT/BananaPi-BPI-R4-sx1262.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Lora:
|
||||||
|
Module: sx1262 # BananaPi-BPI-R4 SPI via 26p GPIO Header
|
||||||
|
## CS: 28
|
||||||
|
IRQ: 50
|
||||||
|
Busy: 62
|
||||||
|
Reset: 51
|
||||||
|
spidev: spidev1.0
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
## https://www.mikroe.com/lr-iot-click
|
||||||
|
Lora:
|
||||||
|
Module: lr1110 # OpenWRT ONE mikroBUS with LR-IOT-CLICK
|
||||||
|
# CS: 25
|
||||||
|
IRQ: 10
|
||||||
|
Busy: 12
|
||||||
|
# Reset: 2
|
||||||
|
spidev: spidev2.0
|
||||||
|
DIO3_TCXO_VOLTAGE: 1.6
|
||||||
8
bin/config.d/OpenWRT/OpenWRT_One_mikroBUS_sx1262.yaml
Normal file
8
bin/config.d/OpenWRT/OpenWRT_One_mikroBUS_sx1262.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Lora:
|
||||||
|
Module: sx1262
|
||||||
|
IRQ: 10
|
||||||
|
Busy: 12
|
||||||
|
# Reset: 2
|
||||||
|
spidev: spidev2.0
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
20
bin/config.d/femtofox/femtofox_LR1121_TCXO.yaml
Normal file
20
bin/config.d/femtofox/femtofox_LR1121_TCXO.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
Lora:
|
||||||
|
## Ebyte E80-900M22S
|
||||||
|
## This is a bit experimental
|
||||||
|
##
|
||||||
|
##
|
||||||
|
Module: lr1121
|
||||||
|
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||||
|
DIO3_TCXO_VOLTAGE: 1.8
|
||||||
|
CS: 16 #pin6 / GPIO48 1C0
|
||||||
|
IRQ: 23 #pin17 / GPIO55 1C7
|
||||||
|
Busy: 22 #pin16 / GPIO54 1C6
|
||||||
|
Reset: 25 #pin13 / GPIO57 1D1
|
||||||
|
|
||||||
|
|
||||||
|
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||||
|
spiSpeed: 2000000
|
||||||
|
|
||||||
|
General:
|
||||||
|
MACAddressSource: eth0
|
||||||
21
bin/config.d/femtofox/femtofox_SX1262_TCXO.yaml
Normal file
21
bin/config.d/femtofox/femtofox_SX1262_TCXO.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
Lora:
|
||||||
|
## Ebyte E22-900M30S, E22-900M22S with or without external RF switching setup
|
||||||
|
## HT-RA62 (Has internal switching, but whatever)
|
||||||
|
## Seeed WIO SX1262 (already has TXEN-DIO2 link, but needs RXEN)
|
||||||
|
## Will work with any module with or without RF switching, and with TCXO
|
||||||
|
Module: sx1262
|
||||||
|
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
CS: 16 #pin6 / GPIO48 1C0
|
||||||
|
IRQ: 23 #pin17 / GPIO55 1C7
|
||||||
|
Busy: 22 #pin16 / GPIO54 1C6
|
||||||
|
Reset: 25 #pin13 / GPIO57 1D1
|
||||||
|
RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things?
|
||||||
|
# TXen: bridge to DIO2 on E22 module
|
||||||
|
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||||
|
spiSpeed: 2000000
|
||||||
|
|
||||||
|
General:
|
||||||
|
MACAddressSource: eth0
|
||||||
21
bin/config.d/femtofox/femtofox_SX1262_XTAL.yaml
Normal file
21
bin/config.d/femtofox/femtofox_SX1262_XTAL.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
Lora:
|
||||||
|
## Ebyte E22-900MM22S with no external RF switching setup
|
||||||
|
## Waveshare SX126X XXXM, AI Thinker RA-01SH
|
||||||
|
## Will work with any module with or without RF switching and no TCXO
|
||||||
|
|
||||||
|
Module: sx1262
|
||||||
|
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: false
|
||||||
|
CS: 16 #pin6 / GPIO48 1C0
|
||||||
|
IRQ: 23 #pin17 / GPIO55 1C7
|
||||||
|
Busy: 22 #pin16 / GPIO54 1C6
|
||||||
|
Reset: 25 #pin13 / GPIO57 1D1
|
||||||
|
RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things?
|
||||||
|
# TXen: bridge to DIO2 on E22 module
|
||||||
|
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||||
|
spiSpeed: 2000000
|
||||||
|
|
||||||
|
General:
|
||||||
|
MACAddressSource: eth0
|
||||||
5
bin/config.d/lora-Adafruit-RFM9x
Normal file
5
bin/config.d/lora-Adafruit-RFM9x
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Module: RF95 # Adafruit RFM9x
|
||||||
|
# Reset: 25
|
||||||
|
# CS: 7
|
||||||
|
# IRQ: 22
|
||||||
|
# Busy: 23
|
||||||
11
bin/config.d/lora-meshstick-1262.yaml
Normal file
11
bin/config.d/lora-meshstick-1262.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Lora:
|
||||||
|
Module: sx1262
|
||||||
|
CS: 0
|
||||||
|
IRQ: 6
|
||||||
|
Reset: 2
|
||||||
|
Busy: 4
|
||||||
|
spidev: ch341
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
# USB_Serialnum: 12345678
|
||||||
|
USB_PID: 0x5512
|
||||||
|
USB_VID: 0x1A86
|
||||||
5
bin/config.d/lora-pinedio-usb-sx1262.yaml
Normal file
5
bin/config.d/lora-pinedio-usb-sx1262.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Lora:
|
||||||
|
Module: sx1262
|
||||||
|
CS: 0
|
||||||
|
IRQ: 10
|
||||||
|
spidev: ch341
|
||||||
@@ -73,7 +73,7 @@ shift "$((OPTIND - 1))"
|
|||||||
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
||||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
$ESPTOOL_CMD erase_flash
|
$ESPTOOL_CMD erase_flash
|
||||||
$ESPTOOL_CMD write_flash 0x00 ${FILENAME}
|
$ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
|
||||||
# Account for S3 board's different OTA partition
|
# Account for S3 board's different OTA partition
|
||||||
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
|
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
|
||||||
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
# trunk-ignore-all(flake8/F821): For SConstruct imports
|
# trunk-ignore-all(flake8/F821): For SConstruct imports
|
||||||
import sys
|
import sys
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
from readprops import readProps
|
from readprops import readProps
|
||||||
|
|
||||||
@@ -90,11 +92,37 @@ prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
|
|||||||
verObj = readProps(prefsLoc)
|
verObj = readProps(prefsLoc)
|
||||||
print("Using meshtastic platformio-custom.py, firmware version " + verObj["long"] + " on " + env.get("PIOENV"))
|
print("Using meshtastic platformio-custom.py, firmware version " + verObj["long"] + " on " + env.get("PIOENV"))
|
||||||
|
|
||||||
|
jsonLoc = env["PROJECT_DIR"] + "/userPrefs.jsonc"
|
||||||
|
with open(jsonLoc) as f:
|
||||||
|
jsonStr = re.sub("//.*","", f.read(), flags=re.MULTILINE)
|
||||||
|
userPrefs = json.loads(jsonStr)
|
||||||
|
|
||||||
|
pref_flags = []
|
||||||
|
# Pre-process the userPrefs
|
||||||
|
for pref in userPrefs:
|
||||||
|
if userPrefs[pref].startswith("{"):
|
||||||
|
pref_flags.append("-D" + pref + "=" + userPrefs[pref])
|
||||||
|
elif userPrefs[pref].replace(".", "").isdigit():
|
||||||
|
pref_flags.append("-D" + pref + "=" + userPrefs[pref])
|
||||||
|
elif userPrefs[pref] == "true" or userPrefs[pref] == "false":
|
||||||
|
pref_flags.append("-D" + pref + "=" + userPrefs[pref])
|
||||||
|
elif userPrefs[pref].startswith("meshtastic_"):
|
||||||
|
pref_flags.append("-D" + pref + "=" + userPrefs[pref])
|
||||||
|
# If the value is a string, we need to wrap it in quotes
|
||||||
|
else:
|
||||||
|
pref_flags.append("-D" + pref + "=" + env.StringifyMacro(userPrefs[pref]) + "")
|
||||||
|
|
||||||
# General options that are passed to the C and C++ compilers
|
# General options that are passed to the C and C++ compilers
|
||||||
projenv.Append(
|
flags = [
|
||||||
CCFLAGS=[
|
|
||||||
"-DAPP_VERSION=" + verObj["long"],
|
"-DAPP_VERSION=" + verObj["long"],
|
||||||
"-DAPP_VERSION_SHORT=" + verObj["short"],
|
"-DAPP_VERSION_SHORT=" + verObj["short"],
|
||||||
"-DAPP_ENV=" + env.get("PIOENV"),
|
"-DAPP_ENV=" + env.get("PIOENV"),
|
||||||
]
|
] + pref_flags
|
||||||
|
|
||||||
|
print ("Using flags:")
|
||||||
|
for flag in flags:
|
||||||
|
print(flag)
|
||||||
|
|
||||||
|
projenv.Append(
|
||||||
|
CCFLAGS=flags,
|
||||||
)
|
)
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import configparser
|
import configparser
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import os
|
||||||
|
run_number = os.getenv('GITHUB_RUN_NUMBER', '0')
|
||||||
|
build_location = os.getenv('BUILD_LOCATION', 'local')
|
||||||
|
|
||||||
def readProps(prefsLoc):
|
def readProps(prefsLoc):
|
||||||
"""Read the version of our project as a string"""
|
"""Read the version of our project as a string"""
|
||||||
@@ -11,6 +13,7 @@ def readProps(prefsLoc):
|
|||||||
verObj = dict(
|
verObj = dict(
|
||||||
short="{}.{}.{}".format(version["major"], version["minor"], version["build"]),
|
short="{}.{}.{}".format(version["major"], version["minor"], version["build"]),
|
||||||
long="unset",
|
long="unset",
|
||||||
|
deb="unset",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
|
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
|
||||||
@@ -27,13 +30,13 @@ def readProps(prefsLoc):
|
|||||||
# if isDirty:
|
# if isDirty:
|
||||||
# # short for 'dirty', we want to keep our verstrings source for protobuf reasons
|
# # short for 'dirty', we want to keep our verstrings source for protobuf reasons
|
||||||
# suffix = sha + "-d"
|
# suffix = sha + "-d"
|
||||||
verObj["long"] = "{}.{}.{}.{}".format(
|
verObj["long"] = "{}.{}".format(verObj["short"], suffix)
|
||||||
version["major"], version["minor"], version["build"], suffix
|
verObj["deb"] = "{}.{}~{}{}".format(verObj["short"], run_number, build_location, sha)
|
||||||
)
|
|
||||||
except:
|
except:
|
||||||
# print("Unexpected error:", sys.exc_info()[0])
|
# print("Unexpected error:", sys.exc_info()[0])
|
||||||
# traceback.print_exc()
|
# traceback.print_exc()
|
||||||
verObj["long"] = verObj["short"]
|
verObj["long"] = verObj["short"]
|
||||||
|
verObj["deb"] = "{}.{}~{}".format(verObj["short"], run_number, build_location)
|
||||||
|
|
||||||
# print("firmware version " + verStr)
|
# print("firmware version " + verStr)
|
||||||
return verObj
|
return verObj
|
||||||
|
|||||||
12
bin/rpkg.macros
Normal file
12
bin/rpkg.macros
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
function meshtastic_version {
|
||||||
|
meshtastic_version=$(python3 bin/buildinfo.py short)
|
||||||
|
echo -n "$meshtastic_version"
|
||||||
|
}
|
||||||
|
function git_commits_num {
|
||||||
|
total_commits=$(git rev-list --all --count)
|
||||||
|
echo -n "$total_commits"
|
||||||
|
}
|
||||||
|
function git_commit_sha {
|
||||||
|
commit_sha=$(git rev-parse --short HEAD)
|
||||||
|
echo -n "$commit_sha"
|
||||||
|
}
|
||||||
41
boards/esp32-s3-zero.json
Normal file
41
boards/esp32-s3-zero.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"partitions": "default.csv",
|
||||||
|
"memory_type": "qio_qspi"
|
||||||
|
},
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DARDUINO_ESP32S3_DEV",
|
||||||
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_EVENT_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DBOARD_HAS_PSRAM"
|
||||||
|
],
|
||||||
|
"f_cpu": "240000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "qio",
|
||||||
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
|
"mcu": "esp32s3",
|
||||||
|
"variant": "esp32s3"
|
||||||
|
},
|
||||||
|
"connectivity": ["wifi", "bluetooth"],
|
||||||
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": ["esp-builtin"],
|
||||||
|
"openocd_target": "esp32s3.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino", "espidf"],
|
||||||
|
"platforms": ["espressif32"],
|
||||||
|
"name": "Espressif ESP32-S3-FH4R2 (4 MB QD, 2MB PSRAM)",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "4MB",
|
||||||
|
"maximum_ram_size": 327680,
|
||||||
|
"maximum_size": 4194304,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 921600
|
||||||
|
},
|
||||||
|
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html",
|
||||||
|
"vendor": "Espressif"
|
||||||
|
}
|
||||||
42
boards/mesh-tab.json
Normal file
42
boards/mesh-tab.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "esp32s3_out.ld",
|
||||||
|
"partitions": "default_16MB.csv",
|
||||||
|
"memory_type": "qio_qspi"
|
||||||
|
},
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DBOARD_HAS_PSRAM",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DARDUINO_USB_MODE=0",
|
||||||
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
|
],
|
||||||
|
"f_cpu": "240000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "qio",
|
||||||
|
"hwids": [["0x303A", "0x80D6"]],
|
||||||
|
"mcu": "esp32s3",
|
||||||
|
"variant": "mesh-tab"
|
||||||
|
},
|
||||||
|
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||||
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": ["esp-builtin"],
|
||||||
|
"openocd_target": "esp32s3.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino", "espidf"],
|
||||||
|
"name": "ESP32-S3 WROOM-1 N16R2 (16 MB FLASH, 2 MB PSRAM)",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "16MB",
|
||||||
|
"maximum_ram_size": 327680,
|
||||||
|
"maximum_size": 16777216,
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"wait_for_upload_port": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 460800
|
||||||
|
},
|
||||||
|
"url": "https://github.com/valzzu/Mesh-Tab",
|
||||||
|
"vendor": "Espressif"
|
||||||
|
}
|
||||||
@@ -15,10 +15,12 @@
|
|||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
|
"f_boot": "120000000L",
|
||||||
|
"boot": "qio",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
"hwids": [["0x1A86", "0x7523"]],
|
"hwids": [["0x1A86", "0x7523"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "esp32s3r8"
|
"variant": "esp32s3"
|
||||||
},
|
},
|
||||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||||
"debug": {
|
"debug": {
|
||||||
@@ -32,9 +34,9 @@
|
|||||||
"flash_size": "8MB",
|
"flash_size": "8MB",
|
||||||
"maximum_ram_size": 327680,
|
"maximum_ram_size": 327680,
|
||||||
"maximum_size": 8388608,
|
"maximum_size": 8388608,
|
||||||
"require_upload_port": true,
|
"require_upload_port": false,
|
||||||
"use_1200bps_touch": true,
|
"use_1200bps_touch": true,
|
||||||
"wait_for_upload_port": true,
|
"wait_for_upload_port": false,
|
||||||
"speed": 921600
|
"speed": 921600
|
||||||
},
|
},
|
||||||
"url": "https://www.seeedstudio.com/Indicator-for-Meshtastic.html",
|
"url": "https://www.seeedstudio.com/Indicator-for-Meshtastic.html",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
"-DARDUINO_USB_MODE=0",
|
"-DARDUINO_USB_MODE=0",
|
||||||
"-DARDUINO_RUNNING_CORE=1",
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=0"
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
|
|||||||
@@ -48,6 +48,6 @@
|
|||||||
"require_upload_port": true,
|
"require_upload_port": true,
|
||||||
"wait_for_upload_port": true
|
"wait_for_upload_port": true
|
||||||
},
|
},
|
||||||
"url": "FIXME",
|
"url": "https://lilygo.cc/products/t-echo-lilygo",
|
||||||
"vendor": "TTGO"
|
"vendor": "LILYGO"
|
||||||
}
|
}
|
||||||
|
|||||||
6
debian/.gitignore
vendored
Normal file
6
debian/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.debhelper
|
||||||
|
debhelper-build-stamp
|
||||||
|
meshtasticd
|
||||||
|
files
|
||||||
|
meshtasticd.substvars
|
||||||
|
meshtasticd.postrm.debhelper
|
||||||
7
debian/changelog
vendored
Normal file
7
debian/changelog
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
meshtasticd (2.5.20.0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* Initial packaging
|
||||||
|
* GitHub Actions Automatic version bump
|
||||||
|
* GitHub Actions Automatic version bump
|
||||||
|
|
||||||
|
-- Austin Lane <github-actions[bot]@users.noreply.github.com> Wed, 15 Jan 2025 14:08:54 +0000
|
||||||
7
debian/ci_changelog.sh
vendored
Executable file
7
debian/ci_changelog.sh
vendored
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
export DEBEMAIL="github-actions[bot]@users.noreply.github.com"
|
||||||
|
PKG_VERSION=$(python3 bin/buildinfo.py short)
|
||||||
|
|
||||||
|
dch --newversion "$PKG_VERSION.0" \
|
||||||
|
--distribution UNRELEASED \
|
||||||
|
"GitHub Actions Automatic version bump"
|
||||||
23
debian/ci_pack_sdeb.sh
vendored
Executable file
23
debian/ci_pack_sdeb.sh
vendored
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
export DEBEMAIL="jbennett@incomsystems.biz"
|
||||||
|
export PLATFORMIO_LIBDEPS_DIR=pio/libdeps
|
||||||
|
export PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||||
|
export PLATFORMIO_CORE_DIR=pio/core
|
||||||
|
|
||||||
|
# Download libraries to `pio`
|
||||||
|
platformio pkg install -e native
|
||||||
|
platformio pkg install -e native -t platformio/tool-scons@4.40502.0
|
||||||
|
# Compress `pio` directory to prevent dh_clean from sanitizing it
|
||||||
|
tar -cf pio.tar pio/
|
||||||
|
rm -rf pio
|
||||||
|
# Download the latest meshtastic/web release build.tar to `web.tar`
|
||||||
|
curl -L https://github.com/meshtastic/web/releases/download/latest/build.tar -o web.tar
|
||||||
|
|
||||||
|
package=$(dpkg-parsechangelog --show-field Source)
|
||||||
|
|
||||||
|
rm -rf debian/changelog
|
||||||
|
dch --create --distribution "$SERIES" --package "$package" --newversion "$PKG_VERSION~$SERIES" \
|
||||||
|
"GitHub Actions Automatic packaging for $PKG_VERSION~$SERIES"
|
||||||
|
|
||||||
|
# Build the source deb
|
||||||
|
debuild -S -nc -k"$GPG_KEY_ID"
|
||||||
32
debian/control
vendored
Normal file
32
debian/control
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Source: meshtasticd
|
||||||
|
Section: misc
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Austin Lane <vidplace7@gmail.com>
|
||||||
|
Build-Depends: debhelper-compat (= 13),
|
||||||
|
tar,
|
||||||
|
gzip,
|
||||||
|
platformio,
|
||||||
|
python3-protobuf,
|
||||||
|
python3-grpcio,
|
||||||
|
git,
|
||||||
|
g++,
|
||||||
|
pkg-config,
|
||||||
|
libyaml-cpp-dev,
|
||||||
|
libgpiod-dev,
|
||||||
|
libbluetooth-dev,
|
||||||
|
libusb-1.0-0-dev,
|
||||||
|
libi2c-dev,
|
||||||
|
openssl,
|
||||||
|
libssl-dev,
|
||||||
|
libulfius-dev,
|
||||||
|
liborcania-dev
|
||||||
|
Standards-Version: 4.6.2
|
||||||
|
Homepage: https://github.com/meshtastic/firmware
|
||||||
|
Rules-Requires-Root: no
|
||||||
|
|
||||||
|
Package: meshtasticd
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Description: Meshtastic daemon for communicating with Meshtastic devices
|
||||||
|
Meshtastic is an off-grid text communication platform that uses inexpensive
|
||||||
|
LoRa radios.
|
||||||
4
debian/meshtasticd.dirs
vendored
Normal file
4
debian/meshtasticd.dirs
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
etc/meshtasticd
|
||||||
|
etc/meshtasticd/config.d
|
||||||
|
etc/meshtasticd/available.d
|
||||||
|
usr/share/meshtasticd/web
|
||||||
8
debian/meshtasticd.install
vendored
Normal file
8
debian/meshtasticd.install
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.pio/build/native/meshtasticd usr/sbin
|
||||||
|
|
||||||
|
bin/config.yaml etc/meshtasticd
|
||||||
|
bin/config.d/* etc/meshtasticd/available.d
|
||||||
|
|
||||||
|
bin/meshtasticd.service lib/systemd/system
|
||||||
|
|
||||||
|
web/* usr/share/meshtasticd/web
|
||||||
23
debian/rules
vendored
Executable file
23
debian/rules
vendored
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# export DH_VERBOSE = 1
|
||||||
|
|
||||||
|
# Use the "dh" sequencer
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
# https://docs.platformio.org/en/latest/envvars.html
|
||||||
|
PIO_ENV:=\
|
||||||
|
PLATFORMIO_CORE_DIR=pio/core \
|
||||||
|
PLATFORMIO_LIBDEPS_DIR=pio/libdeps \
|
||||||
|
PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||||
|
|
||||||
|
override_dh_auto_build:
|
||||||
|
# Extract tarballs within source deb
|
||||||
|
tar -xf pio.tar
|
||||||
|
mkdir -p web && tar -xf web.tar -C web
|
||||||
|
gunzip web/ -r
|
||||||
|
# Build with platformio
|
||||||
|
$(PIO_ENV) platformio run -e native
|
||||||
|
# Move the binary and default config to the correct name
|
||||||
|
mv .pio/build/native/program .pio/build/native/meshtasticd
|
||||||
|
cp bin/config-dist.yaml bin/config.yaml
|
||||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
||||||
2
debian/source/include-binaries
vendored
Normal file
2
debian/source/include-binaries
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pio.tar
|
||||||
|
web.tar
|
||||||
1
debian/source/options
vendored
Normal file
1
debian/source/options
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
extend-diff-ignore = "\.pio"
|
||||||
@@ -1,13 +1,26 @@
|
|||||||
version: "3.7"
|
# USB-Based Meshtastic container-node!
|
||||||
|
|
||||||
|
# Copy .env.example to .env and set the USB_DEVICE and CONFIG_PATH variables
|
||||||
|
|
||||||
services:
|
services:
|
||||||
meshtastic-node:
|
meshtastic-node:
|
||||||
build: .
|
build: .
|
||||||
deploy:
|
container_name: meshtasticd
|
||||||
mode: replicated
|
|
||||||
replicas: 4
|
|
||||||
networks:
|
|
||||||
- mesh
|
|
||||||
|
|
||||||
networks:
|
# Pass USB device through to the container
|
||||||
mesh:
|
devices:
|
||||||
|
- "${USB_DEVICE}"
|
||||||
|
|
||||||
|
# Mount local config file and named volume for data persistence
|
||||||
|
volumes:
|
||||||
|
- "${CONFIG_PATH}:/etc/meshtasticd/config.yaml:ro"
|
||||||
|
- meshtastic_data:/var/lib/meshtasticd
|
||||||
|
|
||||||
|
# Forward the container’s port 4403 to the host
|
||||||
|
ports:
|
||||||
|
- 4403:4403
|
||||||
|
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
meshtastic_data:
|
||||||
|
|||||||
91
meshtasticd.spec.rpkg
Normal file
91
meshtasticd.spec.rpkg
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# meshtasticd spec file for RPM-based distributions
|
||||||
|
#
|
||||||
|
# Build locally with:
|
||||||
|
# ```
|
||||||
|
# sudo dnf install rpkg-util
|
||||||
|
# rpkg local
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# See:
|
||||||
|
# - https://docs.pagure.org/rpkg-util/v3/index.html
|
||||||
|
# - https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/
|
||||||
|
|
||||||
|
Name: meshtasticd
|
||||||
|
# Version Ex: 2.5.19
|
||||||
|
Version: {{{ meshtastic_version }}}
|
||||||
|
# Release Ex: 9127.daily.gitd7f5f620.fc41
|
||||||
|
Release: {{{ git_commits_num }}}%{?copr_projectname:.%{copr_projectname}}.git{{{ git_commit_sha }}}%{?dist}
|
||||||
|
VCS: {{{ git_dir_vcs }}}
|
||||||
|
Summary: Meshtastic daemon for communicating with Meshtastic devices
|
||||||
|
|
||||||
|
License: GPL-3.0
|
||||||
|
URL: https://github.com/meshtastic/firmware
|
||||||
|
Source0: {{{ git_dir_pack }}}
|
||||||
|
Source1: https://github.com/meshtastic/web/releases/download/latest/build.tar
|
||||||
|
|
||||||
|
BuildRequires: systemd-rpm-macros
|
||||||
|
BuildRequires: python3-devel
|
||||||
|
BuildRequires: platformio
|
||||||
|
BuildRequires: python3dist(protobuf)
|
||||||
|
BuildRequires: python3dist(grpcio[protobuf])
|
||||||
|
BuildRequires: python3dist(grpcio-tools)
|
||||||
|
BuildRequires: git-core
|
||||||
|
BuildRequires: gcc-c++
|
||||||
|
BuildRequires: pkgconfig(yaml-cpp)
|
||||||
|
BuildRequires: pkgconfig(libgpiod)
|
||||||
|
BuildRequires: pkgconfig(bluez)
|
||||||
|
BuildRequires: pkgconfig(libusb-1.0)
|
||||||
|
BuildRequires: libi2c-devel
|
||||||
|
# Web components:
|
||||||
|
BuildRequires: pkgconfig(openssl)
|
||||||
|
BuildRequires: pkgconfig(liborcania)
|
||||||
|
BuildRequires: pkgconfig(libyder)
|
||||||
|
BuildRequires: pkgconfig(libulfius)
|
||||||
|
|
||||||
|
%description
|
||||||
|
Meshtastic daemon for controlling Meshtastic devices. Meshtastic is an off-grid
|
||||||
|
text communication platform that uses inexpensive LoRa radios.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
{{{ git_dir_setup_macro }}}
|
||||||
|
# Unpack the web files
|
||||||
|
mkdir -p web
|
||||||
|
tar -xf %{SOURCE1} -C web
|
||||||
|
gzip -dr web
|
||||||
|
|
||||||
|
%build
|
||||||
|
# Use the “native” environment from platformio to build a Linux binary
|
||||||
|
platformio run -e native
|
||||||
|
|
||||||
|
%install
|
||||||
|
mkdir -p %{buildroot}%{_sbindir}
|
||||||
|
install -m 0755 .pio/build/native/program %{buildroot}%{_sbindir}/meshtasticd
|
||||||
|
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd
|
||||||
|
install -m 0644 bin/config-dist.yaml %{buildroot}%{_sysconfdir}/meshtasticd/config.yaml
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/config.d
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/available.d
|
||||||
|
cp -r bin/config.d/* %{buildroot}%{_sysconfdir}/meshtasticd/available.d
|
||||||
|
|
||||||
|
install -D -m 0644 bin/meshtasticd.service %{buildroot}%{_unitdir}/meshtasticd.service
|
||||||
|
|
||||||
|
# Install the web files under /usr/share/meshtasticd/web
|
||||||
|
mkdir -p %{buildroot}%{_datadir}/meshtasticd/web
|
||||||
|
cp -r web/* %{buildroot}%{_datadir}/meshtasticd/web
|
||||||
|
|
||||||
|
%files
|
||||||
|
%license LICENSE
|
||||||
|
%doc README.md
|
||||||
|
%{_sbindir}/meshtasticd
|
||||||
|
%dir %{_sysconfdir}/meshtasticd
|
||||||
|
%dir %{_sysconfdir}/meshtasticd/config.d
|
||||||
|
%dir %{_sysconfdir}/meshtasticd/available.d
|
||||||
|
%config(noreplace) %{_sysconfdir}/meshtasticd/config.yaml
|
||||||
|
%config %{_sysconfdir}/meshtasticd/available.d/*
|
||||||
|
%{_unitdir}/meshtasticd.service
|
||||||
|
%dir %{_datadir}/meshtasticd
|
||||||
|
%dir %{_datadir}/meshtasticd/web
|
||||||
|
%{_datadir}/meshtasticd/web/*
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
%autochangelog
|
||||||
@@ -3,42 +3,7 @@
|
|||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
default_envs = tbeam
|
default_envs = tbeam
|
||||||
;default_envs = pico
|
|
||||||
;default_envs = tbeam-s3-core
|
|
||||||
;default_envs = tbeam0.7
|
|
||||||
;default_envs = heltec-v1
|
|
||||||
;default_envs = heltec-v2_0
|
|
||||||
;default_envs = heltec-v2_1
|
|
||||||
;default_envs = heltec-wireless-tracker
|
|
||||||
;default_envs = chatter2
|
|
||||||
;default_envs = tlora-v1
|
|
||||||
;default_envs = tlora_v1_3
|
|
||||||
;default_envs = tlora-v2
|
|
||||||
;default_envs = tlora-v2-1-1_6
|
|
||||||
;default_envs = tlora-v2-1-1_6-tcxo
|
|
||||||
;default_envs = tlora-t3s3-v1
|
|
||||||
;default_envs = t-echo
|
|
||||||
;default_envs = canaryone
|
|
||||||
;default_envs = native
|
|
||||||
;default_envs = nano-g1
|
|
||||||
;default_envs = pca10059_diy_eink
|
|
||||||
;default_envs = meshtastic-diy-v1
|
|
||||||
;default_envs = meshtastic-diy-v1_1
|
|
||||||
;default_envs = meshtastic-dr-dev
|
|
||||||
;default_envs = m5stack-coreink
|
|
||||||
;default_envs = rak4631
|
|
||||||
;default_envs = rak4631_eth_gw
|
|
||||||
;default_envs = rak2560
|
|
||||||
;default_envs = rak_wismeshtap
|
|
||||||
;default_envs = wio-e5
|
|
||||||
;default_envs = radiomaster_900_bandit_nano
|
|
||||||
;default_envs = radiomaster_900_bandit_micro
|
|
||||||
;default_envs = radiomaster_900_bandit
|
|
||||||
;default_envs = heltec_capsule_sensor_v3
|
|
||||||
;default_envs = heltec_vision_master_t190
|
|
||||||
;default_envs = heltec_vision_master_e213
|
|
||||||
;default_envs = heltec_vision_master_e290
|
|
||||||
;default_envs = heltec_mesh_node_t114
|
|
||||||
extra_configs =
|
extra_configs =
|
||||||
arch/*/*.ini
|
arch/*/*.ini
|
||||||
variants/*/platformio.ini
|
variants/*/platformio.ini
|
||||||
@@ -55,7 +20,7 @@ extra_scripts = bin/platformio-custom.py
|
|||||||
build_flags = -Wno-missing-field-initializers
|
build_flags = -Wno-missing-field-initializers
|
||||||
|
|
||||||
-Wno-format
|
-Wno-format
|
||||||
-Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
|
-Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,"${platformio.build_dir}"/output.map
|
||||||
-DUSE_THREAD_NAMES
|
-DUSE_THREAD_NAMES
|
||||||
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
|
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||||
-DPB_ENABLE_MALLOC=1
|
-DPB_ENABLE_MALLOC=1
|
||||||
@@ -81,9 +46,10 @@ build_flags = -Wno-missing-field-initializers
|
|||||||
-DRADIOLIB_EXCLUDE_LORAWAN=1
|
-DRADIOLIB_EXCLUDE_LORAWAN=1
|
||||||
-DMESHTASTIC_EXCLUDE_DROPZONE=1
|
-DMESHTASTIC_EXCLUDE_DROPZONE=1
|
||||||
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
|
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
|
||||||
|
-DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1
|
||||||
-DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
|
-DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
|
||||||
#-DBUILD_EPOCH=$UNIX_TIME
|
#-DBUILD_EPOCH=$UNIX_TIME
|
||||||
;-D OLED_PL
|
#-D OLED_PL=1
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_filters = direct
|
monitor_filters = direct
|
||||||
@@ -110,7 +76,6 @@ framework = arduino
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
end2endzone/NonBlockingRTTTL@1.3.0
|
end2endzone/NonBlockingRTTTL@1.3.0
|
||||||
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da
|
|
||||||
build_flags = ${env.build_flags} -Os
|
build_flags = ${env.build_flags} -Os
|
||||||
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
|
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
|
||||||
|
|
||||||
@@ -123,7 +88,7 @@ lib_deps =
|
|||||||
|
|
||||||
[radiolib_base]
|
[radiolib_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
jgromes/RadioLib@7.1.0
|
jgromes/RadioLib@7.1.2
|
||||||
|
|
||||||
; Common libs for environmental measurements in telemetry module
|
; Common libs for environmental measurements in telemetry module
|
||||||
; (not included in native / portduino)
|
; (not included in native / portduino)
|
||||||
@@ -154,7 +119,6 @@ lib_deps =
|
|||||||
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
|
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
|
||||||
ClosedCube OPT3001@1.1.2
|
ClosedCube OPT3001@1.1.2
|
||||||
emotibit/EmotiBit MLX90632@1.0.8
|
emotibit/EmotiBit MLX90632@1.0.8
|
||||||
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
|
||||||
adafruit/Adafruit MLX90614 Library@2.1.5
|
adafruit/Adafruit MLX90614 Library@2.1.5
|
||||||
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
||||||
boschsensortec/BME68x Sensor Library@1.1.40407
|
boschsensortec/BME68x Sensor Library@1.1.40407
|
||||||
@@ -162,3 +126,8 @@ lib_deps =
|
|||||||
mprograms/QMC5883LCompass@1.2.3
|
mprograms/QMC5883LCompass@1.2.3
|
||||||
dfrobot/DFRobot_RTU@1.0.3
|
dfrobot/DFRobot_RTU@1.0.3
|
||||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
|
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
|
||||||
|
https://github.com/DFRobot/DFRobot_RainfallSensor#38fea5e02b40a5430be6dab39a99a6f6347d667e
|
||||||
|
robtillaart/INA226@0.6.0
|
||||||
|
|
||||||
|
; Health Sensor Libraries
|
||||||
|
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
||||||
|
|||||||
Submodule protobufs updated: c952f8a4c1...7f13df0e5f
2
rpkg.conf
Normal file
2
rpkg.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[rpkg]
|
||||||
|
user_macros = "${git_props:root}/bin/rpkg.macros"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "ButtonThread.h"
|
#include "ButtonThread.h"
|
||||||
#include "../userPrefs.h"
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#if !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
@@ -190,6 +190,20 @@ int32_t ButtonThread::runOnce()
|
|||||||
case 4:
|
case 4:
|
||||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(RAK_4631)
|
||||||
|
// 5 clicks: start accelerometer/magenetometer calibration for 30 seconds
|
||||||
|
case 5:
|
||||||
|
if (accelerometerThread) {
|
||||||
|
accelerometerThread->calibrate(30);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// 6 clicks: start accelerometer/magenetometer calibration for 60 seconds
|
||||||
|
case 6:
|
||||||
|
if (accelerometerThread) {
|
||||||
|
accelerometerThread->calibrate(60);
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
// No valid multipress action
|
// No valid multipress action
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||||
#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) && !defined(PIO_UNIT_TESTING)
|
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
|
||||||
#define LOG_DEBUG(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
#define LOG_DEBUG(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||||
#define LOG_INFO(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_INFO, __VA_ARGS__)
|
#define LOG_INFO(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_INFO, __VA_ARGS__)
|
||||||
#define LOG_WARN(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_WARN, __VA_ARGS__)
|
#define LOG_WARN(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_WARN, __VA_ARGS__)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
@@ -48,15 +49,6 @@ void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool lfs_assert_failed =
|
|
||||||
false; // Note: we use this global on all platforms, though it can only be set true on nrf52 (in our modified lfs_util.h)
|
|
||||||
|
|
||||||
extern "C" void lfs_assert(const char *reason)
|
|
||||||
{
|
|
||||||
LOG_ERROR("LFS assert: %s", reason);
|
|
||||||
lfs_assert_failed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies a file from one location to another.
|
* @brief Copies a file from one location to another.
|
||||||
*
|
*
|
||||||
@@ -93,6 +85,8 @@ bool copyFile(const char *from, const char *to)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
#elif defined(FSCom)
|
#elif defined(FSCom)
|
||||||
|
// take SPI Lock
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
unsigned char cbuffer[16];
|
unsigned char cbuffer[16];
|
||||||
|
|
||||||
File f1 = FSCom.open(from, FILE_O_READ);
|
File f1 = FSCom.open(from, FILE_O_READ);
|
||||||
@@ -136,16 +130,23 @@ bool renameFile(const char *pathFrom, const char *pathTo)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif defined(FSCom)
|
#elif defined(FSCom)
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
// take SPI Lock
|
||||||
|
spiLock->lock();
|
||||||
// rename was fixed for ESP32 IDF LittleFS in April
|
// rename was fixed for ESP32 IDF LittleFS in April
|
||||||
return FSCom.rename(pathFrom, pathTo);
|
bool result = FSCom.rename(pathFrom, pathTo);
|
||||||
|
spiLock->unlock();
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
|
// copyFile does its own locking.
|
||||||
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
|
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +156,7 @@ bool renameFile(const char *pathFrom, const char *pathTo)
|
|||||||
* @brief Get the list of files in a directory.
|
* @brief Get the list of files in a directory.
|
||||||
*
|
*
|
||||||
* This function returns a list of files in a directory. The list includes the full path of each file.
|
* This function returns a list of files in a directory. The list includes the full path of each file.
|
||||||
|
* We can't use SPILOCK here because of recursion. Callers of this function should use SPILOCK.
|
||||||
*
|
*
|
||||||
* @param dirname The name of the directory.
|
* @param dirname The name of the directory.
|
||||||
* @param levels The number of levels of subdirectories to list.
|
* @param levels The number of levels of subdirectories to list.
|
||||||
@@ -183,7 +185,7 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
|
|||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
meshtastic_FileInfo fileInfo = {"", file.size()};
|
meshtastic_FileInfo fileInfo = {"", static_cast<uint32_t>(file.size())};
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
strcpy(fileInfo.file_name, file.path());
|
strcpy(fileInfo.file_name, file.path());
|
||||||
#else
|
#else
|
||||||
@@ -203,6 +205,7 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists the contents of a directory.
|
* Lists the contents of a directory.
|
||||||
|
* We can't use SPILOCK here because of recursion. Callers of this function should use SPILOCK.
|
||||||
*
|
*
|
||||||
* @param dirname The name of the directory to list.
|
* @param dirname The name of the directory to list.
|
||||||
* @param levels The number of levels of subdirectories to list.
|
* @param levels The number of levels of subdirectories to list.
|
||||||
@@ -316,18 +319,27 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
void rmDir(const char *dirname)
|
void rmDir(const char *dirname)
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||||
listDir(dirname, 10, true);
|
listDir(dirname, 10, true);
|
||||||
#elif defined(ARCH_NRF52)
|
#elif defined(ARCH_NRF52)
|
||||||
// nRF52 implementation of LittleFS has a recursive delete function
|
// nRF52 implementation of LittleFS has a recursive delete function
|
||||||
FSCom.rmdir_r(dirname);
|
FSCom.rmdir_r(dirname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some platforms (nrf52) might need to do an extra step before FSBegin().
|
||||||
|
*/
|
||||||
|
__attribute__((weak, noinline)) void preFSBegin() {}
|
||||||
|
|
||||||
void fsInit()
|
void fsInit()
|
||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
|
preFSBegin();
|
||||||
if (!FSBegin()) {
|
if (!FSBegin()) {
|
||||||
LOG_ERROR("Filesystem mount failed");
|
LOG_ERROR("Filesystem mount failed");
|
||||||
// assert(0); This auto-formats the partition, so no need to fail here.
|
// assert(0); This auto-formats the partition, so no need to fail here.
|
||||||
@@ -347,6 +359,7 @@ void fsInit()
|
|||||||
void setupSDCard()
|
void setupSDCard()
|
||||||
{
|
{
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||||
|
|
||||||
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
||||||
|
|||||||
@@ -58,6 +58,3 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels);
|
|||||||
void listDir(const char *dirname, uint8_t levels, bool del = false);
|
void listDir(const char *dirname, uint8_t levels, bool del = false);
|
||||||
void rmDir(const char *dirname);
|
void rmDir(const char *dirname);
|
||||||
void setupSDCard();
|
void setupSDCard();
|
||||||
|
|
||||||
extern bool lfs_assert_failed; // Note: we use this global on all platforms, though it can only be set true on nrf52 (in our
|
|
||||||
// modified lfs_util.h)
|
|
||||||
|
|||||||
@@ -72,8 +72,9 @@ static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
||||||
INA260Sensor ina260Sensor;
|
|
||||||
INA219Sensor ina219Sensor;
|
INA219Sensor ina219Sensor;
|
||||||
|
INA226Sensor ina226Sensor;
|
||||||
|
INA260Sensor ina260Sensor;
|
||||||
INA3221Sensor ina3221Sensor;
|
INA3221Sensor ina3221Sensor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ MAX17048Sensor max17048Sensor;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && HAS_RAKPROT && !defined(ARCH_PORTDUINO)
|
||||||
RAK9154Sensor rak9154Sensor;
|
RAK9154Sensor rak9154Sensor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -242,7 +243,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
virtual uint16_t getBattVoltage() override
|
virtual uint16_t getBattVoltage() override
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
#if HAS_TELEMETRY && defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && \
|
||||||
|
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
if (hasRAK()) {
|
if (hasRAK()) {
|
||||||
return getRAKVoltage();
|
return getRAKVoltage();
|
||||||
}
|
}
|
||||||
@@ -405,7 +407,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
/// we can't be smart enough to say 'full'?
|
/// we can't be smart enough to say 'full'?
|
||||||
virtual bool isCharging() override
|
virtual bool isCharging() override
|
||||||
{
|
{
|
||||||
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && \
|
||||||
|
!defined(HAS_PMU)
|
||||||
if (hasRAK()) {
|
if (hasRAK()) {
|
||||||
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
|
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
|
||||||
}
|
}
|
||||||
@@ -413,7 +416,20 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
#ifdef EXT_CHRG_DETECT
|
#ifdef EXT_CHRG_DETECT
|
||||||
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
|
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
|
||||||
#else
|
#else
|
||||||
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && \
|
||||||
|
!defined(DISABLE_INA_CHARGING_DETECTION)
|
||||||
|
if (hasINA()) {
|
||||||
|
// get current flow from INA sensor - negative value means power flowing into the battery
|
||||||
|
// default assuming BATTERY+ <--> INA_VIN+ <--> SHUNT RESISTOR <--> INA_VIN- <--> LOAD
|
||||||
|
LOG_DEBUG("Using INA on I2C addr 0x%x for charging detection", config.power.device_battery_ina_address);
|
||||||
|
#if defined(INA_CHARGING_DETECTION_INVERT)
|
||||||
|
return getINACurrent() > 0;
|
||||||
|
#else
|
||||||
|
return getINACurrent() < 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return isBatteryConnect() && isVbusIn();
|
return isBatteryConnect() && isVbusIn();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +449,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
|
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
|
||||||
uint32_t last_read_time_ms = 0;
|
uint32_t last_read_time_ms = 0;
|
||||||
|
|
||||||
#if defined(HAS_RAKPROT)
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT)
|
||||||
|
|
||||||
uint16_t getRAKVoltage() { return rak9154Sensor.getBusVoltageMv(); }
|
uint16_t getRAKVoltage() { return rak9154Sensor.getBusVoltageMv(); }
|
||||||
|
|
||||||
@@ -450,6 +466,9 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
{
|
{
|
||||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||||
return ina219Sensor.getBusVoltageMv();
|
return ina219Sensor.getBusVoltageMv();
|
||||||
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA226].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
|
return ina226Sensor.getBusVoltageMv();
|
||||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
||||||
config.power.device_battery_ina_address) {
|
config.power.device_battery_ina_address) {
|
||||||
return ina260Sensor.getBusVoltageMv();
|
return ina260Sensor.getBusVoltageMv();
|
||||||
@@ -460,6 +479,20 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t getINACurrent()
|
||||||
|
{
|
||||||
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||||
|
return ina219Sensor.getCurrentMa();
|
||||||
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA226].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
|
return ina226Sensor.getCurrentMa();
|
||||||
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA3221].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
|
return ina3221Sensor.getCurrentMa();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasINA()
|
bool hasINA()
|
||||||
{
|
{
|
||||||
if (!config.power.device_battery_ina_address) {
|
if (!config.power.device_battery_ina_address) {
|
||||||
@@ -469,6 +502,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
if (!ina219Sensor.isInitialized())
|
if (!ina219Sensor.isInitialized())
|
||||||
return ina219Sensor.runOnce() > 0;
|
return ina219Sensor.runOnce() > 0;
|
||||||
return ina219Sensor.isRunning();
|
return ina219Sensor.isRunning();
|
||||||
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA226].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
|
if (!ina226Sensor.isInitialized())
|
||||||
|
return ina226Sensor.runOnce() > 0;
|
||||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
||||||
config.power.device_battery_ina_address) {
|
config.power.device_battery_ina_address) {
|
||||||
if (!ina260Sensor.isInitialized())
|
if (!ina260Sensor.isInitialized())
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
|
|
||||||
|
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
|
||||||
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SLEEP_TIME
|
#ifndef SLEEP_TIME
|
||||||
#define SLEEP_TIME 30
|
#define SLEEP_TIME 30
|
||||||
#endif
|
#endif
|
||||||
@@ -377,9 +381,9 @@ void PowerFSM_setup()
|
|||||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// See: https://github.com/meshtastic/firmware/issues/1071
|
// See: https://github.com/meshtastic/firmware/issues/1071
|
||||||
// Don't add power saving transitions if we are a power saving tracker or sensor. Sleep will be initiated through the
|
// Don't add power saving transitions if we are a power saving tracker or sensor or have Wifi enabled. Sleep will be initiated
|
||||||
// modules
|
// through the modules
|
||||||
if ((isRouter || config.power.is_power_saving) && !isTrackerOrSensor) {
|
if ((isRouter || config.power.is_power_saving) && !isWifiAvailable() && !isTrackerOrSensor) {
|
||||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||||
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
||||||
"Min wake timeout");
|
"Min wake timeout");
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
// Only way to work on both esp32 and nrf52
|
// Only way to work on both esp32 and nrf52
|
||||||
static File openFile(const char *filename, bool fullAtomic)
|
static File openFile(const char *filename, bool fullAtomic)
|
||||||
{
|
{
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
|
LOG_DEBUG("Opening %s, fullAtomic=%d", filename, fullAtomic);
|
||||||
|
#ifdef ARCH_NRF52
|
||||||
|
FSCom.remove(filename);
|
||||||
|
return FSCom.open(filename, FILE_O_WRITE);
|
||||||
|
#endif
|
||||||
if (!fullAtomic)
|
if (!fullAtomic)
|
||||||
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
||||||
|
|
||||||
@@ -12,8 +18,6 @@ static File openFile(const char *filename, bool fullAtomic)
|
|||||||
filenameTmp += ".tmp";
|
filenameTmp += ".tmp";
|
||||||
|
|
||||||
// clear any previous LFS errors
|
// clear any previous LFS errors
|
||||||
lfs_assert_failed = false;
|
|
||||||
|
|
||||||
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,15 +57,24 @@ bool SafeFile::close()
|
|||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
spiLock->lock();
|
||||||
f.close();
|
f.close();
|
||||||
|
spiLock->unlock();
|
||||||
|
|
||||||
|
#ifdef ARCH_NRF52
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
if (!testReadback())
|
if (!testReadback())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
{ // Scope for lock
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
// brief window of risk here ;-)
|
// brief window of risk here ;-)
|
||||||
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
||||||
LOG_ERROR("Can't remove old pref file");
|
LOG_ERROR("Can't remove old pref file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String filenameTmp = filename;
|
String filenameTmp = filename;
|
||||||
filenameTmp += ".tmp";
|
filenameTmp += ".tmp";
|
||||||
@@ -76,8 +89,7 @@ bool SafeFile::close()
|
|||||||
/// Read our (closed) tempfile back in and compare the hash
|
/// Read our (closed) tempfile back in and compare the hash
|
||||||
bool SafeFile::testReadback()
|
bool SafeFile::testReadback()
|
||||||
{
|
{
|
||||||
bool lfs_failed = lfs_assert_failed;
|
concurrency::LockGuard g(spiLock);
|
||||||
lfs_assert_failed = false;
|
|
||||||
|
|
||||||
String filenameTmp = filename;
|
String filenameTmp = filename;
|
||||||
filenameTmp += ".tmp";
|
filenameTmp += ".tmp";
|
||||||
@@ -99,7 +111,7 @@ bool SafeFile::testReadback()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !lfs_failed;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
|
#include "SPILock.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define OPT3001_ADDR_ALT 0x44
|
#define OPT3001_ADDR_ALT 0x44
|
||||||
#define MLX90632_ADDR 0x3A
|
#define MLX90632_ADDR 0x3A
|
||||||
#define DFROBOT_LARK_ADDR 0x42
|
#define DFROBOT_LARK_ADDR 0x42
|
||||||
|
#define DFROBOT_RAIN_ADDR 0x1d
|
||||||
#define NAU7802_ADDR 0x2A
|
#define NAU7802_ADDR 0x2A
|
||||||
#define MAX30102_ADDR 0x57
|
#define MAX30102_ADDR 0x57
|
||||||
#define MLX90614_ADDR_DEF 0x5A
|
#define MLX90614_ADDR_DEF 0x5A
|
||||||
@@ -171,7 +172,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Security
|
// Security
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
#define ATECC608B_ADDR 0x35
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// IO Expander
|
// IO Expander
|
||||||
@@ -179,13 +179,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define TCA9535_ADDR 0x20
|
#define TCA9535_ADDR 0x20
|
||||||
#define TCA9555_ADDR 0x26
|
#define TCA9555_ADDR 0x26
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// GPS
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
#ifndef GPS_THREAD_INTERVAL
|
|
||||||
#define GPS_THREAD_INTERVAL 200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Touchscreen
|
// Touchscreen
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -207,6 +200,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define VEXT_ON_VALUE LOW
|
#define VEXT_ON_VALUE LOW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// GPS
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef GPS_BAUDRATE
|
#ifndef GPS_BAUDRATE
|
||||||
#define GPS_BAUDRATE 9600
|
#define GPS_BAUDRATE 9600
|
||||||
#define GPS_BAUDRATE_FIXED 0
|
#define GPS_BAUDRATE_FIXED 0
|
||||||
@@ -214,6 +211,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define GPS_BAUDRATE_FIXED 1
|
#define GPS_BAUDRATE_FIXED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef GPS_THREAD_INTERVAL
|
||||||
|
#define GPS_THREAD_INTERVAL 200
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Step #2: follow with defines common to the architecture;
|
/* Step #2: follow with defines common to the architecture;
|
||||||
also enable HAS_ option not specifically disabled by variant.h */
|
also enable HAS_ option not specifically disabled by variant.h */
|
||||||
#include "architecture.h"
|
#include "architecture.h"
|
||||||
@@ -251,6 +252,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#ifndef HAS_SCREEN
|
#ifndef HAS_SCREEN
|
||||||
#define HAS_SCREEN 0
|
#define HAS_SCREEN 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAS_TFT
|
||||||
|
#define HAS_TFT 0
|
||||||
|
#endif
|
||||||
#ifndef HAS_WIRE
|
#ifndef HAS_WIRE
|
||||||
#define HAS_WIRE 0
|
#define HAS_WIRE 0
|
||||||
#endif
|
#endif
|
||||||
@@ -313,6 +317,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define MESHTASTIC_EXCLUDE_AUDIO 1
|
#define MESHTASTIC_EXCLUDE_AUDIO 1
|
||||||
#define MESHTASTIC_EXCLUDE_DETECTIONSENSOR 1
|
#define MESHTASTIC_EXCLUDE_DETECTIONSENSOR 1
|
||||||
#define MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR 1
|
#define MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR 1
|
||||||
|
#define MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY 1
|
||||||
#define MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION 1
|
#define MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION 1
|
||||||
#define MESHTASTIC_EXCLUDE_PAXCOUNTER 1
|
#define MESHTASTIC_EXCLUDE_PAXCOUNTER 1
|
||||||
#define MESHTASTIC_EXCLUDE_POWER_TELEMETRY 1
|
#define MESHTASTIC_EXCLUDE_POWER_TELEMETRY 1
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ class ScanI2C
|
|||||||
SCREEN_SH1106,
|
SCREEN_SH1106,
|
||||||
SCREEN_UNKNOWN, // has the same address as the two above but does not respond to the same commands
|
SCREEN_UNKNOWN, // has the same address as the two above but does not respond to the same commands
|
||||||
SCREEN_ST7567,
|
SCREEN_ST7567,
|
||||||
ATECC608B,
|
|
||||||
RTC_RV3028,
|
RTC_RV3028,
|
||||||
RTC_PCF8563,
|
RTC_PCF8563,
|
||||||
CARDKB,
|
CARDKB,
|
||||||
@@ -64,7 +63,10 @@ class ScanI2C
|
|||||||
MAX30102,
|
MAX30102,
|
||||||
TPS65233,
|
TPS65233,
|
||||||
MPR121KB,
|
MPR121KB,
|
||||||
CGRADSENS
|
CGRADSENS,
|
||||||
|
INA226,
|
||||||
|
NXP_SE050,
|
||||||
|
DFROBOT_RAIN,
|
||||||
} DeviceType;
|
} DeviceType;
|
||||||
|
|
||||||
// typedef uint8_t DeviceAddress;
|
// typedef uint8_t DeviceAddress;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "linux/LinuxHardwareI2C.h"
|
#include "linux/LinuxHardwareI2C.h"
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
#include "main.h" // atecc
|
|
||||||
#include "meshUtils.h" // vformat
|
#include "meshUtils.h" // vformat
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -72,10 +71,10 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
|
|||||||
r &= 0x0f;
|
r &= 0x0f;
|
||||||
|
|
||||||
if (r == 0x08 || r == 0x00) {
|
if (r == 0x08 || r == 0x00) {
|
||||||
LOG_INFO("sh1106 display found");
|
logFoundDevice("SH1106", (uint8_t)addr.address);
|
||||||
o_probe = SCREEN_SH1106; // SH1106
|
o_probe = SCREEN_SH1106; // SH1106
|
||||||
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
||||||
LOG_INFO("ssd1306 display found");
|
logFoundDevice("SSD1306", (uint8_t)addr.address);
|
||||||
o_probe = SCREEN_SSD1306; // SSD1306
|
o_probe = SCREEN_SSD1306; // SSD1306
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
@@ -84,65 +83,40 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
|
|||||||
|
|
||||||
return o_probe;
|
return o_probe;
|
||||||
}
|
}
|
||||||
void ScanI2CTwoWire::printATECCInfo() const
|
|
||||||
{
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
|
||||||
atecc.readConfigZone(false);
|
|
||||||
|
|
||||||
std::string atecc_numbers = "ATECC608B Serial Number: ";
|
|
||||||
for (int i = 0; i < 9; i++) {
|
|
||||||
atecc_numbers += vformat("%02x", atecc.serialNumber[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
atecc_numbers += ", Rev Number: ";
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
atecc_numbers += vformat("%02x", atecc.revisionNumber[i]);
|
|
||||||
}
|
|
||||||
LOG_DEBUG(atecc_numbers.c_str());
|
|
||||||
|
|
||||||
LOG_DEBUG("ATECC608B Config %s, Data %s, Slot 0 %s", atecc.configLockStatus ? "Locked" : "Unlocked",
|
|
||||||
atecc.dataOTPLockStatus ? "Locked" : "Unlocked", atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
|
||||||
|
|
||||||
std::string atecc_publickey = "";
|
|
||||||
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
|
||||||
if (atecc.generatePublicKey() == false) {
|
|
||||||
atecc_publickey += "ATECC608B Error generating public key";
|
|
||||||
} else {
|
|
||||||
atecc_publickey += "ATECC608B Public Key: ";
|
|
||||||
for (int i = 0; i < 64; i++) {
|
|
||||||
atecc_publickey += vformat("%02x", atecc.publicKey64Bytes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG_DEBUG(atecc_publickey.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation ®isterLocation,
|
uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation ®isterLocation,
|
||||||
ScanI2CTwoWire::ResponseWidth responseWidth) const
|
ScanI2CTwoWire::ResponseWidth responseWidth, bool zeropad = false) const
|
||||||
{
|
{
|
||||||
uint16_t value = 0x00;
|
uint16_t value = 0x00;
|
||||||
TwoWire *i2cBus = fetchI2CBus(registerLocation.i2cAddress);
|
TwoWire *i2cBus = fetchI2CBus(registerLocation.i2cAddress);
|
||||||
|
|
||||||
i2cBus->beginTransmission(registerLocation.i2cAddress.address);
|
i2cBus->beginTransmission(registerLocation.i2cAddress.address);
|
||||||
i2cBus->write(registerLocation.registerAddress);
|
i2cBus->write(registerLocation.registerAddress);
|
||||||
|
if (zeropad) {
|
||||||
|
// Lark Commands need the argument list length in 2 bytes.
|
||||||
|
i2cBus->write((int)0);
|
||||||
|
i2cBus->write((int)0);
|
||||||
|
}
|
||||||
i2cBus->endTransmission();
|
i2cBus->endTransmission();
|
||||||
delay(20);
|
delay(20);
|
||||||
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
|
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
|
||||||
LOG_DEBUG("Wire.available() = %d", i2cBus->available());
|
if (i2cBus->available() > 1) {
|
||||||
if (i2cBus->available() == 2) {
|
|
||||||
// Read MSB, then LSB
|
// Read MSB, then LSB
|
||||||
value = (uint16_t)i2cBus->read() << 8;
|
value = (uint16_t)i2cBus->read() << 8;
|
||||||
value |= i2cBus->read();
|
value |= i2cBus->read();
|
||||||
} else if (i2cBus->available()) {
|
} else if (i2cBus->available()) {
|
||||||
value = i2cBus->read();
|
value = i2cBus->read();
|
||||||
}
|
}
|
||||||
|
// Drain excess bytes
|
||||||
|
for (uint8_t i = 0; i < responseWidth - 1; i++) {
|
||||||
|
if (i2cBus->available())
|
||||||
|
i2cBus->read();
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
|
#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
|
||||||
case ADDR: \
|
case ADDR: \
|
||||||
LOG_INFO(__VA_ARGS__); \
|
logFoundDevice(__VA_ARGS__); \
|
||||||
type = T; \
|
type = T; \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -184,50 +158,36 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
|
|
||||||
for (addr.address = 8; addr.address < 120; addr.address++) {
|
for (addr.address = 8; addr.address < 120; addr.address++) {
|
||||||
if (asize != 0) {
|
if (asize != 0) {
|
||||||
if (!in_array(address, asize, addr.address))
|
if (!in_array(address, asize, (uint8_t)addr.address))
|
||||||
continue;
|
continue;
|
||||||
LOG_DEBUG("Scan address 0x%x", addr.address);
|
LOG_DEBUG("Scan address 0x%x", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
i2cBus->beginTransmission(addr.address);
|
i2cBus->beginTransmission(addr.address);
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
|
err = 2;
|
||||||
|
if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) {
|
||||||
if (i2cBus->read() != -1)
|
if (i2cBus->read() != -1)
|
||||||
err = 0;
|
err = 0;
|
||||||
else
|
} else {
|
||||||
|
err = i2cBus->writeQuick((uint8_t)0);
|
||||||
|
}
|
||||||
|
if (err != 0)
|
||||||
err = 2;
|
err = 2;
|
||||||
#else
|
#else
|
||||||
err = i2cBus->endTransmission();
|
err = i2cBus->endTransmission();
|
||||||
#endif
|
#endif
|
||||||
type = NONE;
|
type = NONE;
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
LOG_DEBUG("I2C device found at address 0x%x", addr.address);
|
|
||||||
|
|
||||||
switch (addr.address) {
|
switch (addr.address) {
|
||||||
case SSD1306_ADDRESS:
|
case SSD1306_ADDRESS:
|
||||||
type = probeOLED(addr);
|
type = probeOLED(addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
|
||||||
case ATECC608B_ADDR:
|
|
||||||
#ifdef RP2040_SLOW_CLOCK
|
|
||||||
if (atecc.begin(addr.address, Wire, Serial2) == true)
|
|
||||||
#else
|
|
||||||
if (atecc.begin(addr.address) == true)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
|
||||||
LOG_INFO("ATECC608B initialized");
|
|
||||||
} else {
|
|
||||||
LOG_WARN("ATECC608B initialization failed");
|
|
||||||
}
|
|
||||||
printATECCInfo();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RV3028_RTC
|
#ifdef RV3028_RTC
|
||||||
case RV3028_RTC:
|
case RV3028_RTC:
|
||||||
// foundDevices[addr] = RTC_RV3028;
|
// foundDevices[addr] = RTC_RV3028;
|
||||||
type = RTC_RV3028;
|
type = RTC_RV3028;
|
||||||
LOG_INFO("RV3028 RTC found");
|
logFoundDevice("RV3028", (uint8_t)addr.address);
|
||||||
rtc.initI2C(*i2cBus);
|
rtc.initI2C(*i2cBus);
|
||||||
rtc.writeToRegister(0x35, 0x07); // no Clkout
|
rtc.writeToRegister(0x35, 0x07); // no Clkout
|
||||||
rtc.writeToRegister(0x37, 0xB4);
|
rtc.writeToRegister(0x37, 0xB4);
|
||||||
@@ -235,7 +195,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PCF8563_RTC
|
#ifdef PCF8563_RTC
|
||||||
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found")
|
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563", (uint8_t)addr.address)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case CARDKB_ADDR:
|
case CARDKB_ADDR:
|
||||||
@@ -243,50 +203,50 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
||||||
if (registerValue == 0x02) {
|
if (registerValue == 0x02) {
|
||||||
// KEYPAD_VERSION
|
// KEYPAD_VERSION
|
||||||
LOG_INFO("RAK14004 found");
|
logFoundDevice("RAK14004", (uint8_t)addr.address);
|
||||||
type = RAK14004;
|
type = RAK14004;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("m5 cardKB found");
|
logFoundDevice("M5 cardKB", (uint8_t)addr.address);
|
||||||
type = CARDKB;
|
type = CARDKB;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found");
|
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found");
|
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10", (uint8_t)addr.address);
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found");
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "ST7567", (uint8_t)addr.address);
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found");
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found")
|
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "AXP192/AXP2101", (uint8_t)addr.address)
|
||||||
#endif
|
#endif
|
||||||
case BME_ADDR:
|
case BME_ADDR:
|
||||||
case BME_ADDR_ALTERNATE:
|
case BME_ADDR_ALTERNATE:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
|
||||||
switch (registerValue) {
|
switch (registerValue) {
|
||||||
case 0x61:
|
case 0x61:
|
||||||
LOG_INFO("BME-680 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("BME680", (uint8_t)addr.address);
|
||||||
type = BME_680;
|
type = BME_680;
|
||||||
break;
|
break;
|
||||||
case 0x60:
|
case 0x60:
|
||||||
LOG_INFO("BME-280 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("BME280", (uint8_t)addr.address);
|
||||||
type = BME_280;
|
type = BME_280;
|
||||||
break;
|
break;
|
||||||
case 0x55:
|
case 0x55:
|
||||||
LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("BMP085/BMP180", (uint8_t)addr.address);
|
||||||
type = BMP_085;
|
type = BMP_085;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
|
||||||
switch (registerValue) {
|
switch (registerValue) {
|
||||||
case 0x50: // BMP-388 should be 0x50
|
case 0x50: // BMP-388 should be 0x50
|
||||||
LOG_INFO("BMP-388 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("BMP-388", (uint8_t)addr.address);
|
||||||
type = BMP_3XX;
|
type = BMP_3XX;
|
||||||
break;
|
break;
|
||||||
case 0x58: // BMP-280 should be 0x58
|
case 0x58: // BMP-280 should be 0x58
|
||||||
default:
|
default:
|
||||||
LOG_INFO("BMP-280 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("BMP-280", (uint8_t)addr.address);
|
||||||
type = BMP_280;
|
type = BMP_280;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -295,7 +255,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
break;
|
break;
|
||||||
#ifndef HAS_NCP5623
|
#ifndef HAS_NCP5623
|
||||||
case AHT10_ADDR:
|
case AHT10_ADDR:
|
||||||
LOG_INFO("AHT10 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("AHT10", (uint8_t)addr.address);
|
||||||
type = AHT10;
|
type = AHT10;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -305,10 +265,18 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||||
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
|
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
|
||||||
if (registerValue == 0x5449) {
|
if (registerValue == 0x5449) {
|
||||||
LOG_INFO("INA260 sensor found at address 0x%x", (uint8_t)addr.address);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 2);
|
||||||
|
LOG_DEBUG("Register DIE_UID: 0x%x", registerValue);
|
||||||
|
|
||||||
|
if (registerValue == 0x2260) {
|
||||||
|
logFoundDevice("INA226", (uint8_t)addr.address);
|
||||||
|
type = INA226;
|
||||||
|
} else {
|
||||||
|
logFoundDevice("INA260", (uint8_t)addr.address);
|
||||||
type = INA260;
|
type = INA260;
|
||||||
|
}
|
||||||
} else { // Assume INA219 if INA260 ID is not found
|
} else { // Assume INA219 if INA260 ID is not found
|
||||||
LOG_INFO("INA219 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("INA219", (uint8_t)addr.address);
|
||||||
type = INA219;
|
type = INA219;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -316,7 +284,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||||
LOG_DEBUG("Register MFG_UID FE: 0x%x", registerValue);
|
LOG_DEBUG("Register MFG_UID FE: 0x%x", registerValue);
|
||||||
if (registerValue == 0x5449) {
|
if (registerValue == 0x5449) {
|
||||||
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("INA3221", (uint8_t)addr.address);
|
||||||
type = INA3221;
|
type = INA3221;
|
||||||
} else {
|
} else {
|
||||||
/* check the first 2 bytes of the 6 byte response register
|
/* check the first 2 bytes of the 6 byte response register
|
||||||
@@ -328,10 +296,10 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
RESPONSE_PAYLOAD 0x01
|
RESPONSE_PAYLOAD 0x01
|
||||||
RESPONSE_PAYLOAD+1 0x00
|
RESPONSE_PAYLOAD+1 0x00
|
||||||
*/
|
*/
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 6, true);
|
||||||
LOG_DEBUG("Register MFG_UID 05: 0x%x", registerValue);
|
LOG_DEBUG("Register MFG_UID 05: 0x%x", registerValue);
|
||||||
if (registerValue == 0x5305) {
|
if (registerValue == 0x5305) {
|
||||||
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("DFRobot Lark", (uint8_t)addr.address);
|
||||||
type = DFROBOT_LARK;
|
type = DFROBOT_LARK;
|
||||||
}
|
}
|
||||||
// else: probably a RAK12500/UBLOX GPS on I2C
|
// else: probably a RAK12500/UBLOX GPS on I2C
|
||||||
@@ -346,7 +314,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
||||||
if (registerValue == 0x8700) {
|
if (registerValue == 0x8700) {
|
||||||
type = STK8BAXX;
|
type = STK8BAXX;
|
||||||
LOG_INFO("STK8BAXX accelerometer found");
|
logFoundDevice("STK8BAXX", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -355,7 +323,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
||||||
if (registerValue == 0x0400) {
|
if (registerValue == 0x0400) {
|
||||||
type = MCP9808;
|
type = MCP9808;
|
||||||
LOG_INFO("MCP9808 sensor found");
|
logFoundDevice("MCP9808", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +331,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
||||||
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
||||||
type = LIS3DH;
|
type = LIS3DH;
|
||||||
LOG_INFO("LIS3DH accelerometer found");
|
logFoundDevice("LIS3DH", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -371,93 +339,92 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
||||||
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) {
|
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) {
|
||||||
type = SHT4X;
|
type = SHT4X;
|
||||||
LOG_INFO("SHT4X sensor found");
|
logFoundDevice("SHT4X", (uint8_t)addr.address);
|
||||||
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
||||||
type = OPT3001;
|
type = OPT3001;
|
||||||
LOG_INFO("OPT3001 light sensor found");
|
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
||||||
} else {
|
} else {
|
||||||
type = SHT31;
|
type = SHT31;
|
||||||
LOG_INFO("SHT31 sensor found");
|
logFoundDevice("SHT31", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found")
|
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3", (uint8_t)addr.address)
|
||||||
case RCWL9620_ADDR:
|
case RCWL9620_ADDR:
|
||||||
// get MAX30102 PARTID
|
// get MAX30102 PARTID
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
|
||||||
if (registerValue == 0x15) {
|
if (registerValue == 0x15) {
|
||||||
type = MAX30102;
|
type = MAX30102;
|
||||||
LOG_INFO("MAX30102 Health sensor found");
|
logFoundDevice("MAX30102", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
type = RCWL9620;
|
type = RCWL9620;
|
||||||
LOG_INFO("RCWL9620 sensor found");
|
logFoundDevice("RCWL9620", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LPS22HB_ADDR_ALT:
|
case LPS22HB_ADDR_ALT:
|
||||||
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found")
|
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB", (uint8_t)addr.address)
|
||||||
|
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310", (uint8_t)addr.address)
|
||||||
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found")
|
|
||||||
|
|
||||||
case QMI8658_ADDR:
|
case QMI8658_ADDR:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
|
||||||
if (registerValue == 0xC0) {
|
if (registerValue == 0xC0) {
|
||||||
type = BQ24295;
|
type = BQ24295;
|
||||||
LOG_INFO("BQ24295 PMU found");
|
logFoundDevice("BQ24295", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
|
||||||
if (registerValue == 0x6A) {
|
if (registerValue == 0x6A) {
|
||||||
type = LSM6DS3;
|
type = LSM6DS3;
|
||||||
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
|
logFoundDevice("LSM6DS3", (uint8_t)addr.address);
|
||||||
} else {
|
} else {
|
||||||
type = QMI8658;
|
type = QMI8658;
|
||||||
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found");
|
logFoundDevice("QMI8658", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found")
|
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L", (uint8_t)addr.address)
|
||||||
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found")
|
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L", (uint8_t)addr.address)
|
||||||
#ifdef HAS_QMA6100P
|
#ifdef HAS_QMA6100P
|
||||||
SCAN_SIMPLE_CASE(QMA6100P_ADDR, QMA6100P, "QMA6100P accelerometer found")
|
SCAN_SIMPLE_CASE(QMA6100P_ADDR, QMA6100P, "QMA6100P", (uint8_t)addr.address)
|
||||||
#else
|
#else
|
||||||
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found")
|
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031", (uint8_t)addr.address)
|
||||||
#endif
|
#endif
|
||||||
case BMA423_ADDR: // this can also be LIS3DH_ADDR_ALT
|
case BMA423_ADDR: // this can also be LIS3DH_ADDR_ALT
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
||||||
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
||||||
type = LIS3DH;
|
type = LIS3DH;
|
||||||
LOG_INFO("LIS3DH accelerometer found");
|
logFoundDevice("LIS3DH", (uint8_t)addr.address);
|
||||||
} else {
|
} else {
|
||||||
type = BMA423;
|
type = BMA423;
|
||||||
LOG_INFO("BMA423 accelerometer found");
|
logFoundDevice("BMA423", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found");
|
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found");
|
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found");
|
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found");
|
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found");
|
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found");
|
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found");
|
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found");
|
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found");
|
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
|
||||||
#ifdef HAS_TPS65233
|
#ifdef HAS_TPS65233
|
||||||
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233 BIAS-T found");
|
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case MLX90614_ADDR_DEF:
|
case MLX90614_ADDR_DEF:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1);
|
||||||
if (registerValue == 0x5a) {
|
if (registerValue == 0x5a) {
|
||||||
type = MLX90614;
|
type = MLX90614;
|
||||||
LOG_INFO("MLX90614 IR temp sensor found");
|
logFoundDevice("MLX90614", (uint8_t)addr.address);
|
||||||
} else {
|
} else {
|
||||||
type = MPR121KB;
|
type = MPR121KB;
|
||||||
LOG_INFO("MPR121KB keyboard found");
|
logFoundDevice("MPR121KB", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -466,34 +433,57 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||||
if (registerValue == 0xEA) {
|
if (registerValue == 0xEA) {
|
||||||
type = ICM20948;
|
type = ICM20948;
|
||||||
LOG_INFO("ICM20948 9-dof motion processor found");
|
logFoundDevice("ICM20948", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
} else if (addr.address == BMX160_ADDR) {
|
} else if (addr.address == BMX160_ADDR) {
|
||||||
type = BMX160;
|
type = BMX160;
|
||||||
LOG_INFO("BMX160 accelerometer found");
|
logFoundDevice("BMX160", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
type = MPU6050;
|
type = MPU6050;
|
||||||
LOG_INFO("MPU6050 accelerometer found");
|
logFoundDevice("MPU6050", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CGRADSENS_ADDR:
|
case CGRADSENS_ADDR:
|
||||||
// Register 0x00 of the RadSens sensor contains is product identifier 0x7D
|
// Register 0x00 of the RadSens sensor contains is product identifier 0x7D
|
||||||
|
// Undocumented, but some devices return a product identifier of 0x7A
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||||
if (registerValue == 0x7D) {
|
if (registerValue == 0x7D || registerValue == 0x7A) {
|
||||||
type = CGRADSENS;
|
type = CGRADSENS;
|
||||||
LOG_INFO("ClimateGuard RadSens Geiger-Muller Sensor found");
|
logFoundDevice("ClimateGuard RadSens", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Unexpected Device ID for RadSense: addr=0x%x id=0x%x", CGRADSENS_ADDR, registerValue);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x48: {
|
||||||
|
i2cBus->beginTransmission(addr.address);
|
||||||
|
uint8_t getInfo[] = {0x5A, 0xC0, 0x00, 0xFF, 0xFC};
|
||||||
|
uint8_t expectedInfo[] = {0xa5, 0xE0, 0x00, 0x3F, 0x19};
|
||||||
|
uint8_t info[5];
|
||||||
|
size_t len = 0;
|
||||||
|
i2cBus->write(getInfo, 5);
|
||||||
|
i2cBus->endTransmission();
|
||||||
|
len = i2cBus->readBytes(info, 5);
|
||||||
|
if (len == 5 && memcmp(expectedInfo, info, len) == 0) {
|
||||||
|
LOG_INFO("NXP SE050 crypto chip found");
|
||||||
|
type = NXP_SE050;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG_INFO("FT6336U touchscreen found");
|
||||||
|
type = FT6336U;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
|
LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
} else if (err == 4) {
|
} else if (err == 4) {
|
||||||
LOG_ERROR("Unknown error at address 0x%x", addr.address);
|
LOG_ERROR("Unknown error at address 0x%x", (uint8_t)addr.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a type was found for the enumerated device - save, if so
|
// Check if a type was found for the enumerated device - save, if so
|
||||||
@@ -526,4 +516,9 @@ size_t ScanI2CTwoWire::countDevices() const
|
|||||||
{
|
{
|
||||||
return foundDevices.size();
|
return foundDevices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScanI2CTwoWire::logFoundDevice(const char *device, uint8_t address)
|
||||||
|
{
|
||||||
|
LOG_INFO("%s found at address 0x%x", device, address);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -53,10 +53,10 @@ class ScanI2CTwoWire : public ScanI2C
|
|||||||
|
|
||||||
concurrency::Lock lock;
|
concurrency::Lock lock;
|
||||||
|
|
||||||
void printATECCInfo() const;
|
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth, bool) const;
|
||||||
|
|
||||||
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
|
|
||||||
|
|
||||||
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
||||||
|
|
||||||
|
static void logFoundDevice(const char *device, uint8_t address);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
115
src/gps/GPS.cpp
115
src/gps/GPS.cpp
@@ -28,29 +28,47 @@
|
|||||||
#define GPS_RESET_MODE HIGH
|
#define GPS_RESET_MODE HIGH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Not all platforms have std::size().
|
||||||
|
template <typename T, std::size_t N> std::size_t array_count(const T (&)[N])
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||||
|
#if defined(RAK2560)
|
||||||
|
HardwareSerial *GPS::_serial_gps = &Serial2;
|
||||||
|
#else
|
||||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||||
|
#endif
|
||||||
#elif defined(ARCH_RP2040)
|
#elif defined(ARCH_RP2040)
|
||||||
SerialUART *GPS::_serial_gps = &Serial1;
|
SerialUART *GPS::_serial_gps = &Serial1;
|
||||||
#else
|
#else
|
||||||
HardwareSerial *GPS::_serial_gps = NULL;
|
HardwareSerial *GPS::_serial_gps = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GPS *gps = nullptr;
|
GPS *gps = nullptr;
|
||||||
|
|
||||||
GPSUpdateScheduling scheduling;
|
static const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
|
||||||
|
|
||||||
|
static GPSUpdateScheduling scheduling;
|
||||||
|
|
||||||
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
||||||
/// only init that port once.
|
/// only init that port once.
|
||||||
static bool didSerialInit;
|
static bool didSerialInit;
|
||||||
|
|
||||||
struct uBloxGnssModelInfo info;
|
static struct uBloxGnssModelInfo {
|
||||||
uint8_t uBloxProtocolVersion;
|
char swVersion[30];
|
||||||
|
char hwVersion[10];
|
||||||
|
uint8_t extensionNo;
|
||||||
|
char extension[10][30];
|
||||||
|
uint8_t protocol_version;
|
||||||
|
} ublox_info;
|
||||||
|
|
||||||
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
|
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
|
||||||
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
|
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
|
||||||
|
|
||||||
// For logging
|
// For logging
|
||||||
const char *getGPSPowerStateString(GPSPowerState state)
|
static const char *getGPSPowerStateString(GPSPowerState state)
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case GPS_ACTIVE:
|
case GPS_ACTIVE:
|
||||||
@@ -69,7 +87,7 @@ const char *getGPSPowerStateString(GPSPowerState state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPS::UBXChecksum(uint8_t *message, size_t length)
|
static void UBXChecksum(uint8_t *message, size_t length)
|
||||||
{
|
{
|
||||||
uint8_t CK_A = 0, CK_B = 0;
|
uint8_t CK_A = 0, CK_B = 0;
|
||||||
|
|
||||||
@@ -85,7 +103,7 @@ void GPS::UBXChecksum(uint8_t *message, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the checksum for a CAS packet
|
// Calculate the checksum for a CAS packet
|
||||||
void GPS::CASChecksum(uint8_t *message, size_t length)
|
static void CASChecksum(uint8_t *message, size_t length)
|
||||||
{
|
{
|
||||||
uint32_t cksum = ((uint32_t)message[5] << 24); // Message ID
|
uint32_t cksum = ((uint32_t)message[5] << 24); // Message ID
|
||||||
cksum += ((uint32_t)message[4]) << 16; // Class
|
cksum += ((uint32_t)message[4]) << 16; // Class
|
||||||
@@ -410,6 +428,15 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GPS_BAUDRATE_FIXED
|
||||||
|
// if GPS_BAUDRATE is specified in variant, only try that.
|
||||||
|
static const int serialSpeeds[1] = {GPS_BAUDRATE};
|
||||||
|
static const int rareSerialSpeeds[1] = {GPS_BAUDRATE};
|
||||||
|
#else
|
||||||
|
static const int serialSpeeds[3] = {9600, 115200, 38400};
|
||||||
|
static const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the GPS based on the model detected.
|
* @brief Setup the GPS based on the model detected.
|
||||||
* We detect the GPS by cycling through a set of baud rates, first common then rare.
|
* We detect the GPS by cycling through a set of baud rates, first common then rare.
|
||||||
@@ -419,7 +446,6 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
*/
|
*/
|
||||||
bool GPS::setup()
|
bool GPS::setup()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!didSerialInit) {
|
if (!didSerialInit) {
|
||||||
int msglen = 0;
|
int msglen = 0;
|
||||||
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||||
@@ -427,7 +453,7 @@ bool GPS::setup()
|
|||||||
LOG_DEBUG("Probe for GPS at %d", serialSpeeds[speedSelect]);
|
LOG_DEBUG("Probe for GPS at %d", serialSpeeds[speedSelect]);
|
||||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||||
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
if (++speedSelect == array_count(serialSpeeds)) {
|
||||||
speedSelect = 0;
|
speedSelect = 0;
|
||||||
++probeTries;
|
++probeTries;
|
||||||
}
|
}
|
||||||
@@ -438,7 +464,7 @@ bool GPS::setup()
|
|||||||
LOG_DEBUG("Probe for GPS at %d", rareSerialSpeeds[speedSelect]);
|
LOG_DEBUG("Probe for GPS at %d", rareSerialSpeeds[speedSelect]);
|
||||||
gnssModel = probe(rareSerialSpeeds[speedSelect]);
|
gnssModel = probe(rareSerialSpeeds[speedSelect]);
|
||||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||||
if (++speedSelect == sizeof(rareSerialSpeeds) / sizeof(int)) {
|
if (++speedSelect == array_count(rareSerialSpeeds)) {
|
||||||
LOG_WARN("Give up on GPS probe and set to %d", GPS_BAUDRATE);
|
LOG_WARN("Give up on GPS probe and set to %d", GPS_BAUDRATE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -634,7 +660,7 @@ bool GPS::setup()
|
|||||||
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
|
||||||
|
|
||||||
if (uBloxProtocolVersion >= 18) {
|
if (ublox_info.protocol_version >= 18) {
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "enable powersave for GPS", 500);
|
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "enable powersave for GPS", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersave details for GPS", 500);
|
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersave details for GPS", 500);
|
||||||
@@ -718,6 +744,7 @@ GPS::~GPS()
|
|||||||
// we really should unregister our sleep observer
|
// we really should unregister our sleep observer
|
||||||
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the GPS hardware into a specified state
|
// Put the GPS hardware into a specified state
|
||||||
void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
||||||
{
|
{
|
||||||
@@ -882,17 +909,17 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
|
|||||||
if (gnssModel != GNSS_MODEL_UBLOX10) {
|
if (gnssModel != GNSS_MODEL_UBLOX10) {
|
||||||
// Encode the sleep time in millis into the packet
|
// Encode the sleep time in millis into the packet
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
gps->_message_PMREQ[0 + i] = sleepMs >> (i * 8);
|
_message_PMREQ[0 + i] = sleepMs >> (i * 8);
|
||||||
|
|
||||||
// Record the message length
|
// Record the message length
|
||||||
msglen = gps->makeUBXPacket(0x02, 0x41, sizeof(_message_PMREQ), gps->_message_PMREQ);
|
msglen = gps->makeUBXPacket(0x02, 0x41, sizeof(_message_PMREQ), _message_PMREQ);
|
||||||
} else {
|
} else {
|
||||||
// Encode the sleep time in millis into the packet
|
// Encode the sleep time in millis into the packet
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
gps->_message_PMREQ_10[4 + i] = sleepMs >> (i * 8);
|
_message_PMREQ_10[4 + i] = sleepMs >> (i * 8);
|
||||||
|
|
||||||
// Record the message length
|
// Record the message length
|
||||||
msglen = gps->makeUBXPacket(0x02, 0x41, sizeof(_message_PMREQ_10), gps->_message_PMREQ_10);
|
msglen = gps->makeUBXPacket(0x02, 0x41, sizeof(_message_PMREQ_10), _message_PMREQ_10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the UBX packet
|
// Send the UBX packet
|
||||||
@@ -1099,17 +1126,19 @@ int GPS::prepareDeepSleep(void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *PROBE_MESSAGE = "Trying %s (%s)...";
|
static const char *PROBE_MESSAGE = "Trying %s (%s)...";
|
||||||
const char *DETECTED_MESSAGE = "%s detected, using %s Module";
|
static const char *DETECTED_MESSAGE = "%s detected, using %s Module";
|
||||||
|
|
||||||
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
||||||
|
do { \
|
||||||
LOG_DEBUG(PROBE_MESSAGE, TOWRITE, CHIP); \
|
LOG_DEBUG(PROBE_MESSAGE, TOWRITE, CHIP); \
|
||||||
clearBuffer(); \
|
clearBuffer(); \
|
||||||
_serial_gps->write(TOWRITE "\r\n"); \
|
_serial_gps->write(TOWRITE "\r\n"); \
|
||||||
if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \
|
if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \
|
||||||
LOG_INFO(DETECTED_MESSAGE, CHIP, #DRIVER); \
|
LOG_INFO(DETECTED_MESSAGE, CHIP, #DRIVER); \
|
||||||
return DRIVER; \
|
return DRIVER; \
|
||||||
}
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
GnssModel_t GPS::probe(int serialSpeed)
|
GnssModel_t GPS::probe(int serialSpeed)
|
||||||
{
|
{
|
||||||
@@ -1127,7 +1156,7 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
|
memset(&ublox_info, 0, sizeof(ublox_info));
|
||||||
uint8_t buffer[768] = {0};
|
uint8_t buffer[768] = {0};
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
@@ -1165,6 +1194,8 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
||||||
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
||||||
|
|
||||||
|
PROBE_SIMPLE("LS20031", "$PMTK605*31", "MC-1513", GNSS_MODEL_LS20031, 500);
|
||||||
|
|
||||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
@@ -1194,64 +1225,64 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
if (len) {
|
if (len) {
|
||||||
uint16_t position = 0;
|
uint16_t position = 0;
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
info.swVersion[i] = buffer[position];
|
ublox_info.swVersion[i] = buffer[position];
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
info.hwVersion[i] = buffer[position];
|
ublox_info.hwVersion[i] = buffer[position];
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len >= position + 30) {
|
while (len >= position + 30) {
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
info.extension[info.extensionNo][i] = buffer[position];
|
ublox_info.extension[ublox_info.extensionNo][i] = buffer[position];
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
info.extensionNo++;
|
ublox_info.extensionNo++;
|
||||||
if (info.extensionNo > 9)
|
if (ublox_info.extensionNo > 9)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Module Info : ");
|
LOG_DEBUG("Module Info : ");
|
||||||
LOG_DEBUG("Soft version: %s", info.swVersion);
|
LOG_DEBUG("Soft version: %s", ublox_info.swVersion);
|
||||||
LOG_DEBUG("Hard version: %s", info.hwVersion);
|
LOG_DEBUG("Hard version: %s", ublox_info.hwVersion);
|
||||||
LOG_DEBUG("Extensions:%d", info.extensionNo);
|
LOG_DEBUG("Extensions:%d", ublox_info.extensionNo);
|
||||||
for (int i = 0; i < info.extensionNo; i++) {
|
for (int i = 0; i < ublox_info.extensionNo; i++) {
|
||||||
LOG_DEBUG(" %s", info.extension[i]);
|
LOG_DEBUG(" %s", ublox_info.extension[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
// tips: extensionNo field is 0 on some 6M GNSS modules
|
// tips: extensionNo field is 0 on some 6M GNSS modules
|
||||||
for (int i = 0; i < info.extensionNo; ++i) {
|
for (int i = 0; i < ublox_info.extensionNo; ++i) {
|
||||||
if (!strncmp(info.extension[i], "MOD=", 4)) {
|
if (!strncmp(ublox_info.extension[i], "MOD=", 4)) {
|
||||||
strncpy((char *)buffer, &(info.extension[i][4]), sizeof(buffer));
|
strncpy((char *)buffer, &(ublox_info.extension[i][4]), sizeof(buffer));
|
||||||
} else if (!strncmp(info.extension[i], "PROTVER", 7)) {
|
} else if (!strncmp(ublox_info.extension[i], "PROTVER", 7)) {
|
||||||
char *ptr = nullptr;
|
char *ptr = nullptr;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
strncpy((char *)buffer, &(info.extension[i][8]), sizeof(buffer));
|
strncpy((char *)buffer, &(ublox_info.extension[i][8]), sizeof(buffer));
|
||||||
LOG_DEBUG("Protocol Version:%s", (char *)buffer);
|
LOG_DEBUG("Protocol Version:%s", (char *)buffer);
|
||||||
if (strlen((char *)buffer)) {
|
if (strlen((char *)buffer)) {
|
||||||
uBloxProtocolVersion = strtoul((char *)buffer, &ptr, 10);
|
ublox_info.protocol_version = strtoul((char *)buffer, &ptr, 10);
|
||||||
LOG_DEBUG("ProtVer=%d", uBloxProtocolVersion);
|
LOG_DEBUG("ProtVer=%d", ublox_info.protocol_version);
|
||||||
} else {
|
} else {
|
||||||
uBloxProtocolVersion = 0;
|
ublox_info.protocol_version = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strncmp(info.hwVersion, "00040007", 8) == 0) {
|
if (strncmp(ublox_info.hwVersion, "00040007", 8) == 0) {
|
||||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 6", "6");
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 6", "6");
|
||||||
return GNSS_MODEL_UBLOX6;
|
return GNSS_MODEL_UBLOX6;
|
||||||
} else if (strncmp(info.hwVersion, "00070000", 8) == 0) {
|
} else if (strncmp(ublox_info.hwVersion, "00070000", 8) == 0) {
|
||||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 7", "7");
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 7", "7");
|
||||||
return GNSS_MODEL_UBLOX7;
|
return GNSS_MODEL_UBLOX7;
|
||||||
} else if (strncmp(info.hwVersion, "00080000", 8) == 0) {
|
} else if (strncmp(ublox_info.hwVersion, "00080000", 8) == 0) {
|
||||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 8", "8");
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 8", "8");
|
||||||
return GNSS_MODEL_UBLOX8;
|
return GNSS_MODEL_UBLOX8;
|
||||||
} else if (strncmp(info.hwVersion, "00190000", 8) == 0) {
|
} else if (strncmp(ublox_info.hwVersion, "00190000", 8) == 0) {
|
||||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 9", "9");
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 9", "9");
|
||||||
return GNSS_MODEL_UBLOX9;
|
return GNSS_MODEL_UBLOX9;
|
||||||
} else if (strncmp(info.hwVersion, "000A0000", 8) == 0) {
|
} else if (strncmp(ublox_info.hwVersion, "000A0000", 8) == 0) {
|
||||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 10", "10");
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 10", "10");
|
||||||
return GNSS_MODEL_UBLOX10;
|
return GNSS_MODEL_UBLOX10;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,6 @@
|
|||||||
#define GPS_EN_ACTIVE 1
|
#define GPS_EN_ACTIVE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct uBloxGnssModelInfo {
|
|
||||||
char swVersion[30];
|
|
||||||
char hwVersion[10];
|
|
||||||
uint8_t extensionNo;
|
|
||||||
char extension[10][30];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GNSS_MODEL_ATGM336H,
|
GNSS_MODEL_ATGM336H,
|
||||||
GNSS_MODEL_MTK,
|
GNSS_MODEL_MTK,
|
||||||
@@ -36,7 +29,8 @@ typedef enum {
|
|||||||
GNSS_MODEL_MTK_L76B,
|
GNSS_MODEL_MTK_L76B,
|
||||||
GNSS_MODEL_MTK_PA1616S,
|
GNSS_MODEL_MTK_PA1616S,
|
||||||
GNSS_MODEL_AG3335,
|
GNSS_MODEL_AG3335,
|
||||||
GNSS_MODEL_AG3352
|
GNSS_MODEL_AG3352,
|
||||||
|
GNSS_MODEL_LS20031
|
||||||
} GnssModel_t;
|
} GnssModel_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -54,9 +48,6 @@ enum GPSPowerState : uint8_t {
|
|||||||
GPS_OFF // Powered off indefinitely
|
GPS_OFF // Powered off indefinitely
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a string representation of DOP
|
|
||||||
const char *getDOPString(uint32_t dop);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A gps class that only reads from the GPS periodically and keeps the gps powered down except when reading
|
* A gps class that only reads from the GPS periodically and keeps the gps powered down except when reading
|
||||||
*
|
*
|
||||||
@@ -122,7 +113,9 @@ class GPS : private concurrency::OSThread
|
|||||||
// Let the GPS hardware save power between updates
|
// Let the GPS hardware save power between updates
|
||||||
void down();
|
void down();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
GPS() : concurrency::OSThread("GPS") {}
|
||||||
|
|
||||||
/// Record that we have a GPS
|
/// Record that we have a GPS
|
||||||
void setConnected();
|
void setConnected();
|
||||||
|
|
||||||
@@ -150,9 +143,6 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
|
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
|
||||||
|
|
||||||
private:
|
|
||||||
GPS() : concurrency::OSThread("GPS") {}
|
|
||||||
|
|
||||||
TinyGPSPlus reader;
|
TinyGPSPlus reader;
|
||||||
uint8_t fixQual = 0; // fix quality from GPGGA
|
uint8_t fixQual = 0; // fix quality from GPGGA
|
||||||
uint32_t lastChecksumFailCount = 0;
|
uint32_t lastChecksumFailCount = 0;
|
||||||
@@ -164,21 +154,13 @@ class GPS : private concurrency::OSThread
|
|||||||
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
|
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
|
||||||
uint8_t fixType = 0; // fix type from GPGSA
|
uint8_t fixType = 0; // fix type from GPGSA
|
||||||
#endif
|
#endif
|
||||||
#if GPS_BAUDRATE_FIXED
|
|
||||||
// if GPS_BAUDRATE is specified in variant, only try that.
|
|
||||||
const int serialSpeeds[1] = {GPS_BAUDRATE};
|
|
||||||
const int rareSerialSpeeds[1] = {GPS_BAUDRATE};
|
|
||||||
#else
|
|
||||||
const int serialSpeeds[3] = {9600, 115200, 38400};
|
|
||||||
const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
|
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
|
||||||
uint32_t rx_gpio = 0;
|
uint32_t rx_gpio = 0;
|
||||||
uint32_t tx_gpio = 0;
|
uint32_t tx_gpio = 0;
|
||||||
|
|
||||||
int speedSelect = 0;
|
uint8_t speedSelect = 0;
|
||||||
int probeTries = 0;
|
uint8_t probeTries = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hasValidLocation - indicates that the position variables contain a complete
|
* hasValidLocation - indicates that the position variables contain a complete
|
||||||
@@ -207,52 +189,6 @@ class GPS : private concurrency::OSThread
|
|||||||
#else
|
#else
|
||||||
static HardwareSerial *_serial_gps;
|
static HardwareSerial *_serial_gps;
|
||||||
#endif
|
#endif
|
||||||
static uint8_t _message_PMREQ[];
|
|
||||||
static uint8_t _message_PMREQ_10[];
|
|
||||||
static const uint8_t _message_CFG_RXM_PSM[];
|
|
||||||
static const uint8_t _message_CFG_RXM_ECO[];
|
|
||||||
static const uint8_t _message_CFG_PM2[];
|
|
||||||
static const uint8_t _message_GNSS_7[];
|
|
||||||
static const uint8_t _message_GNSS_8[];
|
|
||||||
static const uint8_t _message_JAM_6_7[];
|
|
||||||
static const uint8_t _message_JAM_8[];
|
|
||||||
static const uint8_t _message_NAVX5[];
|
|
||||||
static const uint8_t _message_NAVX5_8[];
|
|
||||||
static const uint8_t _message_NMEA[];
|
|
||||||
static const uint8_t _message_DISABLE_TXT_INFO[];
|
|
||||||
static const uint8_t _message_1HZ[];
|
|
||||||
static const uint8_t _message_GLL[];
|
|
||||||
static const uint8_t _message_GSA[];
|
|
||||||
static const uint8_t _message_GSV[];
|
|
||||||
static const uint8_t _message_VTG[];
|
|
||||||
static const uint8_t _message_RMC[];
|
|
||||||
static const uint8_t _message_AID[];
|
|
||||||
static const uint8_t _message_GGA[];
|
|
||||||
static const uint8_t _message_PMS[];
|
|
||||||
static const uint8_t _message_SAVE[];
|
|
||||||
static const uint8_t _message_SAVE_10[];
|
|
||||||
|
|
||||||
// VALSET Commands for M10
|
|
||||||
static const uint8_t _message_VALSET_PM[];
|
|
||||||
static const uint8_t _message_VALSET_PM_RAM[];
|
|
||||||
static const uint8_t _message_VALSET_PM_BBR[];
|
|
||||||
static const uint8_t _message_VALSET_ITFM_RAM[];
|
|
||||||
static const uint8_t _message_VALSET_ITFM_BBR[];
|
|
||||||
static const uint8_t _message_VALSET_DISABLE_NMEA_RAM[];
|
|
||||||
static const uint8_t _message_VALSET_DISABLE_NMEA_BBR[];
|
|
||||||
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_RAM[];
|
|
||||||
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_BBR[];
|
|
||||||
static const uint8_t _message_VALSET_ENABLE_NMEA_RAM[];
|
|
||||||
static const uint8_t _message_VALSET_ENABLE_NMEA_BBR[];
|
|
||||||
static const uint8_t _message_VALSET_DISABLE_SBAS_RAM[];
|
|
||||||
static const uint8_t _message_VALSET_DISABLE_SBAS_BBR[];
|
|
||||||
|
|
||||||
// CASIC commands for ATGM336H
|
|
||||||
static const uint8_t _message_CAS_CFG_RST_FACTORY[];
|
|
||||||
static const uint8_t _message_CAS_CFG_NAVX_CONF[];
|
|
||||||
static const uint8_t _message_CAS_CFG_RATE_1HZ[];
|
|
||||||
|
|
||||||
const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
|
|
||||||
|
|
||||||
// Create a ublox packet for editing in memory
|
// Create a ublox packet for editing in memory
|
||||||
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
|
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
|
||||||
@@ -273,10 +209,6 @@ class GPS : private concurrency::OSThread
|
|||||||
/// always returns 0 to indicate okay to sleep
|
/// always returns 0 to indicate okay to sleep
|
||||||
int prepareDeepSleep(void *unused);
|
int prepareDeepSleep(void *unused);
|
||||||
|
|
||||||
// Calculate checksum
|
|
||||||
void UBXChecksum(uint8_t *message, size_t length);
|
|
||||||
void CASChecksum(uint8_t *message, size_t length);
|
|
||||||
|
|
||||||
/** Set power with EN pin, if relevant
|
/** Set power with EN pin, if relevant
|
||||||
*/
|
*/
|
||||||
void writePinEN(bool on);
|
void writePinEN(bool on);
|
||||||
@@ -305,8 +237,6 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
// delay counter to allow more sats before fixed position stops GPS thread
|
// delay counter to allow more sats before fixed position stops GPS thread
|
||||||
uint8_t fixeddelayCtr = 0;
|
uint8_t fixeddelayCtr = 0;
|
||||||
|
|
||||||
const char *powerStateToString();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GPS *gps;
|
extern GPS *gps;
|
||||||
|
|||||||
@@ -574,3 +574,23 @@ const char *GeoCoord::degreesToBearing(unsigned int degrees)
|
|||||||
else
|
else
|
||||||
return "N";
|
return "N";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GeoCoord::pow_neg(double base, double exponent)
|
||||||
|
{
|
||||||
|
if (exponent == 0) {
|
||||||
|
return 1;
|
||||||
|
} else if (exponent > 0) {
|
||||||
|
return pow(base, exponent);
|
||||||
|
}
|
||||||
|
return 1 / pow(base, -exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
double GeoCoord::toRadians(double deg)
|
||||||
|
{
|
||||||
|
return deg * PI / 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
double GeoCoord::toDegrees(double r)
|
||||||
|
{
|
||||||
|
return r * 180 / PI;
|
||||||
|
}
|
||||||
@@ -13,28 +13,6 @@
|
|||||||
#define OLC_CODE_LEN 11
|
#define OLC_CODE_LEN 11
|
||||||
#define DEG_CONVERT (180 / PI)
|
#define DEG_CONVERT (180 / PI)
|
||||||
|
|
||||||
// Helper functions
|
|
||||||
// Raises a number to an exponent, handling negative exponents.
|
|
||||||
static inline double pow_neg(double base, double exponent)
|
|
||||||
{
|
|
||||||
if (exponent == 0) {
|
|
||||||
return 1;
|
|
||||||
} else if (exponent > 0) {
|
|
||||||
return pow(base, exponent);
|
|
||||||
}
|
|
||||||
return 1 / pow(base, -exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double toRadians(double deg)
|
|
||||||
{
|
|
||||||
return deg * PI / 180;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double toDegrees(double r)
|
|
||||||
{
|
|
||||||
return r * 180 / PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GeoCoord structs/classes
|
// GeoCoord structs/classes
|
||||||
// A struct to hold the data for a DMS coordinate.
|
// A struct to hold the data for a DMS coordinate.
|
||||||
struct DMS {
|
struct DMS {
|
||||||
@@ -120,6 +98,11 @@ class GeoCoord
|
|||||||
static unsigned int bearingToDegrees(const char *bearing);
|
static unsigned int bearingToDegrees(const char *bearing);
|
||||||
static const char *degreesToBearing(unsigned int degrees);
|
static const char *degreesToBearing(unsigned int degrees);
|
||||||
|
|
||||||
|
// Raises a number to an exponent, handling negative exponents.
|
||||||
|
static double pow_neg(double base, double exponent);
|
||||||
|
static double toRadians(double deg);
|
||||||
|
static double toDegrees(double r);
|
||||||
|
|
||||||
// Point to point conversions
|
// Point to point conversions
|
||||||
int32_t distanceTo(const GeoCoord &pointB);
|
int32_t distanceTo(const GeoCoord &pointB);
|
||||||
int32_t bearingTo(const GeoCoord &pointB);
|
int32_t bearingTo(const GeoCoord &pointB);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
// CFG-RST (0x06, 0x02)
|
// CFG-RST (0x06, 0x02)
|
||||||
// Factory reset
|
// Factory reset
|
||||||
const uint8_t GPS::_message_CAS_CFG_RST_FACTORY[] = {
|
static const uint8_t _message_CAS_CFG_RST_FACTORY[] = {
|
||||||
0xFF, 0x03, // Fields to clear
|
0xFF, 0x03, // Fields to clear
|
||||||
0x01, // Reset Mode: Controlled Software reset
|
0x01, // Reset Mode: Controlled Software reset
|
||||||
0x03 // Startup Mode: Factory
|
0x03 // Startup Mode: Factory
|
||||||
@@ -30,7 +30,7 @@ const uint8_t GPS::_message_CAS_CFG_RST_FACTORY[] = {
|
|||||||
// CFG_RATE (0x06, 0x01)
|
// CFG_RATE (0x06, 0x01)
|
||||||
// 1HZ update rate, this should always be the case after
|
// 1HZ update rate, this should always be the case after
|
||||||
// factory reset but update it regardless
|
// factory reset but update it regardless
|
||||||
const uint8_t GPS::_message_CAS_CFG_RATE_1HZ[] = {
|
static const uint8_t _message_CAS_CFG_RATE_1HZ[] = {
|
||||||
0xE8, 0x03, // Update Rate: 0x03E8 = 1000ms
|
0xE8, 0x03, // Update Rate: 0x03E8 = 1000ms
|
||||||
0x00, 0x00 // Reserved
|
0x00, 0x00 // Reserved
|
||||||
};
|
};
|
||||||
@@ -39,7 +39,7 @@ const uint8_t GPS::_message_CAS_CFG_RATE_1HZ[] = {
|
|||||||
// Initial ATGM33H-5N configuration, Updates for Dynamic Mode, Fix Mode, and SV system
|
// Initial ATGM33H-5N configuration, Updates for Dynamic Mode, Fix Mode, and SV system
|
||||||
// Qwirk: The ATGM33H-5N-31 should only support GPS+BDS, however it will happily enable
|
// Qwirk: The ATGM33H-5N-31 should only support GPS+BDS, however it will happily enable
|
||||||
// and use GPS+BDS+GLONASS iff the correct CFG_NAVX command is used.
|
// and use GPS+BDS+GLONASS iff the correct CFG_NAVX command is used.
|
||||||
const uint8_t GPS::_message_CAS_CFG_NAVX_CONF[] = {
|
static const uint8_t _message_CAS_CFG_NAVX_CONF[] = {
|
||||||
0x03, 0x01, 0x00, 0x00, // Update Mask: Dynamic Mode, Fix Mode, Nav Settings
|
0x03, 0x01, 0x00, 0x00, // Update Mask: Dynamic Mode, Fix Mode, Nav Settings
|
||||||
0x03, // Dynamic Mode: Automotive
|
0x03, // Dynamic Mode: Automotive
|
||||||
0x03, // Fix Mode: Auto 2D/3D
|
0x03, // Fix Mode: Auto 2D/3D
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
const char *failMessage = "Unable to %s";
|
static const char *failMessage = "Unable to %s";
|
||||||
|
|
||||||
#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \
|
#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \
|
||||||
|
do { \
|
||||||
msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \
|
msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \
|
||||||
_serial_gps->write(UBXscratch, msglen); \
|
_serial_gps->write(UBXscratch, msglen); \
|
||||||
if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) { \
|
if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) { \
|
||||||
LOG_WARN(failMessage, #ERRMSG); \
|
LOG_WARN(failMessage, #ERRMSG); \
|
||||||
}
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// Power Management
|
// Power Management
|
||||||
|
|
||||||
uint8_t GPS::_message_PMREQ[] PROGMEM = {
|
static uint8_t _message_PMREQ[] PROGMEM = {
|
||||||
0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
|
0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
|
||||||
0x02, 0x00, 0x00, 0x00 // Bitfield, set backup = 1
|
0x02, 0x00, 0x00, 0x00 // Bitfield, set backup = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t GPS::_message_PMREQ_10[] PROGMEM = {
|
static uint8_t _message_PMREQ_10[] PROGMEM = {
|
||||||
0x00, // version (0 for this version)
|
0x00, // version (0 for this version)
|
||||||
0x00, 0x00, 0x00, // Reserved 1
|
0x00, 0x00, 0x00, // Reserved 1
|
||||||
0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
|
0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
|
||||||
@@ -22,18 +24,18 @@ uint8_t GPS::_message_PMREQ_10[] PROGMEM = {
|
|||||||
0x08, 0x00, 0x00, 0x00 // wakeupSources Wake on uartrx
|
0x08, 0x00, 0x00, 0x00 // wakeupSources Wake on uartrx
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = {
|
static const uint8_t _message_CFG_RXM_PSM[] PROGMEM = {
|
||||||
0x08, // Reserved
|
0x08, // Reserved
|
||||||
0x01 // Power save mode
|
0x01 // Power save mode
|
||||||
};
|
};
|
||||||
|
|
||||||
// only for Neo-6
|
// only for Neo-6
|
||||||
const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = {
|
static const uint8_t _message_CFG_RXM_ECO[] PROGMEM = {
|
||||||
0x08, // Reserved
|
0x08, // Reserved
|
||||||
0x04 // eco mode
|
0x04 // eco mode
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
|
static const uint8_t _message_CFG_PM2[] PROGMEM = {
|
||||||
0x01, // version
|
0x01, // version
|
||||||
0x00, // Reserved 1, set to 0x06 by u-Center
|
0x00, // Reserved 1, set to 0x06 by u-Center
|
||||||
0x00, // Reserved 2
|
0x00, // Reserved 2
|
||||||
@@ -58,7 +60,7 @@ const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
|
|||||||
// Constallation setup, none required for Neo-6
|
// Constallation setup, none required for Neo-6
|
||||||
|
|
||||||
// For Neo-7 GPS & SBAS
|
// For Neo-7 GPS & SBAS
|
||||||
const uint8_t GPS::_message_GNSS_7[] = {
|
static const uint8_t _message_GNSS_7[] = {
|
||||||
0x00, // msgVer (0 for this version)
|
0x00, // msgVer (0 for this version)
|
||||||
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||||
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
||||||
@@ -76,7 +78,7 @@ const uint8_t GPS::_message_GNSS_7[] = {
|
|||||||
// There is also a possibility that the module may be GPS-only.
|
// There is also a possibility that the module may be GPS-only.
|
||||||
|
|
||||||
// For M8 GPS, GLONASS, Galileo, SBAS, QZSS
|
// For M8 GPS, GLONASS, Galileo, SBAS, QZSS
|
||||||
const uint8_t GPS::_message_GNSS_8[] = {
|
static const uint8_t _message_GNSS_8[] = {
|
||||||
0x00, // msgVer (0 for this version)
|
0x00, // msgVer (0 for this version)
|
||||||
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||||
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
||||||
@@ -90,7 +92,7 @@ const uint8_t GPS::_message_GNSS_8[] = {
|
|||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
// For M8 GPS, GLONASS, BeiDou, SBAS, QZSS
|
// For M8 GPS, GLONASS, BeiDou, SBAS, QZSS
|
||||||
const uint8_t GPS::_message_GNSS_8_B[] = {
|
static const uint8_t _message_GNSS_8_B[] = {
|
||||||
0x00, // msgVer (0 for this version)
|
0x00, // msgVer (0 for this version)
|
||||||
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||||
0xff, // numTrkChUse (max number of channels to use, 0xff = max available) read only for protocol >23
|
0xff, // numTrkChUse (max number of channels to use, 0xff = max available) read only for protocol >23
|
||||||
@@ -105,7 +107,7 @@ const uint8_t GPS::_message_GNSS_8_B[] = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// For M8 we want to enable NMEA version 4.10 messages to allow for Galileo and or BeiDou
|
// For M8 we want to enable NMEA version 4.10 messages to allow for Galileo and or BeiDou
|
||||||
const uint8_t GPS::_message_NMEA[]{
|
static const uint8_t _message_NMEA[]{
|
||||||
0x00, // filter flags
|
0x00, // filter flags
|
||||||
0x41, // NMEA Version
|
0x41, // NMEA Version
|
||||||
0x00, // Max number of SVs to report per TaklerId
|
0x00, // Max number of SVs to report per TaklerId
|
||||||
@@ -121,13 +123,13 @@ const uint8_t GPS::_message_NMEA[]{
|
|||||||
// Enable jamming/interference monitor
|
// Enable jamming/interference monitor
|
||||||
|
|
||||||
// For Neo-6, Max-7 and Neo-7
|
// For Neo-6, Max-7 and Neo-7
|
||||||
const uint8_t GPS::_message_JAM_6_7[] = {
|
static const uint8_t _message_JAM_6_7[] = {
|
||||||
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable = 1, reserved bits 0x16B156
|
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable = 1, reserved bits 0x16B156
|
||||||
0x1e, 0x03, 0x00, 0x00 // config2 antennaSetting Unknown = 0, reserved 3, = 0x00,0x00, reserved 2 = 0x31E
|
0x1e, 0x03, 0x00, 0x00 // config2 antennaSetting Unknown = 0, reserved 3, = 0x00,0x00, reserved 2 = 0x31E
|
||||||
};
|
};
|
||||||
|
|
||||||
// For M8
|
// For M8
|
||||||
const uint8_t GPS::_message_JAM_8[] = {
|
static const uint8_t _message_JAM_8[] = {
|
||||||
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable1 = 1, reserved bits 0x16B156
|
0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable1 = 1, reserved bits 0x16B156
|
||||||
0x1e, 0x43, 0x00, 0x00 // config2 antennaSetting Unknown = 0, enable2 = 1, generalBits = 0x31E
|
0x1e, 0x43, 0x00, 0x00 // config2 antennaSetting Unknown = 0, enable2 = 1, generalBits = 0x31E
|
||||||
};
|
};
|
||||||
@@ -137,7 +139,7 @@ const uint8_t GPS::_message_JAM_8[] = {
|
|||||||
// ToDo: check UBX-MON-VER for module type and protocol version
|
// ToDo: check UBX-MON-VER for module type and protocol version
|
||||||
|
|
||||||
// For the Neo-6
|
// For the Neo-6
|
||||||
const uint8_t GPS::_message_NAVX5[] = {
|
static const uint8_t _message_NAVX5[] = {
|
||||||
0x00, 0x00, // msgVer (0 for this version)
|
0x00, 0x00, // msgVer (0 for this version)
|
||||||
0x4c, 0x66, // mask1
|
0x4c, 0x66, // mask1
|
||||||
0x00, 0x00, 0x00, 0x00, // Reserved 0
|
0x00, 0x00, 0x00, 0x00, // Reserved 0
|
||||||
@@ -166,7 +168,7 @@ const uint8_t GPS::_message_NAVX5[] = {
|
|||||||
0x00, 0x00, 0x00, 0x00 // Reserved 4
|
0x00, 0x00, 0x00, 0x00 // Reserved 4
|
||||||
};
|
};
|
||||||
// For the M8
|
// For the M8
|
||||||
const uint8_t GPS::_message_NAVX5_8[] = {
|
static const uint8_t _message_NAVX5_8[] = {
|
||||||
0x02, 0x00, // msgVer (2 for this version)
|
0x02, 0x00, // msgVer (2 for this version)
|
||||||
0x4c, 0x66, // mask1
|
0x4c, 0x66, // mask1
|
||||||
0x00, 0x00, 0x00, 0x00, // mask2
|
0x00, 0x00, 0x00, 0x00, // mask2
|
||||||
@@ -197,7 +199,7 @@ const uint8_t GPS::_message_NAVX5_8[] = {
|
|||||||
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
|
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
|
||||||
// is recommended to avoid a known issue with satellites disappearing.
|
// is recommended to avoid a known issue with satellites disappearing.
|
||||||
// The module defaults for M8, M9, M10 are the same as we use here so no update is necessary
|
// The module defaults for M8, M9, M10 are the same as we use here so no update is necessary
|
||||||
const uint8_t GPS::_message_1HZ[] = {
|
static const uint8_t _message_1HZ[] = {
|
||||||
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
|
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
|
||||||
0x01, 0x00, // Navigation rate, always 1 in GPS mode
|
0x01, 0x00, // Navigation rate, always 1 in GPS mode
|
||||||
0x01, 0x00 // Time reference
|
0x01, 0x00 // Time reference
|
||||||
@@ -205,7 +207,7 @@ const uint8_t GPS::_message_1HZ[] = {
|
|||||||
|
|
||||||
// Disable GLL. GLL - Geographic position (latitude and longitude), which provides the current geographical
|
// Disable GLL. GLL - Geographic position (latitude and longitude), which provides the current geographical
|
||||||
// coordinates.
|
// coordinates.
|
||||||
const uint8_t GPS::_message_GLL[] = {
|
static const uint8_t _message_GLL[] = {
|
||||||
0xF0, 0x01, // NMEA ID for GLL
|
0xF0, 0x01, // NMEA ID for GLL
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x00, // Rate for UART1
|
0x00, // Rate for UART1
|
||||||
@@ -217,7 +219,7 @@ const uint8_t GPS::_message_GLL[] = {
|
|||||||
|
|
||||||
// Disable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
|
// Disable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
|
||||||
// the DOP (Dilution of Precision)
|
// the DOP (Dilution of Precision)
|
||||||
const uint8_t GPS::_message_GSA[] = {
|
static const uint8_t _message_GSA[] = {
|
||||||
0xF0, 0x02, // NMEA ID for GSA
|
0xF0, 0x02, // NMEA ID for GSA
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x00, // Rate for UART1
|
0x00, // Rate for UART1
|
||||||
@@ -228,7 +230,7 @@ const uint8_t GPS::_message_GSA[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
|
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
|
||||||
const uint8_t GPS::_message_GSV[] = {
|
static const uint8_t _message_GSV[] = {
|
||||||
0xF0, 0x03, // NMEA ID for GSV
|
0xF0, 0x03, // NMEA ID for GSV
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x00, // Rate for UART1
|
0x00, // Rate for UART1
|
||||||
@@ -240,7 +242,7 @@ const uint8_t GPS::_message_GSV[] = {
|
|||||||
|
|
||||||
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
|
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
|
||||||
// the ground.
|
// the ground.
|
||||||
const uint8_t GPS::_message_VTG[] = {
|
static const uint8_t _message_VTG[] = {
|
||||||
0xF0, 0x05, // NMEA ID for VTG
|
0xF0, 0x05, // NMEA ID for VTG
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x00, // Rate for UART1
|
0x00, // Rate for UART1
|
||||||
@@ -251,7 +253,7 @@ const uint8_t GPS::_message_VTG[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
|
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
|
||||||
const uint8_t GPS::_message_RMC[] = {
|
static const uint8_t _message_RMC[] = {
|
||||||
0xF0, 0x04, // NMEA ID for RMC
|
0xF0, 0x04, // NMEA ID for RMC
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x01, // Rate for UART1
|
0x01, // Rate for UART1
|
||||||
@@ -262,7 +264,7 @@ const uint8_t GPS::_message_RMC[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
|
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
|
||||||
const uint8_t GPS::_message_GGA[] = {
|
static const uint8_t _message_GGA[] = {
|
||||||
0xF0, 0x00, // NMEA ID for GGA
|
0xF0, 0x00, // NMEA ID for GGA
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x01, // Rate for UART1
|
0x01, // Rate for UART1
|
||||||
@@ -274,7 +276,7 @@ const uint8_t GPS::_message_GGA[] = {
|
|||||||
|
|
||||||
// Disable UBX-AID-ALPSRV as it may confuse TinyGPS. The Neo-6 seems to send this message
|
// Disable UBX-AID-ALPSRV as it may confuse TinyGPS. The Neo-6 seems to send this message
|
||||||
// whether the AID Autonomous is enabled or not
|
// whether the AID Autonomous is enabled or not
|
||||||
const uint8_t GPS::_message_AID[] = {
|
static const uint8_t _message_AID[] = {
|
||||||
0x0B, 0x32, // NMEA ID for UBX-AID-ALPSRV
|
0x0B, 0x32, // NMEA ID for UBX-AID-ALPSRV
|
||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x00, // Rate for UART1
|
0x00, // Rate for UART1
|
||||||
@@ -287,7 +289,7 @@ const uint8_t GPS::_message_AID[] = {
|
|||||||
// Turn off TEXT INFO Messages for all but M10 series
|
// Turn off TEXT INFO Messages for all but M10 series
|
||||||
|
|
||||||
// B5 62 06 02 0A 00 01 00 00 00 03 03 00 03 03 00 1F 20
|
// B5 62 06 02 0A 00 01 00 00 00 03 03 00 03 03 00 1F 20
|
||||||
const uint8_t GPS::_message_DISABLE_TXT_INFO[] = {
|
static const uint8_t _message_DISABLE_TXT_INFO[] = {
|
||||||
0x01, // Protocol ID for NMEA
|
0x01, // Protocol ID for NMEA
|
||||||
0x00, 0x00, 0x00, // Reserved
|
0x00, 0x00, 0x00, // Reserved
|
||||||
0x03, // I2C
|
0x03, // I2C
|
||||||
@@ -310,7 +312,7 @@ const uint8_t GPS::_message_DISABLE_TXT_INFO[] = {
|
|||||||
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
|
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
|
||||||
// it must be set to '0'.
|
// it must be set to '0'.
|
||||||
// This command applies to M8 products
|
// This command applies to M8 products
|
||||||
const uint8_t GPS::_message_PMS[] = {
|
static const uint8_t _message_PMS[] = {
|
||||||
0x00, // Version (0)
|
0x00, // Version (0)
|
||||||
0x03, // Power setup value 3 = Agresssive 1Hz
|
0x03, // Power setup value 3 = Agresssive 1Hz
|
||||||
0x00, 0x00, // period: not applicable, set to 0
|
0x00, 0x00, // period: not applicable, set to 0
|
||||||
@@ -318,14 +320,14 @@ const uint8_t GPS::_message_PMS[] = {
|
|||||||
0x00, 0x00 // reserved, generated by u-center
|
0x00, 0x00 // reserved, generated by u-center
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t GPS::_message_SAVE[] = {
|
static const uint8_t _message_SAVE[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
||||||
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||||
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||||
0x17 // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
0x17 // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t GPS::_message_SAVE_10[] = {
|
static const uint8_t _message_SAVE_10[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
||||||
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||||
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||||
@@ -375,10 +377,10 @@ LIMITPEAKCURRENT L 1
|
|||||||
// b5 62 06 8a 26 00 00 02 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0
|
// b5 62 06 8a 26 00 00 02 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0
|
||||||
// 10 01 8c 03
|
// 10 01 8c 03
|
||||||
*/
|
*/
|
||||||
const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40,
|
static const uint8_t _message_VALSET_PM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40,
|
||||||
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0,
|
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0,
|
||||||
0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01};
|
0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01};
|
||||||
const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40,
|
static const uint8_t _message_VALSET_PM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40,
|
||||||
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0,
|
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0,
|
||||||
0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01};
|
0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01};
|
||||||
|
|
||||||
@@ -394,9 +396,9 @@ CFG-ITFM replaced by 5 valset messages which can be combined into one for RAM an
|
|||||||
|
|
||||||
b5 62 06 8a 0e 00 00 01 00 00 0d 00 41 10 01 13 00 41 10 01 63 c6
|
b5 62 06 8a 0e 00 00 01 00 00 0d 00 41 10 01 13 00 41 10 01 63 c6
|
||||||
*/
|
*/
|
||||||
const uint8_t GPS::_message_VALSET_ITFM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x41,
|
static const uint8_t _message_VALSET_ITFM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x41,
|
||||||
0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};
|
0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};
|
||||||
const uint8_t GPS::_message_VALSET_ITFM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x0d, 0x00, 0x41,
|
static const uint8_t _message_VALSET_ITFM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x0d, 0x00, 0x41,
|
||||||
0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};
|
0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};
|
||||||
|
|
||||||
// Turn off all NMEA messages:
|
// Turn off all NMEA messages:
|
||||||
@@ -407,12 +409,12 @@ const uint8_t GPS::_message_VALSET_ITFM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x0d, 0
|
|||||||
// BBR layer config message:
|
// BBR layer config message:
|
||||||
// b5 62 06 8a 13 00 00 02 00 00 ca 00 91 20 00 c5 00 91 20 00 b1 00 91 20 00 f8 4e
|
// b5 62 06 8a 13 00 00 02 00 00 ca 00 91 20 00 c5 00 91 20 00 b1 00 91 20 00 f8 4e
|
||||||
|
|
||||||
const uint8_t GPS::_message_VALSET_DISABLE_NMEA_RAM[] = {
|
static const uint8_t _message_VALSET_DISABLE_NMEA_RAM[] = {
|
||||||
/*0x00, 0x01, 0x00, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5, 0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00 */
|
/*0x00, 0x01, 0x00, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5, 0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00 */
|
||||||
0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x91, 0x20, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5, 0x00, 0x91,
|
0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x91, 0x20, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5, 0x00, 0x91,
|
||||||
0x20, 0x00, 0xac, 0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00, 0xbb, 0x00, 0x91, 0x20, 0x00};
|
0x20, 0x00, 0xac, 0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00, 0xbb, 0x00, 0x91, 0x20, 0x00};
|
||||||
|
|
||||||
const uint8_t GPS::_message_VALSET_DISABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5,
|
static const uint8_t _message_VALSET_DISABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5,
|
||||||
0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00};
|
0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00};
|
||||||
|
|
||||||
// Turn off text info messages:
|
// Turn off text info messages:
|
||||||
@@ -432,16 +434,16 @@ const uint8_t GPS::_message_VALSET_DISABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00,
|
|||||||
// b5 62 06 8a 0e 00 00 04 00 00 bb 00 91 20 01 ac 00 91 20 01 6d b6
|
// b5 62 06 8a 0e 00 00 04 00 00 bb 00 91 20 01 ac 00 91 20 01 6d b6
|
||||||
// Doing this for the FLASH layer isn't really required since we save the config to flash later
|
// Doing this for the FLASH layer isn't really required since we save the config to flash later
|
||||||
|
|
||||||
const uint8_t GPS::_message_VALSET_DISABLE_TXT_INFO_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
|
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
|
||||||
const uint8_t GPS::_message_VALSET_DISABLE_TXT_INFO_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
|
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
|
||||||
|
|
||||||
const uint8_t GPS::_message_VALSET_ENABLE_NMEA_RAM[] = {0x00, 0x01, 0x00, 0x00, 0xbb, 0x00, 0x91,
|
static const uint8_t _message_VALSET_ENABLE_NMEA_RAM[] = {0x00, 0x01, 0x00, 0x00, 0xbb, 0x00, 0x91,
|
||||||
0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
|
0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
|
||||||
const uint8_t GPS::_message_VALSET_ENABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xbb, 0x00, 0x91,
|
static const uint8_t _message_VALSET_ENABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xbb, 0x00, 0x91,
|
||||||
0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
|
0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
|
||||||
const uint8_t GPS::_message_VALSET_DISABLE_SBAS_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x31,
|
static const uint8_t _message_VALSET_DISABLE_SBAS_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x31,
|
||||||
0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};
|
0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};
|
||||||
const uint8_t GPS::_message_VALSET_DISABLE_SBAS_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x31,
|
static const uint8_t _message_VALSET_DISABLE_SBAS_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x31,
|
||||||
0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};
|
0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "../userPrefs.h"
|
|
||||||
#include "PowerMon.h"
|
#include "PowerMon.h"
|
||||||
#include "Throttle.h"
|
#include "Throttle.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
@@ -127,7 +126,7 @@ static bool heartbeat = false;
|
|||||||
/// Check if the display can render a string (detect special chars; emoji)
|
/// Check if the display can render a string (detect special chars; emoji)
|
||||||
static bool haveGlyphs(const char *str)
|
static bool haveGlyphs(const char *str)
|
||||||
{
|
{
|
||||||
#if defined(OLED_PL) || defined(OLED_UA) || defined(OLED_RU)
|
#if defined(OLED_PL) || defined(OLED_UA) || defined(OLED_RU) || defined(OLED_CS)
|
||||||
// Don't want to make any assumptions about custom language support
|
// Don't want to make any assumptions about custom language support
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
@@ -1016,7 +1015,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
|||||||
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
|
||||||
} else if (strcmp(msg, "♥️") == 0 || strcmp(msg, "\U0001F9E1") == 0 || strcmp(msg, "\U00002763") == 0 ||
|
} else if (strcmp(msg, "♥️") == 0 || strcmp(msg, "\U0001F9E1") == 0 || strcmp(msg, "\U00002763") == 0 ||
|
||||||
strcmp(msg, "\U00002764") == 0 || strcmp(msg, "\U0001F495") == 0 || strcmp(msg, "\U0001F496") == 0 ||
|
strcmp(msg, "\U00002764") == 0 || strcmp(msg, "\U0001F495") == 0 || strcmp(msg, "\U0001F496") == 0 ||
|
||||||
strcmp(msg, "\U0001F497") == 0 || strcmp(msg, "\U0001F496") == 0) {
|
strcmp(msg, "\U0001F497") == 0 || strcmp(msg, "\U0001F498") == 0) {
|
||||||
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
|
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
|
||||||
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
|
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
|
||||||
} else {
|
} else {
|
||||||
@@ -1420,7 +1419,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
}
|
}
|
||||||
bool hasNodeHeading = false;
|
bool hasNodeHeading = false;
|
||||||
|
|
||||||
if (ourNode && (hasValidPosition(ourNode) || screen->hasHeading())) {
|
if (ourNode && (nodeDB->hasValidPosition(ourNode) || screen->hasHeading())) {
|
||||||
const meshtastic_PositionLite &op = ourNode->position;
|
const meshtastic_PositionLite &op = ourNode->position;
|
||||||
float myHeading;
|
float myHeading;
|
||||||
if (screen->hasHeading())
|
if (screen->hasHeading())
|
||||||
@@ -1429,7 +1428,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
||||||
|
|
||||||
if (hasValidPosition(node)) {
|
if (nodeDB->hasValidPosition(node)) {
|
||||||
// display direction toward node
|
// display direction toward node
|
||||||
hasNodeHeading = true;
|
hasNodeHeading = true;
|
||||||
const meshtastic_PositionLite &p = node->position;
|
const meshtastic_PositionLite &p = node->position;
|
||||||
@@ -1507,7 +1506,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
#elif defined(USE_ST7567)
|
#elif defined(USE_ST7567)
|
||||||
dispdev = new ST7567Wire(address.address, -1, -1, geometry,
|
dispdev = new ST7567Wire(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO && !HAS_TFT
|
||||||
if (settingsMap[displayPanel] != no_screen) {
|
if (settingsMap[displayPanel] != no_screen) {
|
||||||
LOG_DEBUG("Make TFTDisplay!");
|
LOG_DEBUG("Make TFTDisplay!");
|
||||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||||
@@ -1719,7 +1718,7 @@ void Screen::setup()
|
|||||||
#endif
|
#endif
|
||||||
serialSinceMsec = millis();
|
serialSinceMsec = millis();
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO && !HAS_TFT
|
||||||
if (settingsMap[touchscreenModule]) {
|
if (settingsMap[touchscreenModule]) {
|
||||||
touchScreenImpl1 =
|
touchScreenImpl1 =
|
||||||
new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast<TFTDisplay *>(dispdev)->getTouch);
|
new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast<TFTDisplay *>(dispdev)->getTouch);
|
||||||
@@ -2663,14 +2662,13 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
|
|||||||
|
|
||||||
int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
|
int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
|
||||||
{
|
{
|
||||||
if (showingNormalScreen) {
|
// If auto carousel is disabled -> return 0 and skip new messages handling
|
||||||
// Outgoing message
|
if (config.display.auto_screen_carousel_secs == 0)
|
||||||
if (packet->from == 0)
|
return 0;
|
||||||
setFrames(FOCUS_PRESERVE); // Return to same frame (quietly hiding the rx text message frame)
|
|
||||||
|
|
||||||
// Incoming message
|
// Handle focus change based on message type
|
||||||
else
|
if (showingNormalScreen) {
|
||||||
setFrames(FOCUS_TEXTMESSAGE); // Focus on the new message
|
setFrames(packet->from == 0 ? FOCUS_PRESERVE : FOCUS_TEXTMESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user