mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-17 16:22:48 +00:00
Compare commits
819 Commits
v2.5.18.89
...
no-arduino
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6b115b2dc | ||
|
|
6749d9ffc5 | ||
|
|
21404de7fc | ||
|
|
0f69f6ca71 | ||
|
|
633924ced8 | ||
|
|
298e5d36c9 | ||
|
|
3770e43d86 | ||
|
|
6e376aeea6 | ||
|
|
6f922641b2 | ||
|
|
0ced4188b6 | ||
|
|
f34b9859c6 | ||
|
|
e7e15af282 | ||
|
|
d1c86a088a | ||
|
|
0a5e703a94 | ||
|
|
22be1f031d | ||
|
|
b1e7a26dfc | ||
|
|
134e01aa70 | ||
|
|
a30f5c8d93 | ||
|
|
1df2f32ae0 | ||
|
|
0edccf5b86 | ||
|
|
284b8bcff2 | ||
|
|
29402a5e7a | ||
|
|
6627f2e873 | ||
|
|
5bdae47379 | ||
|
|
3df894106b | ||
|
|
218f5bdbf3 | ||
|
|
749c3ca53c | ||
|
|
43aa906017 | ||
|
|
763c80e571 | ||
|
|
8cbc5fbeae | ||
|
|
9799f10e63 | ||
|
|
f9d4fdbb52 | ||
|
|
ea9c71ecd9 | ||
|
|
53f2f615b2 | ||
|
|
b6cb0b148c | ||
|
|
fe3ad06d21 | ||
|
|
5f36da4374 | ||
|
|
699e1a15b3 | ||
|
|
69058002d7 | ||
|
|
7a7166d575 | ||
|
|
ba53543354 | ||
|
|
cb9429e83e | ||
|
|
f972b62d89 | ||
|
|
9fc98b1154 | ||
|
|
7849a3d291 | ||
|
|
c0c2ec195f | ||
|
|
e31cd0bc77 | ||
|
|
5195815df0 | ||
|
|
303006e1df | ||
|
|
69a08cb69d | ||
|
|
ac0547ca3e | ||
|
|
a66f381a5d | ||
|
|
fda6de2f51 | ||
|
|
8a997eb529 | ||
|
|
42a80d8aed | ||
|
|
da69d88790 | ||
|
|
051e7331f2 | ||
|
|
ec2efa55fc | ||
|
|
96c18d9908 | ||
|
|
8908805894 | ||
|
|
03b59ae39a | ||
|
|
cc2dd66ce2 | ||
|
|
158c88ddef | ||
|
|
138dc89442 | ||
|
|
bdd03bc853 | ||
|
|
aaf9f4011f | ||
|
|
7c9ec46d8f | ||
|
|
4fdc5f094a | ||
|
|
4935e91454 | ||
|
|
baefda213a | ||
|
|
6aff2179d1 | ||
|
|
3741b78a32 | ||
|
|
3108de207e | ||
|
|
dbfa703cfa | ||
|
|
7c4714afbb | ||
|
|
0d37804db5 | ||
|
|
106dd08710 | ||
|
|
f223b8a55d | ||
|
|
75a49d3486 | ||
|
|
7d95b487ef | ||
|
|
2e72850d99 | ||
|
|
8179af3968 | ||
|
|
5fbdf4b6dc | ||
|
|
c47bdd11f9 | ||
|
|
d3b16c1e47 | ||
|
|
e29588d2e2 | ||
|
|
9b69c2a9af | ||
|
|
30e83d36b7 | ||
|
|
e974a58d18 | ||
|
|
b2663d4b19 | ||
|
|
bed25406c1 | ||
|
|
6a22bb5187 | ||
|
|
61de338aa2 | ||
|
|
bf21481bef | ||
|
|
2c9e169451 | ||
|
|
b5f74cead1 | ||
|
|
13421b32b5 | ||
|
|
295ed2a8cf | ||
|
|
8f717d58e7 | ||
|
|
06a65bd80e | ||
|
|
10f1567b96 | ||
|
|
067d01b832 | ||
|
|
3aed7b4190 | ||
|
|
c01db98819 | ||
|
|
4a55f6468a | ||
|
|
9e3cf441a1 | ||
|
|
beba1b4882 | ||
|
|
ba1ef45024 | ||
|
|
b12e9d43be | ||
|
|
c59f16db42 | ||
|
|
7cd50d7044 | ||
|
|
d98612a2ca | ||
|
|
9d9fb2d74c | ||
|
|
351dff14e8 | ||
|
|
2432d0616b | ||
|
|
b35fb886e4 | ||
|
|
53d5801790 | ||
|
|
93aa88129c | ||
|
|
f1d4e5fa48 | ||
|
|
41c1b29d70 | ||
|
|
25b2a75dfe | ||
|
|
6041357cbb | ||
|
|
cf3f35d566 | ||
|
|
3e3a55a971 | ||
|
|
e0f878872f | ||
|
|
4226d4c4f8 | ||
|
|
a4ef8bf5f0 | ||
|
|
021f872507 | ||
|
|
ec50801726 | ||
|
|
6db585051e | ||
|
|
aca5159170 | ||
|
|
c70fa0ef13 | ||
|
|
3fe44755d0 | ||
|
|
16994c8725 | ||
|
|
7f0afcdae2 | ||
|
|
9aff65e313 | ||
|
|
286376e46a | ||
|
|
660a7058c8 | ||
|
|
584ac8bdc9 | ||
|
|
d7697e6dec | ||
|
|
7411dd4f0c | ||
|
|
4d1d89644b | ||
|
|
61ebce5241 | ||
|
|
3dd6dc0296 | ||
|
|
b2d81b740f | ||
|
|
f1440a27d7 | ||
|
|
212005bfe9 | ||
|
|
afc5d1fdeb | ||
|
|
e7352cada4 | ||
|
|
61d918751e | ||
|
|
61e4eb12e6 | ||
|
|
5b312ab917 | ||
|
|
a50a94150a | ||
|
|
3398a52a34 | ||
|
|
a8294b983a | ||
|
|
066609a718 | ||
|
|
2a6944fe12 | ||
|
|
512183c39f | ||
|
|
18d11d28d4 | ||
|
|
1ef4caea05 | ||
|
|
7d8f9c7f6d | ||
|
|
c2d5862161 | ||
|
|
6bba17d463 | ||
|
|
ef9d0d7805 | ||
|
|
60d2cb35e0 | ||
|
|
ed6de5095e | ||
|
|
b63b73ab84 | ||
|
|
3901ae8956 | ||
|
|
7cffd9ba70 | ||
|
|
fc64bea698 | ||
|
|
a51a6b8c47 | ||
|
|
1af4a0bdc9 | ||
|
|
bc313da064 | ||
|
|
f16402dec1 | ||
|
|
feafd2bc0c | ||
|
|
b1955c34aa | ||
|
|
94af3bd1ab | ||
|
|
d9ad2322e8 | ||
|
|
0a8bd1e4be | ||
|
|
ace63eee8d | ||
|
|
9cba2e7b7f | ||
|
|
a7415791a5 | ||
|
|
cc66f7c79b | ||
|
|
e1417cff2e | ||
|
|
efb3f85cd0 | ||
|
|
fe25e5efd5 | ||
|
|
c40fdc9a43 | ||
|
|
7293e542ec | ||
|
|
b9fcd9da23 | ||
|
|
2a06b058fd | ||
|
|
2f4f2b1202 | ||
|
|
62e1974d09 | ||
|
|
d9bfed242c | ||
|
|
4b770ceade | ||
|
|
9fc208df5f | ||
|
|
6542c7bb47 | ||
|
|
b208e1924f | ||
|
|
48dc44ea8f | ||
|
|
b17bb49a63 | ||
|
|
7c9296b0f4 | ||
|
|
23fe093a65 | ||
|
|
c2a38357f1 | ||
|
|
3aee4bfc6b | ||
|
|
6bc9986f22 | ||
|
|
9c4dae3bf6 | ||
|
|
dbc0122bbd | ||
|
|
a1d859bf4c | ||
|
|
71ba6fa9ce | ||
|
|
212963156b | ||
|
|
ae88ec96f7 | ||
|
|
b66d3d7157 | ||
|
|
2a7059c86e | ||
|
|
14752caee5 | ||
|
|
981ecfdb61 | ||
|
|
ca9bf6b31a | ||
|
|
ff2a12d579 | ||
|
|
3a6fc668d8 | ||
|
|
581021031c | ||
|
|
b657ba1abb | ||
|
|
6f256c06f6 | ||
|
|
86217111b2 | ||
|
|
4e8ae7b108 | ||
|
|
0a61ea4137 | ||
|
|
bc1cc0081f | ||
|
|
57d6c1fa85 | ||
|
|
62421a83fd | ||
|
|
867f50ab11 | ||
|
|
1e81ebed06 | ||
|
|
dd2cf633b0 | ||
|
|
fdbe16f650 | ||
|
|
a2903921cd | ||
|
|
9a57a774f6 | ||
|
|
7bc473ed99 | ||
|
|
3596ea20bc | ||
|
|
eebf174735 | ||
|
|
849e06497a | ||
|
|
66a06230c4 | ||
|
|
2d6181fca0 | ||
|
|
a32e45f8f2 | ||
|
|
75c5080fd9 | ||
|
|
055fdcb7f6 | ||
|
|
33093e28fa | ||
|
|
df631d480b | ||
|
|
8bb1f3e869 | ||
|
|
d75c91a760 | ||
|
|
9d31d9f43b | ||
|
|
152b8b1b02 | ||
|
|
10693c4569 | ||
|
|
7da8aea1df | ||
|
|
baae2503d5 | ||
|
|
947191a797 | ||
|
|
987623567a | ||
|
|
a8ab6e82e6 | ||
|
|
5c005aaed5 | ||
|
|
0e1a1c99f0 | ||
|
|
f9fbc3ff86 | ||
|
|
124f4daa71 | ||
|
|
00e2ac33ad | ||
|
|
845088e45b | ||
|
|
e0b1fdb5e8 | ||
|
|
a7ef9e9c08 | ||
|
|
216fbf2343 | ||
|
|
635de2d229 | ||
|
|
72eae42b81 | ||
|
|
b4e8f7dbb6 | ||
|
|
473ef1bc03 | ||
|
|
ca8c177363 | ||
|
|
77e6868d5d | ||
|
|
54c1423039 | ||
|
|
03f19bca0e | ||
|
|
89df9d7686 | ||
|
|
45fcd479f6 | ||
|
|
b1e35cd8b3 | ||
|
|
70ced735d9 | ||
|
|
24e9539d40 | ||
|
|
5f245177bc | ||
|
|
72dd5bd88d | ||
|
|
8812eadd44 | ||
|
|
48dc0e014c | ||
|
|
e03f3de185 | ||
|
|
5d48d2c0a7 | ||
|
|
2b57ffafd7 | ||
|
|
a30f431b6a | ||
|
|
916afb5098 | ||
|
|
d26b50b78c | ||
|
|
c6e5ec055f | ||
|
|
5ab1db0142 | ||
|
|
64a1cd3f99 | ||
|
|
9da141aa8c | ||
|
|
74b3dc34e4 | ||
|
|
e2f6600cb9 | ||
|
|
ef14967fbf | ||
|
|
c177c6d655 | ||
|
|
a36f21b29a | ||
|
|
d74359abf0 | ||
|
|
5fd64d4114 | ||
|
|
816d948ee5 | ||
|
|
e0dafc3618 | ||
|
|
4a9a59342a | ||
|
|
5699d8632e | ||
|
|
e5cd0d613c | ||
|
|
64c8bde04a | ||
|
|
4477031971 | ||
|
|
1138f74e2c | ||
|
|
cf5c8de92e | ||
|
|
7e8294dfad | ||
|
|
98411d408a | ||
|
|
040a34fca8 | ||
|
|
ecd9f015d8 | ||
|
|
4e30023a4b | ||
|
|
b46aad85cc | ||
|
|
c4dc3472ac | ||
|
|
28e62e53e5 | ||
|
|
257165431f | ||
|
|
f1fda7bdeb | ||
|
|
3eb845eaae | ||
|
|
e4c2730f71 | ||
|
|
900a7c4c5e | ||
|
|
e7d0837d01 | ||
|
|
e7ce910c3b | ||
|
|
e957009019 | ||
|
|
7079f538ed | ||
|
|
baa05aacf5 | ||
|
|
4ef9eae695 | ||
|
|
d90b721f7b | ||
|
|
9e4847840a | ||
|
|
854d74f8db | ||
|
|
f1f6b63380 | ||
|
|
56fbfe13ae | ||
|
|
6b2e03e9d2 | ||
|
|
bf9a7d3a7f | ||
|
|
35d4784c5c | ||
|
|
5fa236c77d | ||
|
|
f7849f2bd4 | ||
|
|
91f38797a8 | ||
|
|
06ce6f3e8a | ||
|
|
3694805938 | ||
|
|
6d53ce7956 | ||
|
|
9f56e613f2 | ||
|
|
5c13f3451c | ||
|
|
1008a08c99 | ||
|
|
e98da27446 | ||
|
|
daa03aba30 | ||
|
|
456f94511f | ||
|
|
1888342a57 | ||
|
|
8e40d88e24 | ||
|
|
0d8e39cc2a | ||
|
|
78fa4c5c70 | ||
|
|
536b6d87c6 | ||
|
|
5256ae90dc | ||
|
|
fc3d9f2a15 | ||
|
|
69f938ea98 | ||
|
|
ec298199ee | ||
|
|
f03f547e9e | ||
|
|
0d800b7a22 | ||
|
|
09fd3c0782 | ||
|
|
1b1d4625aa | ||
|
|
fb2010552f | ||
|
|
c94dd1e331 | ||
|
|
ebea34520d | ||
|
|
cfc2a96a45 | ||
|
|
c0dab4a672 | ||
|
|
383ae7a82f | ||
|
|
38b118fb8b | ||
|
|
2a4582da20 | ||
|
|
7c4ac89059 | ||
|
|
12d1305618 | ||
|
|
a084073cc1 | ||
|
|
e2933bcb5b | ||
|
|
606abfc116 | ||
|
|
860e8eca5a | ||
|
|
5a9d70b445 | ||
|
|
2125c03974 | ||
|
|
cdbf0bec2d | ||
|
|
d5d20fe33f | ||
|
|
99f6b398b3 | ||
|
|
396fc1824e | ||
|
|
74325ba439 | ||
|
|
33cfe14d4a | ||
|
|
56eb0c08b2 | ||
|
|
01f7cd998a | ||
|
|
c49f20f96c | ||
|
|
afc710a868 | ||
|
|
9cdeedfcbd | ||
|
|
b7218f4a53 | ||
|
|
08bbff260c | ||
|
|
225e2726f3 | ||
|
|
ae47de152c | ||
|
|
2b7bc6696f | ||
|
|
52d1d8d7c8 | ||
|
|
75490f410b | ||
|
|
67ae1c553c | ||
|
|
a1df41a9e0 | ||
|
|
1b33189fe6 | ||
|
|
25237a15ff | ||
|
|
0110275494 | ||
|
|
65f00e9474 | ||
|
|
6e0cca16d1 | ||
|
|
2711c53b5f | ||
|
|
7856e069a5 | ||
|
|
4dfba50304 | ||
|
|
7494106170 | ||
|
|
0665802823 | ||
|
|
6270c5663c | ||
|
|
1017f6af35 | ||
|
|
11bafae287 | ||
|
|
31130fd49e | ||
|
|
13b4093d84 | ||
|
|
b7aaf3ae47 | ||
|
|
047ccbcb55 | ||
|
|
e4e8d28831 | ||
|
|
594cb0cc1e | ||
|
|
52eb4eca03 | ||
|
|
ef18a9b5b5 | ||
|
|
67fddcc214 | ||
|
|
6f47035420 | ||
|
|
af7a70ce08 | ||
|
|
22b44ce7e6 | ||
|
|
2f8a1dba8f | ||
|
|
f6ed10f329 | ||
|
|
c693cd59a9 | ||
|
|
644849126c | ||
|
|
c271515fb0 | ||
|
|
efc69550ef | ||
|
|
ea4ce8d827 | ||
|
|
128c347c64 | ||
|
|
6ee7644070 | ||
|
|
bb961e855e | ||
|
|
7554ff6c57 | ||
|
|
ae88759059 | ||
|
|
9993306751 | ||
|
|
2c01fad798 | ||
|
|
a5efbfccd7 | ||
|
|
886bffe8f3 | ||
|
|
39408fd3b1 | ||
|
|
3314b00fcc | ||
|
|
72db671e00 | ||
|
|
bd2d2981c9 | ||
|
|
da26ff5b95 | ||
|
|
f626f02005 | ||
|
|
2acb2fee79 | ||
|
|
ca1e09d780 | ||
|
|
71f774aa37 | ||
|
|
99ca59b8a1 | ||
|
|
f18f60cd0b | ||
|
|
850d21dcb9 | ||
|
|
e08177ba98 | ||
|
|
b52c355f2f | ||
|
|
e79d4492e8 | ||
|
|
95523a9659 | ||
|
|
f60c4ec5bc | ||
|
|
7181e1a296 | ||
|
|
aff0834f8e | ||
|
|
32d91ed859 | ||
|
|
a93d779ec0 | ||
|
|
38c8c20a2b | ||
|
|
1fd95d85b8 | ||
|
|
50db11fff6 | ||
|
|
2fc6781322 | ||
|
|
0480ddd266 | ||
|
|
a3a0c14923 | ||
|
|
213a178d71 | ||
|
|
72f6fde772 | ||
|
|
62a6c91c70 | ||
|
|
b89355ffa6 | ||
|
|
8a4a0cc932 | ||
|
|
cbcdc3ed00 | ||
|
|
d663d44647 | ||
|
|
3148e7277d | ||
|
|
7df327664e | ||
|
|
a902776e57 | ||
|
|
ea9485657e | ||
|
|
bd20c74287 | ||
|
|
0491c890d7 | ||
|
|
c9e71173de | ||
|
|
41c44353f7 | ||
|
|
4a3991a8c6 | ||
|
|
c602bfecbd | ||
|
|
7fce089540 | ||
|
|
6c7c0770f9 | ||
|
|
89cde1a8e6 | ||
|
|
02237f5ac6 | ||
|
|
4a12b4eb32 | ||
|
|
1dedd291fb | ||
|
|
a2387c79ee | ||
|
|
d7504921fb | ||
|
|
4e1030ef9c | ||
|
|
1e41c994b3 | ||
|
|
4590ef2e7b | ||
|
|
769f0623be | ||
|
|
52527b24a7 | ||
|
|
6c17694b64 | ||
|
|
640e731ad2 | ||
|
|
ba81a8ad87 | ||
|
|
83d8e3cb09 | ||
|
|
6429eca5e4 | ||
|
|
13101c1bab | ||
|
|
d28af68b5a | ||
|
|
53a7afff41 | ||
|
|
eb375d8e62 | ||
|
|
33f2b7144f | ||
|
|
e5f8218d34 | ||
|
|
0ddb507055 | ||
|
|
3afe84c4f4 | ||
|
|
e9d8a3d7f9 | ||
|
|
e722a97987 | ||
|
|
daa4186d65 | ||
|
|
1ee800e901 | ||
|
|
cf7f0f9d08 | ||
|
|
1e4a0134e6 | ||
|
|
0951fdd49b | ||
|
|
848a3ed6a1 | ||
|
|
fd7a1f2ccb | ||
|
|
5acaf8f897 | ||
|
|
cff93adb5e | ||
|
|
e4d3ec1f59 | ||
|
|
ae27aaaf43 | ||
|
|
31c0e8fa2c | ||
|
|
0d95b1afcc | ||
|
|
46235f6f8b | ||
|
|
d1068fd1e4 | ||
|
|
f41afb14b1 | ||
|
|
f8ad02aab3 | ||
|
|
077759e15d | ||
|
|
22aa2d7582 | ||
|
|
6673cb9292 | ||
|
|
8efc9702d3 | ||
|
|
2876eec7ed | ||
|
|
9cc13e628a | ||
|
|
af8b64e84e | ||
|
|
96ba94843b | ||
|
|
2d565c2921 | ||
|
|
2525111c39 | ||
|
|
64b9cfe199 | ||
|
|
dc100e4d3e | ||
|
|
1640fb105d | ||
|
|
99e42b4d22 | ||
|
|
79233fe99d | ||
|
|
f66784ed2a | ||
|
|
f198d5d49f | ||
|
|
4d34b3d73c | ||
|
|
8efe8a2ea3 | ||
|
|
499ea56e3b | ||
|
|
2473af6995 | ||
|
|
508ab171d6 | ||
|
|
ec59f7d7dd | ||
|
|
f4c79530ec | ||
|
|
e9effb9fff | ||
|
|
cb6dfb66d2 | ||
|
|
8795a63427 | ||
|
|
186e509607 | ||
|
|
7c3eddebc2 | ||
|
|
78b4eff568 | ||
|
|
3c1f92ce84 | ||
|
|
5de6bc1851 | ||
|
|
c54fc5b7c5 | ||
|
|
94de2315c1 | ||
|
|
7f17747d8c | ||
|
|
16a0dce83c | ||
|
|
3fd47d9713 | ||
|
|
284598ed56 | ||
|
|
2a3e1f904d | ||
|
|
60e46cd765 | ||
|
|
563747c5cd | ||
|
|
5c77d42345 | ||
|
|
f0a2ae9ff3 | ||
|
|
f7afa9a81e | ||
|
|
c8bd6c32cc | ||
|
|
f6a9e7d741 | ||
|
|
e6a98b1d6b | ||
|
|
b2ef92a328 | ||
|
|
b25db1f42c | ||
|
|
a924b9d94a | ||
|
|
f5e0e282b6 | ||
|
|
a3a9b2fe84 | ||
|
|
6c8058e1d8 | ||
|
|
445efe9e21 | ||
|
|
b96b027926 | ||
|
|
239e5412b3 | ||
|
|
ede3f7b702 | ||
|
|
f0f2cd0e0e | ||
|
|
fdbadc992c | ||
|
|
2391982c1d | ||
|
|
41875d245e | ||
|
|
95bcd7ab0b | ||
|
|
050f0016c4 | ||
|
|
6715662281 | ||
|
|
b6562e175f | ||
|
|
f89f916f96 | ||
|
|
43a6e711da | ||
|
|
63b20e358f | ||
|
|
12fde696c1 | ||
|
|
5c8f1fb46b | ||
|
|
ce38ac10d1 | ||
|
|
d5ec205572 | ||
|
|
9893d24c62 | ||
|
|
ab61cd65d1 | ||
|
|
baef8dce79 | ||
|
|
99d3e5eb70 | ||
|
|
088fce7d11 | ||
|
|
b46bf16385 | ||
|
|
1c827f5512 | ||
|
|
b437f0fb54 | ||
|
|
ffe4e7b6be | ||
|
|
598cfcc081 | ||
|
|
f2e49aa4ee | ||
|
|
3a0ad9bb58 | ||
|
|
4e575872da | ||
|
|
bf958ed01d | ||
|
|
c93728eb75 | ||
|
|
01c717a41d | ||
|
|
7061fd1f16 | ||
|
|
7d8e0ede6c | ||
|
|
efca2b5849 | ||
|
|
cfcd9cc210 | ||
|
|
fe1ced7480 | ||
|
|
3787cf7803 | ||
|
|
1be28520a7 | ||
|
|
4942c7b71f | ||
|
|
4709d21df8 | ||
|
|
ec0eafedab | ||
|
|
994e22aba9 | ||
|
|
9930bba3f5 | ||
|
|
f1dc1b309a | ||
|
|
337265a07f | ||
|
|
bb73555209 | ||
|
|
93c64cb442 | ||
|
|
5da5803c4c | ||
|
|
79b3a1e60e | ||
|
|
191ca8ce12 | ||
|
|
c67aa25d19 | ||
|
|
3b0232de1b | ||
|
|
7eb77276cd | ||
|
|
7648391f91 | ||
|
|
4407d9e040 | ||
|
|
27fea5fc07 | ||
|
|
2f6cd02111 | ||
|
|
8c9947b05c | ||
|
|
50b7d6a0f7 | ||
|
|
c83ffd4911 | ||
|
|
9b46cb4ef0 | ||
|
|
01935ea35e | ||
|
|
495f69cf90 | ||
|
|
eb650a6adb | ||
|
|
7fdd262d55 | ||
|
|
d1fa27d353 | ||
|
|
8427072d79 | ||
|
|
4e2b47cc67 | ||
|
|
da1d78c882 | ||
|
|
7c4bf38647 | ||
|
|
96262b106c | ||
|
|
39e45d90e1 | ||
|
|
d70a9392af | ||
|
|
4e8c4f0d55 | ||
|
|
4a6a0efcfd | ||
|
|
cb0519dd9c | ||
|
|
9db51a72a4 | ||
|
|
64def246ee | ||
|
|
1c8eb7ece3 | ||
|
|
447533aae5 | ||
|
|
1b457bcfbb | ||
|
|
ed07cc067a | ||
|
|
a3a295488c | ||
|
|
5c17afb2ac | ||
|
|
8cacdb65d6 | ||
|
|
3a34f8beaf | ||
|
|
d740934278 | ||
|
|
b370717dcd | ||
|
|
d9534cfc9d | ||
|
|
4c0e0b8471 | ||
|
|
b5cad2b65e | ||
|
|
cd8592ef4a | ||
|
|
78da8f6fc4 | ||
|
|
6a12760c3d | ||
|
|
30a31a3a13 | ||
|
|
2d42e1b2bc | ||
|
|
4747e73f37 | ||
|
|
10d553087c | ||
|
|
7649e70585 | ||
|
|
a14346bc4f | ||
|
|
fd56995764 | ||
|
|
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 |
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())
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
|
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||||
|
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||||
|
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||||
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
||||||
|
|
||||||
USER root
|
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 \
|
||||||
@@ -27,9 +28,15 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
|||||||
hwdata \
|
hwdata \
|
||||||
gpg \
|
gpg \
|
||||||
gnupg2 \
|
gnupg2 \
|
||||||
|
libusb-1.0-0-dev \
|
||||||
|
libuv1-dev \
|
||||||
|
libi2c-dev \
|
||||||
|
libxcb-xkb-dev \
|
||||||
|
libxkbcommon-dev \
|
||||||
|
libinput-dev \
|
||||||
&& 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
|
||||||
|
|
||||||
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
|
|
||||||
|
pip install --no-cache-dir setuptools
|
||||||
|
pipx install esptool
|
||||||
|
|||||||
1
.dockerignore
Symbolic link
1
.dockerignore
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
.gitignore
|
||||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1,4 +1,5 @@
|
|||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
*.cmd text eol=crlf
|
||||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
*.bat text eol=crlf
|
||||||
|
*.ps1 text eol=crlf
|
||||||
*.{sh,[sS][hH]} text eol=lf
|
*.{sh,[sS][hH]} text eol=lf
|
||||||
|
|||||||
11
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
11
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
name: Bug Report
|
name: Bug Report
|
||||||
description: File a bug report
|
description: File a bug report
|
||||||
title: "[Bug]: "
|
title: "[Bug]: "
|
||||||
labels: ["bug", "triage"]
|
labels: [bug, triage]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
@@ -72,6 +72,15 @@ body:
|
|||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
id: mui
|
||||||
|
attributes:
|
||||||
|
label: Is this bug report about any UI component firmware like InkHUD or Meshtatic UI (MUI)?
|
||||||
|
options:
|
||||||
|
- label: Meshtastic UI aka MUI colorTFT
|
||||||
|
- label: InkHUD ePaper
|
||||||
|
- label: OLED slide UI on any display
|
||||||
|
|
||||||
- type: input
|
- type: input
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/New Board.yml
vendored
2
.github/ISSUE_TEMPLATE/New Board.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
name: New Board
|
name: New Board
|
||||||
description: Request us to support new hardware
|
description: Request us to support new hardware
|
||||||
title: "[Board]: "
|
title: "[Board]: "
|
||||||
labels: ["enhancement", "triage"]
|
labels: [enhancement, triage]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
name: Feature Request
|
name: Feature Request
|
||||||
description: Request a new feature
|
description: Request a new feature
|
||||||
title: "[Feature Request]: "
|
title: "[Feature Request]: "
|
||||||
labels: ["enhancement"]
|
labels: [enhancement]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
5
.github/actionlint.yaml
vendored
Normal file
5
.github/actionlint.yaml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Configuration related to self-hosted runner.
|
||||||
|
self-hosted-runner:
|
||||||
|
# Labels of self-hosted runner in array of strings.
|
||||||
|
labels:
|
||||||
|
- test-runner
|
||||||
21
.github/actions/build-variant/action.yml
vendored
21
.github/actions/build-variant/action.yml
vendored
@@ -34,7 +34,7 @@ inputs:
|
|||||||
arch:
|
arch:
|
||||||
description: Processor arch name
|
description: Processor arch name
|
||||||
required: true
|
required: true
|
||||||
default: "esp32"
|
default: esp32
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
@@ -43,6 +43,13 @@ runs:
|
|||||||
id: base
|
id: base
|
||||||
uses: ./.github/actions/setup-base
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
|
- name: Get web ui version
|
||||||
|
if: inputs.include-web-ui == 'true'
|
||||||
|
id: webver
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "ver=$(cat bin/web.version)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Pull web ui
|
- name: Pull web ui
|
||||||
if: inputs.include-web-ui == 'true'
|
if: inputs.include-web-ui == 'true'
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
uses: dsaltares/fetch-gh-release-asset@master
|
||||||
@@ -51,7 +58,7 @@ runs:
|
|||||||
file: build.tar
|
file: build.tar
|
||||||
target: build.tar
|
target: build.tar
|
||||||
token: ${{ inputs.github_token }}
|
token: ${{ inputs.github_token }}
|
||||||
version: tags/v2.5.3
|
version: tags/v${{ steps.webver.outputs.ver }}
|
||||||
|
|
||||||
- name: Unpack web ui
|
- name: Unpack web ui
|
||||||
if: inputs.include-web-ui == 'true'
|
if: inputs.include-web-ui == 'true'
|
||||||
@@ -68,6 +75,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 +96,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 }}
|
||||||
|
|||||||
21
.github/actions/setup-base/action.yml
vendored
21
.github/actions/setup-base/action.yml
vendored
@@ -1,13 +1,13 @@
|
|||||||
name: "Setup Build Base Composite Action"
|
name: Setup Build Base Composite Action
|
||||||
description: "Base build actions for Meshtastic Platform IO steps"
|
description: Base build actions for Meshtastic Platform IO steps
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: recursive
|
||||||
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}}
|
||||||
|
|
||||||
@@ -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 libuv1-dev
|
||||||
26
.github/dependabot.yml
vendored
26
.github/dependabot.yml
vendored
@@ -1,26 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: docker
|
|
||||||
directory: devcontainer
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
|
||||||
timezone: US/Pacific
|
|
||||||
- package-ecosystem: docker
|
|
||||||
directory: /
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
|
||||||
timezone: US/Pacific
|
|
||||||
- package-ecosystem: gitsubmodule
|
|
||||||
directory: /
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
|
||||||
timezone: US/Pacific
|
|
||||||
- package-ecosystem: github-actions
|
|
||||||
directory: /.github/workflows
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
|
||||||
timezone: US/Pacific
|
|
||||||
BIN
.github/meshtastic_logo.png
vendored
Normal file
BIN
.github/meshtastic_logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
18
.github/pull_request_template.md
vendored
18
.github/pull_request_template.md
vendored
@@ -1,7 +1,6 @@
|
|||||||
|
## 🙏 Thank you for sending in a pull request, here's some tips to get started!
|
||||||
|
|
||||||
### ❌ (Please delete all these tips and replace them with your text) ❌
|
### ❌ (Please delete all these tips and replace them with your text) ❌
|
||||||
|
|
||||||
## Thank you for sending in a pull request, here's some tips to get started!
|
|
||||||
|
|
||||||
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
|
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
|
||||||
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
|
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
|
||||||
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
||||||
@@ -12,4 +11,17 @@
|
|||||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||||
- If your other co-developers have comments on your PR please tweak as needed.
|
- If your other co-developers have comments on your PR please tweak as needed.
|
||||||
- Please also enable "Allow edits by maintainers".
|
- Please also enable "Allow edits by maintainers".
|
||||||
|
- Please do not submit untested code.
|
||||||
|
- If you do not have the affected hardware to test your code changes adequately against regressions, please indicate this, so that contributors and commnunity members can help test your changes.
|
||||||
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
|
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
|
||||||
|
|
||||||
|
|
||||||
|
## 🤝 Attestations
|
||||||
|
- [ ] I have tested that my proposed changes behave as described.
|
||||||
|
- [ ] I have tested that my proposed changes do not cause any obvious regressions on the following devices:
|
||||||
|
- [ ] Heltec (Lora32) V3
|
||||||
|
- [ ] LilyGo T-Deck
|
||||||
|
- [ ] LilyGo T-Beam
|
||||||
|
- [ ] RAK WisBlock 4631
|
||||||
|
- [ ] Seeed Studio T-1000E tracker card
|
||||||
|
- [ ] Other (please specify below)
|
||||||
|
|||||||
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: false
|
||||||
|
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 }}*
|
||||||
51
.github/workflows/build_docker.yml
vendored
51
.github/workflows/build_docker.yml
vendored
@@ -1,51 +0,0 @@
|
|||||||
name: Build Docker
|
|
||||||
|
|
||||||
on: workflow_call
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-native:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
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 "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Docker login
|
|
||||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: meshtastic
|
|
||||||
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
|
|
||||||
|
|
||||||
- name: Docker setup
|
|
||||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Docker build and push tagged versions
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
push: true
|
|
||||||
tags: meshtastic/meshtasticd:${{ 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' }}
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
push: true
|
|
||||||
tags: meshtastic/meshtasticd:latest
|
|
||||||
52
.github/workflows/build_native.yml
vendored
52
.github/workflows/build_native.yml
vendored
@@ -1,52 +0,0 @@
|
|||||||
name: Build Native
|
|
||||||
|
|
||||||
on: workflow_call
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-native:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Install libs needed for native build
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get update --fix-missing
|
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
|
||||||
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -U platformio adafruit-nrfutil
|
|
||||||
pip install -U meshtastic --pre
|
|
||||||
|
|
||||||
- name: Upgrade platformio
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
pio upgrade
|
|
||||||
|
|
||||||
- name: Build Native
|
|
||||||
run: bin/build-native.sh
|
|
||||||
|
|
||||||
- name: Get release version string
|
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
|
||||||
overwrite: true
|
|
||||||
path: |
|
|
||||||
release/meshtasticd_linux_x86_64
|
|
||||||
bin/config-dist.yaml
|
|
||||||
2
.github/workflows/build_nrf52.yml
vendored
2
.github/workflows/build_nrf52.yml
vendored
@@ -7,6 +7,8 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-nrf52:
|
build-nrf52:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
52
.github/workflows/build_raspbian.yml
vendored
52
.github/workflows/build_raspbian.yml
vendored
@@ -1,52 +0,0 @@
|
|||||||
name: Build Raspbian
|
|
||||||
|
|
||||||
on: workflow_call
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-raspbian:
|
|
||||||
runs-on: [self-hosted, linux, ARM64]
|
|
||||||
steps:
|
|
||||||
- name: Install libbluetooth
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
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 libusb-1.0-0-dev libi2c-dev
|
|
||||||
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -U platformio adafruit-nrfutil
|
|
||||||
pip install -U meshtastic --pre
|
|
||||||
|
|
||||||
- name: Upgrade platformio
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
pio upgrade
|
|
||||||
|
|
||||||
- name: Build Raspbian
|
|
||||||
run: bin/build-native.sh
|
|
||||||
|
|
||||||
- name: Get release version string
|
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
|
||||||
overwrite: true
|
|
||||||
path: |
|
|
||||||
release/meshtasticd_linux_aarch64
|
|
||||||
bin/config-dist.yaml
|
|
||||||
52
.github/workflows/build_raspbian_armv7l.yml
vendored
52
.github/workflows/build_raspbian_armv7l.yml
vendored
@@ -1,52 +0,0 @@
|
|||||||
name: Build Raspbian Arm
|
|
||||||
|
|
||||||
on: workflow_call
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-raspbian-armv7l:
|
|
||||||
runs-on: [self-hosted, linux, ARM]
|
|
||||||
steps:
|
|
||||||
- name: Install libbluetooth
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
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 libusb-1.0-0-dev libi2c-dev
|
|
||||||
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -U platformio adafruit-nrfutil
|
|
||||||
pip install -U meshtastic --pre
|
|
||||||
|
|
||||||
- name: Upgrade platformio
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
pio upgrade
|
|
||||||
|
|
||||||
- name: Build Raspbian
|
|
||||||
run: bin/build-native.sh
|
|
||||||
|
|
||||||
- name: Get release version string
|
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
|
||||||
overwrite: true
|
|
||||||
path: |
|
|
||||||
release/meshtasticd_linux_armv7l
|
|
||||||
bin/config-dist.yaml
|
|
||||||
2
.github/workflows/build_rpi2040.yml
vendored
2
.github/workflows/build_rpi2040.yml
vendored
@@ -7,6 +7,8 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-rpi2040:
|
build-rpi2040:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
2
.github/workflows/build_stm32.yml
vendored
2
.github/workflows/build_stm32.yml
vendored
@@ -7,6 +7,8 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-stm32:
|
build-stm32:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
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
|
||||||
99
.github/workflows/docker_build.yml
vendored
Normal file
99
.github/workflows/docker_build.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
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
|
||||||
|
pio_env:
|
||||||
|
description: PlatformIO environment to build
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: native
|
||||||
|
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 }}
|
||||||
|
build-args: |
|
||||||
|
PIO_ENV=${{ inputs.pio_env }}
|
||||||
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 }}
|
||||||
35
.github/workflows/generate-userprefs.yml
vendored
35
.github/workflows/generate-userprefs.yml
vendored
@@ -1,35 +0,0 @@
|
|||||||
name: Generate UsersPrefs JSON manifest
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- userPrefs.h
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
generate-userprefs:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Clang
|
|
||||||
run: sudo apt-get install -y clang
|
|
||||||
|
|
||||||
- name: Install trunk
|
|
||||||
run: curl https://get.trunk.io -fsSL | bash
|
|
||||||
|
|
||||||
- name: Generate userPrefs.jsom
|
|
||||||
run: python3 ./bin/build-userprefs-json.py
|
|
||||||
|
|
||||||
- name: Trunk format json
|
|
||||||
run: trunk format userPrefs.json
|
|
||||||
|
|
||||||
- name: Commit userPrefs.json
|
|
||||||
run: |
|
|
||||||
git config --global user.email "actions@github.com"
|
|
||||||
git config --global user.name "GitHub Actions"
|
|
||||||
git add userPrefs.json
|
|
||||||
git commit -m "Update userPrefs.json"
|
|
||||||
git push
|
|
||||||
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 }}
|
||||||
278
.github/workflows/main_matrix.yml
vendored
278
.github/workflows/main_matrix.yml
vendored
@@ -5,14 +5,20 @@ concurrency:
|
|||||||
on:
|
on:
|
||||||
# # Triggers the workflow on push but only for the master branch
|
# # Triggers the workflow on push but only for the master branch
|
||||||
push:
|
push:
|
||||||
branches: [master, develop]
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- event/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "**.md"
|
- "**.md"
|
||||||
- version.properties
|
- version.properties
|
||||||
|
|
||||||
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
branches: [master, develop]
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- event/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "**.md"
|
- "**.md"
|
||||||
#- "**.yml"
|
#- "**.yml"
|
||||||
@@ -32,12 +38,12 @@ jobs:
|
|||||||
name: Checkout base
|
name: Checkout base
|
||||||
- id: jsonStep
|
- id: jsonStep
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ github.head_ref }}" == "" ]]; then
|
if [[ "$GITHUB_HEAD_REF" == "" ]]; then
|
||||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
|
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
|
||||||
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 }} } 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 }}
|
||||||
@@ -128,30 +134,73 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
package-raspbian:
|
build-debian-src:
|
||||||
uses: ./.github/workflows/package_raspbian.yml
|
uses: ./.github/workflows/build_debian_src.yml
|
||||||
|
with:
|
||||||
package-raspbian-armv7l:
|
series: UNRELEASED
|
||||||
uses: ./.github/workflows/package_raspbian_armv7l.yml
|
build_location: local
|
||||||
|
|
||||||
package-native:
|
|
||||||
uses: ./.github/workflows/package_amd64.yml
|
|
||||||
|
|
||||||
build-docker:
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
|
||||||
uses: ./.github/workflows/build_docker.yml
|
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
after-checks:
|
package-pio-deps-native-tft:
|
||||||
runs-on: ubuntu-latest
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
uses: ./.github/workflows/package_pio_deps.yml
|
||||||
needs: [check]
|
with:
|
||||||
steps:
|
pio_env: native-tft
|
||||||
- name: Checkout code
|
secrets: inherit
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
test-native:
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
if: ${{ !contains(github.ref_name, 'event/') }}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
uses: ./.github/workflows/test_native.yml
|
||||||
|
|
||||||
|
docker-deb-amd64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: false
|
||||||
|
|
||||||
|
docker-deb-amd64-tft:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: false
|
||||||
|
pio_env: native-tft
|
||||||
|
|
||||||
|
docker-alp-amd64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: alpine
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: false
|
||||||
|
|
||||||
|
docker-alp-amd64-tft:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: alpine
|
||||||
|
platform: linux/amd64
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
push: false
|
||||||
|
pio_env: native-tft
|
||||||
|
|
||||||
|
docker-deb-arm64:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/arm64
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: false
|
||||||
|
|
||||||
|
docker-deb-armv7:
|
||||||
|
uses: ./.github/workflows/docker_build.yml
|
||||||
|
with:
|
||||||
|
distro: debian
|
||||||
|
platform: linux/arm/v7
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
push: false
|
||||||
|
|
||||||
gather-artifacts:
|
gather-artifacts:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -189,7 +238,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
@@ -198,7 +247,7 @@ jobs:
|
|||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./firmware-*.bin
|
./firmware-*.bin
|
||||||
@@ -215,7 +264,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -229,12 +278,12 @@ jobs:
|
|||||||
chmod +x ./output/device-update.sh
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: ./*.elf
|
path: ./*.elf
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
@@ -242,8 +291,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,12 +301,9 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
needs:
|
needs:
|
||||||
[
|
- gather-artifacts
|
||||||
gather-artifacts,
|
- build-debian-src
|
||||||
package-raspbian,
|
- package-pio-deps-native-tft
|
||||||
package-raspbian-armv7l,
|
|
||||||
package-native,
|
|
||||||
]
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -268,73 +314,56 @@ 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 source deb
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
pattern: firmware-debian-${{ steps.version.outputs.deb }}~UNRELEASED-src
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output/debian-src
|
||||||
|
|
||||||
|
- name: Download `native-tft` pio deps
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: platformio-deps-native-tft-${{ steps.version.outputs.long }}
|
||||||
|
merge-multiple: true
|
||||||
|
path: ./output/pio-deps-native-tft
|
||||||
|
|
||||||
|
- name: Zip Linux sources
|
||||||
|
working-directory: output
|
||||||
|
run: |
|
||||||
|
zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
|
||||||
|
zip -9 -r ./platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip ./pio-deps-native-tft
|
||||||
|
|
||||||
# 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 Linux sources to GtiHub Release
|
||||||
uses: actions/upload-release-asset@v1
|
# Only run when targeting master branch with workflow_dispatch
|
||||||
|
if: ${{ github.ref_name == 'master' }}
|
||||||
|
run: |
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
|
||||||
|
gh release upload v${{ steps.version.outputs.long }} ./output/platformio-deps-native-tft-${{ steps.version.outputs.long }}.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
|
|
||||||
run: >-
|
|
||||||
bin/bump_version.py
|
|
||||||
|
|
||||||
- name: Create version.properties pull request
|
|
||||||
uses: peter-evans/create-pull-request@v7
|
|
||||||
with:
|
|
||||||
title: Bump version.properties
|
|
||||||
add-paths: |
|
|
||||||
version.properties
|
|
||||||
|
|
||||||
release-firmware:
|
release-firmware:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -354,12 +383,12 @@ jobs:
|
|||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -372,37 +401,68 @@ 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 GitHub Release
|
||||||
uses: actions/upload-release-asset@v1
|
# Only run when targeting master branch with workflow_dispatch
|
||||||
|
if: ${{ github.ref_name == 'master' }}
|
||||||
|
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
|
publish-firmware:
|
||||||
uses: actions/upload-release-asset@v1
|
runs-on: ubuntu-latest
|
||||||
env:
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
needs: [release-firmware]
|
||||||
|
env:
|
||||||
|
targets: esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,stm32
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
|
python-version: 3.x
|
||||||
asset_path: ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
- name: Get release version string
|
||||||
asset_content_type: application/zip
|
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: firmware-{${{ env.targets }}}-${{ steps.version.outputs.long }}
|
||||||
|
merge-multiple: true
|
||||||
|
path: ./publish
|
||||||
|
|
||||||
|
- name: Publish firmware to meshtastic.github.io
|
||||||
|
uses: peaceiris/actions-gh-pages@v4
|
||||||
|
env:
|
||||||
|
# On event/* branches, use the event name as the destination prefix
|
||||||
|
DEST_PREFIX: ${{ contains(github.ref_name, 'event/') && format('{0}/', github.ref_name) || '' }}
|
||||||
|
with:
|
||||||
|
deploy_key: ${{ secrets.DIST_PAGES_DEPLOY_KEY }}
|
||||||
|
external_repository: meshtastic/meshtastic.github.io
|
||||||
|
publish_branch: master
|
||||||
|
publish_dir: ./publish
|
||||||
|
destination_dir: ${{ env.DEST_PREFIX }}firmware-${{ steps.version.outputs.long }}
|
||||||
|
keep_files: true
|
||||||
|
user_name: github-actions[bot]
|
||||||
|
user_email: github-actions[bot]@users.noreply.github.com
|
||||||
|
commit_message: ${{ steps.version.outputs.long }}
|
||||||
|
enable_jekyll: true
|
||||||
|
|||||||
24
.github/workflows/nightly.yml
vendored
24
.github/workflows/nightly.yml
vendored
@@ -4,16 +4,34 @@ on:
|
|||||||
- cron: 0 8 * * 1-5
|
- cron: 0 8 * * 1-5
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
trunk_check:
|
trunk_check:
|
||||||
name: Trunk Check Upload
|
name: Trunk Check and Upload
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Trunk Check
|
- name: Trunk Check
|
||||||
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
|
uses: trunk-io/trunk-action@v1
|
||||||
with:
|
with:
|
||||||
trunk-token: ${{ secrets.TRUNK_TOKEN }}
|
trunk-token: ${{ secrets.TRUNK_TOKEN }}
|
||||||
|
|
||||||
|
trunk_upgrade:
|
||||||
|
# See: https://github.com/trunk-io/trunk-action/blob/v1/readme.md#automatic-upgrades
|
||||||
|
name: Trunk Upgrade (PR)
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
contents: write # For trunk to create PRs
|
||||||
|
pull-requests: write # For trunk to create PRs
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Trunk Upgrade
|
||||||
|
uses: trunk-io/trunk-action/upgrade@v1
|
||||||
|
with:
|
||||||
|
base: master
|
||||||
|
|||||||
90
.github/workflows/package_amd64.yml
vendored
90
.github/workflows/package_amd64.yml
vendored
@@ -1,90 +0,0 @@
|
|||||||
name: Package Native
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-native:
|
|
||||||
uses: ./.github/workflows/build_native.yml
|
|
||||||
|
|
||||||
package-native:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
needs: build-native
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Pull web ui
|
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
|
||||||
with:
|
|
||||||
repo: meshtastic/web
|
|
||||||
file: build.tar
|
|
||||||
target: build.tar
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Get release version string
|
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Download artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
|
||||||
run: ls -R
|
|
||||||
|
|
||||||
- name: build .debpkg
|
|
||||||
run: |
|
|
||||||
mkdir -p .debpkg/DEBIAN
|
|
||||||
mkdir -p .debpkg/usr/share/meshtasticd/web
|
|
||||||
mkdir -p .debpkg/usr/sbin
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
|
||||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
|
||||||
tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web
|
|
||||||
shopt -s dotglob nullglob
|
|
||||||
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/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; 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/meshtasticd/web/ -r
|
|
||||||
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
|
|
||||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
|
||||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ -r
|
|
||||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
|
||||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
|
||||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
|
||||||
chmod +x .debpkg/DEBIAN/conffiles
|
|
||||||
# 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
|
|
||||||
with:
|
|
||||||
package: meshtasticd
|
|
||||||
package_root: .debpkg
|
|
||||||
maintainer: Jonathan Bennett
|
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
|
||||||
arch: amd64
|
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
|
||||||
desc: Native Linux Meshtastic binary.
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
|
||||||
overwrite: true
|
|
||||||
path: |
|
|
||||||
./*.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 }}"
|
||||||
65
.github/workflows/package_pio_deps.yml
vendored
Normal file
65
.github/workflows/package_pio_deps.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
name: Package PlatformIO Library Dependencies
|
||||||
|
# trunk-ignore-all(checkov/CKV_GHA_7): Allow workflow_dispatch inputs for testing
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
pio_env:
|
||||||
|
description: PlatformIO environment to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pio_env:
|
||||||
|
description: PlatformIO environment to target
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pkg-pio-libdeps:
|
||||||
|
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: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
pip install platformio
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: |
|
||||||
|
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Fetch libdeps
|
||||||
|
shell: bash
|
||||||
|
run: |-
|
||||||
|
platformio pkg install -e ${{ inputs.pio_env }}
|
||||||
|
platformio pkg install -e ${{ inputs.pio_env }} -t platformio/tool-scons@4.40502.0
|
||||||
|
env:
|
||||||
|
PLATFORMIO_LIBDEPS_DIR: pio/libdeps
|
||||||
|
PLATFORMIO_PACKAGES_DIR: pio/packages
|
||||||
|
PLATFORMIO_CORE_DIR: pio/core
|
||||||
|
|
||||||
|
- name: Store binaries as an artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
||||||
|
overwrite: true
|
||||||
|
include-hidden-files: true
|
||||||
|
path: |
|
||||||
|
pio/*
|
||||||
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
|
||||||
90
.github/workflows/package_raspbian.yml
vendored
90
.github/workflows/package_raspbian.yml
vendored
@@ -1,90 +0,0 @@
|
|||||||
name: Package Raspbian
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-raspbian:
|
|
||||||
uses: ./.github/workflows/build_raspbian.yml
|
|
||||||
|
|
||||||
package-raspbian:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
needs: build-raspbian
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Pull web ui
|
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
|
||||||
with:
|
|
||||||
repo: meshtastic/web
|
|
||||||
file: build.tar
|
|
||||||
target: build.tar
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Get release version string
|
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Download artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
|
||||||
run: ls -R
|
|
||||||
|
|
||||||
- name: build .debpkg
|
|
||||||
run: |
|
|
||||||
mkdir -p .debpkg/DEBIAN
|
|
||||||
mkdir -p .debpkg/usr/share/meshtasticd/web
|
|
||||||
mkdir -p .debpkg/usr/sbin
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
|
||||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
|
||||||
tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web
|
|
||||||
shopt -s dotglob nullglob
|
|
||||||
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/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; 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/meshtasticd/web/ -r
|
|
||||||
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
|
|
||||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
|
||||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ -r
|
|
||||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
|
||||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
|
||||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
|
||||||
chmod +x .debpkg/DEBIAN/conffiles
|
|
||||||
# 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
|
|
||||||
with:
|
|
||||||
package: meshtasticd
|
|
||||||
package_root: .debpkg
|
|
||||||
maintainer: Jonathan Bennett
|
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
|
||||||
arch: arm64
|
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
|
||||||
desc: Native Linux Meshtastic binary.
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
|
||||||
overwrite: true
|
|
||||||
path: |
|
|
||||||
./*.deb
|
|
||||||
90
.github/workflows/package_raspbian_armv7l.yml
vendored
90
.github/workflows/package_raspbian_armv7l.yml
vendored
@@ -1,90 +0,0 @@
|
|||||||
name: Package Raspbian
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-raspbian_armv7l:
|
|
||||||
uses: ./.github/workflows/build_raspbian_armv7l.yml
|
|
||||||
|
|
||||||
package-raspbian_armv7l:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
needs: build-raspbian_armv7l
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
ref: ${{github.event.pull_request.head.ref}}
|
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
||||||
|
|
||||||
- name: Pull web ui
|
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
|
||||||
with:
|
|
||||||
repo: meshtastic/web
|
|
||||||
file: build.tar
|
|
||||||
target: build.tar
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Get release version string
|
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
|
||||||
id: version
|
|
||||||
|
|
||||||
- name: Download artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-raspbian-armv7l-${{ steps.version.outputs.version }}.zip
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
|
||||||
run: ls -R
|
|
||||||
|
|
||||||
- name: build .debpkg
|
|
||||||
run: |
|
|
||||||
mkdir -p .debpkg/DEBIAN
|
|
||||||
mkdir -p .debpkg/usr/share/meshtasticd/web
|
|
||||||
mkdir -p .debpkg/usr/sbin
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
|
||||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
|
||||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
|
||||||
tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web
|
|
||||||
shopt -s dotglob nullglob
|
|
||||||
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/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; 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/meshtasticd/web/ -r
|
|
||||||
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
|
|
||||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
|
||||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ -r
|
|
||||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
|
||||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
|
||||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
|
||||||
chmod +x .debpkg/DEBIAN/conffiles
|
|
||||||
# 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
|
|
||||||
with:
|
|
||||||
package: meshtasticd
|
|
||||||
package_root: .debpkg
|
|
||||||
maintainer: Jonathan Bennett
|
|
||||||
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
|
||||||
arch: armhf
|
|
||||||
depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0
|
|
||||||
desc: Native Linux Meshtastic binary.
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
|
||||||
overwrite: true
|
|
||||||
path: |
|
|
||||||
./*.deb
|
|
||||||
106
.github/workflows/release_channels.yml
vendored
Normal file
106
.github/workflows/release_channels.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
# Create a PR to bump version when a release is Published
|
||||||
|
bump-version:
|
||||||
|
if: github.event.action == 'published'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
contents: write
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
|
||||||
|
- name: Bump version.properties
|
||||||
|
run: |
|
||||||
|
# Bump version.properties
|
||||||
|
chmod +x ./bin/bump_version.py
|
||||||
|
./bin/bump_version.py
|
||||||
|
|
||||||
|
- name: Get new release version string
|
||||||
|
run: |
|
||||||
|
echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT
|
||||||
|
id: new_version
|
||||||
|
|
||||||
|
- name: Ensure debian deps are installed
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y devscripts
|
||||||
|
|
||||||
|
- name: Update debian changelog
|
||||||
|
run: |
|
||||||
|
# Update debian changelog
|
||||||
|
chmod +x ./debian/ci_changelog.sh
|
||||||
|
./debian/ci_changelog.sh
|
||||||
|
|
||||||
|
- name: Bump org.meshtastic.meshtasticd.metainfo.xml
|
||||||
|
run: |
|
||||||
|
# Bump org.meshtastic.meshtasticd.metainfo.xml
|
||||||
|
pip install -r bin/bump_metainfo/requirements.txt -q
|
||||||
|
chmod +x ./bin/bump_metainfo/bump_metainfo.py
|
||||||
|
./bin/bump_metainfo/bump_metainfo.py --file bin/org.meshtastic.meshtasticd.metainfo.xml "${{ steps.new_version.outputs.short }}"
|
||||||
|
env:
|
||||||
|
PIP_DISABLE_PIP_VERSION_CHECK: 1
|
||||||
|
|
||||||
|
- name: Create Bumps pull request
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
base: ${{ github.event.repository.default_branch }}
|
||||||
|
title: Bump release version
|
||||||
|
commit-message: automated bumps
|
||||||
|
add-paths: |
|
||||||
|
version.properties
|
||||||
|
debian/changelog
|
||||||
|
bin/org.meshtastic.meshtasticd.metainfo.xml
|
||||||
41
.github/workflows/sec_sast_flawfinder.yml
vendored
41
.github/workflows/sec_sast_flawfinder.yml
vendored
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
name: Flawfinder Scan
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master, develop]
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
- "version.properties"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
flawfinder:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Flawfinder
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# step 1
|
|
||||||
- name: clone application source code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
# step 2
|
|
||||||
- name: flawfinder_scan
|
|
||||||
uses: david-a-wheeler/flawfinder@2.0.19
|
|
||||||
with:
|
|
||||||
arguments: "--sarif ./"
|
|
||||||
output: "flawfinder_report.sarif"
|
|
||||||
|
|
||||||
# step 3
|
|
||||||
- name: save report as pipeline artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: flawfinder_report.sarif
|
|
||||||
overwrite: true
|
|
||||||
path: flawfinder_report.sarif
|
|
||||||
|
|
||||||
# step 4
|
|
||||||
- name: publish code scanning alerts
|
|
||||||
uses: github/codeql-action/upload-sarif@v3
|
|
||||||
with:
|
|
||||||
sarif_file: flawfinder_report.sarif
|
|
||||||
category: flawfinder
|
|
||||||
11
.github/workflows/sec_sast_semgrep_cron.yml
vendored
11
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -3,14 +3,17 @@ name: Semgrep Full Scan
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 1 * * 6"
|
- cron: 0 1 * * 6
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
semgrep-full:
|
semgrep-full:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04
|
||||||
container:
|
container:
|
||||||
image: semgrep/semgrep
|
image: semgrep/semgrep
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/sec_sast_semgrep_pull.yml
vendored
4
.github/workflows/sec_sast_semgrep_pull.yml
vendored
@@ -2,9 +2,11 @@
|
|||||||
name: Semgrep Differential Scan
|
name: Semgrep Differential Scan
|
||||||
on: pull_request
|
on: pull_request
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
semgrep-diff:
|
semgrep-diff:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
container:
|
container:
|
||||||
image: semgrep/semgrep
|
image: semgrep/semgrep
|
||||||
|
|
||||||
|
|||||||
3
.github/workflows/stale_bot.yml
vendored
3
.github/workflows/stale_bot.yml
vendored
@@ -16,7 +16,8 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Stale PR+Issues
|
- name: Stale PR+Issues
|
||||||
uses: actions/stale@v9.0.0
|
uses: actions/stale@v9.1.0
|
||||||
with:
|
with:
|
||||||
|
days-before-stale: 45
|
||||||
exempt-issue-labels: pinned,3.0
|
exempt-issue-labels: pinned,3.0
|
||||||
exempt-pr-labels: pinned,3.0
|
exempt-pr-labels: pinned,3.0
|
||||||
|
|||||||
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@v2.1.0
|
||||||
|
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
|
||||||
84
.github/workflows/tests.yml
vendored
84
.github/workflows/tests.yml
vendored
@@ -2,83 +2,17 @@ name: End to end tests
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *" # Run every day at midnight
|
- cron: 0 0 * * * # Run every day at midnight
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: read
|
||||||
|
checks: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-simulator:
|
native-tests:
|
||||||
runs-on: ubuntu-latest
|
uses: ./.github/workflows/test_native.yml
|
||||||
env:
|
|
||||||
LCOV_CAPTURE_FLAGS: --quiet --capture --include "${PWD}/src/*" --exclude '*/src/mesh/generated/*' --directory .pio/build/coverage/src --base-directory "${PWD}"
|
|
||||||
steps:
|
|
||||||
- name: Install libs needed for native build
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get update --fix-missing
|
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
|
||||||
sudo apt-get install -y lcov
|
|
||||||
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Upgrade python tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install -U platformio adafruit-nrfutil dotmap
|
|
||||||
pip install -U meshtastic --pre
|
|
||||||
|
|
||||||
- name: Upgrade platformio
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
pio upgrade
|
|
||||||
|
|
||||||
- name: Build Native
|
|
||||||
run: bin/build-native.sh
|
|
||||||
|
|
||||||
# We now run integration test before other build steps (to quickly see runtime failures)
|
|
||||||
- name: Build for native/coverage
|
|
||||||
run: |
|
|
||||||
platformio run -e coverage
|
|
||||||
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --initial --output-file coverage_base.info
|
|
||||||
|
|
||||||
- name: Integration test
|
|
||||||
run: |
|
|
||||||
.pio/build/coverage/program &
|
|
||||||
PID=$!
|
|
||||||
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
|
|
||||||
echo "Simulator started, launching python test..."
|
|
||||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
|
||||||
wait
|
|
||||||
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name integration --output-file coverage_integration.info
|
|
||||||
|
|
||||||
- name: PlatformIO Tests
|
|
||||||
run: |
|
|
||||||
platformio test -e coverage --junit-output-path testreport.xml
|
|
||||||
lcov ${{ env.LCOV_CAPTURE_FLAGS }} --test-name tests --output-file coverage_tests.info
|
|
||||||
|
|
||||||
- name: Test Report
|
|
||||||
uses: dorny/test-reporter@v1.9.1
|
|
||||||
if: success() || failure() # run this step even if previous step failed
|
|
||||||
with:
|
|
||||||
name: PlatformIO Tests
|
|
||||||
path: testreport.xml
|
|
||||||
reporter: java-junit
|
|
||||||
|
|
||||||
- name: Generate Code Coverage Report
|
|
||||||
run: |
|
|
||||||
lcov --quiet --add-tracefile coverage_base.info --add-tracefile coverage_integration.info --add-tracefile coverage_tests.info --output-file coverage_src.info
|
|
||||||
mkdir code-coverage-report
|
|
||||||
genhtml --quiet --legend --prefix "${PWD}" coverage_src.info --output-directory code-coverage-report
|
|
||||||
mv coverage_*.info code-coverage-report
|
|
||||||
|
|
||||||
- name: Save Code Coverage Report
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: code-coverage-report
|
|
||||||
path: code-coverage-report
|
|
||||||
|
|
||||||
hardware-tests:
|
hardware-tests:
|
||||||
runs-on: test-runner
|
runs-on: test-runner
|
||||||
@@ -113,7 +47,7 @@ jobs:
|
|||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 22
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
|
|||||||
26
.github/workflows/trunk_annotate_pr.yml
vendored
Normal file
26
.github/workflows/trunk_annotate_pr.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: Annotate PR with trunk issues
|
||||||
|
# See: https://github.com/trunk-io/trunk-action/blob/v1/readme.md#getting-inline-annotations-for-fork-prs
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: [Pull Request] # Name from `trunk_check.yml`
|
||||||
|
types: [completed]
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
trunk_check:
|
||||||
|
name: Trunk Code Quality Annotate
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
checks: write # For trunk to post annotations
|
||||||
|
contents: read # For repo checkout
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Trunk Check
|
||||||
|
uses: trunk-io/trunk-action@v1
|
||||||
|
with:
|
||||||
|
post-annotations: true
|
||||||
@@ -9,7 +9,7 @@ permissions: read-all
|
|||||||
jobs:
|
jobs:
|
||||||
trunk_check:
|
trunk_check:
|
||||||
name: Trunk Check Runner
|
name: Trunk Check Runner
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
checks: write # For trunk to post annotations
|
checks: write # For trunk to post annotations
|
||||||
contents: read # For repo checkout
|
contents: read # For repo checkout
|
||||||
@@ -20,3 +20,5 @@ jobs:
|
|||||||
|
|
||||||
- name: Trunk Check
|
- name: Trunk Check
|
||||||
uses: trunk-io/trunk-action@v1
|
uses: trunk-io/trunk-action@v1
|
||||||
|
with:
|
||||||
|
save-annotations: true
|
||||||
12
.github/workflows/trunk_format_pr.yml
vendored
12
.github/workflows/trunk_format_pr.yml
vendored
@@ -4,11 +4,15 @@ on:
|
|||||||
issue_comment:
|
issue_comment:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
trunk-fmt:
|
trunk-fmt:
|
||||||
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
|
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -22,12 +26,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
@@ -1,10 +1,14 @@
|
|||||||
name: Update protobufs and regenerate classes
|
name: Update protobufs and regenerate classes
|
||||||
on: workflow_dispatch
|
on: workflow_dispatch
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-protobufs:
|
update-protobufs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -12,6 +16,7 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Update submodule
|
- name: Update submodule
|
||||||
|
if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
run: |
|
run: |
|
||||||
git submodule update --remote protobufs
|
git submodule update --remote protobufs
|
||||||
|
|
||||||
|
|||||||
9
.gitignore
vendored
9
.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
|
||||||
@@ -30,4 +37,4 @@ release/
|
|||||||
.vscode/extensions.json
|
.vscode/extensions.json
|
||||||
/compile_commands.json
|
/compile_commands.json
|
||||||
src/mesh/raspihttp/certificate.pem
|
src/mesh/raspihttp/certificate.pem
|
||||||
src/mesh/raspihttp/private_key.pem
|
src/mesh/raspihttp/private_key.pem
|
||||||
@@ -8,3 +8,4 @@ line_length: false
|
|||||||
spaces: false
|
spaces: false
|
||||||
url: false
|
url: false
|
||||||
whitespace: false
|
whitespace: false
|
||||||
|
headings: false
|
||||||
|
|||||||
1
.trunk/configs/.prettierignore
Normal file
1
.trunk/configs/.prettierignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
renovate.json
|
||||||
10
.trunk/configs/.prettierrc
Normal file
10
.trunk/configs/.prettierrc
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "userPrefs.jsonc",
|
||||||
|
"options": {
|
||||||
|
"trailingComma": "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,37 +1,35 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.22.8
|
version: 1.24.0
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v1.6.6
|
ref: v1.7.0
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- prettier@3.4.2
|
- checkov@3.2.435
|
||||||
- trufflehog@3.86.1
|
- renovate@40.34.4
|
||||||
- yamllint@1.35.1
|
- prettier@3.5.3
|
||||||
- bandit@1.8.0
|
- trufflehog@3.88.34
|
||||||
- checkov@3.2.334
|
- yamllint@1.37.1
|
||||||
- terrascan@1.19.9
|
- bandit@1.8.3
|
||||||
- trivy@0.58.0
|
- trivy@0.62.1
|
||||||
#- trufflehog@3.63.2-rc0
|
|
||||||
- taplo@0.9.3
|
- taplo@0.9.3
|
||||||
- ruff@0.8.3
|
- ruff@0.11.11
|
||||||
- isort@5.13.2
|
- isort@6.0.1
|
||||||
- markdownlint@0.43.0
|
- markdownlint@0.45.0
|
||||||
- oxipng@9.1.3
|
- oxipng@9.1.5
|
||||||
- svgo@3.3.2
|
- svgo@3.3.2
|
||||||
- actionlint@1.7.4
|
- actionlint@1.7.7
|
||||||
- flake8@7.1.1
|
- flake8@7.2.0
|
||||||
- hadolint@2.12.1-beta
|
- 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@25.1.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.21.2
|
- gitleaks@8.26.0
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
#- prettier@3.3.3
|
|
||||||
ignore:
|
ignore:
|
||||||
- linters: [ALL]
|
- linters: [ALL]
|
||||||
paths:
|
paths:
|
||||||
@@ -40,7 +38,7 @@ runtimes:
|
|||||||
enabled:
|
enabled:
|
||||||
- python@3.10.8
|
- python@3.10.8
|
||||||
- go@1.21.0
|
- go@1.21.0
|
||||||
- node@18.20.5
|
- node@22.16.0
|
||||||
actions:
|
actions:
|
||||||
disabled:
|
disabled:
|
||||||
- trunk-announce
|
- trunk-announce
|
||||||
|
|||||||
57
.vscode/settings.json
vendored
57
.vscode/settings.json
vendored
@@ -7,5 +7,62 @@
|
|||||||
"cmake.configureOnOpen": false,
|
"cmake.configureOnOpen": false,
|
||||||
"[cpp]": {
|
"[cpp]": {
|
||||||
"editor.defaultFormatter": "trunk.io"
|
"editor.defaultFormatter": "trunk.io"
|
||||||
|
},
|
||||||
|
"[powershell]": {
|
||||||
|
"editor.defaultFormatter": "ms-vscode.powershell"
|
||||||
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"csignal": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"*.xbm": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
Dockerfile
56
Dockerfile
@@ -1,47 +1,67 @@
|
|||||||
# 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(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
|
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||||
|
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||||
|
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||||
|
|
||||||
FROM python:3.12-bookworm AS builder
|
FROM python:3.13-bookworm AS builder
|
||||||
|
ARG PIO_ENV=native
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Etc/UTC
|
ENV TZ=Etc/UTC
|
||||||
|
|
||||||
# Install Dependencies
|
# Install Dependencies
|
||||||
ENV PIP_ROOT_USER_ACTION=ignore
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y wget g++ zip git ca-certificates \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
|
curl wget g++ zip git ca-certificates pkg-config \
|
||||||
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config && \
|
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev \
|
||||||
pip install --no-cache-dir -U platformio==6.1.16 && \
|
libx11-dev libinput-dev libxkbcommon-x11-dev \
|
||||||
mkdir /tmp/firmware
|
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& pip install --no-cache-dir -U platformio \
|
||||||
|
&& mkdir /tmp/firmware
|
||||||
|
|
||||||
# Copy source code
|
# Copy source code
|
||||||
WORKDIR /tmp/firmware
|
WORKDIR /tmp/firmware
|
||||||
COPY . /tmp/firmware
|
COPY . /tmp/firmware
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
RUN bash ./bin/build-native.sh && \
|
RUN bash ./bin/build-native.sh "$PIO_ENV" && \
|
||||||
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
||||||
|
|
||||||
|
# Fetch web assets
|
||||||
|
RUN curl -L "https://github.com/meshtastic/web/releases/download/v$(cat /tmp/firmware/bin/web.version)/build.tar" -o /tmp/web.tar \
|
||||||
|
&& mkdir -p /tmp/web \
|
||||||
|
&& tar -xf /tmp/web.tar -C /tmp/web/ \
|
||||||
|
&& gzip -dr /tmp/web \
|
||||||
|
&& rm /tmp/web.tar
|
||||||
|
|
||||||
##### PRODUCTION BUILD #############
|
##### PRODUCTION BUILD #############
|
||||||
|
|
||||||
FROM debian:bookworm-slim
|
FROM debian:bookworm-slim
|
||||||
|
LABEL org.opencontainers.image.title="Meshtastic" \
|
||||||
|
org.opencontainers.image.description="Debian Meshtastic daemon and web interface" \
|
||||||
|
org.opencontainers.image.url="https://meshtastic.org" \
|
||||||
|
org.opencontainers.image.documentation="https://meshtastic.org/docs/" \
|
||||||
|
org.opencontainers.image.authors="Meshtastic" \
|
||||||
|
org.opencontainers.image.licenses="GPL-3.0-or-later" \
|
||||||
|
org.opencontainers.image.source="https://github.com/meshtastic/firmware/"
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Etc/UTC
|
ENV TZ=Etc/UTC
|
||||||
|
|
||||||
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
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 && \
|
RUN apt-get update && apt-get --no-install-recommends -y install \
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/* \
|
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev \
|
||||||
|
liborcania2.3 libulfius2.7 libssl3 \
|
||||||
|
libx11-6 libinput10 libxkbcommon-x11-0 \
|
||||||
|
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /var/lib/meshtasticd \
|
&& mkdir -p /var/lib/meshtasticd \
|
||||||
&& mkdir -p /etc/meshtasticd/config.d
|
&& mkdir -p /etc/meshtasticd/config.d \
|
||||||
|
&& mkdir -p /etc/meshtasticd/ssl
|
||||||
|
|
||||||
# Fetch compiled binary from the builder
|
# Fetch compiled binary from the builder
|
||||||
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
|
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/bin/
|
||||||
|
COPY --from=builder /tmp/web /usr/share/meshtasticd/
|
||||||
# Copy config templates
|
# Copy config templates
|
||||||
COPY ./bin/config.d /etc/meshtasticd/available.d
|
COPY ./bin/config.d /etc/meshtasticd/available.d
|
||||||
|
|
||||||
@@ -50,7 +70,9 @@ VOLUME /var/lib/meshtasticd
|
|||||||
|
|
||||||
# Expose Meshtastic TCP API port from the host
|
# Expose Meshtastic TCP API port from the host
|
||||||
EXPOSE 4403
|
EXPOSE 4403
|
||||||
|
# Expose Meshtastic Web UI port from the host
|
||||||
|
EXPOSE 9443
|
||||||
|
|
||||||
CMD [ "sh", "-cx", "meshtasticd -d /var/lib/meshtasticd" ]
|
CMD [ "sh", "-cx", "meshtasticd --fsdir=/var/lib/meshtasticd" ]
|
||||||
|
|
||||||
HEALTHCHECK NONE
|
HEALTHCHECK NONE
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -1,4 +1,7 @@
|
|||||||
# Meshtastic Firmware
|
<div align="center" markdown="1">
|
||||||
|
|
||||||
|
<img src=".github/meshtastic_logo.png" alt="Meshtastic Logo" width="80"/>
|
||||||
|
<h1>Meshtastic Firmware</h1>
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/meshtastic/firmware/actions/workflows/ci.yml)
|
[](https://github.com/meshtastic/firmware/actions/workflows/ci.yml)
|
||||||
@@ -6,13 +9,31 @@
|
|||||||
[](https://opencollective.com/meshtastic/)
|
[](https://opencollective.com/meshtastic/)
|
||||||
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
|
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
|
||||||
|
|
||||||
|
<a href="https://trendshift.io/repositories/5524" target="_blank"><img src="https://trendshift.io/api/badge/repositories/5524" alt="meshtastic%2Ffirmware | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://meshtastic.org">Website</a>
|
||||||
|
-
|
||||||
|
<a href="https://meshtastic.org/docs/">Documentation</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This repository contains the device firmware for the Meshtastic project.
|
This repository contains the official device firmware for Meshtastic, an open-source LoRa mesh networking project designed for long-range, low-power communication without relying on internet or cellular infrastructure. The firmware supports various hardware platforms, including ESP32, nRF52, RP2040/RP2350, and Linux-based devices.
|
||||||
|
|
||||||
- **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
Meshtastic enables text messaging, location sharing, and telemetry over a decentralized mesh network, making it ideal for outdoor adventures, emergency preparedness, and remote operations.
|
||||||
- **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
|
||||||
|
### Get Started
|
||||||
|
|
||||||
|
- 🔧 **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)** – Learn how to compile the firmware from source.
|
||||||
|
- ⚡ **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)** – Install or update the firmware on your device.
|
||||||
|
|
||||||
|
Join our community and help improve Meshtastic! 🚀
|
||||||
|
|
||||||
## Stats
|
## Stats
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
| Firmware Version | Supported |
|
| Firmware Version | Supported |
|
||||||
| ---------------- | ------------------ |
|
| ---------------- | ------------------ |
|
||||||
| 2.5.x | :white_check_mark: |
|
| 2.6.x | :white_check_mark: |
|
||||||
| <= 2.4.x | :x: |
|
| <= 2.5.x | :x: |
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
# trunk-ignore-all(trivy/DS002): 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
|
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||||
|
# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
|
||||||
|
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||||
|
|
||||||
FROM python:3.12-alpine3.21 AS builder
|
FROM python:3.13-alpine3.21 AS builder
|
||||||
|
ARG PIO_ENV=native
|
||||||
ENV PIP_ROOT_USER_ACTION=ignore
|
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 && \
|
RUN apk --no-cache add \
|
||||||
pip install --no-cache-dir -U platformio==6.1.16 && \
|
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||||
mkdir /tmp/firmware
|
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
|
||||||
|
libx11-dev libinput-dev libxkbcommon-dev \
|
||||||
|
&& rm -rf /var/cache/apk/* \
|
||||||
|
&& pip install --no-cache-dir -U platformio \
|
||||||
|
&& mkdir /tmp/firmware
|
||||||
|
|
||||||
WORKDIR /tmp/firmware
|
WORKDIR /tmp/firmware
|
||||||
COPY . /tmp/firmware
|
COPY . /tmp/firmware
|
||||||
@@ -17,20 +22,35 @@ COPY . /tmp/firmware
|
|||||||
# Add `argp` for musl
|
# Add `argp` for musl
|
||||||
ENV PLATFORMIO_BUILD_FLAGS="-Os -ffunction-sections -fdata-sections -Wl,--gc-sections -largp"
|
ENV PLATFORMIO_BUILD_FLAGS="-Os -ffunction-sections -fdata-sections -Wl,--gc-sections -largp"
|
||||||
|
|
||||||
RUN bash ./bin/build-native.sh && \
|
RUN bash ./bin/build-native.sh "$PIO_ENV" && \
|
||||||
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
||||||
|
|
||||||
# ##### PRODUCTION BUILD #############
|
# ##### PRODUCTION BUILD #############
|
||||||
|
|
||||||
FROM alpine:3.21
|
FROM alpine:3.21
|
||||||
|
LABEL org.opencontainers.image.title="Meshtastic" \
|
||||||
|
org.opencontainers.image.description="Alpine Meshtastic daemon" \
|
||||||
|
org.opencontainers.image.url="https://meshtastic.org" \
|
||||||
|
org.opencontainers.image.documentation="https://meshtastic.org/docs/" \
|
||||||
|
org.opencontainers.image.authors="Meshtastic" \
|
||||||
|
org.opencontainers.image.licenses="GPL-3.0-or-later" \
|
||||||
|
org.opencontainers.image.source="https://github.com/meshtastic/firmware/"
|
||||||
|
|
||||||
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN apk add libstdc++ libgpiod yaml-cpp libusb i2c-tools \
|
RUN apk --no-cache add \
|
||||||
|
shadow libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
|
||||||
|
libx11 libinput libxkbcommon \
|
||||||
|
&& rm -rf /var/cache/apk/* \
|
||||||
&& mkdir -p /var/lib/meshtasticd \
|
&& mkdir -p /var/lib/meshtasticd \
|
||||||
&& mkdir -p /etc/meshtasticd/config.d
|
&& mkdir -p /etc/meshtasticd/config.d \
|
||||||
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
|
&& mkdir -p /etc/meshtasticd/ssl
|
||||||
|
|
||||||
|
# Fetch compiled binary from the builder
|
||||||
|
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/bin/
|
||||||
|
# Copy config templates
|
||||||
|
COPY ./bin/config.d /etc/meshtasticd/available.d
|
||||||
|
|
||||||
WORKDIR /var/lib/meshtasticd
|
WORKDIR /var/lib/meshtasticd
|
||||||
VOLUME /var/lib/meshtasticd
|
VOLUME /var/lib/meshtasticd
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
custom_esp32_kind = esp32
|
custom_esp32_kind = esp32
|
||||||
platform = platformio/espressif32@6.9.0
|
platform =
|
||||||
|
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
|
||||||
|
platformio/espressif32@6.10.0
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||||
@@ -37,19 +39,27 @@ build_flags =
|
|||||||
-DLIBPAX_ARDUINO
|
-DLIBPAX_ARDUINO
|
||||||
-DLIBPAX_WIFI
|
-DLIBPAX_WIFI
|
||||||
-DLIBPAX_BLE
|
-DLIBPAX_BLE
|
||||||
|
-DHAS_UDP_MULTICAST=1
|
||||||
;-DDEBUG_HEAP
|
;-DDEBUG_HEAP
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
|
${environmental_extra.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
||||||
h2zero/NimBLE-Arduino@^1.4.2
|
https://github.com/meshtastic/esp32_https_server/archive/896f1771ceb5979987a0b41028bf1b4e7aad419b.zip
|
||||||
https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1
|
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
||||||
lewisxhe/XPowersLib@^0.2.6
|
h2zero/NimBLE-Arduino@^1.4.3
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
||||||
rweather/Crypto@^0.4.0
|
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||||
|
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
|
||||||
|
lewisxhe/XPowersLib@^0.2.7
|
||||||
|
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
||||||
|
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||||
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
|
rweather/Crypto@0.4.0
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
segger_rtt
|
segger_rtt
|
||||||
@@ -65,4 +75,4 @@ lib_ignore =
|
|||||||
|
|
||||||
; customize the partition table
|
; customize the partition table
|
||||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||||
board_build.partitions = partition-table.csv
|
board_build.partitions = partition-table.csv
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
[esp32c6_base]
|
[esp32c6_base]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
platform = https://github.com/Jason2866/platform-espressif32.git#22faa566df8c789000f8136cd8d0aca49617af55
|
platform =
|
||||||
|
# Do not renovate until we have switched to pioarduino tagged builds
|
||||||
|
https://github.com/Jason2866/platform-espressif32/archive/22faa566df8c789000f8136cd8d0aca49617af55.zip
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
-Wall
|
-Wall
|
||||||
@@ -23,10 +25,14 @@ lib_deps =
|
|||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
|
${environmental_extra.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
lewisxhe/XPowersLib@^0.2.6
|
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
lewisxhe/XPowersLib@^0.2.7
|
||||||
rweather/Crypto@^0.4.0
|
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
||||||
|
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||||
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
|
rweather/Crypto@0.4.0
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32_base.build_src_filter} -<mesh/http>
|
${esp32_base.build_src_filter} -<mesh/http>
|
||||||
@@ -38,4 +44,4 @@ lib_ignore =
|
|||||||
NonBlockingRTTTL
|
NonBlockingRTTTL
|
||||||
NimBLE-Arduino
|
NimBLE-Arduino
|
||||||
libpax
|
libpax
|
||||||
|
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ build_flags =
|
|||||||
lib_ignore =
|
lib_ignore =
|
||||||
${esp32_base.lib_ignore}
|
${esp32_base.lib_ignore}
|
||||||
NimBLE-Arduino
|
NimBLE-Arduino
|
||||||
libpax
|
libpax
|
||||||
|
|||||||
@@ -3,4 +3,3 @@ extends = esp32_base
|
|||||||
custom_esp32_kind = esp32s3
|
custom_esp32_kind = esp32s3
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
[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.7.0
|
platform =
|
||||||
|
# renovate: datasource=custom.pio depName=platformio/nordicnrf52 packageName=platformio/platform/nordicnrf52
|
||||||
|
platformio/nordicnrf52@^10.8.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
|
# TODO renovate
|
||||||
toolchain-gccarmnoneeabi@~1.90301.0
|
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
||||||
|
; Don't renovate toolchain-gccarmnoneeabi
|
||||||
|
platformio/toolchain-gccarmnoneeabi@~1.90301.0
|
||||||
|
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags =
|
build_flags =
|
||||||
@@ -17,7 +21,6 @@ build_flags =
|
|||||||
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
||||||
-DMESHTASTIC_EXCLUDE_AUDIO=1
|
-DMESHTASTIC_EXCLUDE_AUDIO=1
|
||||||
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
|
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
|
||||||
-DMAX_NUM_NODES=80
|
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||||
@@ -25,8 +28,9 @@ build_src_filter =
|
|||||||
lib_deps=
|
lib_deps=
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
|
rweather/Crypto@0.4.0
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
lvgl
|
lvgl
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ build_flags = ${nrf52_base.build_flags}
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52_base.lib_deps}
|
${nrf52_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
|
${environmental_extra.lib_deps}
|
||||||
|
# renovate: datasource=git-refs depName=Kongduino-Adafruit_nRFCrypto packageName=https://github.com/Kongduino/Adafruit_nRFCrypto gitBranch=master
|
||||||
|
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/5f838d2709461a2c981f642917aa50254a25c14c.zip
|
||||||
|
|
||||||
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or 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#562d189828f09fbf4c4093b3c0104bae9d8e9ff9
|
platform =
|
||||||
|
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
||||||
|
https://github.com/meshtastic/platform-native/archive/622341c6de8a239704318b10c3dbb00c21a3eab3.zip
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
@@ -15,18 +17,19 @@ build_src_filter =
|
|||||||
+<mesh/raspihttp/>
|
+<mesh/raspihttp/>
|
||||||
-<mesh/eth/>
|
-<mesh/eth/>
|
||||||
-<modules/esp32>
|
-<modules/esp32>
|
||||||
-<modules/Telemetry/EnvironmentTelemetry.cpp>
|
|
||||||
-<modules/Telemetry/AirQualityTelemetry.cpp>
|
|
||||||
-<modules/Telemetry/Sensor>
|
|
||||||
+<../variants/portduino>
|
+<../variants/portduino>
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
${environmental_base.lib_deps}
|
||||||
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
https://github.com/pine64/libch341-spi-userspace#a9b17e3452f7fb747000d9b4ad4409155b39f6ef
|
rweather/Crypto@0.4.0
|
||||||
|
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
||||||
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
|
# renovate: datasource=git-refs depName=libch341-spi-userspace packageName=https://github.com/pine64/libch341-spi-userspace gitBranch=main
|
||||||
|
https://github.com/pine64/libch341-spi-userspace/archive/af9bc27c9c30fa90772279925b7c5913dff789b4.zip
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
@@ -34,10 +37,15 @@ build_flags =
|
|||||||
-Isrc/platform/portduino
|
-Isrc/platform/portduino
|
||||||
-DRADIOLIB_EEPROM_UNSUPPORTED
|
-DRADIOLIB_EEPROM_UNSUPPORTED
|
||||||
-DPORTDUINO_LINUX_HARDWARE
|
-DPORTDUINO_LINUX_HARDWARE
|
||||||
|
-DHAS_UDP_MULTICAST
|
||||||
-lpthread
|
-lpthread
|
||||||
-lstdc++fs
|
-lstdc++fs
|
||||||
-lbluetooth
|
-lbluetooth
|
||||||
-lgpiod
|
-lgpiod
|
||||||
-lyaml-cpp
|
-lyaml-cpp
|
||||||
-li2c
|
-li2c
|
||||||
-std=c++17
|
-luv
|
||||||
|
-std=gnu17
|
||||||
|
-std=c++17
|
||||||
|
|
||||||
|
lib_ignore = Adafruit NeoPixel
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
; 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 =
|
||||||
|
# TODO renovate
|
||||||
|
https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5
|
||||||
|
; For arduino-pico >= 4.4.3
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
|
platform_packages =
|
||||||
|
# TODO renovate
|
||||||
|
framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
@@ -18,9 +23,12 @@ build_src_filter =
|
|||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
lvgl
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
|
${environmental_extra.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
|
rweather/Crypto@0.4.0
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2350 Processor based targets
|
||||||
[rp2350_base]
|
[rp2350_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico >=4.2.1
|
platform =
|
||||||
|
# TODO renovate
|
||||||
|
https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5
|
||||||
|
; For arduino-pico >= 4.4.3
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
|
platform_packages =
|
||||||
|
# TODO renovate
|
||||||
|
framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
|
||||||
|
|
||||||
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
|
|
||||||
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
|
||||||
@@ -21,5 +25,7 @@ lib_ignore =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
|
${environmental_extra.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto
|
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||||
|
rweather/Crypto@0.4.0
|
||||||
|
|||||||
@@ -1,38 +1,47 @@
|
|||||||
[stm32_base]
|
[stm32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = ststm32
|
platform =
|
||||||
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#ea74156acd823b6d14739f389e6cdc648f8ee36e
|
# renovate: datasource=custom.pio depName=platformio/ststm32 packageName=platformio/platform/ststm32
|
||||||
|
platformio/ststm32@19.1.0
|
||||||
|
platform_packages =
|
||||||
|
# TODO renovate
|
||||||
|
platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.10.1.zip
|
||||||
|
extra_scripts =
|
||||||
|
${env.extra_scripts}
|
||||||
|
post:extra_scripts/extra_stm32.py
|
||||||
|
|
||||||
build_type = release
|
build_type = release
|
||||||
|
|
||||||
;board_build.flash_offset = 0x08000000
|
build_flags =
|
||||||
|
|
||||||
build_flags =
|
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
-flto
|
-flto
|
||||||
-Isrc/platform/stm32wl -g
|
-Isrc/platform/stm32wl -g
|
||||||
-DMESHTASTIC_MINIMIZE_BUILD
|
-DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
|
-DMESHTASTIC_EXCLUDE_INPUTBROKER
|
||||||
|
-DMESHTASTIC_EXCLUDE_I2C
|
||||||
|
-DMESHTASTIC_EXCLUDE_POWERMON
|
||||||
|
-DMESHTASTIC_EXCLUDE_SCREEN
|
||||||
|
-DMESHTASTIC_EXCLUDE_MQTT
|
||||||
|
-DMESHTASTIC_EXCLUDE_BLUETOOTH
|
||||||
-DMESHTASTIC_EXCLUDE_GPS
|
-DMESHTASTIC_EXCLUDE_GPS
|
||||||
-DDEBUG_MUTE
|
;-DDEBUG_MUTE
|
||||||
; -DVECT_TAB_OFFSET=0x08000000
|
|
||||||
-DconfigUSE_CMSIS_RTOS_V2=1
|
|
||||||
; -DSPI_MODE_0=SPI_MODE0
|
|
||||||
-fmerge-all-constants
|
-fmerge-all-constants
|
||||||
-ffunction-sections
|
-ffunction-sections
|
||||||
-fdata-sections
|
-fdata-sections
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
||||||
|
|
||||||
board_upload.offset_address = 0x08000000
|
board_upload.offset_address = 0x08000000
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
|
debug_tool = stlink
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
charlesbaynham/OSFS@^1.2.3
|
${radiolib_base.lib_deps}
|
||||||
jgromes/RadioLib@7.0.2
|
# renovate: datasource=git-refs depName=caveman99-stm32-Crypto packageName=https://github.com/caveman99/Crypto gitBranch=main
|
||||||
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
|
https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
mathertel/OneButton@2.6.1
|
mathertel/OneButton@2.6.1
|
||||||
Wire
|
Wire
|
||||||
|
|||||||
1
bin/.gitignore
vendored
Normal file
1
bin/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
config.yaml
|
||||||
7
bin/99-meshtasticd-udev.rules
Normal file
7
bin/99-meshtasticd-udev.rules
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Set spidev ownership to 'spi' group
|
||||||
|
SUBSYSTEM=="spidev", KERNEL=="spidev*", GROUP="spi", MODE="0660"
|
||||||
|
# Allow access to USB CH341 devices
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="5512", MODE="0666"
|
||||||
|
# Set gpio ownership to 'gpio' group
|
||||||
|
SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660"
|
||||||
|
SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"
|
||||||
@@ -35,11 +35,11 @@ cp $SRCBIN $OUTDIR/$basename-update.bin
|
|||||||
|
|
||||||
echo "Building Filesystem for ESP32 targets"
|
echo "Building Filesystem for ESP32 targets"
|
||||||
pio run --environment $1 -t buildfs
|
pio run --environment $1 -t buildfs
|
||||||
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$VERSION.bin
|
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$1-$VERSION.bin
|
||||||
# Remove webserver files from the filesystem and rebuild
|
# Remove webserver files from the filesystem and rebuild
|
||||||
ls -l data/static # Diagnostic list of files
|
ls -l data/static # Diagnostic list of files
|
||||||
rm -rf data/static
|
rm -rf data/static
|
||||||
pio run --environment $1 -t buildfs
|
pio run --environment $1 -t buildfs
|
||||||
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
|
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$1-$VERSION.bin
|
||||||
cp bin/device-install.* $OUTDIR
|
cp bin/device-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
cp bin/device-update.* $OUTDIR
|
||||||
18
bin/build-firmware.sh
Normal file
18
bin/build-firmware.sh
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
|
||||||
|
|
||||||
|
export PIP_BREAK_SYSTEM_PACKAGES=1
|
||||||
|
|
||||||
|
if (echo $2 | grep -q "esp32"); then
|
||||||
|
bin/build-esp32.sh $1
|
||||||
|
elif (echo $2 | grep -q "nrf52"); then
|
||||||
|
bin/build-nrf52.sh $1
|
||||||
|
elif (echo $2 | grep -q "stm32"); then
|
||||||
|
bin/build-stm32.sh $1
|
||||||
|
elif (echo $2 | grep -q "rpi2040"); then
|
||||||
|
bin/build-rpi2040.sh $1
|
||||||
|
else
|
||||||
|
echo "Unknown target $2"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -15,6 +15,7 @@ platformioFailed() {
|
|||||||
|
|
||||||
VERSION=$(bin/buildinfo.py long)
|
VERSION=$(bin/buildinfo.py long)
|
||||||
SHORT_VERSION=$(bin/buildinfo.py short)
|
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||||
|
PIO_ENV=${1:-native}
|
||||||
|
|
||||||
OUTDIR=release/
|
OUTDIR=release/
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ mkdir -p $OUTDIR/
|
|||||||
rm -r $OUTDIR/* || true
|
rm -r $OUTDIR/* || true
|
||||||
|
|
||||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||||
platformio pkg update --environment native || platformioFailed
|
pio pkg update --environment "$PIO_ENV" || platformioFailed
|
||||||
pio run --environment native || platformioFailed
|
pio run --environment "$PIO_ENV" || platformioFailed
|
||||||
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
cp ".pio/build/$PIO_ENV/program" "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
||||||
cp bin/native-install.* $OUTDIR
|
cp bin/native-install.* $OUTDIR
|
||||||
|
|||||||
72
bin/bump_metainfo/bump_metainfo.py
Executable file
72
bin/bump_metainfo/bump_metainfo.py
Executable file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from defusedxml.ElementTree import parse
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
|
||||||
|
# Indent by 2 spaces to align with xml formatting.
|
||||||
|
def indent(elem, level=0):
|
||||||
|
i = "\n" + level * " "
|
||||||
|
if len(elem):
|
||||||
|
if not elem.text or not elem.text.strip():
|
||||||
|
elem.text = i + " "
|
||||||
|
for child in elem:
|
||||||
|
indent(child, level + 1)
|
||||||
|
if not child.tail or not child.tail.strip():
|
||||||
|
child.tail = i
|
||||||
|
if level and (not elem.tail or not elem.tail.strip()):
|
||||||
|
elem.tail = i
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Prepend new release entry to metainfo.xml file.")
|
||||||
|
parser.add_argument("--file", help="Path to the metainfo.xml file",
|
||||||
|
default="org.meshtastic.meshtasticd.metainfo.xml")
|
||||||
|
parser.add_argument("version", help="Version string (e.g. 2.6.4)")
|
||||||
|
parser.add_argument("--date", help="Release date (YYYY-MM-DD), defaults to today",
|
||||||
|
default=datetime.now(timezone.utc).date().isoformat())
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
tree = parse(args.file)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
releases = root.find('releases')
|
||||||
|
if releases is None:
|
||||||
|
raise RuntimeError("<releases> element not found in XML.")
|
||||||
|
|
||||||
|
existing_versions = {
|
||||||
|
release.get('version'): release
|
||||||
|
for release in releases.findall('release')
|
||||||
|
}
|
||||||
|
existing_release = existing_versions.get(args.version)
|
||||||
|
|
||||||
|
if existing_release is not None:
|
||||||
|
if not existing_release.get('date'):
|
||||||
|
print(f"Version {args.version} found without date. Adding date...")
|
||||||
|
existing_release.set('date', args.date)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"Version {args.version} is already present with date, skipping insertion.")
|
||||||
|
else:
|
||||||
|
new_release = ET.Element('release', {
|
||||||
|
'version': args.version,
|
||||||
|
'date': args.date
|
||||||
|
})
|
||||||
|
url = ET.SubElement(new_release, 'url', {'type': 'details'})
|
||||||
|
url.text = f"https://github.com/meshtastic/firmware/releases?q=tag%3Av{args.version}"
|
||||||
|
|
||||||
|
releases.insert(0, new_release)
|
||||||
|
|
||||||
|
indent(releases, level=1)
|
||||||
|
releases.tail = "\n"
|
||||||
|
|
||||||
|
print(f"Inserted new release: {args.version}")
|
||||||
|
|
||||||
|
tree.write(args.file, encoding='UTF-8', xml_declaration=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1
bin/bump_metainfo/requirements.txt
Normal file
1
bin/bump_metainfo/requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
defusedxml==0.7.1
|
||||||
@@ -6,18 +6,18 @@
|
|||||||
### Including the "Module:" line!
|
### Including the "Module:" line!
|
||||||
---
|
---
|
||||||
Lora:
|
Lora:
|
||||||
|
# Default to auto-detecting the module type
|
||||||
|
# This will be overridden by configs from config.d
|
||||||
|
Module: auto
|
||||||
|
|
||||||
|
# # Uncomment to enable Simulation mode, or use --sim
|
||||||
|
# Module: sim
|
||||||
|
|
||||||
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
|
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
|
||||||
# CS: 7
|
# CS: 7
|
||||||
# IRQ: 17
|
# IRQ: 17
|
||||||
# Reset: 22
|
# Reset: 22
|
||||||
|
|
||||||
# Module: RF95 # Adafruit RFM9x
|
|
||||||
# Reset: 25
|
|
||||||
# CS: 7
|
|
||||||
# IRQ: 22
|
|
||||||
# Busy: 23
|
|
||||||
|
|
||||||
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
|
# Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html
|
||||||
# Reset: 22
|
# Reset: 22
|
||||||
# CS: 7
|
# CS: 7
|
||||||
@@ -29,6 +29,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
|
||||||
@@ -43,9 +84,11 @@ Lora:
|
|||||||
# TXen: x # TX and RX enable pins
|
# TXen: x # TX and RX enable pins
|
||||||
# RXen: x
|
# RXen: x
|
||||||
|
|
||||||
|
# SX126X_MAX_POWER: 8 # Limit the output power to 8 dBm, useful for amped nodes
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
@@ -145,12 +188,22 @@ Logging:
|
|||||||
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
||||||
|
|
||||||
Webserver:
|
Webserver:
|
||||||
# Port: 443 # Port for Webserver & Webservices
|
# Port: 9443 # Port for Webserver & Webservices
|
||||||
# RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer
|
# RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer
|
||||||
|
# SSLKey: /etc/meshtasticd/ssl/private_key.pem # Path to SSL Key, generated if not present
|
||||||
|
# SSLCert: /etc/meshtasticd/ssl/certificate.pem # Path to SSL Certificate, generated if not present
|
||||||
|
|
||||||
|
|
||||||
|
HostMetrics:
|
||||||
|
# ReportInterval: 30 # Interval in minutes between HostMetrics report packets, or 0 for disabled
|
||||||
|
# Channel: 0 # channel to send Host Metrics over. Defaults to the primary channel.
|
||||||
|
# UserStringCommand: cat /sys/firmware/devicetree/base/serial-number # Command to execute, to send the results as the userString
|
||||||
|
|
||||||
|
|
||||||
General:
|
General:
|
||||||
MaxNodes: 200
|
MaxNodes: 200
|
||||||
MaxMessageQueue: 100
|
MaxMessageQueue: 100
|
||||||
ConfigDirectory: /etc/meshtasticd/config.d/
|
ConfigDirectory: /etc/meshtasticd/config.d/
|
||||||
|
AvailableDirectory: /etc/meshtasticd/available.d/
|
||||||
# MACAddress: AA:BB:CC:DD:EE:FF
|
# MACAddress: AA:BB:CC:DD:EE:FF
|
||||||
# MACAddressSource: eth0
|
# MACAddressSource: eth0
|
||||||
|
|||||||
4
bin/config.d/MUI/X11_480x480.yaml
Normal file
4
bin/config.d/MUI/X11_480x480.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Display:
|
||||||
|
Panel: X11
|
||||||
|
Width: 480
|
||||||
|
Height: 480
|
||||||
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
|
||||||
6
bin/config.d/lora-Adafruit-RFM9x.yaml
Normal file
6
bin/config.d/lora-Adafruit-RFM9x.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Lora:
|
||||||
|
Module: RF95 # Adafruit RFM9x
|
||||||
|
Reset: 25
|
||||||
|
CS: 7
|
||||||
|
IRQ: 22
|
||||||
|
# Busy: 23
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# MeshAdv-Pi E22-900M30S
|
||||||
|
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
|
||||||
Lora:
|
Lora:
|
||||||
Module: sx1262
|
Module: sx1262
|
||||||
CS: 21
|
CS: 21
|
||||||
@@ -7,3 +9,6 @@ Lora:
|
|||||||
TXen: 13
|
TXen: 13
|
||||||
RXen: 12
|
RXen: 12
|
||||||
DIO3_TCXO_VOLTAGE: true
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
# Only for E22-900M33S:
|
||||||
|
# Limit the output power to 8 dBm
|
||||||
|
# SX126X_MAX_POWER: 8
|
||||||
|
|||||||
11
bin/config.d/lora-MeshAdv-Mini-900M22S.yaml
Normal file
11
bin/config.d/lora-MeshAdv-Mini-900M22S.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# MeshAdv Mini E22-900M22S
|
||||||
|
# https://github.com/chrismyers2000/MeshAdv-Mini
|
||||||
|
Lora:
|
||||||
|
Module: sx1262 # Ebyte E22-900M22S
|
||||||
|
CS: 8
|
||||||
|
IRQ: 16
|
||||||
|
Busy: 20
|
||||||
|
Reset: 24
|
||||||
|
TXen: 13
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
11
bin/config.d/lora-piggystick-lr1121.yaml
Normal file
11
bin/config.d/lora-piggystick-lr1121.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Lora:
|
||||||
|
Module: lr1121
|
||||||
|
CS: 0
|
||||||
|
IRQ: 6
|
||||||
|
Reset: 2
|
||||||
|
Busy: 4
|
||||||
|
spidev: ch341
|
||||||
|
DIO3_TCXO_VOLTAGE: 1.8
|
||||||
|
# USB_Serialnum: 12345678
|
||||||
|
USB_PID: 0x5512
|
||||||
|
USB_VID: 0x1A86
|
||||||
49
bin/config.d/lora-raxda-rock2f-starter-edition-hat.yaml
Normal file
49
bin/config.d/lora-raxda-rock2f-starter-edition-hat.yaml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
Lora:
|
||||||
|
|
||||||
|
### Raxda Rock 2F running Armbian Linux 6.1.99-vendor-rk35xx
|
||||||
|
### https://github.com/markbirss/rock-2f
|
||||||
|
### https://github.com/markbirss/lora-starter-edition-sx1262-i2c
|
||||||
|
### https://github.com/radxa-pkg/radxa-overlays/blob/main/arch/arm64/boot/dts/rockchip/overlays/rk3528-spi0-cs1-spidev.dts
|
||||||
|
### Require install of https://github.com/radxa-pkg/radxa-overlays and rk3528-spi0-cs1-spidev.dtbo copied to /boot/dtb/rockchip/overlay and enabled
|
||||||
|
### in /boot/armbianEnv.txt - overlays=rk3528-spi0-cs1-spidev
|
||||||
|
### The Radxa Rock 2F 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 Rock 2F + Starter Edition SX1262 HAT by Mark Birss
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: 1.8
|
||||||
|
spidev: spidev0.1
|
||||||
|
CS: # NSS PIN_24 -> chip 4, line 14
|
||||||
|
pin: 24
|
||||||
|
gpiochip: 4
|
||||||
|
line: 14
|
||||||
|
SCK: # SCK PIN_23 -> chip 4, line 12
|
||||||
|
pin: 23
|
||||||
|
gpiochip: 4
|
||||||
|
line: 12
|
||||||
|
Busy: # BUSY PIN_7 -> chip 4, line 6
|
||||||
|
pin: 7
|
||||||
|
gpiochip: 4
|
||||||
|
line: 6
|
||||||
|
MOSI: # MOSI PIN_19 -> chip 4, line 10
|
||||||
|
pin: 19
|
||||||
|
gpiochip: 4
|
||||||
|
line: 10
|
||||||
|
MISO: # MISO PIN_21 -> chip 4, line 11
|
||||||
|
pin: 21
|
||||||
|
gpiochip: 4
|
||||||
|
line: 11
|
||||||
|
Reset: # NRST PIN_12 -> chip 1, line 13
|
||||||
|
pin: 12
|
||||||
|
gpiochip: 1
|
||||||
|
line: 13
|
||||||
|
IRQ: # DIO1 PIN_15 -> chip 4, line 22
|
||||||
|
pin: 15
|
||||||
|
gpiochip: 4
|
||||||
|
line: 22
|
||||||
|
# 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
|
||||||
10
bin/config.d/lora-starter-edition-sx1262-i2c.yaml
Normal file
10
bin/config.d/lora-starter-edition-sx1262-i2c.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# https://www.waveshare.com/core1262-868m.htm
|
||||||
|
# https://github.com/markbirss/lora-starter-edition-sx1262-i2c
|
||||||
|
Lora:
|
||||||
|
Module: sx1262 # Starter Edition SX1262 I2C Raspberry Pi HAT
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
CS: 8
|
||||||
|
IRQ: 22
|
||||||
|
Busy: 4
|
||||||
|
Reset: 18
|
||||||
17
bin/config.d/lora-usb-meshtoad-e22.yaml
Normal file
17
bin/config.d/lora-usb-meshtoad-e22.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Lora:
|
||||||
|
Module: sx1262
|
||||||
|
CS: 0
|
||||||
|
IRQ: 6
|
||||||
|
Reset: 2
|
||||||
|
Busy: 4
|
||||||
|
RXen: 1
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
spidev: ch341
|
||||||
|
USB_PID: 0x5512
|
||||||
|
USB_VID: 0x1A86
|
||||||
|
# Optional: Reduce power to 10 dBm to
|
||||||
|
# avoid over-drawing the USB port
|
||||||
|
# SX126X_MAX_POWER: 10
|
||||||
|
# Optional: Set the serial number for multi-radio support
|
||||||
|
# USB_Serialnum: 13374201
|
||||||
10
bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml
Normal file
10
bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# https://www.waveshare.com/pico-lora-sx1262-868m.htm
|
||||||
|
# https://github.com/markbirss/lora-ws-raspberry-pi-pico-to-rpi-adapter
|
||||||
|
Lora:
|
||||||
|
Module: sx1262 # Waveshare Raspberry Pi Pico to Raspberry Pi HAT Adapter
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
CS: 21
|
||||||
|
IRQ: 16
|
||||||
|
Busy: 20
|
||||||
|
Reset: 18
|
||||||
@@ -1,72 +1,295 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
SETLOCAL EnableDelayedExpansion
|
||||||
|
TITLE Meshtastic device-install
|
||||||
|
|
||||||
set PYTHON=python
|
SET "SCRIPT_NAME=%~nx0"
|
||||||
set WEB_APP=0
|
SET "DEBUG=0"
|
||||||
|
SET "PYTHON="
|
||||||
|
SET "WEB_APP=0"
|
||||||
|
SET "TFT_BUILD=0"
|
||||||
|
SET "BIGDB8=0"
|
||||||
|
SET "BIGDB16=0"
|
||||||
|
SET "ESPTOOL_BAUD=115200"
|
||||||
|
SET "ESPTOOL_CMD="
|
||||||
|
SET "LOGCOUNTER=0"
|
||||||
|
|
||||||
:: Determine the correct esptool command to use
|
@REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable.
|
||||||
where esptool >nul 2>&1
|
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
|
||||||
if %ERRORLEVEL% EQU 0 (
|
SET "C3=esp32c3"
|
||||||
set "ESPTOOL_CMD=esptool"
|
@REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable.
|
||||||
) else (
|
SET "BIGDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core tracksenger"
|
||||||
set "ESPTOOL_CMD=%PYTHON% -m esptool"
|
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite t-watch-s3"
|
||||||
)
|
|
||||||
|
|
||||||
goto GETOPTS
|
GOTO getopts
|
||||||
:HELP
|
:help
|
||||||
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] [--web]
|
ECHO Flash image file to device, but first erasing and writing system information.
|
||||||
echo Flash image file to device, but first erasing and writing system information
|
ECHO.
|
||||||
echo.
|
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python] (--web)
|
||||||
echo -h Display this help and exit
|
ECHO.
|
||||||
echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
|
ECHO Options:
|
||||||
echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%)
|
ECHO -f filename The firmware .bin file to flash. Custom to your device type and region. (required)
|
||||||
echo -f FILENAME The .bin file to flash. Custom to your device type and region.
|
ECHO The file must be located in this current directory.
|
||||||
echo --web Flash WEB APP.
|
ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
|
||||||
goto EOF
|
ECHO If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
|
ECHO -P python Specify alternate python interpreter to use to invoke esptool. (default: python)
|
||||||
|
ECHO If supplied the script will use python.
|
||||||
|
ECHO If not supplied the script will try to find esptool in Path.
|
||||||
|
ECHO --web Enable WebUI. (default: false)
|
||||||
|
ECHO.
|
||||||
|
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4.bin -p COM11
|
||||||
|
ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.bin -p COM11 --web
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
:GETOPTS
|
:version
|
||||||
if /I "%1"=="-h" goto HELP
|
ECHO %SCRIPT_NAME% [Version 2.6.1]
|
||||||
if /I "%1"=="--help" goto HELP
|
ECHO Meshtastic
|
||||||
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
|
GOTO eof
|
||||||
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
|
|
||||||
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
|
:getopts
|
||||||
if /I "%1"=="--web" set WEB_APP=1 & SHIFT
|
IF "%~1"=="" GOTO endopts
|
||||||
|
IF /I "%~1"=="-?" GOTO help
|
||||||
|
IF /I "%~1"=="-h" GOTO help
|
||||||
|
IF /I "%~1"=="--help" GOTO help
|
||||||
|
IF /I "%~1"=="-v" GOTO version
|
||||||
|
IF /I "%~1"=="--version" GOTO version
|
||||||
|
IF /I "%~1"=="--debug" SET "DEBUG=1" & CALL :LOG_MESSAGE DEBUG "DEBUG mode: enabled."
|
||||||
|
IF /I "%~1"=="-f" SET "FILENAME=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-p" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--port" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-P" SET "PYTHON=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--web" SET "WEB_APP=1"
|
||||||
SHIFT
|
SHIFT
|
||||||
IF NOT "__%1__"=="____" goto GETOPTS
|
GOTO getopts
|
||||||
|
:endopts
|
||||||
|
|
||||||
IF "__%FILENAME%__" == "____" (
|
CALL :LOG_MESSAGE DEBUG "Checking FILENAME parameter..."
|
||||||
echo "Missing FILENAME"
|
IF "__!FILENAME!__"=="____" (
|
||||||
goto HELP
|
CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
|
||||||
)
|
GOTO help
|
||||||
IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
) ELSE (
|
||||||
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
|
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
|
||||||
%ESPTOOL_CMD% --baud 115200 erase_flash
|
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x00 %FILENAME%
|
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
|
||||||
|
GOTO help
|
||||||
@REM Account for S3 and C3 board's different OTA partition
|
|
||||||
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% IF x%FILENAME:station-g2=%==x%FILENAME% IF x%FILENAME:unphone=%==x%FILENAME% (
|
|
||||||
IF x%FILENAME:esp32c3=%==x%FILENAME% (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota.bin
|
|
||||||
) else (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-c3.bin
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin
|
|
||||||
)
|
)
|
||||||
IF %WEB_APP%==1 (
|
IF "__!FILENAME:firmware-=!__"=="__!FILENAME!__" (
|
||||||
for %%f in (littlefswebui-*.bin) do (
|
CALL :LOG_MESSAGE ERROR "Filename must be a firmware-* file."
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
|
GOTO help
|
||||||
)
|
|
||||||
) else (
|
|
||||||
for %%f in (littlefs-*.bin) do (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
) else (
|
@REM Remove ".\" or "./" file prefix if present.
|
||||||
echo "Invalid file: %FILENAME%"
|
SET "FILENAME=!FILENAME:.\=!"
|
||||||
goto HELP
|
SET "FILENAME=!FILENAME:./=!"
|
||||||
) else (
|
|
||||||
echo "Invalid file: %FILENAME%"
|
|
||||||
goto HELP
|
|
||||||
)
|
)
|
||||||
|
|
||||||
:EOF
|
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
|
||||||
|
IF NOT EXIST !FILENAME! (
|
||||||
|
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
|
||||||
|
IF NOT "!FILENAME:update=!"=="!FILENAME!" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Use script device-update.bat to flash update !FILENAME!."
|
||||||
|
GOTO eof
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
|
||||||
|
IF NOT "__%PYTHON%__"=="____" (
|
||||||
|
SET "ESPTOOL_CMD=!PYTHON! -m esptool"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
|
||||||
|
WHERE esptool >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% EQU 0 (
|
||||||
|
@REM WHERE exits with code 0 if esptool is found.
|
||||||
|
SET "ESPTOOL_CMD=esptool"
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=python -m esptool"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
||||||
|
!ESPTOOL_CMD! >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% GEQ 2 (
|
||||||
|
@REM esptool exits with code 1 if help is displayed.
|
||||||
|
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
||||||
|
EXIT /B 1
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
IF %DEBUG% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
||||||
|
SET "ESPTOOL_CMD=REM !ESPTOOL_CMD!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
|
||||||
|
IF "__!ESPTOOL_PORT!__" == "____" (
|
||||||
|
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
|
||||||
|
)
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
|
||||||
|
|
||||||
|
@REM Check if FILENAME contains "-tft-" and set target partitionScheme accordingly.
|
||||||
|
@REM https://github.com/meshtastic/web-flasher/blob/main/types/resources.ts#L3
|
||||||
|
IF NOT "!FILENAME:-tft-=!"=="!FILENAME!" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are working with a *-tft-* file. !FILENAME!"
|
||||||
|
IF %WEB_APP% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Cannot enable WebUI (--web) and MUI." & GOTO eof
|
||||||
|
)
|
||||||
|
SET "TFT_BUILD=1"
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *-tft-* file. !FILENAME!"
|
||||||
|
)
|
||||||
|
|
||||||
|
FOR %%a IN (%BIGDB_8MB%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %BIGDB_8MB%.
|
||||||
|
SET "BIGDB8=1"
|
||||||
|
GOTO end_loop_bigdb_8mb
|
||||||
|
)
|
||||||
|
)
|
||||||
|
:end_loop_bigdb_8mb
|
||||||
|
|
||||||
|
FOR %%a IN (%BIGDB_16MB%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %BIGDB_16MB%.
|
||||||
|
SET "BIGDB16=1"
|
||||||
|
GOTO end_loop_bigdb_16mb
|
||||||
|
)
|
||||||
|
)
|
||||||
|
:end_loop_bigdb_16mb
|
||||||
|
|
||||||
|
IF %BIGDB8% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 8mb partition selected."
|
||||||
|
IF %BIGDB16% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 16mb partition selected."
|
||||||
|
|
||||||
|
@REM Extract BASENAME from %FILENAME% for later use.
|
||||||
|
SET "BASENAME=!FILENAME:firmware-=!"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Computed firmware basename: !BASENAME!"
|
||||||
|
|
||||||
|
@REM Account for S3 and C3 board's different OTA partition.
|
||||||
|
FOR %%a IN (%S3%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %S3%.
|
||||||
|
SET "OTA_FILENAME=bleota-s3.bin"
|
||||||
|
GOTO :end_loop_s3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
FOR %%a IN (%C3%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %C3%.
|
||||||
|
SET "OTA_FILENAME=bleota-c3.bin"
|
||||||
|
GOTO :end_loop_c3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Everything else
|
||||||
|
SET "OTA_FILENAME=bleota.bin"
|
||||||
|
:end_loop_s3
|
||||||
|
:end_loop_c3
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set OTA_FILENAME to: !OTA_FILENAME!"
|
||||||
|
|
||||||
|
@REM Check if (--web) is enabled and prefix BASENAME with "littlefswebui-" else "littlefs-".
|
||||||
|
IF %WEB_APP% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE INFO "WebUI selected."
|
||||||
|
SET "SPIFFS_FILENAME=littlefswebui-%BASENAME%"
|
||||||
|
) ELSE (
|
||||||
|
SET "SPIFFS_FILENAME=littlefs-%BASENAME%"
|
||||||
|
)
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
|
||||||
|
|
||||||
|
@REM Default offsets.
|
||||||
|
@REM https://github.com/meshtastic/web-flasher/blob/main/stores/firmwareStore.ts#L202
|
||||||
|
SET "OTA_OFFSET=0x260000"
|
||||||
|
SET "SPIFFS_OFFSET=0x300000"
|
||||||
|
|
||||||
|
@REM Offsets for BigDB 8mb.
|
||||||
|
IF %BIGDB8% EQU 1 (
|
||||||
|
SET "OTA_OFFSET=0x340000"
|
||||||
|
SET "SPIFFS_OFFSET=0x670000"
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Offsets for BigDB 16mb.
|
||||||
|
IF %BIGDB16% EQU 1 (
|
||||||
|
SET "OTA_OFFSET=0x650000"
|
||||||
|
SET "SPIFFS_OFFSET=0xc90000"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set OTA_OFFSET to: !OTA_OFFSET!"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_OFFSET to: !SPIFFS_OFFSET!"
|
||||||
|
|
||||||
|
@REM Ensure target files exist before flashing operations.
|
||||||
|
IF NOT EXIST !FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
|
||||||
|
IF NOT EXIST !OTA_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!OTA_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
|
||||||
|
IF NOT EXIST !SPIFFS_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!SPIFFS_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
|
||||||
|
|
||||||
|
@REM Flashing operations.
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash "!FILENAME!", but first erasing and writing system information..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! erase_flash || GOTO eof
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x00 "!FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash BLEOTA "!OTA_FILENAME!" at OTA_OFFSET !OTA_OFFSET!..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !OTA_OFFSET! "!OTA_FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash SPIFFS "!SPIFFS_FILENAME!" at SPIFFS_OFFSET !SPIFFS_OFFSET!..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !SPIFFS_OFFSET! "!SPIFFS_FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Script complete!."
|
||||||
|
|
||||||
|
:eof
|
||||||
|
ENDLOCAL
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|
||||||
|
:RUN_ESPTOOL
|
||||||
|
@REM Subroutine used to run ESPTOOL_CMD with arguments.
|
||||||
|
@REM Also handles %ERRORLEVEL%.
|
||||||
|
@REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
|
||||||
|
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4
|
||||||
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Error running command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:LOG_MESSAGE
|
||||||
|
@REM Subroutine used to print log messages in four different levels.
|
||||||
|
@REM DEBUG messages only get printed if [-d] flag is passed to script.
|
||||||
|
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
|
||||||
|
SET /A LOGCOUNTER=LOGCOUNTER+1
|
||||||
|
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO [91m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[91m%~2[0m
|
||||||
|
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO [32m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[32m%~2[0m
|
||||||
|
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO [33m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[33m%~2[0m
|
||||||
|
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO [34m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[34m%~2[0m
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:GET_TIMESTAMP
|
||||||
|
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
|
||||||
|
@REM CALL :GET_TIMESTAMP
|
||||||
|
@REM.
|
||||||
|
@REM Updates: !TIMESTAMP!
|
||||||
|
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
|
||||||
|
SET "HH=%%a"
|
||||||
|
SET "MM=%%b"
|
||||||
|
SET "ss=%%c"
|
||||||
|
)
|
||||||
|
SET "TIMESTAMP=!HH!:!MM!:!ss!"
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:RESET_ERROR
|
||||||
|
@REM Subroutine to reset %ERRORLEVEL% to 0.
|
||||||
|
@REM CALL :RESET_ERROR
|
||||||
|
@REM.
|
||||||
|
@REM Updates: %ERRORLEVEL%
|
||||||
|
EXIT /B 0
|
||||||
|
GOTO :eof
|
||||||
|
|||||||
@@ -1,18 +1,70 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
||||||
WEB_APP=false
|
WEB_APP=false
|
||||||
|
TFT_BUILD=false
|
||||||
|
MCU=""
|
||||||
|
|
||||||
|
# Variant groups
|
||||||
|
BIGDB_8MB=(
|
||||||
|
"picomputer-s3"
|
||||||
|
"unphone"
|
||||||
|
"seeed-sensecap-indicator"
|
||||||
|
"crowpanel-esp32s3"
|
||||||
|
"heltec_capsule_sensor_v3"
|
||||||
|
"heltec-v3"
|
||||||
|
"heltec-vision-master-e213"
|
||||||
|
"heltec-vision-master-e290"
|
||||||
|
"heltec-vision-master-t190"
|
||||||
|
"heltec-wireless-paper"
|
||||||
|
"heltec-wireless-tracker"
|
||||||
|
"heltec-wsl-v3"
|
||||||
|
"icarus"
|
||||||
|
"seeed-xiao-s3"
|
||||||
|
"tbeam-s3-core"
|
||||||
|
"tracksenger"
|
||||||
|
)
|
||||||
|
BIGDB_16MB=(
|
||||||
|
"t-deck"
|
||||||
|
"mesh-tab"
|
||||||
|
"t-energy-s3"
|
||||||
|
"dreamcatcher"
|
||||||
|
"ESP32-S3-Pico"
|
||||||
|
"m5stack-cores3"
|
||||||
|
"station-g2"
|
||||||
|
"t-eth-elite"
|
||||||
|
"t-watch-s3"
|
||||||
|
)
|
||||||
|
S3_VARIANTS=(
|
||||||
|
"s3"
|
||||||
|
"-v3"
|
||||||
|
"t-deck"
|
||||||
|
"wireless-paper"
|
||||||
|
"wireless-tracker"
|
||||||
|
"station-g2"
|
||||||
|
"unphone"
|
||||||
|
"t-eth-elite"
|
||||||
|
"mesh-tab"
|
||||||
|
"dreamcatcher"
|
||||||
|
"ESP32-S3-Pico"
|
||||||
|
"seeed-sensecap-indicator"
|
||||||
|
"heltec_capsule_sensor_v3"
|
||||||
|
"vision-master"
|
||||||
|
"icarus"
|
||||||
|
"tracksenger"
|
||||||
|
"elecrow-adv"
|
||||||
|
)
|
||||||
|
|
||||||
# Determine the correct esptool command to use
|
# Determine the correct esptool command to use
|
||||||
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="$PYTHON -m esptool"
|
ESPTOOL_CMD="$PYTHON -m esptool"
|
||||||
elif command -v esptool >/dev/null 2>&1; then
|
elif command -v esptool >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="esptool"
|
ESPTOOL_CMD="esptool"
|
||||||
elif command -v esptool.py >/dev/null 2>&1; then
|
elif command -v esptool.py >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="esptool.py"
|
ESPTOOL_CMD="esptool.py"
|
||||||
else
|
else
|
||||||
echo "Error: esptool not found"
|
echo "Error: esptool not found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
@@ -20,76 +72,142 @@ set -e
|
|||||||
# Usage info
|
# Usage info
|
||||||
show_help() {
|
show_help() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--web]
|
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME] [--web]
|
||||||
Flash image file to device, but first erasing and writing system information"
|
Flash image file to device, but first erasing and writing system information.
|
||||||
|
|
||||||
-h Display this help and exit
|
-h Display this help and exit.
|
||||||
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
||||||
-f FILENAME The .bin file to flash. Custom to your device type and region.
|
-f FILENAME The firmware .bin file to flash. Custom to your device type and region.
|
||||||
--web Flash WEB APP.
|
--web Enable WebUI. (Default: false)
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
# Preprocess long options like --web
|
# Parse arguments using a single while loop
|
||||||
for arg in "$@"; do
|
while [ $# -gt 0 ]; do
|
||||||
case "$arg" in
|
case "$1" in
|
||||||
--web)
|
-h | --help)
|
||||||
WEB_APP=true
|
|
||||||
shift # Remove this argument from the list
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
while getopts ":hp:P:f:" opt; do
|
|
||||||
case "${opt}" in
|
|
||||||
h)
|
|
||||||
show_help
|
show_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
p)
|
-p)
|
||||||
export ESPTOOL_PORT=${OPTARG}
|
ESPTOOL_CMD="$ESPTOOL_CMD --port $2"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
P)
|
-P)
|
||||||
PYTHON=${OPTARG}
|
PYTHON="$2"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
f)
|
-f)
|
||||||
FILENAME=${OPTARG}
|
FILENAME="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--web)
|
||||||
|
WEB_APP=true
|
||||||
|
;;
|
||||||
|
--) # Stop parsing options
|
||||||
|
shift
|
||||||
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid flag."
|
echo "Unknown argument: $1" >&2
|
||||||
show_help >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
shift # Move to the next argument
|
||||||
done
|
done
|
||||||
shift "$((OPTIND - 1))"
|
|
||||||
|
|
||||||
[ -z "$FILENAME" -a -n "$1" ] && {
|
[ -z "$FILENAME" -a -n "$1" ] && {
|
||||||
FILENAME=$1
|
FILENAME=$1
|
||||||
shift
|
shift
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [[ $FILENAME != firmware-* ]]; then
|
||||||
|
echo "Filename must be a firmware-* file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if FILENAME contains "-tft-" and prevent web/mui comingling.
|
||||||
|
if [[ ${FILENAME//-tft-/} != "$FILENAME" ]]; then
|
||||||
|
TFT_BUILD=true
|
||||||
|
if [[ $WEB_APP == true ]] && [[ $TFT_BUILD == true ]]; then
|
||||||
|
echo "Cannot enable WebUI (--web) and MUI."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract BASENAME from %FILENAME% for later use.
|
||||||
|
BASENAME="${FILENAME/firmware-/}"
|
||||||
|
|
||||||
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"
|
# Default littlefs* offset (--web).
|
||||||
$ESPTOOL_CMD erase_flash
|
OFFSET=0x300000
|
||||||
$ESPTOOL_CMD write_flash 0x00 ${FILENAME}
|
|
||||||
|
# Default OTA Offset
|
||||||
|
OTA_OFFSET=0x260000
|
||||||
|
|
||||||
|
# littlefs* offset for BigDB 8mb and OTA OFFSET.
|
||||||
|
for variant in "${BIGDB_8MB[@]}"; do
|
||||||
|
if [ -z "${FILENAME##*"$variant"*}" ]; then
|
||||||
|
OFFSET=0x670000
|
||||||
|
OTA_OFFSET=0x340000
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# littlefs* offset for BigDB 16mb and OTA OFFSET.
|
||||||
|
for variant in "${BIGDB_16MB[@]}"; do
|
||||||
|
if [ -z "${FILENAME##*"$variant"*}" ]; then
|
||||||
|
OFFSET=0xc90000
|
||||||
|
OTA_OFFSET=0x650000
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# 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
|
# FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable
|
||||||
|
for variant in "${S3_VARIANTS[@]}"; do
|
||||||
|
if [ -z "${FILENAME##*"$variant"*}" ]; then
|
||||||
|
MCU="esp32s3"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$MCU" != "esp32s3" ]; then
|
||||||
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota.bin
|
OTAFILE=bleota.bin
|
||||||
else
|
else
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota-c3.bin
|
OTAFILE=bleota-c3.bin
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota-s3.bin
|
OTAFILE=bleota-s3.bin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if WEB_APP (--web) is enabled and add "littlefswebui-" to BASENAME else "littlefs-".
|
||||||
if [ "$WEB_APP" = true ]; then
|
if [ "$WEB_APP" = true ]; then
|
||||||
$ESPTOOL_CMD write_flash 0x300000 littlefswebui-*.bin
|
SPIFFSFILE=littlefswebui-${BASENAME}
|
||||||
else
|
else
|
||||||
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
|
SPIFFSFILE=littlefs-${BASENAME}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f $FILENAME ]]; then
|
||||||
|
echo "Error: file ${FILENAME} wasn't found. Terminating."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f $OTAFILE ]]; then
|
||||||
|
echo "Error: file ${OTAFILE} wasn't found. Terminating."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f $SPIFFSFILE ]]; then
|
||||||
|
echo "Error: file ${SPIFFSFILE} wasn't found. Terminating."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
|
$ESPTOOL_CMD erase_flash
|
||||||
|
$ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
|
||||||
|
echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
|
||||||
|
$ESPTOOL_CMD write_flash $OTA_OFFSET "${OTAFILE}"
|
||||||
|
echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"
|
||||||
|
$ESPTOOL_CMD write_flash $OFFSET "${SPIFFSFILE}"
|
||||||
|
|
||||||
else
|
else
|
||||||
show_help
|
show_help
|
||||||
echo "Invalid file: ${FILENAME}"
|
echo "Invalid file: ${FILENAME}"
|
||||||
|
|||||||
112
bin/device-install_test.ps1
Normal file
112
bin/device-install_test.ps1
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Unit-test for .\device-install.bat.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This script performs a positive unit-test on .\device-install.bat by creating the expected .bin
|
||||||
|
files for a device followed by running the .bat script without flashing the firmware (--debug).
|
||||||
|
If any errors are hit they are presented in the standard output. Investigate accordingly.
|
||||||
|
|
||||||
|
This script needs to be placed in the same directory as .\device-install.bat.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\device-install_test.ps1
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\device-install_test.ps1 -Verbose
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
.\device-install.bat --help
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
function New-EmptyFile() {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Position = 0, Mandatory = $true)]
|
||||||
|
# Specifies the file name.
|
||||||
|
[string]$FileName,
|
||||||
|
[Parameter(Position = 1)]
|
||||||
|
# Specifies the target path. (Get-Location).Path is the default.
|
||||||
|
[string]$Directory = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
$filePath = Join-Path -Path $Directory -ChildPath $FileName
|
||||||
|
|
||||||
|
Write-Verbose -Message "Create empty test file if it doesn't exist: $($FileName)"
|
||||||
|
New-Item -Path "$filePath" -ItemType File -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Remove-EmptyFile() {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Position = 0, Mandatory = $true)]
|
||||||
|
# Specifies the file name.
|
||||||
|
[string]$FileName,
|
||||||
|
[Parameter(Position = 1)]
|
||||||
|
# Specifies the target path. (Get-Location).Path is the default.
|
||||||
|
[string]$Directory = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
$filePath = Join-Path -Path $Directory -ChildPath $FileName
|
||||||
|
|
||||||
|
Write-Verbose -Message "Deleted empty test file: $($FileName)"
|
||||||
|
Remove-Item -Path "$filePath" | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$TestCases = New-Object -TypeName PSObject -Property @{
|
||||||
|
# Use this PSObject to define testcases according to this syntax:
|
||||||
|
# "testname" = @("firmware-testname","bleota","littlefs-testname","args")
|
||||||
|
"t-deck" = @("firmware-t-deck-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefs-t-deck-2.6.0.0b106d4.bin", "")
|
||||||
|
"t-deck_web" = @("firmware-t-deck-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefswebui-t-deck-2.6.0.0b106d4.bin", "--web")
|
||||||
|
"t-deck-tft" = @("firmware-t-deck-tft-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefs-t-deck-tft-2.6.0.0b106d4.bin", "")
|
||||||
|
"heltec-ht62-esp32c3" = @("firmware-heltec-ht62-esp32c3-sx1262-2.6.0.0b106d4.bin", "bleota-c3.bin", "littlefs-heltec-ht62-esp32c3-sx1262-2.6.0.0b106d4.bin", "")
|
||||||
|
"tlora-c6" = @("firmware-tlora-c6-2.6.0.0b106d4.bin", "bleota.bin", "littlefs-tlora-c6-2.6.0.0b106d4.bin", "")
|
||||||
|
"heltec-v3_web" = @("firmware-heltec-v3-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefswebui-heltec-v3-2.6.0.0b106d4.bin", "--web")
|
||||||
|
"seeed-sensecap-indicator-tft" = @("firmware-seeed-sensecap-indicator-tft-2.6.0.0b106d4.bin", "bleota.bin", "littlefs-seeed-sensecap-indicator-tft-2.6.0.0b106d4.bin", "")
|
||||||
|
"picomputer-s3-tft" = @("firmware-picomputer-s3-tft-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefs-picomputer-s3-tft-2.6.0.0b106d4.bin", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($TestCase in $TestCases.PSObject.Properties) {
|
||||||
|
$Name = $TestCase.Name
|
||||||
|
$Files = $TestCase.Value
|
||||||
|
$Errors = $null
|
||||||
|
$Counter = 0
|
||||||
|
|
||||||
|
Write-Host -Object "Testcase: $Name`:" -ForegroundColor Green
|
||||||
|
foreach ($File in $Files) {
|
||||||
|
if ($File.EndsWith(".bin")) {
|
||||||
|
New-EmptyFile -FileName $File
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host -Object "Performing test on $Name..." -ForegroundColor Blue
|
||||||
|
$Test = Invoke-Expression -Command "cmd /c .\device-install.bat --debug -f $($TestCases."$Name"[0]) $($TestCases."$Name"[3])"
|
||||||
|
|
||||||
|
foreach ($Line in $Test) {
|
||||||
|
if ($Line -match "Set OTA_OFFSET to" -or `
|
||||||
|
$Line -match "Set SPIFFS_OFFSET to") {
|
||||||
|
Write-Host -Object "$($Line -replace "^.*?Set","Set")" -ForegroundColor Blue
|
||||||
|
}
|
||||||
|
elseif ($VerbosePreference -eq "Continue") {
|
||||||
|
Write-Host -Object $Line
|
||||||
|
}
|
||||||
|
if ($Line -match "ERROR") {
|
||||||
|
$Errors += $Line
|
||||||
|
$Counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($null -ne $Errors) {
|
||||||
|
Write-Host -Object "$Counter ERROR(s) detected!" -ForegroundColor Red
|
||||||
|
if (-not ($VerbosePreference -eq "Continue")) { Write-Host -Object $Errors }
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($File in $Files) {
|
||||||
|
if ($File.EndsWith(".bin")) {
|
||||||
|
Remove-EmptyFile -FileName $File
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,48 +1,176 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
SETLOCAL EnableDelayedExpansion
|
||||||
|
TITLE Meshtastic device-update
|
||||||
|
|
||||||
set PYTHON=python
|
SET "SCRIPT_NAME=%~nx0"
|
||||||
|
SET "DEBUG=0"
|
||||||
|
SET "PYTHON="
|
||||||
|
SET "ESPTOOL_BAUD=115200"
|
||||||
|
SET "ESPTOOL_CMD="
|
||||||
|
SET "LOGCOUNTER=0"
|
||||||
|
|
||||||
:: Determine the correct esptool command to use
|
GOTO getopts
|
||||||
where esptool >nul 2>&1
|
:help
|
||||||
if %ERRORLEVEL% EQU 0 (
|
ECHO Flash image file to device, but leave existing system intact.
|
||||||
set "ESPTOOL_CMD=esptool"
|
ECHO.
|
||||||
) else (
|
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python]
|
||||||
set "ESPTOOL_CMD=%PYTHON% -m esptool"
|
ECHO.
|
||||||
)
|
ECHO Options:
|
||||||
|
ECHO -f filename The update .bin file to flash. Custom to your device type and region. (required)
|
||||||
|
ECHO The file must be located in this current directory.
|
||||||
|
ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
|
||||||
|
ECHO If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
|
ECHO -P python Specify alternate python interpreter to use to invoke esptool. (default: python)
|
||||||
|
ECHO If supplied the script will use python.
|
||||||
|
ECHO If not supplied the script will try to find esptool in Path.
|
||||||
|
ECHO.
|
||||||
|
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4-update.bin -p COM11
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
goto GETOPTS
|
:version
|
||||||
:HELP
|
ECHO %SCRIPT_NAME% [Version 2.6.1]
|
||||||
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME]
|
ECHO Meshtastic
|
||||||
echo Flash image file to device, leave existing system intact.
|
GOTO eof
|
||||||
echo.
|
|
||||||
echo -h Display this help and exit
|
|
||||||
echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
|
|
||||||
echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%)
|
|
||||||
echo -f FILENAME The *update.bin file to flash. Custom to your device type.
|
|
||||||
goto EOF
|
|
||||||
|
|
||||||
:GETOPTS
|
:getopts
|
||||||
if /I "%1"=="-h" goto HELP
|
IF "%~1"=="" GOTO endopts
|
||||||
if /I "%1"=="--help" goto HELP
|
IF /I "%~1"=="-?" GOTO help
|
||||||
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
|
IF /I "%~1"=="-h" GOTO help
|
||||||
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
|
IF /I "%~1"=="--help" GOTO help
|
||||||
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
|
IF /I "%~1"=="-v" GOTO version
|
||||||
|
IF /I "%~1"=="--version" GOTO version
|
||||||
|
IF /I "%~1"=="--debug" SET "DEBUG=1" & CALL :LOG_MESSAGE DEBUG "DEBUG mode: enabled."
|
||||||
|
IF /I "%~1"=="-f" SET "FILENAME=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-p" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--port" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-P" SET "PYTHON=%~2" & SHIFT
|
||||||
SHIFT
|
SHIFT
|
||||||
IF NOT "__%1__"=="____" goto GETOPTS
|
GOTO getopts
|
||||||
|
:endopts
|
||||||
|
|
||||||
IF "__%FILENAME%__" == "____" (
|
CALL :LOG_MESSAGE DEBUG "Checking FILENAME parameter..."
|
||||||
echo "Missing FILENAME"
|
IF "__!FILENAME!__"=="____" (
|
||||||
goto HELP
|
CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
|
||||||
)
|
GOTO help
|
||||||
IF EXIST %FILENAME% IF NOT x%FILENAME:update=%==x%FILENAME% (
|
) ELSE (
|
||||||
echo Trying to flash update %FILENAME%
|
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x10000 %FILENAME%
|
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
|
||||||
) else (
|
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
|
||||||
echo "Invalid file: %FILENAME%"
|
GOTO help
|
||||||
goto HELP
|
)
|
||||||
) else (
|
@REM Remove ".\" or "./" file prefix if present.
|
||||||
echo "Invalid file: %FILENAME%"
|
SET "FILENAME=!FILENAME:.\=!"
|
||||||
goto HELP
|
SET "FILENAME=!FILENAME:./=!"
|
||||||
)
|
)
|
||||||
|
|
||||||
:EOF
|
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
|
||||||
|
IF NOT EXIST !FILENAME! (
|
||||||
|
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
|
||||||
|
IF "!FILENAME:update=!"=="!FILENAME!" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash !FILENAME!."
|
||||||
|
GOTO eof
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
|
||||||
|
IF NOT "__%PYTHON%__"=="____" (
|
||||||
|
SET "ESPTOOL_CMD=!PYTHON! -m esptool"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
|
||||||
|
WHERE esptool >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% EQU 0 (
|
||||||
|
@REM WHERE exits with code 0 if esptool is found.
|
||||||
|
SET "ESPTOOL_CMD=esptool"
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=python -m esptool"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
||||||
|
!ESPTOOL_CMD! >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% GEQ 2 (
|
||||||
|
@REM esptool exits with code 1 if help is displayed.
|
||||||
|
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
||||||
|
EXIT /B 1
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
IF %DEBUG% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
||||||
|
SET "ESPTOOL_CMD=REM !ESPTOOL_CMD!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
|
||||||
|
IF "__!ESPTOOL_PORT!__" == "____" (
|
||||||
|
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
|
||||||
|
)
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
|
||||||
|
|
||||||
|
@REM Flashing operations.
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash update "!FILENAME!" at OFFSET 0x10000..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x10000 "!FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Script complete!."
|
||||||
|
|
||||||
|
:eof
|
||||||
|
ENDLOCAL
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|
||||||
|
:RUN_ESPTOOL
|
||||||
|
@REM Subroutine used to run ESPTOOL_CMD with arguments.
|
||||||
|
@REM Also handles %ERRORLEVEL%.
|
||||||
|
@REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
|
||||||
|
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4
|
||||||
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Error running command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:LOG_MESSAGE
|
||||||
|
@REM Subroutine used to print log messages in four different levels.
|
||||||
|
@REM DEBUG messages only get printed if [-d] flag is passed to script.
|
||||||
|
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
|
||||||
|
SET /A LOGCOUNTER=LOGCOUNTER+1
|
||||||
|
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO [91m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[91m%~2[0m
|
||||||
|
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO [32m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[32m%~2[0m
|
||||||
|
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO [33m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[33m%~2[0m
|
||||||
|
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO [34m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[34m%~2[0m
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:GET_TIMESTAMP
|
||||||
|
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
|
||||||
|
@REM CALL :GET_TIMESTAMP
|
||||||
|
@REM.
|
||||||
|
@REM Updates: !TIMESTAMP!
|
||||||
|
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
|
||||||
|
SET "HH=%%a"
|
||||||
|
SET "MM=%%b"
|
||||||
|
SET "ss=%%c"
|
||||||
|
)
|
||||||
|
SET "TIMESTAMP=!HH!:!MM!:!ss!"
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:RESET_ERROR
|
||||||
|
@REM Subroutine to reset %ERRORLEVEL% to 0.
|
||||||
|
@REM CALL :RESET_ERROR
|
||||||
|
@REM.
|
||||||
|
@REM Updates: %ERRORLEVEL%
|
||||||
|
EXIT /B 0
|
||||||
|
GOTO :eof
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ while getopts ":hp:P:f:" opt; do
|
|||||||
show_help
|
show_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
p) export ESPTOOL_PORT=${OPTARG}
|
p) ESPTOOL_CMD="$ESPTOOL_CMD --port ${OPTARG}"
|
||||||
;;
|
;;
|
||||||
P) PYTHON=${OPTARG}
|
P) PYTHON=${OPTARG}
|
||||||
;;
|
;;
|
||||||
f) FILENAME=${OPTARG}
|
f) FILENAME=${OPTARG}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user