mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-13 05:06:30 +04:00
Compare commits
586 Commits
un1-0f6f9a
...
un3-f61a8f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ee82ba865 | ||
|
|
6e9658608e | ||
|
|
d49ca17824 | ||
|
|
fc776446de | ||
|
|
5a7fa30199 | ||
|
|
e4cdae4922 | ||
|
|
c7a67c1308 | ||
|
|
fd3e70492d | ||
|
|
a4ee73b470 | ||
|
|
8f5cbdc4c2 | ||
|
|
6d999abb80 | ||
|
|
89d49fdba7 | ||
|
|
04d67ca8ae | ||
|
|
4f7ca617cc | ||
|
|
f61a8fda53 | ||
|
|
5e35e51c57 | ||
|
|
dfbe21e720 | ||
|
|
18e7d2eb41 | ||
|
|
e7aaf3dbb2 | ||
|
|
76aecb597a | ||
|
|
d2018dfa1d | ||
|
|
8ec5527ae4 | ||
|
|
3a50021348 | ||
|
|
20c63664ca | ||
|
|
9b6abd8ef0 | ||
|
|
f96f2e2411 | ||
|
|
6442caa3e4 | ||
|
|
f06930e4ae | ||
|
|
865baed0bb | ||
|
|
f81999ea4a | ||
|
|
89a4b77e73 | ||
|
|
ead9f134f4 | ||
|
|
9ff29d12b2 | ||
|
|
5f3637ca44 | ||
|
|
effcb445ce | ||
|
|
55bad280ee | ||
|
|
b003ede76c | ||
|
|
57362b3eab | ||
|
|
cb0d9ec591 | ||
|
|
dad4772bec | ||
|
|
a16542cda6 | ||
|
|
a5d22154a9 | ||
|
|
ce173fd44c | ||
|
|
d547307357 | ||
|
|
c198a51b1c | ||
|
|
d5b239595f | ||
|
|
947e44ce86 | ||
|
|
55f8beef9f | ||
|
|
e46e6f8ee9 | ||
|
|
ff6c4f9957 | ||
|
|
8fdee1e460 | ||
|
|
558f85603d | ||
|
|
b909321699 | ||
|
|
ff52f7d9ba | ||
|
|
abfe53f156 | ||
|
|
9a2228bfa4 | ||
|
|
da17adb5ee | ||
|
|
7b16de2d6f | ||
|
|
735056628c | ||
|
|
9941df48bb | ||
|
|
8e0e4b5e2c | ||
|
|
220adf2375 | ||
|
|
39cd10f061 | ||
|
|
af1fb2018a | ||
|
|
3dde6089fc | ||
|
|
5f28eafcd2 | ||
|
|
94d2d5c99f | ||
|
|
3a569d4be8 | ||
|
|
db2f4847ba | ||
|
|
50dc2d7389 | ||
|
|
ede3bac799 | ||
|
|
eb4ff3c0fd | ||
|
|
afff1adf8f | ||
|
|
92a738bf77 | ||
|
|
b3d9523322 | ||
|
|
155cbeeb11 | ||
|
|
0d273bd15c | ||
|
|
2e047ff411 | ||
|
|
80a406afd3 | ||
|
|
6b5631e5b0 | ||
|
|
80735d4f51 | ||
|
|
e1e46b89b1 | ||
|
|
b7bdc4c985 | ||
|
|
f429d14ab5 | ||
|
|
744b61ca28 | ||
|
|
8520daf28b | ||
|
|
aa9f958f07 | ||
|
|
b3f96306ed | ||
|
|
022315e93d | ||
|
|
702786078d | ||
|
|
e78d73c35f | ||
|
|
2552278a3d | ||
|
|
34406f0607 | ||
|
|
04f5ad83f8 | ||
|
|
06c0adfe98 | ||
|
|
b0d4146c76 | ||
|
|
be293757c0 | ||
|
|
79e7c87b94 | ||
|
|
b6dfeac7ca | ||
|
|
349a151330 | ||
|
|
40dc80499f | ||
|
|
b0c31da36a | ||
|
|
a76259add9 | ||
|
|
3f3ee1822a | ||
|
|
0714df4a4a | ||
|
|
52361b4adf | ||
|
|
61fe66c178 | ||
|
|
016ebd3afc | ||
|
|
82b9d74b38 | ||
|
|
6d1929af25 | ||
|
|
384397c282 | ||
|
|
0abd54ccc8 | ||
|
|
ea833d891f | ||
|
|
9152299562 | ||
|
|
906124b091 | ||
|
|
9c0391a887 | ||
|
|
7ded162c94 | ||
|
|
382f620aff | ||
|
|
323a56e987 | ||
|
|
b65a2e9c94 | ||
|
|
eed8cd1824 | ||
|
|
500456b03d | ||
|
|
4b8221d813 | ||
|
|
c7a454752a | ||
|
|
b1f8073333 | ||
|
|
e489c57fc0 | ||
|
|
b4a3ac468f | ||
|
|
877a9202fd | ||
|
|
acbe7a10e2 | ||
|
|
b6b33a70e9 | ||
|
|
1132653d7a | ||
|
|
3fd30a9132 | ||
|
|
50e9f7d3ca | ||
|
|
e7de975885 | ||
|
|
f5a1872db4 | ||
|
|
409d2e5f05 | ||
|
|
91d7a38ca6 | ||
|
|
00323892f2 | ||
|
|
45840a1146 | ||
|
|
b0c9af9c06 | ||
|
|
7643fdad7c | ||
|
|
a1ede0a2fc | ||
|
|
b86f42e7fb | ||
|
|
31c0346adc | ||
|
|
9ba7e625ca | ||
|
|
981f7ff8b0 | ||
|
|
c38c42906f | ||
|
|
7c8eacb168 | ||
|
|
c13929330e | ||
|
|
88ca267466 | ||
|
|
1adf76d54d | ||
|
|
7ec4cb4b7a | ||
|
|
aedde45de8 | ||
|
|
184b467f62 | ||
|
|
0c5146e047 | ||
|
|
221ac1ed3b | ||
|
|
464c725a48 | ||
|
|
3e538a8ade | ||
|
|
ae76f45339 | ||
|
|
4cb585e4b9 | ||
|
|
16ea8dc568 | ||
|
|
4c9d62a33f | ||
|
|
d10e16ca3c | ||
|
|
37b5e58a60 | ||
|
|
b4b3c182c5 | ||
|
|
bdd052937b | ||
|
|
1a1f711897 | ||
|
|
4000f0cac5 | ||
|
|
1f742b611a | ||
|
|
38a82a1907 | ||
|
|
d1843c0094 | ||
|
|
3367bc6f68 | ||
|
|
515e6db69c | ||
|
|
81faca79ee | ||
|
|
eaa3adf98a | ||
|
|
dde18cd343 | ||
|
|
72b3d7f414 | ||
|
|
19cb469e4b | ||
|
|
01f7a3e5b5 | ||
|
|
6dde5586af | ||
|
|
5de2c32c81 | ||
|
|
69b9c54b2f | ||
|
|
dbf4b65d84 | ||
|
|
2ffb246e69 | ||
|
|
e3a5df5959 | ||
|
|
90eefeb2ed | ||
|
|
fda541c7fb | ||
|
|
42494d801f | ||
|
|
1253a78dba | ||
|
|
d07c2dbe54 | ||
|
|
8f1812655e | ||
|
|
3802171009 | ||
|
|
03ad1770f8 | ||
|
|
b86756b581 | ||
|
|
11681d8ee8 | ||
|
|
061f53cd3c | ||
|
|
4bbeeb19e2 | ||
|
|
61189c3c82 | ||
|
|
9bf11d9fd2 | ||
|
|
c76fcf5072 | ||
|
|
007a11d70d | ||
|
|
b61e41163b | ||
|
|
a69e150e2f | ||
|
|
f16cdd1477 | ||
|
|
ac286dfed8 | ||
|
|
a93008b218 | ||
|
|
31aaa593fc | ||
|
|
5a2719663f | ||
|
|
adccb87499 | ||
|
|
693f78e501 | ||
|
|
6eb610762e | ||
|
|
3e4d8a41e0 | ||
|
|
c60bfbf271 | ||
|
|
0796263e81 | ||
|
|
4bf29827f8 | ||
|
|
baf5034817 | ||
|
|
04e16970db | ||
|
|
a8b48771e4 | ||
|
|
1424878d65 | ||
|
|
a37b0d464c | ||
|
|
96502e21ae | ||
|
|
b5d6d60535 | ||
|
|
32e64fd29e | ||
|
|
8f9d81b972 | ||
|
|
23e0566273 | ||
|
|
4141483147 | ||
|
|
30e005d5c4 | ||
|
|
e3a2711eb3 | ||
|
|
8569641ce6 | ||
|
|
cafd06c71b | ||
|
|
06a7bda69b | ||
|
|
c43ce93936 | ||
|
|
2288855163 | ||
|
|
c0765c1114 | ||
|
|
683c6254da | ||
|
|
2ef515ef56 | ||
|
|
667be798fc | ||
|
|
0f9598099a | ||
|
|
0d6f729386 | ||
|
|
b452b6fd32 | ||
|
|
9403128a03 | ||
|
|
71589b28a7 | ||
|
|
8b0fa6d0b1 | ||
|
|
cf47da0ff4 | ||
|
|
d6b7fae7e4 | ||
|
|
110dc48b96 | ||
|
|
37c666ddf5 | ||
|
|
6ddca568b9 | ||
|
|
8993db56b8 | ||
|
|
3c1efda1db | ||
|
|
b62b7956a6 | ||
|
|
dce5af5c2e | ||
|
|
fbacdc5b7b | ||
|
|
8dba4f25ae | ||
|
|
43ef4046ed | ||
|
|
1e63f57bf7 | ||
|
|
649887fe0f | ||
|
|
be42c390f2 | ||
|
|
cbda5d996f | ||
|
|
de1ec97512 | ||
|
|
8af749c965 | ||
|
|
4d3f45e911 | ||
|
|
63fee41a1f | ||
|
|
f441fed68d | ||
|
|
6e0eeed773 | ||
|
|
6bf306200e | ||
|
|
e2faf31b45 | ||
|
|
85eb740559 | ||
|
|
cea14ae9c5 | ||
|
|
e9a11cfce0 | ||
|
|
87a14b96e1 | ||
|
|
bbd3f9cf71 | ||
|
|
230f09dddd | ||
|
|
24e744f1d1 | ||
|
|
127b700642 | ||
|
|
0f9ea925d3 | ||
|
|
836de3df16 | ||
|
|
c92217a109 | ||
|
|
41c93431c8 | ||
|
|
f0ea8f3a84 | ||
|
|
4d8f294e7a | ||
|
|
f543753873 | ||
|
|
1fb1a68842 | ||
|
|
54fedb9bc8 | ||
|
|
8af9c00ddb | ||
|
|
5a22803bbc | ||
|
|
824f5ea027 | ||
|
|
76d38e832e | ||
|
|
aba20b6af8 | ||
|
|
226f8517f3 | ||
|
|
7df70d7c62 | ||
|
|
9176387b9f | ||
|
|
972c0dcb4a | ||
|
|
62e56e2618 | ||
|
|
f202d27206 | ||
|
|
bcfb12bf28 | ||
|
|
5883e134d4 | ||
|
|
f8b532f063 | ||
|
|
e25b424188 | ||
|
|
4241ad24a3 | ||
|
|
6bcc6f363b | ||
|
|
3dcd8a73f1 | ||
|
|
9ad7f7825d | ||
|
|
aa00606d22 | ||
|
|
9c62e1f6ac | ||
|
|
b934c41ed0 | ||
|
|
0ebb3f060e | ||
|
|
8f2bd3be57 | ||
|
|
cc02d57857 | ||
|
|
0c5f11f713 | ||
|
|
006d27ed93 | ||
|
|
746b732034 | ||
|
|
2ec9aeeefa | ||
|
|
8be08093e2 | ||
|
|
406247c5d8 | ||
|
|
22a87d5707 | ||
|
|
4271246d8a | ||
|
|
a3db6718c2 | ||
|
|
0f0473bee6 | ||
|
|
497be7ccb0 | ||
|
|
12a6290e91 | ||
|
|
e6e1e7fe15 | ||
|
|
cb14d23108 | ||
|
|
c4783664c0 | ||
|
|
91f3774246 | ||
|
|
1f8a034a71 | ||
|
|
8cc3e2f35a | ||
|
|
069dd29f08 | ||
|
|
91c06a2168 | ||
|
|
545c4349d6 | ||
|
|
a40e1a2be2 | ||
|
|
286300b35b | ||
|
|
633145495c | ||
|
|
a0bcbf731d | ||
|
|
60242cd7c4 | ||
|
|
3e9409a1a8 | ||
|
|
a9210b2849 | ||
|
|
a58807c57a | ||
|
|
5bb7cabea6 | ||
|
|
f201062819 | ||
|
|
9f501034c3 | ||
|
|
7bd0c8ff2c | ||
|
|
cdcf80ed05 | ||
|
|
3e3a167764 | ||
|
|
fa9602bd68 | ||
|
|
efb09380bd | ||
|
|
61fee8e269 | ||
|
|
5e30b14d90 | ||
|
|
c07e3a34dd | ||
|
|
be7e11e60f | ||
|
|
e96e414561 | ||
|
|
0c99cb52ec | ||
|
|
ad9e1ce4df | ||
|
|
22dc5190d1 | ||
|
|
f2fd97d9c5 | ||
|
|
08084d5763 | ||
|
|
add1ad6949 | ||
|
|
87654e60b8 | ||
|
|
6f92cd645e | ||
|
|
23f6ea2e05 | ||
|
|
a6b98ccbbe | ||
|
|
ba5f590dab | ||
|
|
f1048733d2 | ||
|
|
ea7f68fcab | ||
|
|
8013aacd94 | ||
|
|
be8f409098 | ||
|
|
97e6fe8f4e | ||
|
|
54757428e6 | ||
|
|
bd39d81324 | ||
|
|
2a2078d9b5 | ||
|
|
01ca588488 | ||
|
|
f86eada292 | ||
|
|
bc777b2eff | ||
|
|
6f91fa42f0 | ||
|
|
e6d22ed147 | ||
|
|
436f70b69b | ||
|
|
ec9ce0cad7 | ||
|
|
7e2008095e | ||
|
|
92e440c77d | ||
|
|
666821e9ce | ||
|
|
1bca477a43 | ||
|
|
41571ce9ad | ||
|
|
038d098c85 | ||
|
|
b03cc8ddc3 | ||
|
|
c8e3d9b040 | ||
|
|
aeb02500de | ||
|
|
eadd7801af | ||
|
|
6d2b0a3b6c | ||
|
|
8093721c24 | ||
|
|
32a7642761 | ||
|
|
e8bb45496d | ||
|
|
3846852f2b | ||
|
|
17d01f5c29 | ||
|
|
e6bcba6959 | ||
|
|
e13edc2f70 | ||
|
|
de6ff1d9c9 | ||
|
|
bea15134ba | ||
|
|
28a55bf576 | ||
|
|
e70121e20f | ||
|
|
432ff41d6a | ||
|
|
87393a086c | ||
|
|
6000d47a0f | ||
|
|
d986ef4104 | ||
|
|
f85dc1675d | ||
|
|
7c7ac07e6a | ||
|
|
ca02826cfd | ||
|
|
96ad7f3cef | ||
|
|
c213ff596a | ||
|
|
b2589698ff | ||
|
|
3360f818a1 | ||
|
|
066da4080b | ||
|
|
b2c118f267 | ||
|
|
a8db46124e | ||
|
|
672e27f258 | ||
|
|
e762a68265 | ||
|
|
8659becc9d | ||
|
|
82e1e8af6a | ||
|
|
a71d05a114 | ||
|
|
8d68bf62a5 | ||
|
|
2c85adb270 | ||
|
|
e2123c55bb | ||
|
|
f5ff6438d1 | ||
|
|
9f3b80e606 | ||
|
|
111656d2c1 | ||
|
|
2045a29d3f | ||
|
|
26e46f9267 | ||
|
|
d003db0404 | ||
|
|
5a31e35dc2 | ||
|
|
c7cd5721ed | ||
|
|
fb476c29e6 | ||
|
|
d80329b323 | ||
|
|
3d3c422751 | ||
|
|
ed385594a3 | ||
|
|
787df44c79 | ||
|
|
f0eedc3243 | ||
|
|
365d055dc5 | ||
|
|
650ba8a91f | ||
|
|
654d6dc6ec | ||
|
|
18b70ac6b5 | ||
|
|
51369d6219 | ||
|
|
181533df1b | ||
|
|
d85731636f | ||
|
|
6f66f87fab | ||
|
|
85d4dedb15 | ||
|
|
0a4cddb84c | ||
|
|
4e17230290 | ||
|
|
aa99ac53c7 | ||
|
|
875f70196b | ||
|
|
1e71d212fe | ||
|
|
269a6ce562 | ||
|
|
cd2014c51b | ||
|
|
08f80ab645 | ||
|
|
14bd8f2c49 | ||
|
|
8ce5fae626 | ||
|
|
087bf41392 | ||
|
|
d390381d5a | ||
|
|
c3e31663ef | ||
|
|
c28e4ea733 | ||
|
|
96a3da24c9 | ||
|
|
9d4b318357 | ||
|
|
ef5d0aa483 | ||
|
|
66487abaee | ||
|
|
d2bb1ef4d3 | ||
|
|
0e15090629 | ||
|
|
1413d7c937 | ||
|
|
d97a3ef161 | ||
|
|
870dfd188c | ||
|
|
71a6844a5f | ||
|
|
d67d5da034 | ||
|
|
c894948d4f | ||
|
|
e25148ce72 | ||
|
|
07301935b5 | ||
|
|
3a1705bcf9 | ||
|
|
df87b04fa9 | ||
|
|
75f5efce03 | ||
|
|
00585fa16a | ||
|
|
30aaae33be | ||
|
|
c0e7c2a929 | ||
|
|
286b4876ce | ||
|
|
10c2ae5a05 | ||
|
|
8915c0c66c | ||
|
|
ec7676182a | ||
|
|
e23dbb9f99 | ||
|
|
19d201085b | ||
|
|
17a4e03656 | ||
|
|
1fd9240481 | ||
|
|
fc9996377d | ||
|
|
7f4b586b13 | ||
|
|
72de4af6db | ||
|
|
5bbb13c5c9 | ||
|
|
3efb093125 | ||
|
|
60bce7b8d8 | ||
|
|
8b05bd1106 | ||
|
|
668b7857b4 | ||
|
|
8b3b5fa802 | ||
|
|
a6052be0f1 | ||
|
|
007a3d295e | ||
|
|
28beff1ab6 | ||
|
|
9c95562fad | ||
|
|
83e036da14 | ||
|
|
8fd4225939 | ||
|
|
a3234995db | ||
|
|
98312860a6 | ||
|
|
9dbcd43e66 | ||
|
|
ffce0aeec9 | ||
|
|
361a239d3e | ||
|
|
51ffdcd3bc | ||
|
|
d47fdce337 | ||
|
|
3fbaad1488 | ||
|
|
b9a766d909 | ||
|
|
1b8684eb53 | ||
|
|
7a2b5be137 | ||
|
|
873e1f114b | ||
|
|
abce958db9 | ||
|
|
d4c44d7500 | ||
|
|
444035d06a | ||
|
|
c8c75d5f14 | ||
|
|
1fda069579 | ||
|
|
fccb99d847 | ||
|
|
4a61a28f57 | ||
|
|
b00117e02c | ||
|
|
6b91c660d4 | ||
|
|
9c3406895c | ||
|
|
ee6b59ab9d | ||
|
|
bd594c7134 | ||
|
|
4417a37a2e | ||
|
|
1b6794ce7c | ||
|
|
c96bfba95a | ||
|
|
fe8ad22132 | ||
|
|
bcb5af1813 | ||
|
|
77be3db143 | ||
|
|
7a2a1d6007 | ||
|
|
1c00709ea6 | ||
|
|
9ad96f782e | ||
|
|
67955b6ab8 | ||
|
|
37ce143527 | ||
|
|
771e948cfc | ||
|
|
9dc337a02c | ||
|
|
3ea01f8413 | ||
|
|
5623842892 | ||
|
|
a8d37879cb | ||
|
|
bcaf898c57 | ||
|
|
248d222459 | ||
|
|
fd230b6d09 | ||
|
|
d55da415c2 | ||
|
|
f94517fdab | ||
|
|
177fabe50c | ||
|
|
7930f73a4e | ||
|
|
b0633af0b6 | ||
|
|
e0efb2bf37 | ||
|
|
239eca0543 | ||
|
|
de4e7b9dd9 | ||
|
|
8e986c58c3 | ||
|
|
bbe5c9cae1 | ||
|
|
a3193e3bbd | ||
|
|
f34dafeecc | ||
|
|
b10727435a | ||
|
|
fe7d089593 | ||
|
|
380fe2633a | ||
|
|
58cc7c1814 | ||
|
|
7681e9a257 | ||
|
|
365d2977ef | ||
|
|
a8895d56ea | ||
|
|
7acd814970 | ||
|
|
2ad9aec802 | ||
|
|
f84d5e9b85 | ||
|
|
1a60093689 | ||
|
|
a8eb53af4e | ||
|
|
5cb074fc24 | ||
|
|
d9265164a3 | ||
|
|
b67dfb5821 | ||
|
|
4c2e38b51c | ||
|
|
d13b4e3bd5 | ||
|
|
91c7441fa8 | ||
|
|
b7922a2a49 | ||
|
|
f0937e91f1 | ||
|
|
ac08c92a35 | ||
|
|
b2ba7b5e59 | ||
|
|
9b89acfec0 | ||
|
|
7c1a48a377 | ||
|
|
c8ad361818 | ||
|
|
1a52e55a73 | ||
|
|
f6a071ed6b | ||
|
|
05b6f9a901 | ||
|
|
31e06da7e7 | ||
|
|
1bb1022d51 |
151
.clang-format
151
.clang-format
@@ -1,86 +1,191 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 99
|
||||
ColumnLimit: 99
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
QualifierAlignment: Leave
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
PackConstructorInitializers: BinPack
|
||||
BasedOnStyle: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
FixNamespaceComments: false
|
||||
|
||||
IncludeBlocks: Preserve
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: true
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
|
||||
# Taken from git's rules
|
||||
PenaltyBreakAssignment: 10
|
||||
PenaltyBreakBeforeFirstCallParameter: 30
|
||||
PenaltyBreakComment: 10
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 10
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Left
|
||||
ReflowComments: false
|
||||
SortIncludes: false
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: false
|
||||
RemoveBracesLLVM: false
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: Never
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: Never
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: false
|
||||
AfterForeachMacros: false
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: false
|
||||
AfterOverloadedOperator: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp03
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: c++03
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
|
||||
|
||||
33
.drone.yml
33
.drone.yml
@@ -28,37 +28,9 @@ steps:
|
||||
FBT_TOOLS_CUSTOM_LINK:
|
||||
from_secret: fbt_link
|
||||
|
||||
- name: "Bundle resources"
|
||||
image: kramos/alpine-zip
|
||||
commands:
|
||||
- mkdir sd-card
|
||||
- mkdir -p sd-card/subghz/assets
|
||||
- mkdir -p sd-card/nfc/assets
|
||||
- mkdir -p sd-card/infrared/assets
|
||||
- mkdir -p sd-card/unirf
|
||||
- mkdir -p sd-card/rfidfuzzer
|
||||
- mkdir -p sd-card/badusb/layouts
|
||||
- cp assets/resources/badusb/layouts/* sd-card/badusb/layouts/
|
||||
- cp assets/resources/subghz/assets/dangerous_settings sd-card/subghz/assets/dangerous_settings
|
||||
- cp assets/resources/subghz/assets/setting_user sd-card/subghz/assets/setting_user
|
||||
- cp assets/resources/subghz/assets/keeloq_mfcodes sd-card/subghz/assets/keeloq_mfcodes
|
||||
- cp assets/resources/nfc/assets/mf_classic_dict.nfc sd-card/nfc/assets/mf_classic_dict.nfc
|
||||
- cp assets/resources/infrared/assets/tv.ir sd-card/infrared/assets/tv.ir
|
||||
- cp assets/resources/infrared/assets/ac.ir sd-card/infrared/assets/ac.ir
|
||||
- cp assets/resources/infrared/assets/fans.ir sd-card/infrared/assets/fans.ir
|
||||
- cp assets/resources/infrared/assets/projectors.ir sd-card/infrared/assets/projectors.ir
|
||||
- cp assets/resources/infrared/assets/audio.ir sd-card/infrared/assets/audio.ir
|
||||
- cp assets/resources/unirf/unirf_map_example.txt sd-card/unirf/unirf_map_example.txt
|
||||
- cp assets/resources/rfidfuzzer/example_uids.txt sd-card/rfidfuzzer/example_uids.txt
|
||||
- cp assets/resources/Manifest sd-card/Manifest
|
||||
- zip -r artifacts-default/sd-card-${DRONE_TAG}.zip sd-card
|
||||
- rm -rf sd-card
|
||||
- ls -laS artifacts-default
|
||||
|
||||
- name: "Bundle self-update packages"
|
||||
image: kramos/alpine-zip
|
||||
commands:
|
||||
- tar czpf artifacts-default/flipper-z-f7-update-${DRONE_TAG}.tgz -C artifacts-default f7-update-${DRONE_TAG}
|
||||
- cp artifacts-default/flipper-z-f7-update-${DRONE_TAG}.tgz .
|
||||
- zip -r artifacts-default/flipper-z-f7-update-${DRONE_TAG}.zip artifacts-default/f7-update-${DRONE_TAG}
|
||||
- rm -rf artifacts-default/f7-update-${DRONE_TAG}
|
||||
@@ -91,7 +63,6 @@ steps:
|
||||
files:
|
||||
- artifacts-default/*.tgz
|
||||
- artifacts-default/*.zip
|
||||
- artifacts-default/flipper-z-f7-full-${DRONE_TAG}.dfu
|
||||
title: ${DRONE_TAG}
|
||||
note: CHANGELOG.md
|
||||
checksum:
|
||||
@@ -113,7 +84,7 @@ steps:
|
||||
Version: {{build.tag}}
|
||||
|
||||
|
||||
[-Github-](https://github.com/Eng1n33r/flipperzero-firmware/releases/tag/${DRONE_TAG})
|
||||
[-Github-](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/${DRONE_TAG})
|
||||
|
||||
|
||||
[-Install via Web Updater-](https://my.flipp.dev/?url=https://unleashedflip.com/builds/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=dev-cfw&version=${DRONE_TAG})"
|
||||
@@ -133,7 +104,7 @@ steps:
|
||||
Version: {{build.tag}}
|
||||
|
||||
|
||||
[[Github]](https://github.com/Eng1n33r/flipperzero-firmware/releases/tag/${DRONE_TAG})
|
||||
[[Github]](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/${DRONE_TAG})
|
||||
|
||||
|
||||
[-Install via Web Updater-](https://my.flipp.dev/?url=https://unleashedflip.com/builds/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=dev-cfw&version=${DRONE_TAG})"
|
||||
|
||||
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* @xMasterX
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -4,5 +4,5 @@ contact_links:
|
||||
url: https://t.me/flipperzero_unofficial
|
||||
about: Unofficial Telegram chat
|
||||
- name: Discord
|
||||
url: https://discord.gg/58D6E8BtTU
|
||||
url: https://discord.unleashedflip.com
|
||||
about: Unofficial Discord Community
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -28,3 +28,6 @@
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/Mbed-TLS/mbedtls.git
|
||||
[submodule "lib/cxxheaderparser"]
|
||||
path = lib/cxxheaderparser
|
||||
url = https://github.com/robotpy/cxxheaderparser.git
|
||||
|
||||
20
.vscode/example/launch.json
vendored
20
.vscode/example/launch.json
vendored
@@ -9,6 +9,10 @@
|
||||
"type": "command",
|
||||
"command": "shellCommand.execute",
|
||||
"args": {
|
||||
"useSingleResult": true,
|
||||
"env": {
|
||||
"PATH": "${workspaceFolder};${env:PATH}"
|
||||
},
|
||||
"command": "./fbt get_blackmagic",
|
||||
"description": "Get Blackmagic device",
|
||||
}
|
||||
@@ -24,14 +28,18 @@
|
||||
"servertype": "openocd",
|
||||
"device": "stlink",
|
||||
"svdFile": "./debug/STM32WB55_CM4.svd",
|
||||
// If you're debugging early in the boot process, before OS scheduler is running,
|
||||
// you have to comment out the following line.
|
||||
"rtos": "FreeRTOS",
|
||||
"configFiles": [
|
||||
"interface/stlink.cfg",
|
||||
"./debug/stm32wbx.cfg",
|
||||
],
|
||||
"postAttachCommands": [
|
||||
// "attach 1",
|
||||
"compare-sections",
|
||||
// "compare-sections",
|
||||
"source debug/flipperapps.py",
|
||||
// "source debug/FreeRTOS/FreeRTOS.py",
|
||||
// "svd_load debug/STM32WB55_CM4.svd"
|
||||
]
|
||||
// "showDevDebugOutput": "raw",
|
||||
},
|
||||
@@ -50,7 +58,8 @@
|
||||
"attach 1",
|
||||
"set confirm off",
|
||||
"set mem inaccessible-by-default off",
|
||||
"compare-sections",
|
||||
"source debug/flipperapps.py",
|
||||
// "compare-sections",
|
||||
]
|
||||
// "showDevDebugOutput": "raw",
|
||||
},
|
||||
@@ -65,6 +74,9 @@
|
||||
"device": "STM32WB55RG",
|
||||
"svdFile": "./debug/STM32WB55_CM4.svd",
|
||||
"rtos": "FreeRTOS",
|
||||
"postAttachCommands": [
|
||||
"source debug/flipperapps.py",
|
||||
]
|
||||
// "showDevDebugOutput": "raw",
|
||||
},
|
||||
{
|
||||
@@ -73,7 +85,7 @@
|
||||
"request": "launch",
|
||||
"program": "./lib/scons/scripts/scons.py",
|
||||
"args": [
|
||||
"sdk"
|
||||
"plugin_dist"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
5
.vscode/example/settings.json
vendored
5
.vscode/example/settings.json
vendored
@@ -12,6 +12,9 @@
|
||||
"cortex-debug.openocdPath.windows": "${workspaceFolder}/toolchain/i686-windows/openocd/bin/openocd.exe",
|
||||
"cortex-debug.openocdPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/openocd/bin/openocd",
|
||||
"cortex-debug.openocdPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/openocd/bin/openocd",
|
||||
"cortex-debug.gdbPath.windows": "${workspaceFolder}/toolchain/i686-windows/bin/arm-none-eabi-gdb-py.bat",
|
||||
"cortex-debug.gdbPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py",
|
||||
"cortex-debug.gdbPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gdb-py",
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
"*.scons": "python",
|
||||
@@ -19,4 +22,4 @@
|
||||
"SConstruct": "python",
|
||||
"*.fam": "python",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
.vscode/example/tasks.json
vendored
30
.vscode/example/tasks.json
vendored
@@ -93,11 +93,41 @@
|
||||
"type": "shell",
|
||||
"command": "./fbt FIRMWARE_APP_SET=unit_tests FORCE=1 flash_usb"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Flash (USB, with resources)",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt FORCE=1 flash_usb_full"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Flash (USB, with resources)",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Build FAPs",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt plugin_dist"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Build FAPs",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt COMPACT=1 DEBUG=0 plugin_dist"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Launch App on Flipper",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt launch_app APPSRC=${relativeFileDirname}"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Launch App on Flipper",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt COMPACT=1 DEBUG=0 launch_app APPSRC=${relativeFileDirname}"
|
||||
}
|
||||
]
|
||||
}
|
||||
34
CHANGELOG.md
34
CHANGELOG.md
@@ -1,23 +1,23 @@
|
||||
### New changes
|
||||
* Add SubGhz Bruteforce plugin (by @Ganapati & @xMasterX) (PR #57) - saving functionality and many fixes by @xMasterX
|
||||
* Fix GUI and add new icon in LF-RFID App (icon by @Svaarich)
|
||||
* GUI Changes to LFRFID Fuzzer
|
||||
* New Battery info (from @theeogflip) (PR #60)
|
||||
* NRFSniff: Adds unique count display (by @Graf3x) (PR #56)
|
||||
* Updated universal remote assets (by @Amec0e)
|
||||
* OFW: RFID app port to plain C
|
||||
* OFW: SubGhz: fix decoder keeloq
|
||||
* OFW PR: Picopass: detect and show SE / SIO - OFW PR 1701 (by pcunning)
|
||||
* OFW PR: Fix MFClassic 4k reading - OFW PR 1712 (by Astrrra)
|
||||
* OFW: SubGhz: handle missing key in cryptostore. Lib: lower default display contrast.
|
||||
* OFW: Furi: wait for timer wind down in destructor
|
||||
* PR -> Power: remove % sign from desktop and center numbers (by @TQMatvey | PR #115)
|
||||
* Plugins: Heap Defence Game (aka Stack Attack) [(original by wquinoa & Vedmein)](https://github.com/Vedmein/flipperzero-firmware/tree/hd/svisto-perdelki) -> Ported to latest firmware by @xMasterX
|
||||
|
||||
**Note: To avoid issues prefer installing using web updater or by self update package, all needed assets will be installed**
|
||||
#### [🎲 Download extra apps pack](https://download-directory.github.io/?url=https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed)
|
||||
|
||||
Self-update package (update from microSD) - `flipper-z-f7-update-(version).zip` or `.tgz` for iOS mobile app
|
||||
[-> How to install firmware](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)
|
||||
|
||||
DFU for update using qFlipper - `flipper-z-f7-full-(version).dfu`
|
||||
[-> Download qFlipper 1.2.1 (allows .tgz installation) (official link)](https://update.flipperzero.one/builds/qFlipper/1.2.1/)
|
||||
|
||||
If using DFU update method, download this archive and unpack it to your microSD, replacing all files except files you have edited manually -
|
||||
`sd-card-(version).zip`
|
||||
## Please support development of the project
|
||||
* Boosty: https://boosty.to/mmxdev
|
||||
* ETH/BSC/ERC20-Tokens: `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`
|
||||
* BTC: `bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`
|
||||
* DOGE: `D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`
|
||||
* LTC: `ltc1q3ex4ejkl0xpx3znwrmth4lyuadr5qgv8tmq8z9`
|
||||
|
||||
**Note: To avoid issues with .dfu, prefer installing using .tgz with qFlipper, web updater or by self update package, all needed assets will be installed**
|
||||
|
||||
Self-update package (update from microSD) - `flipper-z-f7-update-(version).zip` or download `.tgz` for iOS mobile app / qFlipper
|
||||
|
||||
Update using qFlipper (1.2.0+) is now possible with `.tgz` update package! Also you can use Web Updater or self-update package.
|
||||
|
||||
|
||||
94
ReadMe.md
94
ReadMe.md
@@ -1,5 +1,5 @@
|
||||
<h3 align="center">
|
||||
<a href="https://github.com/Eng1n33r/flipperzero-firmware">
|
||||
<a href="https://github.com/DarkFlippers/unleashed-firmware">
|
||||
<img src="https://user-images.githubusercontent.com/10697207/186202043-26947e28-b1cc-459a-8f20-ffcc7fc0c71c.png" align="center" alt="fzCUSTOM" border="0">
|
||||
</a>
|
||||
</h3>
|
||||
@@ -16,7 +16,7 @@ Please help us implement emulation for all subghz dynamic (rolling code) protoco
|
||||
<br>
|
||||
Our Discord Community:
|
||||
<br>
|
||||
<a href="https://discord.gg/58D6E8BtTU"><img src="https://discordapp.com/api/guilds/937479784148115456/widget.png?style=banner4" alt="Unofficial Discord Community"></a>
|
||||
<a href="https://discord.unleashedflip.com"><img src="https://discordapp.com/api/guilds/937479784148115456/widget.png?style=banner4" alt="Unofficial Discord Community"></a>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
@@ -36,22 +36,33 @@ Our Discord Community:
|
||||
* Universal remote for Projectors, Fans, A/Cs and Audio(soundbars, etc.)
|
||||
* BadUSB keyboard layouts
|
||||
* Customizable Flipper name
|
||||
* SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes
|
||||
* SubGHz -> Long press OK button in SubGHz Frequency analyzer to switch to Read menu
|
||||
* Other small fixes and changes throughout
|
||||
* See other changes in changelog and in readme below
|
||||
|
||||
See changelog in releases for latest updates!
|
||||
Also check changelog in releases for latest updates!
|
||||
|
||||
### Current modified and new SubGHz protocols list:
|
||||
- HCS101
|
||||
- An-Motors
|
||||
- Keeloq [Not ALL systems supported for decode or emulation yet!] - [Supported manufacturers list](https://0bin.net/paste/VwR2lNJY#WH9vnPgvcp7w6zVKucFCuNREKAcOij8KsJ6vqLfMn3b)
|
||||
- Keeloq: HCS101
|
||||
- Keeloq: AN-Motors
|
||||
- Keeloq: JCM Tech
|
||||
- Keeloq: MHouse
|
||||
- Keeloq: Nice Smilo
|
||||
- Keeloq: DTM Neo
|
||||
- Keeloq: FAAC RC,XT
|
||||
- Keeloq: Mutancode
|
||||
- Keeloq: Normstahl
|
||||
- CAME Atomo
|
||||
- FAAC SLH (Spa) [External seed calculation required]
|
||||
- BFT Mitto [External seed calculation required]
|
||||
- Keeloq [Not ALL systems supported yet!]
|
||||
- Nice Flor S
|
||||
- FAAC SLH (Spa) [External seed calculation required (For info conatct me in Discord: Nano#8998)]
|
||||
- BFT Mitto [External seed calculation required (For info conatct me in Discord: Nano#8998)]
|
||||
- Security+ v1 & v2
|
||||
- Star Line
|
||||
- Star Line (saving only)
|
||||
|
||||
## Support us so we can buy equipment and develop new features
|
||||
* Boosty: https://boosty.to/mmxdev
|
||||
* ETH/BSC/ERC20-Tokens: `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`
|
||||
* BTC: `bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`
|
||||
* DOGE: `D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`
|
||||
@@ -59,50 +70,72 @@ See changelog in releases for latest updates!
|
||||
|
||||
### Community apps included:
|
||||
|
||||
- RFID Fuzzer plugin [(by Ganapati)](https://github.com/Eng1n33r/flipperzero-firmware/pull/54) with some changes by xMasterX
|
||||
- Sub-GHz bruteforce plugin [(by Ganapati & xMasterX)](https://github.com/Eng1n33r/flipperzero-firmware/pull/57)
|
||||
- RFID Fuzzer plugin [(by Ganapati)](https://github.com/DarkFlippers/unleashed-firmware/pull/54) with changes by @xMasterX & New protocols by @mvanzanten
|
||||
- Sub-GHz bruteforce plugin [(by Ganapati & xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/57) & Refactored by @derskythe
|
||||
- Sub-GHz playlist plugin [(by darmiel)](https://github.com/DarkFlippers/unleashed-firmware/pull/62)
|
||||
- ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module)
|
||||
- WiFi Scanner plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module)
|
||||
- MultiConverter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff)
|
||||
- USB Keyboard plugin [(by huuck)](https://github.com/huuck/FlipperZeroUSBKeyboard)
|
||||
- WAV player plugin (fixed) [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player)
|
||||
- UPC-A Barcode generator plugin [(by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator)
|
||||
- GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin)
|
||||
- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion)
|
||||
- NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker)
|
||||
- Simple Clock (fixed) [(Original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61)
|
||||
- Simple Clock (timer by GMMan / settings by kowalski7cc) [(Original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61)
|
||||
- UniversalRF Remix / Sub-GHz Remote [(by ESurge)](https://github.com/ESurge/flipperzero-firmware-unirfremix)[(updated and all protocol support added by darmiel & xMasterX)](https://github.com/darmiel/flipper-playlist/tree/feat/unirf-protocols)
|
||||
- Tetris (with fixes) [(by jeffplang)](https://github.com/jeffplang/flipperzero-firmware/tree/tetris_game/applications/tetris_game)
|
||||
- Spectrum Analyzer (with changes) [(by jolcese)](https://github.com/jolcese/flipperzero-firmware/tree/spectrum/applications/spectrum_analyzer) - [Ultra Narrow mode & scan channels non-consecutively](https://github.com/theY4Kman/flipperzero-firmware/commits?author=theY4Kman)
|
||||
- Arkanoid (with fixes) [(by gotnull)](https://github.com/gotnull/flipperzero-firmware-wPlugins)
|
||||
- Tic Tac Toe (with fixes) [(by gotnull)](https://github.com/gotnull/flipperzero-firmware-wPlugins)
|
||||
- Metronome [(by panki27)](https://github.com/panki27/Metronome)
|
||||
- DTMF Dolphin [(by litui)](https://github.com/litui/dtmf_dolphin)
|
||||
- **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator)
|
||||
|
||||
Games:
|
||||
- DOOM (fixed) [(By p4nic4ttack)](https://github.com/p4nic4ttack/doom-flipper-zero/)
|
||||
- Zombiez [(Reworked By DevMilanIan)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/240) [(Original By Dooskington)](https://github.com/Dooskington/flipperzero-zombiez)
|
||||
- Flappy Bird [(By DroomOne)](https://github.com/DroomOne/flipperzero-firmware/tree/dev/applications/flappy_bird)
|
||||
- Arkanoid (refactored by xMasterX) [(by gotnull)](https://github.com/gotnull/flipperzero-firmware-wPlugins)
|
||||
- Tic Tac Toe (refactored by xMasterX) [(by gotnull)](https://github.com/gotnull/flipperzero-firmware-wPlugins)
|
||||
- Tetris (with fixes) [(by jeffplang)](https://github.com/jeffplang/flipperzero-firmware/tree/tetris_game/applications/tetris_game)
|
||||
- Minesweeper [(by panki27)](https://github.com/panki27/minesweeper)
|
||||
- Heap Defence (aka Stack Attack) [(original by wquinoa & Vedmein)](https://github.com/Vedmein/flipperzero-firmware/tree/hd/svisto-perdelki) -> Ported to latest firmware by @xMasterX
|
||||
|
||||
### Other changes
|
||||
|
||||
- BadUSB Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout)
|
||||
- New frequency analyzer - [(by ClusterM)](https://github.com/ClusterM)
|
||||
- BadUSB -> Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout)
|
||||
- SubGHz -> New frequency analyzer - [(by ClusterM)](https://github.com/DarkFlippers/unleashed-firmware/pull/43)
|
||||
- SubGHz -> Detect RAW feature - [(by perspecdev)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/152)
|
||||
- SubGHz -> Save last used frequency and moduluation [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
|
||||
- SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
|
||||
- SubGHz -> Long press OK button in SubGHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79)
|
||||
|
||||
# Instructions
|
||||
## [- How to install firmware](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md)
|
||||
## [- How to install firmware](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)
|
||||
|
||||
## [- How to build firmware](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToBuild.md)
|
||||
## [- How to build firmware](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToBuild.md)
|
||||
|
||||
## [- BadUSB: how to add new keyboard layouts](https://github.com/dummy-decoy/flipperzero_badusb_kl)
|
||||
|
||||
## [- How to change Flipper name](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/CustomFlipperName.md)
|
||||
## [- How to change Flipper name](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/CustomFlipperName.md)
|
||||
|
||||
### **Plugins**
|
||||
|
||||
## [- Configure Sub-GHz Remote App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/SubGHzRemotePlugin.md)
|
||||
## [- 🎲 Download Extra plugins for Unleashed](https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed)
|
||||
|
||||
## [- Barcode Generator](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/BarcodeGenerator.md)
|
||||
## [- Configure Sub-GHz Remote App](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemotePlugin.md)
|
||||
|
||||
## [- Multi Converter](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/MultiConverter.md)
|
||||
## [- TOTP (Authenticator) config description](https://github.com/akopachov/flipper-zero_authenticator/blob/master/.github/conf-file_description.md)
|
||||
|
||||
## [- Barcode Generator](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/BarcodeGenerator.md)
|
||||
|
||||
## [- Multi Converter](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/MultiConverter.md)
|
||||
|
||||
## [- WAV Player sample files & how to convert](https://github.com/UberGuidoZ/Flipper/tree/main/Wav_Player#readme)
|
||||
|
||||
## [- SubGHz playlist generator script](https://github.com/darmiel/flipper-scripts/blob/main/playlist/playlist_creator_by_chunk.py)
|
||||
|
||||
### **Plugins that works with external hardware**
|
||||
|
||||
## [- How to use: [NRF24] plugins](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/NRF24.md)
|
||||
## [- How to use: [NRF24] plugins](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/NRF24.md)
|
||||
|
||||
## [- How to use: [WiFi] Scanner](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module#readme)
|
||||
|
||||
@@ -116,28 +149,29 @@ See changelog in releases for latest updates!
|
||||
|
||||
## [- Windows: How to Upload .bin to ESP32/ESP8266](https://github.com/SequoiaSan/Guide-How-To-Upload-bin-to-ESP8266-ESP32)
|
||||
|
||||
## [- How to use: [GPIO] SentrySafe plugin](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/SentrySafe.md)
|
||||
## [- How to use: [GPIO] SentrySafe plugin](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SentrySafe.md)
|
||||
|
||||
### **SubGHz**
|
||||
|
||||
## [- Transmission is blocked? - How to extend SubGHz frequency range](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/DangerousSettings.md)
|
||||
## [- Transmission is blocked? - How to extend SubGHz frequency range](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/DangerousSettings.md)
|
||||
|
||||
## [- How to add extra SubGHz frequencies](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/SubGHzSettings.md)
|
||||
## [- How to add extra SubGHz frequencies](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md)
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
# Where I can find IR, SubGhz, ... files, DBs, and other stuff?
|
||||
## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero)
|
||||
## [UberGuidoZ Playground - Large collection of files - Github](https://github.com/UberGuidoZ/Flipper)
|
||||
## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero)
|
||||
## [CAME-12bit, NICE-12bit, Linear-10bit, PT-2240 - SubGHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce)
|
||||
## [SMC5326, UNILARM - SubGHz fixed code bruteforce](https://github.com/Hong5489/flipperzero-gate-bruteforce)
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
# Links
|
||||
|
||||
* Unofficial Discord: [discord.gg/58D6E8BtTU](https://discord.gg/58D6E8BtTU)
|
||||
* Unofficial Discord: [discord.unleashedflip.com](https://discord.unleashedflip.com)
|
||||
* Docs by atmanos / How to write your own app (outdated API): [https://flipper.atmanos.com/docs/overview/intro](https://flipper.atmanos.com/docs/overview/intro)
|
||||
|
||||
* Official Docs: [http://docs.flipperzero.one](http://docs.flipperzero.one)
|
||||
@@ -155,4 +189,4 @@ See changelog in releases for latest updates!
|
||||
- `site_scons` - Build helpers
|
||||
- `scripts` - Supplementary scripts and python libraries home
|
||||
|
||||
Also pay attention to `ReadMe.md` files inside of those directories.
|
||||
Also pay attention to `ReadMe.md` files inside those directories.
|
||||
|
||||
88
SConstruct
88
SConstruct
@@ -7,24 +7,29 @@
|
||||
# construction of certain targets behind command-line options.
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
|
||||
EnsurePythonVersion(3, 8)
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
# Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
|
||||
|
||||
|
||||
# This environment is created only for loading options & validating file/dir existence
|
||||
fbt_variables = SConscript("site_scons/commandline.scons")
|
||||
cmd_environment = Environment(tools=[], variables=fbt_variables)
|
||||
Help(fbt_variables.GenerateHelpText(cmd_environment))
|
||||
cmd_environment = Environment(
|
||||
toolpath=["#/scripts/fbt_tools"],
|
||||
tools=[
|
||||
("fbt_help", {"vars": fbt_variables}),
|
||||
],
|
||||
variables=fbt_variables,
|
||||
)
|
||||
|
||||
# Building basic environment - tools, utility methods, cross-compilation
|
||||
# settings, gcc flags for Cortex-M4, basic builders and more
|
||||
coreenv = SConscript(
|
||||
"site_scons/environ.scons",
|
||||
exports={"VAR_ENV": cmd_environment},
|
||||
toolpath=["#/scripts/fbt_tools"],
|
||||
)
|
||||
SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
|
||||
|
||||
@@ -34,37 +39,13 @@ coreenv["ROOT_DIR"] = Dir(".")
|
||||
|
||||
# Create a separate "dist" environment and add construction envs to it
|
||||
distenv = coreenv.Clone(
|
||||
tools=["fbt_dist", "openocd", "blackmagic", "jflash"],
|
||||
OPENOCD_GDB_PIPE=[
|
||||
"|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"
|
||||
tools=[
|
||||
"fbt_dist",
|
||||
"fbt_debugopts",
|
||||
"openocd",
|
||||
"blackmagic",
|
||||
"jflash",
|
||||
],
|
||||
GDBOPTS_BASE=[
|
||||
"-ex",
|
||||
"target extended-remote ${GDBREMOTE}",
|
||||
"-ex",
|
||||
"set confirm off",
|
||||
],
|
||||
GDBOPTS_BLACKMAGIC=[
|
||||
"-ex",
|
||||
"monitor swdp_scan",
|
||||
"-ex",
|
||||
"monitor debug_bmp enable",
|
||||
"-ex",
|
||||
"attach 1",
|
||||
"-ex",
|
||||
"set mem inaccessible-by-default off",
|
||||
],
|
||||
GDBPYOPTS=[
|
||||
"-ex",
|
||||
"source debug/FreeRTOS/FreeRTOS.py",
|
||||
"-ex",
|
||||
"source debug/PyCortexMDebug/PyCortexMDebug.py",
|
||||
"-ex",
|
||||
"svd_load ${SVD_FILE}",
|
||||
"-ex",
|
||||
"compare-sections",
|
||||
],
|
||||
JFLASHPROJECT="${ROOT_DIR.abspath}/debug/fw.jflash",
|
||||
ENV=os.environ,
|
||||
)
|
||||
|
||||
@@ -160,11 +141,34 @@ if GetOption("fullenv") or any(
|
||||
basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
|
||||
distenv.Default(basic_dist)
|
||||
|
||||
dist_dir = distenv.GetProjetDirName()
|
||||
fap_dist = [
|
||||
distenv.Install(
|
||||
f"#/dist/{dist_dir}/apps/debug_elf",
|
||||
firmware_env["FW_EXTAPPS"]["debug"].values(),
|
||||
),
|
||||
*(
|
||||
distenv.Install(f"#/dist/{dist_dir}/apps/{dist_entry[0]}", dist_entry[1])
|
||||
for dist_entry in firmware_env["FW_EXTAPPS"]["dist"].values()
|
||||
),
|
||||
]
|
||||
Depends(fap_dist, firmware_env["FW_EXTAPPS"]["validators"].values())
|
||||
Alias("fap_dist", fap_dist)
|
||||
# distenv.Default(fap_dist)
|
||||
|
||||
plugin_resources_dist = list(
|
||||
distenv.Install(f"#/assets/resources/apps/{dist_entry[0]}", dist_entry[1])
|
||||
for dist_entry in firmware_env["FW_EXTAPPS"]["dist"].values()
|
||||
)
|
||||
distenv.Depends(firmware_env["FW_RESOURCES"], plugin_resources_dist)
|
||||
|
||||
|
||||
# Target for bundling core2 package for qFlipper
|
||||
copro_dist = distenv.CoproBuilder(
|
||||
distenv.Dir("assets/core2_firmware"),
|
||||
"#/build/core2_firmware.tgz",
|
||||
[],
|
||||
)
|
||||
distenv.AlwaysBuild(copro_dist)
|
||||
distenv.Alias("copro_dist", copro_dist)
|
||||
|
||||
firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
|
||||
@@ -209,10 +213,19 @@ distenv.PhonyTarget(
|
||||
distenv.PhonyTarget(
|
||||
"debug_other",
|
||||
"${GDBPYCOM}",
|
||||
GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
|
||||
GDBOPTS="${GDBOPTS_BASE}",
|
||||
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
||||
GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
|
||||
)
|
||||
|
||||
distenv.PhonyTarget(
|
||||
"debug_other_blackmagic",
|
||||
"${GDBPYCOM}",
|
||||
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
||||
GDBREMOTE="$${BLACKMAGIC_ADDR}",
|
||||
)
|
||||
|
||||
|
||||
# Just start OpenOCD
|
||||
distenv.PhonyTarget(
|
||||
"openocd",
|
||||
@@ -240,7 +253,6 @@ firmware_env.Append(
|
||||
"site_scons",
|
||||
"scripts",
|
||||
# Extra files
|
||||
"applications/extapps.scons",
|
||||
"SConstruct",
|
||||
"firmware.scons",
|
||||
"fbt_options.py",
|
||||
|
||||
@@ -1,38 +1,89 @@
|
||||
# Structure
|
||||
|
||||
- `about` - Small About application that shows flipper info
|
||||
- `accessor` - Wiegand server
|
||||
## debug
|
||||
|
||||
Applications for factory testing the Flipper.
|
||||
|
||||
- `accessor` - Wiegand server
|
||||
- `battery_test_app` - Battery debug app
|
||||
- `blink_test` - LED blinker
|
||||
- `bt_debug_app` - BT test app. Requires full BT stack installed
|
||||
- `display_test` - Various display tests & tweaks
|
||||
- `file_browser_test` - Test UI for file picker
|
||||
- `keypad_test` - Keypad test
|
||||
- `lfrfid_debug` - LF RFID debug tool
|
||||
- `text_box_test` - UI tests
|
||||
- `uart_echo` - UART mode test
|
||||
- `unit_tests` - Unit tests
|
||||
- `usb_mouse` - USB HID test
|
||||
- `usb_test` - Other USB tests
|
||||
- `vibro_test` - Vibro test
|
||||
|
||||
|
||||
## main
|
||||
|
||||
Applications for main Flipper menu.
|
||||
|
||||
- `archive` - Archive and file manager
|
||||
- `bad_usb` - Bad USB application
|
||||
- `fap_loader` - External applications loader
|
||||
- `gpio` - GPIO application: includes USART bridge and GPIO control
|
||||
- `ibutton` - iButton application, onewire keys and more
|
||||
- `infrared` - Infrared application, controls your IR devices
|
||||
- `lfrfid` - LF RFID application
|
||||
- `nfc` - NFC application, HF rfid, EMV and etc
|
||||
- `subghz` - SubGhz application, 433 fobs and etc
|
||||
- `u2f` - U2F Application
|
||||
|
||||
|
||||
## plugins
|
||||
|
||||
Extra apps for Plugins & App Loader menus.
|
||||
|
||||
- `bt_hid_app` - BT Remote controller
|
||||
- `music_player` - Music player app (demo)
|
||||
- `picopass` - Picopass tool
|
||||
- `snake_game` - Snake game application
|
||||
|
||||
|
||||
## services
|
||||
|
||||
Background services providing system APIs to applications.
|
||||
|
||||
- `applications.h` - Firmware application list header
|
||||
|
||||
- `bt` - BLE service and application
|
||||
- `cli` - Console service and API
|
||||
- `crypto` - Crypto cli tools
|
||||
- `debug_tools` - Different tools that we use for debug
|
||||
- `desktop` - Desktop service
|
||||
- `dialogs` - Dialogs service: GUI Dialogs for your app
|
||||
- `dolphin` - Dolphin service and supplementary apps
|
||||
- `gpio` - GPIO application: includes USART bridge and GPIO control
|
||||
- `gui` - GUI service and API
|
||||
- `ibutton` - iButton application, onewire keys and more
|
||||
- `input` - Input service
|
||||
- `infrared` - Infrared application, controls your IR devices
|
||||
- `lfrfid` - LF RFID application
|
||||
- `lfrfid_debug` - LF RFID debug tool
|
||||
- `loader` - Application loader service
|
||||
- `music_player` - Music player app (demo)
|
||||
- `nfc` - NFC application, HF rfid, EMV and etc
|
||||
- `notification` - Notification service
|
||||
- `power` - Power service
|
||||
- `power_observer` - Power debug tool
|
||||
- `rpc` - RPC service and API
|
||||
- `scened_app_example` - C++ application example
|
||||
- `snake_game` - Snake game application
|
||||
- `storage` - Storage service, internal + sdcard
|
||||
- `storage_settings` - Storage settings app
|
||||
- `subghz` - SubGhz application, 433 fobs and etc
|
||||
- `system` - System settings, tools and API
|
||||
- `tests` - Unit tests and etc
|
||||
- `u2f` - U2F Application
|
||||
- `updater` - Update service & application
|
||||
|
||||
- `application.h` - Firmware application list header
|
||||
|
||||
## settings
|
||||
|
||||
Small applications providing configuration for basic firmware and its services.
|
||||
|
||||
- `about` - Small About application that shows flipper info
|
||||
- `bt_settings_app` - Bluetooth options
|
||||
- `desktop_settings` - Desktop configuration
|
||||
- `dolphin_passport` - Dolphin passport app
|
||||
- `notification_settings` - LCD brightness, sound volume, etc configuration
|
||||
- `power_settings_app` - Basic power options
|
||||
- `storage_settings` - Storage settings app
|
||||
- `system` - System settings
|
||||
|
||||
|
||||
## system
|
||||
|
||||
Utility apps not visible in other menus.
|
||||
|
||||
- `storage_move_to_sd` - Data migration tool for internal storage
|
||||
- `updater` - Update service & application
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#include "archive_i.h"
|
||||
#include "m-string.h"
|
||||
|
||||
bool archive_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
ArchiveApp* archive = (ArchiveApp*)context;
|
||||
return scene_manager_handle_custom_event(archive->scene_manager, event);
|
||||
}
|
||||
|
||||
bool archive_back_event_callback(void* context) {
|
||||
furi_assert(context);
|
||||
ArchiveApp* archive = (ArchiveApp*)context;
|
||||
return scene_manager_handle_back_event(archive->scene_manager);
|
||||
}
|
||||
|
||||
ArchiveApp* archive_alloc() {
|
||||
ArchiveApp* archive = malloc(sizeof(ArchiveApp));
|
||||
|
||||
archive->gui = furi_record_open(RECORD_GUI);
|
||||
archive->text_input = text_input_alloc();
|
||||
string_init(archive->fav_move_str);
|
||||
|
||||
archive->view_dispatcher = view_dispatcher_alloc();
|
||||
archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive);
|
||||
|
||||
view_dispatcher_enable_queue(archive->view_dispatcher);
|
||||
view_dispatcher_attach_to_gui(
|
||||
archive->view_dispatcher, archive->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
view_dispatcher_set_event_callback_context(archive->view_dispatcher, archive);
|
||||
view_dispatcher_set_custom_event_callback(
|
||||
archive->view_dispatcher, archive_custom_event_callback);
|
||||
view_dispatcher_set_navigation_event_callback(
|
||||
archive->view_dispatcher, archive_back_event_callback);
|
||||
|
||||
archive->browser = browser_alloc();
|
||||
|
||||
view_dispatcher_add_view(
|
||||
archive->view_dispatcher, ArchiveViewBrowser, archive_browser_get_view(archive->browser));
|
||||
|
||||
view_dispatcher_add_view(
|
||||
archive->view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input));
|
||||
|
||||
archive->widget = widget_alloc();
|
||||
view_dispatcher_add_view(
|
||||
archive->view_dispatcher, ArchiveViewWidget, widget_get_view(archive->widget));
|
||||
|
||||
return archive;
|
||||
}
|
||||
|
||||
void archive_free(ArchiveApp* archive) {
|
||||
furi_assert(archive);
|
||||
|
||||
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewBrowser);
|
||||
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewTextInput);
|
||||
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewWidget);
|
||||
widget_free(archive->widget);
|
||||
view_dispatcher_free(archive->view_dispatcher);
|
||||
scene_manager_free(archive->scene_manager);
|
||||
browser_free(archive->browser);
|
||||
string_clear(archive->fav_move_str);
|
||||
|
||||
text_input_free(archive->text_input);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
archive->gui = NULL;
|
||||
|
||||
free(archive);
|
||||
}
|
||||
|
||||
int32_t archive_app(void* p) {
|
||||
UNUSED(p);
|
||||
ArchiveApp* archive = archive_alloc();
|
||||
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
|
||||
view_dispatcher_run(archive->view_dispatcher);
|
||||
archive_free(archive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
#include "../archive_i.h"
|
||||
#include "../helpers/archive_favorites.h"
|
||||
#include "../helpers/archive_files.h"
|
||||
#include "../helpers/archive_browser.h"
|
||||
#include "archive/views/archive_browser_view.h"
|
||||
#include "toolbox/path.h"
|
||||
|
||||
#define SCENE_RENAME_CUSTOM_EVENT (0UL)
|
||||
#define MAX_TEXT_INPUT_LEN 22
|
||||
|
||||
void archive_scene_rename_text_input_callback(void* context) {
|
||||
ArchiveApp* archive = (ArchiveApp*)context;
|
||||
view_dispatcher_send_custom_event(archive->view_dispatcher, SCENE_RENAME_CUSTOM_EVENT);
|
||||
}
|
||||
|
||||
void archive_scene_rename_on_enter(void* context) {
|
||||
ArchiveApp* archive = (ArchiveApp*)context;
|
||||
|
||||
TextInput* text_input = archive->text_input;
|
||||
ArchiveFile_t* current = archive_get_current_file(archive->browser);
|
||||
|
||||
string_t filename;
|
||||
string_init(filename);
|
||||
path_extract_filename(current->path, filename, true);
|
||||
strlcpy(archive->text_store, string_get_cstr(filename), MAX_NAME_LEN);
|
||||
|
||||
path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN);
|
||||
|
||||
text_input_set_header_text(text_input, "Rename:");
|
||||
|
||||
text_input_set_result_callback(
|
||||
text_input,
|
||||
archive_scene_rename_text_input_callback,
|
||||
archive,
|
||||
archive->text_store,
|
||||
MAX_TEXT_INPUT_LEN,
|
||||
false);
|
||||
|
||||
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
|
||||
string_get_cstr(archive->browser->path), archive->file_extension, "");
|
||||
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
|
||||
|
||||
string_clear(filename);
|
||||
|
||||
view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput);
|
||||
}
|
||||
|
||||
bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
|
||||
ArchiveApp* archive = (ArchiveApp*)context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SCENE_RENAME_CUSTOM_EVENT) {
|
||||
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
const char* path_src = archive_get_name(archive->browser);
|
||||
ArchiveFile_t* file = archive_get_current_file(archive->browser);
|
||||
|
||||
string_t path_dst;
|
||||
string_init(path_dst);
|
||||
path_extract_dirname(path_src, path_dst);
|
||||
string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]);
|
||||
|
||||
storage_common_rename(fs_api, path_src, string_get_cstr(path_dst));
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
if(file->fav) {
|
||||
archive_favorites_rename(path_src, string_get_cstr(path_dst));
|
||||
}
|
||||
|
||||
string_clear(path_dst);
|
||||
|
||||
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void archive_scene_rename_on_exit(void* context) {
|
||||
ArchiveApp* archive = (ArchiveApp*)context;
|
||||
|
||||
// Clear view
|
||||
void* validator_context = text_input_get_validator_callback_context(archive->text_input);
|
||||
text_input_set_validator(archive->text_input, NULL, NULL);
|
||||
validator_is_file_free(validator_context);
|
||||
|
||||
text_input_reset(archive->text_input);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
App(
|
||||
appid="arkanoid_game",
|
||||
name="Arkanoid",
|
||||
apptype=FlipperAppType.GAME,
|
||||
entry_point="arkanoid_game_app",
|
||||
cdefines=["APP_ARKANOID_GAME"],
|
||||
requires=["gui"],
|
||||
stack_size=4 * 1024,
|
||||
order=30,
|
||||
)
|
||||
@@ -1,66 +0,0 @@
|
||||
App(
|
||||
appid="bt",
|
||||
name="BtSrv",
|
||||
apptype=FlipperAppType.SERVICE,
|
||||
entry_point="bt_srv",
|
||||
cdefines=["SRV_BT"],
|
||||
requires=[
|
||||
"cli",
|
||||
"dialogs",
|
||||
],
|
||||
provides=[
|
||||
"bt_start",
|
||||
"bt_settings",
|
||||
"bt_debug",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=20,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_start",
|
||||
apptype=FlipperAppType.STARTUP,
|
||||
entry_point="bt_on_system_start",
|
||||
order=70,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_settings",
|
||||
name="Bluetooth",
|
||||
apptype=FlipperAppType.SETTINGS,
|
||||
entry_point="bt_settings_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
],
|
||||
order=10,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_debug",
|
||||
name="Bluetooth Debug",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="bt_debug_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
"dialogs",
|
||||
],
|
||||
order=110,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="bt_hid",
|
||||
name="Bluetooth Remote",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="bt_hid_app",
|
||||
stack_size=1 * 1024,
|
||||
cdefines=["APP_BLE_HID"],
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
],
|
||||
order=10,
|
||||
)
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "cli_i.h"
|
||||
|
||||
void cli_command_gpio(Cli* cli, string_t args, void* context);
|
||||
@@ -1,11 +0,0 @@
|
||||
App(
|
||||
appid="clock",
|
||||
name="Clock",
|
||||
apptype=FlipperAppType.APP,
|
||||
entry_point="clock_app",
|
||||
cdefines=["APP_CLOCK"],
|
||||
requires=["gui"],
|
||||
icon="A_Clock_14",
|
||||
stack_size=2 * 1024,
|
||||
order=9,
|
||||
)
|
||||
@@ -1,146 +0,0 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <gui/elements.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
|
||||
#define TAG "Clock"
|
||||
#define CLOCK_DATE_FORMAT "%.4d-%.2d-%.2d"
|
||||
#define CLOCK_TIME_FORMAT "%.2d:%.2d:%.2d"
|
||||
|
||||
typedef enum {
|
||||
EventTypeTick,
|
||||
EventTypeKey,
|
||||
} EventType;
|
||||
|
||||
typedef struct {
|
||||
EventType type;
|
||||
InputEvent input;
|
||||
} PluginEvent;
|
||||
|
||||
typedef struct {
|
||||
FuriHalRtcDateTime datetime;
|
||||
} ClockState;
|
||||
|
||||
static void clock_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
furi_assert(event_queue);
|
||||
|
||||
PluginEvent event = {.type = EventTypeKey, .input = *input_event};
|
||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
|
||||
static void clock_render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
ClockState* state = (ClockState*)acquire_mutex((ValueMutex*)ctx, 25);
|
||||
|
||||
char strings[2][20];
|
||||
|
||||
snprintf(
|
||||
strings[0],
|
||||
sizeof(strings[0]),
|
||||
CLOCK_DATE_FORMAT,
|
||||
state->datetime.year,
|
||||
state->datetime.month,
|
||||
state->datetime.day);
|
||||
snprintf(
|
||||
strings[1],
|
||||
sizeof(strings[1]),
|
||||
CLOCK_TIME_FORMAT,
|
||||
state->datetime.hour,
|
||||
state->datetime.minute,
|
||||
state->datetime.second);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, state);
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(canvas, 64, 42 - 16, AlignCenter, AlignCenter, strings[1]);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 64, 52 - 8, AlignCenter, AlignTop, strings[0]);
|
||||
}
|
||||
|
||||
static void clock_state_init(ClockState* const state) {
|
||||
furi_hal_rtc_get_datetime(&state->datetime);
|
||||
}
|
||||
|
||||
// Runs every 1000ms by default
|
||||
static void clock_tick(void* ctx) {
|
||||
furi_assert(ctx);
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
PluginEvent event = {.type = EventTypeTick};
|
||||
// It's OK to loose this event if system overloaded
|
||||
furi_message_queue_put(event_queue, &event, 0);
|
||||
}
|
||||
|
||||
int32_t clock_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||
|
||||
ClockState* plugin_state = malloc(sizeof(ClockState));
|
||||
clock_state_init(plugin_state);
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(ClockState))) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
furi_message_queue_free(event_queue);
|
||||
free(plugin_state);
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, clock_render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, clock_input_callback, event_queue);
|
||||
FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, event_queue);
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency());
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
// Main loop
|
||||
PluginEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
ClockState* plugin_state = (ClockState*)acquire_mutex_block(&state_mutex);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) {
|
||||
switch(event.input.key) {
|
||||
case InputKeyUp:
|
||||
case InputKeyDown:
|
||||
case InputKeyRight:
|
||||
case InputKeyLeft:
|
||||
case InputKeyOk:
|
||||
break;
|
||||
case InputKeyBack:
|
||||
// Exit the plugin
|
||||
processing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(event.type == EventTypeTick) {
|
||||
furi_hal_rtc_get_datetime(&plugin_state->datetime);
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "furi_message_queue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
}
|
||||
|
||||
furi_timer_free(timer);
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -7,4 +7,5 @@ App(
|
||||
requires=["gui"],
|
||||
stack_size=4 * 1024,
|
||||
order=40,
|
||||
fap_category="Debug",
|
||||
)
|
||||
16
applications/debug/application.fam
Normal file
16
applications/debug/application.fam
Normal file
@@ -0,0 +1,16 @@
|
||||
App(
|
||||
appid="debug_apps",
|
||||
name="Basic debug apps bundle",
|
||||
apptype=FlipperAppType.METAPACKAGE,
|
||||
provides=[
|
||||
"blink_test",
|
||||
"vibro_test",
|
||||
"keypad_test",
|
||||
"usb_test",
|
||||
"USB_Mouse",
|
||||
"UART_Echo",
|
||||
"display_test",
|
||||
"text_box_test",
|
||||
"file_browser_test",
|
||||
],
|
||||
)
|
||||
14
applications/debug/battery_test_app/application.fam
Normal file
14
applications/debug/battery_test_app/application.fam
Normal file
@@ -0,0 +1,14 @@
|
||||
App(
|
||||
appid="battery_test",
|
||||
name="Battery Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="battery_test_app",
|
||||
cdefines=["APP_BATTERY_TEST"],
|
||||
requires=[
|
||||
"gui",
|
||||
"power",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=130,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -27,7 +27,7 @@ static void battery_test_battery_info_update_model(void* context) {
|
||||
.charge = app->info.charge,
|
||||
.health = app->info.health,
|
||||
};
|
||||
battery_info_set_data(app->batery_info, &battery_info_data);
|
||||
battery_info_set_data(app->battery_info, &battery_info_data);
|
||||
notification_message(app->notifications, &sequence_display_backlight_on);
|
||||
}
|
||||
|
||||
@@ -48,13 +48,13 @@ BatteryTestApp* battery_test_alloc() {
|
||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
// Views
|
||||
app->batery_info = battery_info_alloc();
|
||||
app->battery_info = battery_info_alloc();
|
||||
view_set_previous_callback(
|
||||
battery_info_get_view(app->batery_info), battery_test_exit_confirm_view);
|
||||
battery_info_get_view(app->battery_info), battery_test_exit_confirm_view);
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
BatteryTestAppViewBatteryInfo,
|
||||
battery_info_get_view(app->batery_info));
|
||||
battery_info_get_view(app->battery_info));
|
||||
|
||||
app->dialog = dialog_ex_alloc();
|
||||
dialog_ex_set_header(app->dialog, "Close Battery Test?", 64, 12, AlignCenter, AlignTop);
|
||||
@@ -76,7 +76,7 @@ void battery_test_free(BatteryTestApp* app) {
|
||||
|
||||
// Views
|
||||
view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
|
||||
battery_info_free(app->batery_info);
|
||||
battery_info_free(app->battery_info);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewExitDialog);
|
||||
dialog_ex_free(app->dialog);
|
||||
// View dispatcher
|
||||
@@ -6,14 +6,15 @@
|
||||
#include <notification/notification.h>
|
||||
|
||||
#include <gui/modules/dialog_ex.h>
|
||||
#include <power/power_settings_app/views/battery_info.h>
|
||||
// FIXME
|
||||
#include "../settings/power_settings_app/views/battery_info.h"
|
||||
|
||||
typedef struct {
|
||||
Power* power;
|
||||
Gui* gui;
|
||||
NotificationApp* notifications;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
BatteryInfo* batery_info;
|
||||
BatteryInfo* battery_info;
|
||||
DialogEx* dialog;
|
||||
PowerInfo info;
|
||||
} BatteryTestApp;
|
||||
11
applications/debug/blink_test/application.fam
Normal file
11
applications/debug/blink_test/application.fam
Normal file
@@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="blink_test",
|
||||
name="Blink Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="blink_test_app",
|
||||
cdefines=["APP_BLINK"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=10,
|
||||
fap_category="Debug",
|
||||
)
|
||||
18
applications/debug/bt_debug_app/application.fam
Normal file
18
applications/debug/bt_debug_app/application.fam
Normal file
@@ -0,0 +1,18 @@
|
||||
App(
|
||||
appid="bt_debug",
|
||||
name="Bluetooth Debug",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="bt_debug_app",
|
||||
cdefines=["SRV_BT"],
|
||||
requires=[
|
||||
"bt",
|
||||
"gui",
|
||||
"dialogs",
|
||||
],
|
||||
provides=[
|
||||
"bt_debug",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=110,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <gui/modules/submenu.h>
|
||||
#include "views/bt_carrier_test.h"
|
||||
#include "views/bt_packet_test.h"
|
||||
#include "../bt_settings.h"
|
||||
#include <bt/bt_settings.h>
|
||||
|
||||
typedef struct {
|
||||
BtSettings settings;
|
||||
@@ -3,14 +3,13 @@
|
||||
#include <gui/canvas.h>
|
||||
#include <gui/elements.h>
|
||||
#include <m-array.h>
|
||||
#include <m-string.h>
|
||||
#include <furi.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct BtTestParam {
|
||||
const char* label;
|
||||
uint8_t current_value_index;
|
||||
string_t current_value_text;
|
||||
FuriString* current_value_text;
|
||||
uint8_t values_count;
|
||||
BtTestParamChangeCallback change_callback;
|
||||
void* context;
|
||||
@@ -85,7 +84,8 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) {
|
||||
canvas_draw_str(canvas, 50, param_text_y, "<");
|
||||
}
|
||||
|
||||
canvas_draw_str(canvas, 61, param_text_y, string_get_cstr(param->current_value_text));
|
||||
canvas_draw_str(
|
||||
canvas, 61, param_text_y, furi_string_get_cstr(param->current_value_text));
|
||||
|
||||
if(param->current_value_index < (param->values_count - 1)) {
|
||||
canvas_draw_str(canvas, 113, param_text_y, ">");
|
||||
@@ -154,7 +154,9 @@ static bool bt_test_input_callback(InputEvent* event, void* context) {
|
||||
|
||||
void bt_test_process_up(BtTest* bt_test) {
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
uint8_t params_on_screen = 3;
|
||||
if(model->position > 0) {
|
||||
model->position--;
|
||||
@@ -168,13 +170,15 @@ void bt_test_process_up(BtTest* bt_test) {
|
||||
model->window_position = model->position - (params_on_screen - 1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void bt_test_process_down(BtTest* bt_test) {
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
uint8_t params_on_screen = 3;
|
||||
if(model->position < (BtTestParamArray_size(model->params) - 1)) {
|
||||
model->position++;
|
||||
@@ -187,8 +191,8 @@ void bt_test_process_down(BtTest* bt_test) {
|
||||
model->position = 0;
|
||||
model->window_position = 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
BtTestParam* bt_test_get_selected_param(BtTestModel* model) {
|
||||
@@ -213,7 +217,9 @@ BtTestParam* bt_test_get_selected_param(BtTestModel* model) {
|
||||
void bt_test_process_left(BtTest* bt_test) {
|
||||
BtTestParam* param;
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
param = bt_test_get_selected_param(model);
|
||||
if(param->current_value_index > 0) {
|
||||
param->current_value_index--;
|
||||
@@ -225,8 +231,8 @@ void bt_test_process_left(BtTest* bt_test) {
|
||||
model->packets_num_tx = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
if(param->change_callback) {
|
||||
param->change_callback(param);
|
||||
}
|
||||
@@ -235,7 +241,9 @@ void bt_test_process_left(BtTest* bt_test) {
|
||||
void bt_test_process_right(BtTest* bt_test) {
|
||||
BtTestParam* param;
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
param = bt_test_get_selected_param(model);
|
||||
if(param->current_value_index < (param->values_count - 1)) {
|
||||
param->current_value_index++;
|
||||
@@ -247,8 +255,8 @@ void bt_test_process_right(BtTest* bt_test) {
|
||||
model->packets_num_tx = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
if(param->change_callback) {
|
||||
param->change_callback(param);
|
||||
}
|
||||
@@ -257,7 +265,9 @@ void bt_test_process_right(BtTest* bt_test) {
|
||||
void bt_test_process_ok(BtTest* bt_test) {
|
||||
BtTestState state;
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
if(model->state == BtTestStateStarted) {
|
||||
model->state = BtTestStateStopped;
|
||||
model->message = BT_TEST_START_MESSAGE;
|
||||
@@ -269,8 +279,8 @@ void bt_test_process_ok(BtTest* bt_test) {
|
||||
model->message = BT_TEST_STOP_MESSAGE;
|
||||
}
|
||||
state = model->state;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
if(bt_test->change_state_callback) {
|
||||
bt_test->change_state_callback(state, bt_test->context);
|
||||
}
|
||||
@@ -278,13 +288,15 @@ void bt_test_process_ok(BtTest* bt_test) {
|
||||
|
||||
void bt_test_process_back(BtTest* bt_test) {
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
model->state = BtTestStateStopped;
|
||||
model->rssi = 0.0f;
|
||||
model->packets_num_rx = 0;
|
||||
model->packets_num_tx = 0;
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
if(bt_test->back_callback) {
|
||||
bt_test->back_callback(bt_test->context);
|
||||
}
|
||||
@@ -299,7 +311,9 @@ BtTest* bt_test_alloc() {
|
||||
view_set_input_callback(bt_test->view, bt_test_input_callback);
|
||||
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
model->state = BtTestStateStopped;
|
||||
model->message = "Ok - Start";
|
||||
BtTestParamArray_init(model->params);
|
||||
@@ -308,8 +322,8 @@ BtTest* bt_test_alloc() {
|
||||
model->rssi = 0.0f;
|
||||
model->packets_num_tx = 0;
|
||||
model->packets_num_rx = 0;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return bt_test;
|
||||
}
|
||||
@@ -318,15 +332,17 @@ void bt_test_free(BtTest* bt_test) {
|
||||
furi_assert(bt_test);
|
||||
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
BtTestParamArray_it_t it;
|
||||
for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it);
|
||||
BtTestParamArray_next(it)) {
|
||||
string_clear(BtTestParamArray_ref(it)->current_value_text);
|
||||
furi_string_free(BtTestParamArray_ref(it)->current_value_text);
|
||||
}
|
||||
BtTestParamArray_clear(model->params);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
view_free(bt_test->view);
|
||||
free(bt_test);
|
||||
}
|
||||
@@ -347,16 +363,18 @@ BtTestParam* bt_test_param_add(
|
||||
furi_assert(bt_test);
|
||||
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
bt_test->view,
|
||||
BtTestModel * model,
|
||||
{
|
||||
param = BtTestParamArray_push_new(model->params);
|
||||
param->label = label;
|
||||
param->values_count = values_count;
|
||||
param->change_callback = change_callback;
|
||||
param->context = context;
|
||||
param->current_value_index = 0;
|
||||
string_init(param->current_value_text);
|
||||
return true;
|
||||
});
|
||||
param->current_value_text = furi_string_alloc();
|
||||
},
|
||||
true);
|
||||
|
||||
return param;
|
||||
}
|
||||
@@ -364,28 +382,19 @@ BtTestParam* bt_test_param_add(
|
||||
void bt_test_set_rssi(BtTest* bt_test, float rssi) {
|
||||
furi_assert(bt_test);
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
model->rssi = rssi;
|
||||
return true;
|
||||
});
|
||||
bt_test->view, BtTestModel * model, { model->rssi = rssi; }, true);
|
||||
}
|
||||
|
||||
void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num) {
|
||||
furi_assert(bt_test);
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
model->packets_num_tx = packets_num;
|
||||
return true;
|
||||
});
|
||||
bt_test->view, BtTestModel * model, { model->packets_num_tx = packets_num; }, true);
|
||||
}
|
||||
|
||||
void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num) {
|
||||
furi_assert(bt_test);
|
||||
with_view_model(
|
||||
bt_test->view, (BtTestModel * model) {
|
||||
model->packets_num_rx = packets_num;
|
||||
return true;
|
||||
});
|
||||
bt_test->view, BtTestModel * model, { model->packets_num_rx = packets_num; }, true);
|
||||
}
|
||||
|
||||
void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback) {
|
||||
@@ -410,7 +419,7 @@ void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_i
|
||||
}
|
||||
|
||||
void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text) {
|
||||
string_set_str(param->current_value_text, current_value_text);
|
||||
furi_string_set(param->current_value_text, current_value_text);
|
||||
}
|
||||
|
||||
uint8_t bt_test_get_current_value_index(BtTestParam* param) {
|
||||
11
applications/debug/display_test/application.fam
Normal file
11
applications/debug/display_test/application.fam
Normal file
@@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="display_test",
|
||||
name="Display Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="display_test_app",
|
||||
cdefines=["APP_DISPLAY_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=120,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -113,11 +113,11 @@ static void display_config_set_regulation_ratio(VariableItem* item) {
|
||||
static void display_config_set_contrast(VariableItem* item) {
|
||||
DisplayTest* instance = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
string_t temp;
|
||||
string_init(temp);
|
||||
string_cat_printf(temp, "%d", index);
|
||||
variable_item_set_current_value_text(item, string_get_cstr(temp));
|
||||
string_clear(temp);
|
||||
FuriString* temp;
|
||||
temp = furi_string_alloc();
|
||||
furi_string_cat_printf(temp, "%d", index);
|
||||
variable_item_set_current_value_text(item, furi_string_get_cstr(temp));
|
||||
furi_string_free(temp);
|
||||
instance->config_contrast = index;
|
||||
display_test_reload_config(instance);
|
||||
}
|
||||
@@ -110,7 +110,9 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) {
|
||||
bool consumed = false;
|
||||
if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
|
||||
with_view_model(
|
||||
instance->view, (ViewDisplayTestModel * model) {
|
||||
instance->view,
|
||||
ViewDisplayTestModel * model,
|
||||
{
|
||||
if(event->key == InputKeyLeft && model->test > 0) {
|
||||
model->test--;
|
||||
consumed = true;
|
||||
@@ -129,8 +131,8 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) {
|
||||
model->flip_flop = !model->flip_flop;
|
||||
consumed = true;
|
||||
}
|
||||
return consumed;
|
||||
});
|
||||
},
|
||||
consumed);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
@@ -149,10 +151,7 @@ static void view_display_test_exit(void* context) {
|
||||
static void view_display_test_timer_callback(void* context) {
|
||||
ViewDisplayTest* instance = context;
|
||||
with_view_model(
|
||||
instance->view, (ViewDisplayTestModel * model) {
|
||||
model->counter++;
|
||||
return true;
|
||||
});
|
||||
instance->view, ViewDisplayTestModel * model, { model->counter++; }, true);
|
||||
}
|
||||
|
||||
ViewDisplayTest* view_display_test_alloc() {
|
||||
11
applications/debug/file_browser_test/application.fam
Normal file
11
applications/debug/file_browser_test/application.fam
Normal file
@@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="file_browser_test",
|
||||
name="File Browser Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="file_browser_app",
|
||||
cdefines=["APP_FILE_BROWSER_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=150,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "assets_icons.h"
|
||||
#include "file_browser_app_i.h"
|
||||
#include "gui/modules/file_browser.h"
|
||||
#include "m-string.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <storage/storage.h>
|
||||
@@ -47,7 +46,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) {
|
||||
|
||||
app->widget = widget_alloc();
|
||||
|
||||
string_init(app->file_path);
|
||||
app->file_path = furi_string_alloc();
|
||||
app->file_browser = file_browser_alloc(app->file_path);
|
||||
file_browser_configure(app->file_browser, "*", true, &I_badusb_10px, true);
|
||||
|
||||
@@ -84,7 +83,7 @@ void file_browser_app_free(FileBrowserApp* app) {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
|
||||
string_clear(app->file_path);
|
||||
furi_string_free(app->file_path);
|
||||
|
||||
free(app);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ struct FileBrowserApp {
|
||||
Widget* widget;
|
||||
FileBrowser* file_browser;
|
||||
|
||||
string_t file_path;
|
||||
FuriString* file_path;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "../file_browser_app_i.h"
|
||||
#include <core/check.h>
|
||||
#include <core/log.h>
|
||||
#include "furi_hal.h"
|
||||
#include "m-string.h"
|
||||
#include <furi.h>
|
||||
|
||||
#define DEFAULT_PATH "/"
|
||||
#define EXTENSION "*"
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "../file_browser_app_i.h"
|
||||
#include "furi_hal.h"
|
||||
#include "m-string.h"
|
||||
#include <furi.h>
|
||||
|
||||
void file_browser_scene_result_ok_callback(InputType type, void* context) {
|
||||
furi_assert(context);
|
||||
@@ -24,7 +23,13 @@ void file_browser_scene_result_on_enter(void* context) {
|
||||
FileBrowserApp* app = context;
|
||||
|
||||
widget_add_string_multiline_element(
|
||||
app->widget, 64, 10, AlignCenter, AlignTop, FontSecondary, string_get_cstr(app->file_path));
|
||||
app->widget,
|
||||
64,
|
||||
10,
|
||||
AlignCenter,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
furi_string_get_cstr(app->file_path));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewResult);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
string_set_str(app->file_path, ANY_PATH("badusb/demo_windows.txt"));
|
||||
furi_string_set(app->file_path, ANY_PATH("badusb/demo_windows.txt"));
|
||||
scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser);
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeTick) {
|
||||
11
applications/debug/keypad_test/application.fam
Normal file
11
applications/debug/keypad_test/application.fam
Normal file
@@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="keypad_test",
|
||||
name="Keypad Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="keypad_test_app",
|
||||
cdefines=["APP_KEYPAD_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=30,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -5,8 +5,11 @@ App(
|
||||
entry_point="lfrfid_debug_app",
|
||||
requires=[
|
||||
"gui",
|
||||
"lfrfid",
|
||||
],
|
||||
provides=[
|
||||
"lfrfid_debug",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
order=100,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -9,9 +9,8 @@
|
||||
|
||||
#include <gui/modules/submenu.h>
|
||||
|
||||
#include <lfrfid_debug/views/lfrfid_debug_view_tune.h>
|
||||
|
||||
#include <lfrfid_debug/scenes/lfrfid_debug_scene.h>
|
||||
#include "views/lfrfid_debug_view_tune.h"
|
||||
#include "scenes/lfrfid_debug_scene.h"
|
||||
|
||||
typedef struct LfRfidDebug LfRfidDebug;
|
||||
|
||||
@@ -52,23 +52,29 @@ static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) {
|
||||
|
||||
static void lfrfid_debug_view_tune_button_up(LfRfidTuneView* tune_view) {
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
if(model->pos > 0) model->pos--;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void lfrfid_debug_view_tune_button_down(LfRfidTuneView* tune_view) {
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
if(model->pos < 1) model->pos++;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) {
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
if(model->pos == 0) {
|
||||
if(model->fine) {
|
||||
model->ARR -= 1;
|
||||
@@ -84,13 +90,15 @@ static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) {
|
||||
}
|
||||
|
||||
model->dirty = true;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) {
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
if(model->pos == 0) {
|
||||
if(model->fine) {
|
||||
model->ARR += 1;
|
||||
@@ -106,16 +114,13 @@ static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) {
|
||||
}
|
||||
|
||||
model->dirty = true;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void lfrfid_debug_view_tune_button_ok(LfRfidTuneView* tune_view) {
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
model->fine = !model->fine;
|
||||
return true;
|
||||
});
|
||||
tune_view->view, LfRfidTuneViewModel * model, { model->fine = !model->fine; }, true);
|
||||
}
|
||||
|
||||
static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* context) {
|
||||
@@ -158,14 +163,16 @@ LfRfidTuneView* lfrfid_debug_view_tune_alloc() {
|
||||
view_allocate_model(tune_view->view, ViewModelTypeLocking, sizeof(LfRfidTuneViewModel));
|
||||
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
model->dirty = true;
|
||||
model->fine = false;
|
||||
model->ARR = 511;
|
||||
model->CCR = 255;
|
||||
model->pos = 0;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
view_set_draw_callback(tune_view->view, lfrfid_debug_view_tune_draw_callback);
|
||||
view_set_input_callback(tune_view->view, lfrfid_debug_view_tune_input_callback);
|
||||
@@ -184,24 +191,28 @@ View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view) {
|
||||
|
||||
void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view) {
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
model->dirty = true;
|
||||
model->fine = false;
|
||||
model->ARR = 511;
|
||||
model->CCR = 255;
|
||||
model->pos = 0;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) {
|
||||
bool result = false;
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
tune_view->view,
|
||||
LfRfidTuneViewModel * model,
|
||||
{
|
||||
result = model->dirty;
|
||||
model->dirty = false;
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -209,10 +220,7 @@ bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) {
|
||||
uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) {
|
||||
uint32_t result = false;
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
result = model->ARR;
|
||||
return false;
|
||||
});
|
||||
tune_view->view, LfRfidTuneViewModel * model, { result = model->ARR; }, false);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -220,10 +228,7 @@ uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) {
|
||||
uint32_t lfrfid_debug_view_tune_get_ccr(LfRfidTuneView* tune_view) {
|
||||
uint32_t result = false;
|
||||
with_view_model(
|
||||
tune_view->view, (LfRfidTuneViewModel * model) {
|
||||
result = model->CCR;
|
||||
return false;
|
||||
});
|
||||
tune_view->view, LfRfidTuneViewModel * model, { result = model->CCR; }, false);
|
||||
|
||||
return result;
|
||||
}
|
||||
11
applications/debug/text_box_test/application.fam
Normal file
11
applications/debug/text_box_test/application.fam
Normal file
@@ -0,0 +1,11 @@
|
||||
App(
|
||||
appid="text_box_test",
|
||||
name="Text Box Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="text_box_test_app",
|
||||
cdefines=["APP_TEXT_BOX_TEST"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=140,
|
||||
fap_category="Debug",
|
||||
)
|
||||
12
applications/debug/uart_echo/application.fam
Normal file
12
applications/debug/uart_echo/application.fam
Normal file
@@ -0,0 +1,12 @@
|
||||
App(
|
||||
appid="UART_Echo",
|
||||
name="UART Echo",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="uart_echo_app",
|
||||
cdefines=["APP_UART_ECHO"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=70,
|
||||
fap_icon="uart_10px.png",
|
||||
fap_category="Misc",
|
||||
)
|
||||
BIN
applications/debug/uart_echo/uart_10px.png
Normal file
BIN
applications/debug/uart_echo/uart_10px.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,10 +1,8 @@
|
||||
#include <furi.h>
|
||||
#include <m-string.h>
|
||||
#include <gui/gui.h>
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <gui/elements.h>
|
||||
#include <stream_buffer.h>
|
||||
#include <furi_hal_uart.h>
|
||||
#include <furi_hal_console.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
@@ -21,11 +19,11 @@ typedef struct {
|
||||
ViewDispatcher* view_dispatcher;
|
||||
View* view;
|
||||
FuriThread* worker_thread;
|
||||
StreamBufferHandle_t rx_stream;
|
||||
FuriStreamBuffer* rx_stream;
|
||||
} UartEchoApp;
|
||||
|
||||
typedef struct {
|
||||
string_t text;
|
||||
FuriString* text;
|
||||
} ListElement;
|
||||
|
||||
struct UartDumpModel {
|
||||
@@ -64,10 +62,11 @@ static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) {
|
||||
canvas,
|
||||
0,
|
||||
(i + 1) * (canvas_current_font_height(canvas) - 1),
|
||||
string_get_cstr(model->list[i]->text));
|
||||
furi_string_get_cstr(model->list[i]->text));
|
||||
|
||||
if(i == model->line) {
|
||||
uint8_t width = canvas_string_width(canvas, string_get_cstr(model->list[i]->text));
|
||||
uint8_t width =
|
||||
canvas_string_width(canvas, furi_string_get_cstr(model->list[i]->text));
|
||||
|
||||
canvas_draw_box(
|
||||
canvas,
|
||||
@@ -92,13 +91,11 @@ static uint32_t uart_echo_exit(void* context) {
|
||||
|
||||
static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
|
||||
furi_assert(context);
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
UartEchoApp* app = context;
|
||||
|
||||
if(ev == UartIrqEventRXNE) {
|
||||
xStreamBufferSendFromISR(app->rx_stream, &data, 1, &xHigherPriorityTaskWoken);
|
||||
furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
|
||||
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +110,7 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) {
|
||||
model->escape = true;
|
||||
} else if((data >= ' ' && data <= '~') || (data == '\n' || data == '\r')) {
|
||||
bool new_string_needed = false;
|
||||
if(string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) {
|
||||
if(furi_string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) {
|
||||
new_string_needed = true;
|
||||
} else if((data == '\n' || data == '\r')) {
|
||||
// pack line breaks
|
||||
@@ -132,13 +129,13 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) {
|
||||
model->list[i - 1] = model->list[i];
|
||||
}
|
||||
|
||||
string_reset(first->text);
|
||||
furi_string_reset(first->text);
|
||||
model->list[model->line] = first;
|
||||
}
|
||||
}
|
||||
|
||||
if(data != '\n' && data != '\r') {
|
||||
string_push_back(model->list[model->line]->text, data);
|
||||
furi_string_push_back(model->list[model->line]->text, data);
|
||||
}
|
||||
}
|
||||
model->last_char = data;
|
||||
@@ -158,25 +155,24 @@ static int32_t uart_echo_worker(void* context) {
|
||||
size_t length = 0;
|
||||
do {
|
||||
uint8_t data[64];
|
||||
length = xStreamBufferReceive(app->rx_stream, data, 64, 0);
|
||||
length = furi_stream_buffer_receive(app->rx_stream, data, 64, 0);
|
||||
if(length > 0) {
|
||||
furi_hal_uart_tx(FuriHalUartIdUSART1, data, length);
|
||||
with_view_model(
|
||||
app->view, (UartDumpModel * model) {
|
||||
app->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
uart_echo_push_to_list(model, data[i]);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
} while(length > 0);
|
||||
|
||||
notification_message(app->notification, &sequence_notification);
|
||||
with_view_model(
|
||||
app->view, (UartDumpModel * model) {
|
||||
UNUSED(model);
|
||||
return true;
|
||||
});
|
||||
app->view, UartDumpModel * model, { UNUSED(model); }, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +182,7 @@ static int32_t uart_echo_worker(void* context) {
|
||||
static UartEchoApp* uart_echo_app_alloc() {
|
||||
UartEchoApp* app = malloc(sizeof(UartEchoApp));
|
||||
|
||||
app->rx_stream = xStreamBufferCreate(2048, 1);
|
||||
app->rx_stream = furi_stream_buffer_alloc(2048, 1);
|
||||
|
||||
// Gui
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
@@ -203,15 +199,17 @@ static UartEchoApp* uart_echo_app_alloc() {
|
||||
view_set_input_callback(app->view, uart_echo_view_input_callback);
|
||||
view_allocate_model(app->view, ViewModelTypeLocking, sizeof(UartDumpModel));
|
||||
with_view_model(
|
||||
app->view, (UartDumpModel * model) {
|
||||
app->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
for(size_t i = 0; i < LINES_ON_SCREEN; i++) {
|
||||
model->line = 0;
|
||||
model->escape = false;
|
||||
model->list[i] = malloc(sizeof(ListElement));
|
||||
string_init(model->list[i]->text);
|
||||
model->list[i]->text = furi_string_alloc();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
view_set_previous_callback(app->view, uart_echo_exit);
|
||||
view_dispatcher_add_view(app->view_dispatcher, 0, app->view);
|
||||
@@ -245,13 +243,15 @@ static void uart_echo_app_free(UartEchoApp* app) {
|
||||
view_dispatcher_remove_view(app->view_dispatcher, 0);
|
||||
|
||||
with_view_model(
|
||||
app->view, (UartDumpModel * model) {
|
||||
app->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
for(size_t i = 0; i < LINES_ON_SCREEN; i++) {
|
||||
string_clear(model->list[i]->text);
|
||||
furi_string_free(model->list[i]->text);
|
||||
free(model->list[i]);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
view_free(app->view);
|
||||
view_dispatcher_free(app->view_dispatcher);
|
||||
|
||||
@@ -260,7 +260,7 @@ static void uart_echo_app_free(UartEchoApp* app) {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
app->gui = NULL;
|
||||
|
||||
vStreamBufferDelete(app->rx_stream);
|
||||
furi_stream_buffer_free(app->rx_stream);
|
||||
|
||||
// Free rest
|
||||
free(app);
|
||||
@@ -10,7 +10,7 @@ App(
|
||||
App(
|
||||
appid="delay_test",
|
||||
name="Delay Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
apptype=FlipperAppType.SYSTEM,
|
||||
entry_point="delay_test_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=["unit_tests"],
|
||||
@@ -58,7 +58,7 @@ static const char* test_data_win = "Filetype: Flipper Format test\r\n"
|
||||
#define ARRAY_W_BSIZE(x) (x), (sizeof(x))
|
||||
|
||||
MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
string_t tmpstr;
|
||||
FuriString* tmpstr;
|
||||
uint32_t version;
|
||||
uint32_t uint32_data[COUNT_OF(test_uint_data)];
|
||||
int32_t int32_data[COUNT_OF(test_int_data)];
|
||||
@@ -101,14 +101,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
|
||||
|
||||
// read test
|
||||
string_init(tmpstr);
|
||||
tmpstr = furi_string_alloc();
|
||||
|
||||
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
|
||||
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
|
||||
mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
|
||||
mu_assert_int_eq(test_version, version);
|
||||
|
||||
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
|
||||
mu_assert_string_eq(test_string_data, string_get_cstr(tmpstr));
|
||||
mu_assert_string_eq(test_string_data, furi_string_get_cstr(tmpstr));
|
||||
|
||||
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
|
||||
mu_assert_int_eq(COUNT_OF(test_int_data), count);
|
||||
@@ -133,7 +133,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
|
||||
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
|
||||
|
||||
string_clear(tmpstr);
|
||||
furi_string_free(tmpstr);
|
||||
|
||||
// update data
|
||||
mu_check(flipper_format_rewind(flipper_format));
|
||||
@@ -155,14 +155,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
uint8_t hex_updated_data[COUNT_OF(test_hex_updated_data)];
|
||||
|
||||
mu_check(flipper_format_rewind(flipper_format));
|
||||
string_init(tmpstr);
|
||||
tmpstr = furi_string_alloc();
|
||||
|
||||
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
|
||||
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
|
||||
mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
|
||||
mu_assert_int_eq(test_version, version);
|
||||
|
||||
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
|
||||
mu_assert_string_eq(test_string_updated_data, string_get_cstr(tmpstr));
|
||||
mu_assert_string_eq(test_string_updated_data, furi_string_get_cstr(tmpstr));
|
||||
|
||||
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
|
||||
mu_assert_int_eq(COUNT_OF(test_int_updated_data), count);
|
||||
@@ -190,7 +190,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
|
||||
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
|
||||
|
||||
string_clear(tmpstr);
|
||||
furi_string_free(tmpstr);
|
||||
|
||||
// update data
|
||||
mu_check(flipper_format_rewind(flipper_format));
|
||||
@@ -214,14 +214,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
uint8_t hex_new_data[COUNT_OF(test_hex_new_data)];
|
||||
|
||||
mu_check(flipper_format_rewind(flipper_format));
|
||||
string_init(tmpstr);
|
||||
tmpstr = furi_string_alloc();
|
||||
|
||||
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
|
||||
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
|
||||
mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
|
||||
mu_assert_int_eq(test_version, version);
|
||||
|
||||
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
|
||||
mu_assert_string_eq(test_string_updated_2_data, string_get_cstr(tmpstr));
|
||||
mu_assert_string_eq(test_string_updated_2_data, furi_string_get_cstr(tmpstr));
|
||||
|
||||
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
|
||||
mu_assert_int_eq(COUNT_OF(test_int_updated_2_data), count);
|
||||
@@ -255,7 +255,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
|
||||
|
||||
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
|
||||
|
||||
string_clear(tmpstr);
|
||||
furi_string_free(tmpstr);
|
||||
|
||||
// delete key test
|
||||
mu_check(flipper_format_rewind(flipper_format));
|
||||
@@ -57,6 +57,23 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n"
|
||||
"Hex data: DE AD BE";
|
||||
|
||||
#define READ_TEST_FLP "ff_flp.test"
|
||||
#define READ_TEST_ODD "ff_oddities.test"
|
||||
static const char* test_data_odd = "Filetype: Flipper File test\n"
|
||||
// Tabs before newline
|
||||
"Version: 666\t\t\n"
|
||||
"# This is comment\n"
|
||||
// Windows newline in a UNIX file
|
||||
"String data: String\r\n"
|
||||
// Trailing whitespace
|
||||
"Int32 data: 1234 -6345 7813 0 \n"
|
||||
// Extra whitespace
|
||||
"Uint32 data: 1234 0 5678 9098 7654321 \n"
|
||||
// Mixed whitespace
|
||||
"Float data: 1.5\t \t1000.0\n"
|
||||
// Leading tabs after key
|
||||
"Bool data:\t\ttrue false\n"
|
||||
// Mixed trailing whitespace
|
||||
"Hex data: DE AD BE\t ";
|
||||
|
||||
// data created by user on linux machine
|
||||
static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
|
||||
@@ -64,6 +81,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
|
||||
static const char* test_file_windows = TEST_DIR READ_TEST_WIN;
|
||||
// data created by flipper itself
|
||||
static const char* test_file_flipper = TEST_DIR READ_TEST_FLP;
|
||||
// data containing odd user input
|
||||
static const char* test_file_oddities = TEST_DIR READ_TEST_ODD;
|
||||
|
||||
static bool storage_write_string(const char* path, const char* data) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
@@ -102,8 +121,8 @@ static bool test_read(const char* file_name) {
|
||||
bool result = false;
|
||||
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
string_t string_value;
|
||||
string_init(string_value);
|
||||
FuriString* string_value;
|
||||
string_value = furi_string_alloc();
|
||||
uint32_t uint32_value;
|
||||
void* scratchpad = malloc(512);
|
||||
|
||||
@@ -111,11 +130,11 @@ static bool test_read(const char* file_name) {
|
||||
if(!flipper_format_file_open_existing(file, file_name)) break;
|
||||
|
||||
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
|
||||
if(string_cmp_str(string_value, test_filetype) != 0) break;
|
||||
if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
|
||||
if(uint32_value != test_version) break;
|
||||
|
||||
if(!flipper_format_read_string(file, test_string_key, string_value)) break;
|
||||
if(string_cmp_str(string_value, test_string_data) != 0) break;
|
||||
if(furi_string_cmp_str(string_value, test_string_data) != 0) break;
|
||||
|
||||
if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
|
||||
if(uint32_value != COUNT_OF(test_int_data)) break;
|
||||
@@ -150,7 +169,7 @@ static bool test_read(const char* file_name) {
|
||||
} while(false);
|
||||
|
||||
free(scratchpad);
|
||||
string_clear(string_value);
|
||||
furi_string_free(string_value);
|
||||
|
||||
flipper_format_free(file);
|
||||
|
||||
@@ -164,8 +183,8 @@ static bool test_read_updated(const char* file_name) {
|
||||
bool result = false;
|
||||
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
string_t string_value;
|
||||
string_init(string_value);
|
||||
FuriString* string_value;
|
||||
string_value = furi_string_alloc();
|
||||
uint32_t uint32_value;
|
||||
void* scratchpad = malloc(512);
|
||||
|
||||
@@ -173,11 +192,11 @@ static bool test_read_updated(const char* file_name) {
|
||||
if(!flipper_format_file_open_existing(file, file_name)) break;
|
||||
|
||||
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
|
||||
if(string_cmp_str(string_value, test_filetype) != 0) break;
|
||||
if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
|
||||
if(uint32_value != test_version) break;
|
||||
|
||||
if(!flipper_format_read_string(file, test_string_key, string_value)) break;
|
||||
if(string_cmp_str(string_value, test_string_updated_data) != 0) break;
|
||||
if(furi_string_cmp_str(string_value, test_string_updated_data) != 0) break;
|
||||
|
||||
if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
|
||||
if(uint32_value != COUNT_OF(test_int_updated_data)) break;
|
||||
@@ -228,7 +247,7 @@ static bool test_read_updated(const char* file_name) {
|
||||
} while(false);
|
||||
|
||||
free(scratchpad);
|
||||
string_clear(string_value);
|
||||
furi_string_free(string_value);
|
||||
|
||||
flipper_format_free(file);
|
||||
|
||||
@@ -401,14 +420,14 @@ static bool test_read_multikey(const char* file_name) {
|
||||
bool result = false;
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
|
||||
string_t string_value;
|
||||
string_init(string_value);
|
||||
FuriString* string_value;
|
||||
string_value = furi_string_alloc();
|
||||
uint32_t uint32_value;
|
||||
|
||||
do {
|
||||
if(!flipper_format_file_open_existing(file, file_name)) break;
|
||||
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
|
||||
if(string_cmp_str(string_value, test_filetype) != 0) break;
|
||||
if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
|
||||
if(uint32_value != test_version) break;
|
||||
|
||||
bool error = false;
|
||||
@@ -429,7 +448,7 @@ static bool test_read_multikey(const char* file_name) {
|
||||
result = true;
|
||||
} while(false);
|
||||
|
||||
string_clear(string_value);
|
||||
furi_string_free(string_value);
|
||||
|
||||
flipper_format_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
@@ -503,6 +522,12 @@ MU_TEST(flipper_format_multikey_test) {
|
||||
mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error");
|
||||
}
|
||||
|
||||
MU_TEST(flipper_format_oddities_test) {
|
||||
mu_assert(
|
||||
storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]");
|
||||
mu_assert(test_read(test_file_linux), "Read test error [Oddities]");
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(flipper_format) {
|
||||
tests_setup();
|
||||
MU_RUN_TEST(flipper_format_write_test);
|
||||
@@ -516,6 +541,7 @@ MU_TEST_SUITE(flipper_format) {
|
||||
MU_RUN_TEST(flipper_format_update_2_test);
|
||||
MU_RUN_TEST(flipper_format_update_2_result_test);
|
||||
MU_RUN_TEST(flipper_format_multikey_test);
|
||||
MU_RUN_TEST(flipper_format_oddities_test);
|
||||
tests_teardown();
|
||||
}
|
||||
|
||||
469
applications/debug/unit_tests/furi/furi_string_test.c
Normal file
469
applications/debug/unit_tests/furi/furi_string_test.c
Normal file
@@ -0,0 +1,469 @@
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
|
||||
static void test_setup(void) {
|
||||
}
|
||||
|
||||
static void test_teardown(void) {
|
||||
}
|
||||
|
||||
static FuriString* furi_string_alloc_vprintf_test(const char format[], ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
FuriString* string = furi_string_alloc_vprintf(format, args);
|
||||
va_end(args);
|
||||
return string;
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_alloc_free) {
|
||||
FuriString* tmp;
|
||||
FuriString* string;
|
||||
|
||||
// test alloc and free
|
||||
string = furi_string_alloc();
|
||||
mu_check(string != NULL);
|
||||
mu_check(furi_string_empty(string));
|
||||
furi_string_free(string);
|
||||
|
||||
// test furi_string_alloc_set_str and free
|
||||
string = furi_string_alloc_set_str("test");
|
||||
mu_check(string != NULL);
|
||||
mu_check(!furi_string_empty(string));
|
||||
mu_check(furi_string_cmp(string, "test") == 0);
|
||||
furi_string_free(string);
|
||||
|
||||
// test furi_string_alloc_set and free
|
||||
tmp = furi_string_alloc_set("more");
|
||||
string = furi_string_alloc_set(tmp);
|
||||
furi_string_free(tmp);
|
||||
mu_check(string != NULL);
|
||||
mu_check(!furi_string_empty(string));
|
||||
mu_check(furi_string_cmp(string, "more") == 0);
|
||||
furi_string_free(string);
|
||||
|
||||
// test alloc_printf and free
|
||||
string = furi_string_alloc_printf("test %d %s %c 0x%02x", 1, "two", '3', 0x04);
|
||||
mu_check(string != NULL);
|
||||
mu_check(!furi_string_empty(string));
|
||||
mu_check(furi_string_cmp(string, "test 1 two 3 0x04") == 0);
|
||||
furi_string_free(string);
|
||||
|
||||
// test alloc_vprintf and free
|
||||
string = furi_string_alloc_vprintf_test("test %d %s %c 0x%02x", 4, "five", '6', 0x07);
|
||||
mu_check(string != NULL);
|
||||
mu_check(!furi_string_empty(string));
|
||||
mu_check(furi_string_cmp(string, "test 4 five 6 0x07") == 0);
|
||||
furi_string_free(string);
|
||||
|
||||
// test alloc_move and free
|
||||
tmp = furi_string_alloc_set("move");
|
||||
string = furi_string_alloc_move(tmp);
|
||||
mu_check(string != NULL);
|
||||
mu_check(!furi_string_empty(string));
|
||||
mu_check(furi_string_cmp(string, "move") == 0);
|
||||
furi_string_free(string);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_mem) {
|
||||
FuriString* string = furi_string_alloc_set("test");
|
||||
mu_check(string != NULL);
|
||||
mu_check(!furi_string_empty(string));
|
||||
|
||||
// TODO: how to test furi_string_reserve?
|
||||
|
||||
// test furi_string_reset
|
||||
furi_string_reset(string);
|
||||
mu_check(furi_string_empty(string));
|
||||
|
||||
// test furi_string_swap
|
||||
furi_string_set(string, "test");
|
||||
FuriString* swap_string = furi_string_alloc_set("swap");
|
||||
furi_string_swap(string, swap_string);
|
||||
mu_check(furi_string_cmp(string, "swap") == 0);
|
||||
mu_check(furi_string_cmp(swap_string, "test") == 0);
|
||||
furi_string_free(swap_string);
|
||||
|
||||
// test furi_string_move
|
||||
FuriString* move_string = furi_string_alloc_set("move");
|
||||
furi_string_move(string, move_string);
|
||||
mu_check(furi_string_cmp(string, "move") == 0);
|
||||
// move_string is now empty
|
||||
// and tested by leaked memory check at the end of the tests
|
||||
|
||||
furi_string_set(string, "abracadabra");
|
||||
|
||||
// test furi_string_hash
|
||||
mu_assert_int_eq(0xc3bc16d7, furi_string_hash(string));
|
||||
|
||||
// test furi_string_size
|
||||
mu_assert_int_eq(11, furi_string_size(string));
|
||||
|
||||
// test furi_string_empty
|
||||
mu_check(!furi_string_empty(string));
|
||||
furi_string_reset(string);
|
||||
mu_check(furi_string_empty(string));
|
||||
|
||||
furi_string_free(string);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_getters) {
|
||||
FuriString* string = furi_string_alloc_set("test");
|
||||
|
||||
// test furi_string_get_char
|
||||
mu_check(furi_string_get_char(string, 0) == 't');
|
||||
mu_check(furi_string_get_char(string, 1) == 'e');
|
||||
mu_check(furi_string_get_char(string, 2) == 's');
|
||||
mu_check(furi_string_get_char(string, 3) == 't');
|
||||
|
||||
// test furi_string_get_cstr
|
||||
mu_assert_string_eq("test", furi_string_get_cstr(string));
|
||||
furi_string_free(string);
|
||||
}
|
||||
|
||||
static FuriString* furi_string_vprintf_test(FuriString* string, const char format[], ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
furi_string_vprintf(string, format, args);
|
||||
va_end(args);
|
||||
return string;
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_setters) {
|
||||
FuriString* tmp;
|
||||
FuriString* string = furi_string_alloc();
|
||||
|
||||
// test furi_string_set_str
|
||||
furi_string_set_str(string, "test");
|
||||
mu_assert_string_eq("test", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_set
|
||||
tmp = furi_string_alloc_set("more");
|
||||
furi_string_set(string, tmp);
|
||||
furi_string_free(tmp);
|
||||
mu_assert_string_eq("more", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_set_strn
|
||||
furi_string_set_strn(string, "test", 2);
|
||||
mu_assert_string_eq("te", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_set_char
|
||||
furi_string_set_char(string, 0, 'a');
|
||||
furi_string_set_char(string, 1, 'b');
|
||||
mu_assert_string_eq("ab", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_set_n
|
||||
tmp = furi_string_alloc_set("dodecahedron");
|
||||
furi_string_set_n(string, tmp, 4, 5);
|
||||
furi_string_free(tmp);
|
||||
mu_assert_string_eq("cahed", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_printf
|
||||
furi_string_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
|
||||
mu_assert_string_eq("test 1 two 3 0x04", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_vprintf
|
||||
furi_string_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
|
||||
mu_assert_string_eq("test 4 five 6 0x07", furi_string_get_cstr(string));
|
||||
|
||||
furi_string_free(string);
|
||||
}
|
||||
|
||||
static FuriString* furi_string_cat_vprintf_test(FuriString* string, const char format[], ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
furi_string_cat_vprintf(string, format, args);
|
||||
va_end(args);
|
||||
return string;
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_appends) {
|
||||
FuriString* tmp;
|
||||
FuriString* string = furi_string_alloc();
|
||||
|
||||
// test furi_string_push_back
|
||||
furi_string_push_back(string, 't');
|
||||
furi_string_push_back(string, 'e');
|
||||
furi_string_push_back(string, 's');
|
||||
furi_string_push_back(string, 't');
|
||||
mu_assert_string_eq("test", furi_string_get_cstr(string));
|
||||
furi_string_push_back(string, '!');
|
||||
mu_assert_string_eq("test!", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_cat_str
|
||||
furi_string_cat_str(string, "test");
|
||||
mu_assert_string_eq("test!test", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_cat
|
||||
tmp = furi_string_alloc_set("more");
|
||||
furi_string_cat(string, tmp);
|
||||
furi_string_free(tmp);
|
||||
mu_assert_string_eq("test!testmore", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_cat_printf
|
||||
furi_string_cat_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
|
||||
mu_assert_string_eq("test!testmoretest 1 two 3 0x04", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_cat_vprintf
|
||||
furi_string_cat_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
|
||||
mu_assert_string_eq(
|
||||
"test!testmoretest 1 two 3 0x04test 4 five 6 0x07", furi_string_get_cstr(string));
|
||||
|
||||
furi_string_free(string);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_compare) {
|
||||
FuriString* string_1 = furi_string_alloc_set("string_1");
|
||||
FuriString* string_2 = furi_string_alloc_set("string_2");
|
||||
|
||||
// test furi_string_cmp
|
||||
mu_assert_int_eq(0, furi_string_cmp(string_1, string_1));
|
||||
mu_assert_int_eq(0, furi_string_cmp(string_2, string_2));
|
||||
mu_assert_int_eq(-1, furi_string_cmp(string_1, string_2));
|
||||
mu_assert_int_eq(1, furi_string_cmp(string_2, string_1));
|
||||
|
||||
// test furi_string_cmp_str
|
||||
mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string_1"));
|
||||
mu_assert_int_eq(0, furi_string_cmp_str(string_2, "string_2"));
|
||||
mu_assert_int_eq(-1, furi_string_cmp_str(string_1, "string_2"));
|
||||
mu_assert_int_eq(1, furi_string_cmp_str(string_2, "string_1"));
|
||||
|
||||
// test furi_string_cmpi
|
||||
furi_string_set(string_1, "string");
|
||||
furi_string_set(string_2, "StrIng");
|
||||
mu_assert_int_eq(0, furi_string_cmpi(string_1, string_1));
|
||||
mu_assert_int_eq(0, furi_string_cmpi(string_2, string_2));
|
||||
mu_assert_int_eq(0, furi_string_cmpi(string_1, string_2));
|
||||
mu_assert_int_eq(0, furi_string_cmpi(string_2, string_1));
|
||||
furi_string_set(string_1, "string_1");
|
||||
furi_string_set(string_2, "StrIng_2");
|
||||
mu_assert_int_eq(32, furi_string_cmp(string_1, string_2));
|
||||
mu_assert_int_eq(-32, furi_string_cmp(string_2, string_1));
|
||||
mu_assert_int_eq(-1, furi_string_cmpi(string_1, string_2));
|
||||
mu_assert_int_eq(1, furi_string_cmpi(string_2, string_1));
|
||||
|
||||
// test furi_string_cmpi_str
|
||||
furi_string_set(string_1, "string");
|
||||
mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string"));
|
||||
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "String"));
|
||||
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STring"));
|
||||
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRing"));
|
||||
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRIng"));
|
||||
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRINg"));
|
||||
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRING"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "string"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "String"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STring"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRing"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRIng"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRINg"));
|
||||
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRING"));
|
||||
|
||||
furi_string_free(string_1);
|
||||
furi_string_free(string_2);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_search) {
|
||||
// 012345678901234567
|
||||
FuriString* haystack = furi_string_alloc_set("test321test123test");
|
||||
FuriString* needle = furi_string_alloc_set("test");
|
||||
|
||||
// test furi_string_search
|
||||
mu_assert_int_eq(0, furi_string_search(haystack, needle));
|
||||
mu_assert_int_eq(7, furi_string_search(haystack, needle, 1));
|
||||
mu_assert_int_eq(14, furi_string_search(haystack, needle, 8));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, needle, 15));
|
||||
|
||||
FuriString* tmp = furi_string_alloc_set("testnone");
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, tmp));
|
||||
furi_string_free(tmp);
|
||||
|
||||
// test furi_string_search_str
|
||||
mu_assert_int_eq(0, furi_string_search_str(haystack, "test"));
|
||||
mu_assert_int_eq(7, furi_string_search_str(haystack, "test", 1));
|
||||
mu_assert_int_eq(14, furi_string_search_str(haystack, "test", 8));
|
||||
mu_assert_int_eq(4, furi_string_search_str(haystack, "321"));
|
||||
mu_assert_int_eq(11, furi_string_search_str(haystack, "123"));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "testnone"));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "test", 15));
|
||||
|
||||
// test furi_string_search_char
|
||||
mu_assert_int_eq(0, furi_string_search_char(haystack, 't'));
|
||||
mu_assert_int_eq(1, furi_string_search_char(haystack, 'e'));
|
||||
mu_assert_int_eq(2, furi_string_search_char(haystack, 's'));
|
||||
mu_assert_int_eq(3, furi_string_search_char(haystack, 't', 1));
|
||||
mu_assert_int_eq(7, furi_string_search_char(haystack, 't', 4));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_char(haystack, 'x'));
|
||||
|
||||
// test furi_string_search_rchar
|
||||
mu_assert_int_eq(17, furi_string_search_rchar(haystack, 't'));
|
||||
mu_assert_int_eq(15, furi_string_search_rchar(haystack, 'e'));
|
||||
mu_assert_int_eq(16, furi_string_search_rchar(haystack, 's'));
|
||||
mu_assert_int_eq(13, furi_string_search_rchar(haystack, '3'));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, '3', 14));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, 'x'));
|
||||
|
||||
furi_string_free(haystack);
|
||||
furi_string_free(needle);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_equality) {
|
||||
FuriString* string = furi_string_alloc_set("test");
|
||||
FuriString* string_eq = furi_string_alloc_set("test");
|
||||
FuriString* string_neq = furi_string_alloc_set("test2");
|
||||
|
||||
// test furi_string_equal
|
||||
mu_check(furi_string_equal(string, string_eq));
|
||||
mu_check(!furi_string_equal(string, string_neq));
|
||||
|
||||
// test furi_string_equal_str
|
||||
mu_check(furi_string_equal_str(string, "test"));
|
||||
mu_check(!furi_string_equal_str(string, "test2"));
|
||||
mu_check(furi_string_equal_str(string_neq, "test2"));
|
||||
mu_check(!furi_string_equal_str(string_neq, "test"));
|
||||
|
||||
furi_string_free(string);
|
||||
furi_string_free(string_eq);
|
||||
furi_string_free(string_neq);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_replace) {
|
||||
FuriString* needle = furi_string_alloc_set("test");
|
||||
FuriString* replace = furi_string_alloc_set("replace");
|
||||
FuriString* string = furi_string_alloc_set("test123test");
|
||||
|
||||
// test furi_string_replace_at
|
||||
furi_string_replace_at(string, 4, 3, "!biglongword!");
|
||||
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_replace
|
||||
mu_assert_int_eq(17, furi_string_replace(string, needle, replace, 1));
|
||||
mu_assert_string_eq("test!biglongword!replace", furi_string_get_cstr(string));
|
||||
mu_assert_int_eq(0, furi_string_replace(string, needle, replace));
|
||||
mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace(string, needle, replace));
|
||||
mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_replace_str
|
||||
mu_assert_int_eq(20, furi_string_replace_str(string, "replace", "test", 1));
|
||||
mu_assert_string_eq("replace!biglongword!test", furi_string_get_cstr(string));
|
||||
mu_assert_int_eq(0, furi_string_replace_str(string, "replace", "test"));
|
||||
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
|
||||
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace_str(string, "replace", "test"));
|
||||
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_replace_all
|
||||
furi_string_replace_all(string, needle, replace);
|
||||
mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_replace_all_str
|
||||
furi_string_replace_all_str(string, "replace", "test");
|
||||
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
|
||||
|
||||
furi_string_free(string);
|
||||
furi_string_free(needle);
|
||||
furi_string_free(replace);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_start_end) {
|
||||
FuriString* string = furi_string_alloc_set("start_end");
|
||||
FuriString* start = furi_string_alloc_set("start");
|
||||
FuriString* end = furi_string_alloc_set("end");
|
||||
|
||||
// test furi_string_start_with
|
||||
mu_check(furi_string_start_with(string, start));
|
||||
mu_check(!furi_string_start_with(string, end));
|
||||
|
||||
// test furi_string_start_with_str
|
||||
mu_check(furi_string_start_with_str(string, "start"));
|
||||
mu_check(!furi_string_start_with_str(string, "end"));
|
||||
|
||||
// test furi_string_end_with
|
||||
mu_check(furi_string_end_with(string, end));
|
||||
mu_check(!furi_string_end_with(string, start));
|
||||
|
||||
// test furi_string_end_with_str
|
||||
mu_check(furi_string_end_with_str(string, "end"));
|
||||
mu_check(!furi_string_end_with_str(string, "start"));
|
||||
|
||||
furi_string_free(string);
|
||||
furi_string_free(start);
|
||||
furi_string_free(end);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_trim) {
|
||||
FuriString* string = furi_string_alloc_set("biglongstring");
|
||||
|
||||
// test furi_string_left
|
||||
furi_string_left(string, 7);
|
||||
mu_assert_string_eq("biglong", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_right
|
||||
furi_string_right(string, 3);
|
||||
mu_assert_string_eq("long", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_mid
|
||||
furi_string_mid(string, 1, 2);
|
||||
mu_assert_string_eq("on", furi_string_get_cstr(string));
|
||||
|
||||
// test furi_string_trim
|
||||
furi_string_set(string, " \n\r\tbiglongstring \n\r\t ");
|
||||
furi_string_trim(string);
|
||||
mu_assert_string_eq("biglongstring", furi_string_get_cstr(string));
|
||||
furi_string_set(string, "aaaabaaaabbaaabaaaabbtestaaaaaabbaaabaababaa");
|
||||
furi_string_trim(string, "ab");
|
||||
mu_assert_string_eq("test", furi_string_get_cstr(string));
|
||||
|
||||
furi_string_free(string);
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_string_utf8) {
|
||||
FuriString* utf8_string = furi_string_alloc_set("イルカ");
|
||||
|
||||
// test furi_string_utf8_length
|
||||
mu_assert_int_eq(9, furi_string_size(utf8_string));
|
||||
mu_assert_int_eq(3, furi_string_utf8_length(utf8_string));
|
||||
|
||||
// test furi_string_utf8_decode
|
||||
const uint8_t dolphin_emoji_array[4] = {0xF0, 0x9F, 0x90, 0xAC};
|
||||
FuriStringUTF8State state = FuriStringUTF8StateStarting;
|
||||
FuriStringUnicodeValue value = 0;
|
||||
furi_string_utf8_decode(dolphin_emoji_array[0], &state, &value);
|
||||
mu_assert_int_eq(FuriStringUTF8StateDecoding3, state);
|
||||
furi_string_utf8_decode(dolphin_emoji_array[1], &state, &value);
|
||||
mu_assert_int_eq(FuriStringUTF8StateDecoding2, state);
|
||||
furi_string_utf8_decode(dolphin_emoji_array[2], &state, &value);
|
||||
mu_assert_int_eq(FuriStringUTF8StateDecoding1, state);
|
||||
furi_string_utf8_decode(dolphin_emoji_array[3], &state, &value);
|
||||
mu_assert_int_eq(FuriStringUTF8StateStarting, state);
|
||||
mu_assert_int_eq(0x1F42C, value);
|
||||
|
||||
// test furi_string_utf8_push
|
||||
furi_string_set(utf8_string, "");
|
||||
furi_string_utf8_push(utf8_string, value);
|
||||
mu_assert_string_eq("🐬", furi_string_get_cstr(utf8_string));
|
||||
|
||||
furi_string_free(utf8_string);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(mu_test_furi_string_alloc_free);
|
||||
MU_RUN_TEST(mu_test_furi_string_mem);
|
||||
MU_RUN_TEST(mu_test_furi_string_getters);
|
||||
MU_RUN_TEST(mu_test_furi_string_setters);
|
||||
MU_RUN_TEST(mu_test_furi_string_appends);
|
||||
MU_RUN_TEST(mu_test_furi_string_compare);
|
||||
MU_RUN_TEST(mu_test_furi_string_search);
|
||||
MU_RUN_TEST(mu_test_furi_string_equality);
|
||||
MU_RUN_TEST(mu_test_furi_string_replace);
|
||||
MU_RUN_TEST(mu_test_furi_string_start_end);
|
||||
MU_RUN_TEST(mu_test_furi_string_trim);
|
||||
MU_RUN_TEST(mu_test_furi_string_utf8);
|
||||
}
|
||||
|
||||
int run_minunit_test_furi_string() {
|
||||
MU_RUN_SUITE(test_suite);
|
||||
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
typedef struct {
|
||||
InfraredDecoderHandler* decoder_handler;
|
||||
InfraredEncoderHandler* encoder_handler;
|
||||
string_t file_path;
|
||||
FuriString* file_path;
|
||||
FlipperFormat* ff;
|
||||
} InfraredTest;
|
||||
|
||||
@@ -23,7 +23,7 @@ static void infrared_test_alloc() {
|
||||
test->decoder_handler = infrared_alloc_decoder();
|
||||
test->encoder_handler = infrared_alloc_encoder();
|
||||
test->ff = flipper_format_buffered_file_alloc(storage);
|
||||
string_init(test->file_path);
|
||||
test->file_path = furi_string_alloc();
|
||||
}
|
||||
|
||||
static void infrared_test_free() {
|
||||
@@ -31,18 +31,18 @@ static void infrared_test_free() {
|
||||
infrared_free_decoder(test->decoder_handler);
|
||||
infrared_free_encoder(test->encoder_handler);
|
||||
flipper_format_free(test->ff);
|
||||
string_clear(test->file_path);
|
||||
furi_string_free(test->file_path);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
free(test);
|
||||
test = NULL;
|
||||
}
|
||||
|
||||
static bool infrared_test_prepare_file(const char* protocol_name) {
|
||||
string_t file_type;
|
||||
string_init(file_type);
|
||||
FuriString* file_type;
|
||||
file_type = furi_string_alloc();
|
||||
bool success = false;
|
||||
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
test->file_path,
|
||||
"%s%s%s%s",
|
||||
IR_TEST_FILES_DIR,
|
||||
@@ -52,14 +52,15 @@ static bool infrared_test_prepare_file(const char* protocol_name) {
|
||||
|
||||
do {
|
||||
uint32_t format_version;
|
||||
if(!flipper_format_buffered_file_open_existing(test->ff, string_get_cstr(test->file_path)))
|
||||
if(!flipper_format_buffered_file_open_existing(
|
||||
test->ff, furi_string_get_cstr(test->file_path)))
|
||||
break;
|
||||
if(!flipper_format_read_header(test->ff, file_type, &format_version)) break;
|
||||
if(string_cmp_str(file_type, "IR tests file") || format_version != 1) break;
|
||||
if(furi_string_cmp_str(file_type, "IR tests file") || format_version != 1) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
string_clear(file_type);
|
||||
furi_string_free(file_type);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -68,18 +69,18 @@ static bool infrared_test_load_raw_signal(
|
||||
const char* signal_name,
|
||||
uint32_t** timings,
|
||||
uint32_t* timings_count) {
|
||||
string_t buf;
|
||||
string_init(buf);
|
||||
FuriString* buf;
|
||||
buf = furi_string_alloc();
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
bool is_name_found = false;
|
||||
for(; !is_name_found && flipper_format_read_string(ff, "name", buf);
|
||||
is_name_found = !string_cmp_str(buf, signal_name))
|
||||
is_name_found = !furi_string_cmp(buf, signal_name))
|
||||
;
|
||||
|
||||
if(!is_name_found) break;
|
||||
if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "raw")) break;
|
||||
if(!flipper_format_read_string(ff, "type", buf) || furi_string_cmp_str(buf, "raw")) break;
|
||||
if(!flipper_format_get_value_count(ff, "data", timings_count)) break;
|
||||
if(!*timings_count) break;
|
||||
|
||||
@@ -91,18 +92,18 @@ static bool infrared_test_load_raw_signal(
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
string_clear(buf);
|
||||
furi_string_free(buf);
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* message) {
|
||||
string_t buf;
|
||||
string_init(buf);
|
||||
FuriString* buf;
|
||||
buf = furi_string_alloc();
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!flipper_format_read_string(ff, "protocol", buf)) break;
|
||||
message->protocol = infrared_get_protocol_by_name(string_get_cstr(buf));
|
||||
message->protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf));
|
||||
if(!infrared_is_protocol_valid(message->protocol)) break;
|
||||
if(!flipper_format_read_hex(ff, "address", (uint8_t*)&message->address, sizeof(uint32_t)))
|
||||
break;
|
||||
@@ -112,7 +113,7 @@ static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* messa
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
string_clear(buf);
|
||||
furi_string_free(buf);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -121,18 +122,19 @@ static bool infrared_test_load_messages(
|
||||
const char* signal_name,
|
||||
InfraredMessage** messages,
|
||||
uint32_t* messages_count) {
|
||||
string_t buf;
|
||||
string_init(buf);
|
||||
FuriString* buf;
|
||||
buf = furi_string_alloc();
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
bool is_name_found = false;
|
||||
for(; !is_name_found && flipper_format_read_string(ff, "name", buf);
|
||||
is_name_found = !string_cmp_str(buf, signal_name))
|
||||
is_name_found = !furi_string_cmp(buf, signal_name))
|
||||
;
|
||||
|
||||
if(!is_name_found) break;
|
||||
if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "parsed_array"))
|
||||
if(!flipper_format_read_string(ff, "type", buf) ||
|
||||
furi_string_cmp_str(buf, "parsed_array"))
|
||||
break;
|
||||
if(!flipper_format_read_uint32(ff, "count", messages_count, 1)) break;
|
||||
if(!*messages_count) break;
|
||||
@@ -151,7 +153,7 @@ static bool infrared_test_load_messages(
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
string_clear(buf);
|
||||
furi_string_free(buf);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -213,26 +215,26 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i
|
||||
InfraredMessage* input_messages;
|
||||
uint32_t input_messages_count;
|
||||
|
||||
string_t buf;
|
||||
string_init(buf);
|
||||
FuriString* buf;
|
||||
buf = furi_string_alloc();
|
||||
|
||||
const char* protocol_name = infrared_get_protocol_name(protocol);
|
||||
mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file");
|
||||
|
||||
string_printf(buf, "encoder_input%d", test_index);
|
||||
furi_string_printf(buf, "encoder_input%ld", test_index);
|
||||
mu_assert(
|
||||
infrared_test_load_messages(
|
||||
test->ff, string_get_cstr(buf), &input_messages, &input_messages_count),
|
||||
test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count),
|
||||
"Failed to load messages from file");
|
||||
|
||||
string_printf(buf, "encoder_expected%d", test_index);
|
||||
furi_string_printf(buf, "encoder_expected%ld", test_index);
|
||||
mu_assert(
|
||||
infrared_test_load_raw_signal(
|
||||
test->ff, string_get_cstr(buf), &expected_timings, &expected_timings_count),
|
||||
test->ff, furi_string_get_cstr(buf), &expected_timings, &expected_timings_count),
|
||||
"Failed to load raw signal from file");
|
||||
|
||||
flipper_format_buffered_file_close(test->ff);
|
||||
string_clear(buf);
|
||||
furi_string_free(buf);
|
||||
|
||||
uint32_t j = 0;
|
||||
timings = malloc(sizeof(uint32_t) * timings_count);
|
||||
@@ -267,22 +269,22 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_
|
||||
uint32_t input_messages_count;
|
||||
bool level = false;
|
||||
|
||||
string_t buf;
|
||||
string_init(buf);
|
||||
FuriString* buf;
|
||||
buf = furi_string_alloc();
|
||||
|
||||
timings = malloc(sizeof(uint32_t) * timings_count);
|
||||
|
||||
const char* protocol_name = infrared_get_protocol_name(protocol);
|
||||
mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file");
|
||||
|
||||
string_printf(buf, "encoder_decoder_input%d", test_index);
|
||||
furi_string_printf(buf, "encoder_decoder_input%ld", test_index);
|
||||
mu_assert(
|
||||
infrared_test_load_messages(
|
||||
test->ff, string_get_cstr(buf), &input_messages, &input_messages_count),
|
||||
test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count),
|
||||
"Failed to load messages from file");
|
||||
|
||||
flipper_format_buffered_file_close(test->ff);
|
||||
string_clear(buf);
|
||||
furi_string_free(buf);
|
||||
|
||||
for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) {
|
||||
const InfraredMessage* message_encoded = &input_messages[message_counter];
|
||||
@@ -327,25 +329,27 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i
|
||||
InfraredMessage* messages;
|
||||
uint32_t messages_count;
|
||||
|
||||
string_t buf;
|
||||
string_init(buf);
|
||||
FuriString* buf;
|
||||
buf = furi_string_alloc();
|
||||
|
||||
mu_assert(
|
||||
infrared_test_prepare_file(infrared_get_protocol_name(protocol)),
|
||||
"Failed to prepare test file");
|
||||
|
||||
string_printf(buf, "decoder_input%d", test_index);
|
||||
furi_string_printf(buf, "decoder_input%ld", test_index);
|
||||
mu_assert(
|
||||
infrared_test_load_raw_signal(test->ff, string_get_cstr(buf), &timings, &timings_count),
|
||||
infrared_test_load_raw_signal(
|
||||
test->ff, furi_string_get_cstr(buf), &timings, &timings_count),
|
||||
"Failed to load raw signal from file");
|
||||
|
||||
string_printf(buf, "decoder_expected%d", test_index);
|
||||
furi_string_printf(buf, "decoder_expected%ld", test_index);
|
||||
mu_assert(
|
||||
infrared_test_load_messages(test->ff, string_get_cstr(buf), &messages, &messages_count),
|
||||
infrared_test_load_messages(
|
||||
test->ff, furi_string_get_cstr(buf), &messages, &messages_count),
|
||||
"Failed to load messages from file");
|
||||
|
||||
flipper_format_buffered_file_close(test->ff);
|
||||
string_clear(buf);
|
||||
furi_string_free(buf);
|
||||
|
||||
InfraredMessage message_decoded_check_local;
|
||||
bool level = 0;
|
||||
303
applications/debug/unit_tests/nfc/nfc_test.c
Normal file
303
applications/debug/unit_tests/nfc/nfc_test.c
Normal file
@@ -0,0 +1,303 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <storage/storage.h>
|
||||
#include <lib/flipper_format/flipper_format.h>
|
||||
#include <lib/nfc/protocols/nfca.h>
|
||||
#include <lib/nfc/helpers/mf_classic_dict.h>
|
||||
#include <lib/digital_signal/digital_signal.h>
|
||||
|
||||
#include <lib/flipper_format/flipper_format_i.h>
|
||||
#include <lib/toolbox/stream/file_stream.h>
|
||||
|
||||
#include "../minunit.h"
|
||||
|
||||
#define TAG "NfcTest"
|
||||
|
||||
#define NFC_TEST_RESOURCES_DIR EXT_PATH("unit_tests/nfc/")
|
||||
#define NFC_TEST_SIGNAL_SHORT_FILE "nfc_nfca_signal_short.nfc"
|
||||
#define NFC_TEST_SIGNAL_LONG_FILE "nfc_nfca_signal_long.nfc"
|
||||
#define NFC_TEST_DICT_PATH EXT_PATH("unit_tests/mf_classic_dict.nfc")
|
||||
|
||||
static const char* nfc_test_file_type = "Flipper NFC test";
|
||||
static const uint32_t nfc_test_file_version = 1;
|
||||
|
||||
#define NFC_TEST_DATA_MAX_LEN 18
|
||||
#define NFC_TETS_TIMINGS_MAX_LEN 1350
|
||||
|
||||
typedef struct {
|
||||
Storage* storage;
|
||||
NfcaSignal* signal;
|
||||
uint32_t test_data_len;
|
||||
uint8_t test_data[NFC_TEST_DATA_MAX_LEN];
|
||||
uint32_t test_timings_len;
|
||||
uint32_t test_timings[NFC_TETS_TIMINGS_MAX_LEN];
|
||||
} NfcTest;
|
||||
|
||||
static NfcTest* nfc_test = NULL;
|
||||
|
||||
static void nfc_test_alloc() {
|
||||
nfc_test = malloc(sizeof(NfcTest));
|
||||
nfc_test->signal = nfca_signal_alloc();
|
||||
nfc_test->storage = furi_record_open(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
static void nfc_test_free() {
|
||||
furi_assert(nfc_test);
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
nfca_signal_free(nfc_test->signal);
|
||||
free(nfc_test);
|
||||
nfc_test = NULL;
|
||||
}
|
||||
|
||||
static bool nfc_test_read_signal_from_file(const char* file_name) {
|
||||
bool success = false;
|
||||
|
||||
FlipperFormat* file = flipper_format_file_alloc(nfc_test->storage);
|
||||
FuriString* file_type;
|
||||
file_type = furi_string_alloc();
|
||||
uint32_t file_version = 0;
|
||||
|
||||
do {
|
||||
if(!flipper_format_file_open_existing(file, file_name)) break;
|
||||
if(!flipper_format_read_header(file, file_type, &file_version)) break;
|
||||
if(furi_string_cmp_str(file_type, nfc_test_file_type) ||
|
||||
file_version != nfc_test_file_version)
|
||||
break;
|
||||
if(!flipper_format_read_uint32(file, "Data length", &nfc_test->test_data_len, 1)) break;
|
||||
if(nfc_test->test_data_len > NFC_TEST_DATA_MAX_LEN) break;
|
||||
if(!flipper_format_read_hex(
|
||||
file, "Plain data", nfc_test->test_data, nfc_test->test_data_len))
|
||||
break;
|
||||
if(!flipper_format_read_uint32(file, "Timings length", &nfc_test->test_timings_len, 1))
|
||||
break;
|
||||
if(nfc_test->test_timings_len > NFC_TETS_TIMINGS_MAX_LEN) break;
|
||||
if(!flipper_format_read_uint32(
|
||||
file, "Timings", nfc_test->test_timings, nfc_test->test_timings_len))
|
||||
break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
furi_string_free(file_type);
|
||||
flipper_format_free(file);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool nfc_test_digital_signal_test_encode(
|
||||
const char* file_name,
|
||||
uint32_t encode_max_time,
|
||||
uint32_t timing_tolerance,
|
||||
uint32_t timings_sum_tolerance) {
|
||||
furi_assert(nfc_test);
|
||||
|
||||
bool success = false;
|
||||
uint32_t time = 0;
|
||||
uint32_t dut_timings_sum = 0;
|
||||
uint32_t ref_timings_sum = 0;
|
||||
uint8_t parity[10] = {};
|
||||
|
||||
do {
|
||||
// Read test data
|
||||
if(!nfc_test_read_signal_from_file(file_name)) break;
|
||||
|
||||
// Encode signal
|
||||
FURI_CRITICAL_ENTER();
|
||||
time = DWT->CYCCNT;
|
||||
nfca_signal_encode(
|
||||
nfc_test->signal, nfc_test->test_data, nfc_test->test_data_len * 8, parity);
|
||||
digital_signal_prepare_arr(nfc_test->signal->tx_signal);
|
||||
time = (DWT->CYCCNT - time) / furi_hal_cortex_instructions_per_microsecond();
|
||||
FURI_CRITICAL_EXIT();
|
||||
|
||||
// Check timings
|
||||
if(time > encode_max_time) {
|
||||
FURI_LOG_E(
|
||||
TAG, "Encoding time: %ld us while accepted value: %ld us", time, encode_max_time);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check data
|
||||
if(nfc_test->signal->tx_signal->edge_cnt != nfc_test->test_timings_len) {
|
||||
FURI_LOG_E(TAG, "Not equal timings buffers length");
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t timings_diff = 0;
|
||||
uint32_t* ref = nfc_test->test_timings;
|
||||
uint32_t* dut = nfc_test->signal->tx_signal->reload_reg_buff;
|
||||
bool timing_check_success = true;
|
||||
for(size_t i = 0; i < nfc_test->test_timings_len; i++) {
|
||||
timings_diff = dut[i] > ref[i] ? dut[i] - ref[i] : ref[i] - dut[i];
|
||||
dut_timings_sum += dut[i];
|
||||
ref_timings_sum += ref[i];
|
||||
if(timings_diff > timing_tolerance) {
|
||||
FURI_LOG_E(
|
||||
TAG, "Too big differece in %d timings. Ref: %ld, DUT: %ld", i, ref[i], dut[i]);
|
||||
timing_check_success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!timing_check_success) break;
|
||||
uint32_t sum_diff = dut_timings_sum > ref_timings_sum ? dut_timings_sum - ref_timings_sum :
|
||||
ref_timings_sum - dut_timings_sum;
|
||||
if(sum_diff > timings_sum_tolerance) {
|
||||
FURI_LOG_E(
|
||||
TAG,
|
||||
"Too big difference in timings sum. Ref: %ld, DUT: %ld",
|
||||
ref_timings_sum,
|
||||
dut_timings_sum);
|
||||
break;
|
||||
}
|
||||
|
||||
FURI_LOG_I(TAG, "Encoding time: %ld us. Acceptable time: %ld us", time, encode_max_time);
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Timings sum difference: %ld [1/64MHZ]. Acceptable difference: %ld [1/64MHz]",
|
||||
sum_diff,
|
||||
timings_sum_tolerance);
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
MU_TEST(nfc_digital_signal_test) {
|
||||
mu_assert(
|
||||
nfc_test_digital_signal_test_encode(
|
||||
NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_SHORT_FILE, 500, 1, 37),
|
||||
"NFC short digital signal test failed\r\n");
|
||||
mu_assert(
|
||||
nfc_test_digital_signal_test_encode(
|
||||
NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_LONG_FILE, 2000, 1, 37),
|
||||
"NFC long digital signal test failed\r\n");
|
||||
}
|
||||
|
||||
MU_TEST(mf_classic_dict_test) {
|
||||
MfClassicDict* instance = NULL;
|
||||
uint64_t key = 0;
|
||||
FuriString* temp_str;
|
||||
temp_str = furi_string_alloc();
|
||||
|
||||
instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest);
|
||||
mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n");
|
||||
|
||||
mu_assert(
|
||||
mf_classic_dict_get_total_keys(instance) == 0,
|
||||
"mf_classic_dict_get_total_keys == 0 assert failed\r\n");
|
||||
|
||||
furi_string_set(temp_str, "2196FAD8115B");
|
||||
mu_assert(
|
||||
mf_classic_dict_add_key_str(instance, temp_str),
|
||||
"mf_classic_dict_add_key == true assert failed\r\n");
|
||||
|
||||
mu_assert(
|
||||
mf_classic_dict_get_total_keys(instance) == 1,
|
||||
"mf_classic_dict_get_total_keys == 1 assert failed\r\n");
|
||||
|
||||
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
|
||||
|
||||
mu_assert(
|
||||
mf_classic_dict_get_key_at_index_str(instance, temp_str, 0),
|
||||
"mf_classic_dict_get_key_at_index_str == true assert failed\r\n");
|
||||
mu_assert(
|
||||
furi_string_cmp(temp_str, "2196FAD8115B") == 0,
|
||||
"string_cmp(temp_str, \"2196FAD8115B\") == 0 assert failed\r\n");
|
||||
|
||||
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
|
||||
|
||||
mu_assert(
|
||||
mf_classic_dict_get_key_at_index(instance, &key, 0),
|
||||
"mf_classic_dict_get_key_at_index == true assert failed\r\n");
|
||||
mu_assert(key == 0x2196FAD8115B, "key == 0x2196FAD8115B assert failed\r\n");
|
||||
|
||||
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
|
||||
|
||||
mu_assert(
|
||||
mf_classic_dict_delete_index(instance, 0),
|
||||
"mf_classic_dict_delete_index == true assert failed\r\n");
|
||||
|
||||
mf_classic_dict_free(instance);
|
||||
furi_string_free(temp_str);
|
||||
}
|
||||
|
||||
MU_TEST(mf_classic_dict_load_test) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
mu_assert(storage != NULL, "storage != NULL assert failed\r\n");
|
||||
|
||||
// Delete unit test dict file if exists
|
||||
if(storage_file_exists(storage, NFC_TEST_DICT_PATH)) {
|
||||
mu_assert(
|
||||
storage_simply_remove(storage, NFC_TEST_DICT_PATH),
|
||||
"remove == true assert failed\r\n");
|
||||
}
|
||||
|
||||
// Create unit test dict file
|
||||
Stream* file_stream = file_stream_alloc(storage);
|
||||
mu_assert(file_stream != NULL, "file_stream != NULL assert failed\r\n");
|
||||
mu_assert(
|
||||
file_stream_open(file_stream, NFC_TEST_DICT_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS),
|
||||
"file_stream_open == true assert failed\r\n");
|
||||
|
||||
// Write unit test dict file
|
||||
char key_str[] = "a0a1a2a3a4a5";
|
||||
mu_assert(
|
||||
stream_write_cstring(file_stream, key_str) == strlen(key_str),
|
||||
"write == true assert failed\r\n");
|
||||
// Close unit test dict file
|
||||
mu_assert(file_stream_close(file_stream), "file_stream_close == true assert failed\r\n");
|
||||
|
||||
// Load unit test dict file
|
||||
MfClassicDict* instance = NULL;
|
||||
instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest);
|
||||
mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n");
|
||||
uint32_t total_keys = mf_classic_dict_get_total_keys(instance);
|
||||
mu_assert(total_keys == 1, "total_keys == 1 assert failed\r\n");
|
||||
|
||||
// Read key
|
||||
uint64_t key_ref = 0xa0a1a2a3a4a5;
|
||||
uint64_t key_dut = 0;
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
mu_assert(
|
||||
mf_classic_dict_get_next_key_str(instance, temp_str),
|
||||
"get_next_key_str == true assert failed\r\n");
|
||||
mu_assert(furi_string_cmp_str(temp_str, key_str) == 0, "invalid key loaded\r\n");
|
||||
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
|
||||
mu_assert(
|
||||
mf_classic_dict_get_next_key(instance, &key_dut),
|
||||
"get_next_key == true assert failed\r\n");
|
||||
mu_assert(key_dut == key_ref, "invalid key loaded\r\n");
|
||||
furi_string_free(temp_str);
|
||||
mf_classic_dict_free(instance);
|
||||
|
||||
// Check that MfClassicDict added new line to the end of the file
|
||||
mu_assert(
|
||||
file_stream_open(file_stream, NFC_TEST_DICT_PATH, FSAM_READ, FSOM_OPEN_EXISTING),
|
||||
"file_stream_open == true assert failed\r\n");
|
||||
mu_assert(stream_seek(file_stream, -1, StreamOffsetFromEnd), "seek == true assert failed\r\n");
|
||||
uint8_t last_char = 0;
|
||||
mu_assert(stream_read(file_stream, &last_char, 1) == 1, "read == true assert failed\r\n");
|
||||
mu_assert(last_char == '\n', "last_char == '\\n' assert failed\r\n");
|
||||
mu_assert(file_stream_close(file_stream), "file_stream_close == true assert failed\r\n");
|
||||
|
||||
// Delete unit test dict file
|
||||
mu_assert(
|
||||
storage_simply_remove(storage, NFC_TEST_DICT_PATH), "remove == true assert failed\r\n");
|
||||
stream_free(file_stream);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(nfc) {
|
||||
nfc_test_alloc();
|
||||
|
||||
MU_RUN_TEST(nfc_digital_signal_test);
|
||||
MU_RUN_TEST(mf_classic_dict_test);
|
||||
MU_RUN_TEST(mf_classic_dict_load_test);
|
||||
|
||||
nfc_test_free();
|
||||
}
|
||||
|
||||
int run_minunit_test_nfc() {
|
||||
MU_RUN_SUITE(nfc);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include <stdint.h>
|
||||
#include <stream_buffer.h>
|
||||
#include <pb.h>
|
||||
#include <pb_encode.h>
|
||||
#include <m-list.h>
|
||||
@@ -34,7 +33,7 @@ static uint32_t command_id = 0;
|
||||
|
||||
typedef struct {
|
||||
RpcSession* session;
|
||||
StreamBufferHandle_t output_stream;
|
||||
FuriStreamBuffer* output_stream;
|
||||
SemaphoreHandle_t close_session_semaphore;
|
||||
SemaphoreHandle_t terminate_semaphore;
|
||||
TickType_t timeout;
|
||||
@@ -90,7 +89,7 @@ static void test_rpc_setup(void) {
|
||||
}
|
||||
furi_check(rpc_session[0].session);
|
||||
|
||||
rpc_session[0].output_stream = xStreamBufferCreate(1000, 1);
|
||||
rpc_session[0].output_stream = furi_stream_buffer_alloc(1000, 1);
|
||||
rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback);
|
||||
rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary();
|
||||
rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary();
|
||||
@@ -110,7 +109,7 @@ static void test_rpc_setup_second_session(void) {
|
||||
}
|
||||
furi_check(rpc_session[1].session);
|
||||
|
||||
rpc_session[1].output_stream = xStreamBufferCreate(1000, 1);
|
||||
rpc_session[1].output_stream = furi_stream_buffer_alloc(1000, 1);
|
||||
rpc_session_set_send_bytes_callback(rpc_session[1].session, output_bytes_callback);
|
||||
rpc_session[1].close_session_semaphore = xSemaphoreCreateBinary();
|
||||
rpc_session[1].terminate_semaphore = xSemaphoreCreateBinary();
|
||||
@@ -126,7 +125,7 @@ static void test_rpc_teardown(void) {
|
||||
rpc_session_close(rpc_session[0].session);
|
||||
furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY));
|
||||
furi_record_close(RECORD_RPC);
|
||||
vStreamBufferDelete(rpc_session[0].output_stream);
|
||||
furi_stream_buffer_free(rpc_session[0].output_stream);
|
||||
vSemaphoreDelete(rpc_session[0].close_session_semaphore);
|
||||
vSemaphoreDelete(rpc_session[0].terminate_semaphore);
|
||||
++command_id;
|
||||
@@ -141,7 +140,7 @@ static void test_rpc_teardown_second_session(void) {
|
||||
xSemaphoreTake(rpc_session[1].terminate_semaphore, 0);
|
||||
rpc_session_close(rpc_session[1].session);
|
||||
furi_check(xSemaphoreTake(rpc_session[1].terminate_semaphore, portMAX_DELAY));
|
||||
vStreamBufferDelete(rpc_session[1].output_stream);
|
||||
furi_stream_buffer_free(rpc_session[1].output_stream);
|
||||
vSemaphoreDelete(rpc_session[1].close_session_semaphore);
|
||||
vSemaphoreDelete(rpc_session[1].terminate_semaphore);
|
||||
++command_id;
|
||||
@@ -268,8 +267,8 @@ static PB_CommandStatus test_rpc_storage_get_file_error(File* file) {
|
||||
static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size) {
|
||||
RpcSessionContext* callbacks_context = ctx;
|
||||
|
||||
size_t bytes_sent =
|
||||
xStreamBufferSend(callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever);
|
||||
size_t bytes_sent = furi_stream_buffer_send(
|
||||
callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever);
|
||||
(void)bytes_sent;
|
||||
furi_check(bytes_sent == got_size);
|
||||
}
|
||||
@@ -534,7 +533,8 @@ static bool test_rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_
|
||||
TickType_t now = xTaskGetTickCount();
|
||||
int32_t time_left = session_context->timeout - now;
|
||||
time_left = MAX(time_left, 0);
|
||||
bytes_received = xStreamBufferReceive(session_context->output_stream, buf, count, time_left);
|
||||
bytes_received =
|
||||
furi_stream_buffer_receive(session_context->output_stream, buf, count, time_left);
|
||||
return (count == bytes_received);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ typedef struct {
|
||||
bool visited;
|
||||
} StorageTestPath;
|
||||
|
||||
DICT_DEF2(StorageTestPathDict, string_t, STRING_OPLIST, StorageTestPath, M_POD_OPLIST)
|
||||
DICT_DEF2(StorageTestPathDict, FuriString*, FURI_STRING_OPLIST, StorageTestPath, M_POD_OPLIST)
|
||||
|
||||
static StorageTestPathDict_t*
|
||||
storage_test_paths_alloc(const StorageTestPathDesc paths[], size_t paths_count) {
|
||||
@@ -83,15 +83,15 @@ static StorageTestPathDict_t*
|
||||
StorageTestPathDict_init(*data);
|
||||
|
||||
for(size_t i = 0; i < paths_count; i++) {
|
||||
string_t key;
|
||||
string_init_set(key, paths[i].path);
|
||||
FuriString* key;
|
||||
key = furi_string_alloc_set(paths[i].path);
|
||||
StorageTestPath value = {
|
||||
.is_dir = paths[i].is_dir,
|
||||
.visited = false,
|
||||
};
|
||||
|
||||
StorageTestPathDict_set_at(*data, key, value);
|
||||
string_clear(key);
|
||||
furi_string_free(key);
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -102,7 +102,7 @@ static void storage_test_paths_free(StorageTestPathDict_t* data) {
|
||||
free(data);
|
||||
}
|
||||
|
||||
static bool storage_test_paths_mark(StorageTestPathDict_t* data, string_t path, bool is_dir) {
|
||||
static bool storage_test_paths_mark(StorageTestPathDict_t* data, FuriString* path, bool is_dir) {
|
||||
bool found = false;
|
||||
|
||||
StorageTestPath* record = StorageTestPathDict_get(*data, path);
|
||||
@@ -148,27 +148,27 @@ static bool write_file_13DA(Storage* storage, const char* path) {
|
||||
}
|
||||
|
||||
static void storage_dirs_create(Storage* storage, const char* base) {
|
||||
string_t path;
|
||||
string_init(path);
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
|
||||
storage_common_mkdir(storage, base);
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_paths); i++) {
|
||||
string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]);
|
||||
storage_common_mkdir(storage, string_get_cstr(path));
|
||||
furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]);
|
||||
storage_common_mkdir(storage, furi_string_get_cstr(path));
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_files); i++) {
|
||||
string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]);
|
||||
write_file_13DA(storage, string_get_cstr(path));
|
||||
furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]);
|
||||
write_file_13DA(storage, furi_string_get_cstr(path));
|
||||
}
|
||||
|
||||
string_clear(path);
|
||||
furi_string_free(path);
|
||||
}
|
||||
|
||||
MU_TEST_1(test_dirwalk_full, Storage* storage) {
|
||||
string_t path;
|
||||
string_init(path);
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
FileInfo fileinfo;
|
||||
|
||||
StorageTestPathDict_t* paths =
|
||||
@@ -178,12 +178,12 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) {
|
||||
mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk")));
|
||||
|
||||
while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) {
|
||||
string_right(path, strlen(EXT_PATH("dirwalk/")));
|
||||
furi_string_right(path, strlen(EXT_PATH("dirwalk/")));
|
||||
mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY)));
|
||||
}
|
||||
|
||||
dir_walk_free(dir_walk);
|
||||
string_clear(path);
|
||||
furi_string_free(path);
|
||||
|
||||
mu_check(storage_test_paths_check(paths) == false);
|
||||
|
||||
@@ -191,8 +191,8 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) {
|
||||
}
|
||||
|
||||
MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) {
|
||||
string_t path;
|
||||
string_init(path);
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
FileInfo fileinfo;
|
||||
|
||||
StorageTestPathDict_t* paths = storage_test_paths_alloc(
|
||||
@@ -203,12 +203,12 @@ MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) {
|
||||
mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk")));
|
||||
|
||||
while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) {
|
||||
string_right(path, strlen(EXT_PATH("dirwalk/")));
|
||||
furi_string_right(path, strlen(EXT_PATH("dirwalk/")));
|
||||
mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY)));
|
||||
}
|
||||
|
||||
dir_walk_free(dir_walk);
|
||||
string_clear(path);
|
||||
furi_string_free(path);
|
||||
|
||||
mu_check(storage_test_paths_check(paths) == false);
|
||||
|
||||
@@ -230,8 +230,8 @@ static bool test_dirwalk_filter_no_folder_ext(const char* name, FileInfo* filein
|
||||
}
|
||||
|
||||
MU_TEST_1(test_dirwalk_filter, Storage* storage) {
|
||||
string_t path;
|
||||
string_init(path);
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
FileInfo fileinfo;
|
||||
|
||||
StorageTestPathDict_t* paths = storage_test_paths_alloc(
|
||||
@@ -242,12 +242,12 @@ MU_TEST_1(test_dirwalk_filter, Storage* storage) {
|
||||
mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk")));
|
||||
|
||||
while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) {
|
||||
string_right(path, strlen(EXT_PATH("dirwalk/")));
|
||||
furi_string_right(path, strlen(EXT_PATH("dirwalk/")));
|
||||
mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY)));
|
||||
}
|
||||
|
||||
dir_walk_free(dir_walk);
|
||||
string_clear(path);
|
||||
furi_string_free(path);
|
||||
|
||||
mu_check(storage_test_paths_check(paths) == false);
|
||||
|
||||
@@ -58,7 +58,7 @@ MU_TEST(storage_file_open_lock) {
|
||||
storage_file_close(file);
|
||||
|
||||
// file_locker thread stop
|
||||
mu_check(furi_thread_join(locker_thread) == FuriStatusOk);
|
||||
mu_check(furi_thread_join(locker_thread));
|
||||
furi_thread_free(locker_thread);
|
||||
|
||||
// clean data
|
||||
@@ -148,7 +148,7 @@ MU_TEST(storage_dir_open_lock) {
|
||||
storage_dir_close(file);
|
||||
|
||||
// file_locker thread stop
|
||||
mu_check(furi_thread_join(locker_thread) == FuriStatusOk);
|
||||
mu_check(furi_thread_join(locker_thread));
|
||||
furi_thread_free(locker_thread);
|
||||
|
||||
// clean data
|
||||
@@ -211,22 +211,22 @@ static bool check_file_13DA(Storage* storage, const char* path) {
|
||||
}
|
||||
|
||||
static void storage_dir_create(Storage* storage, const char* base) {
|
||||
string_t path;
|
||||
string_init(path);
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
|
||||
storage_common_mkdir(storage, base);
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) {
|
||||
string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
|
||||
storage_common_mkdir(storage, string_get_cstr(path));
|
||||
furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
|
||||
storage_common_mkdir(storage, furi_string_get_cstr(path));
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) {
|
||||
string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
|
||||
write_file_13DA(storage, string_get_cstr(path));
|
||||
furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
|
||||
write_file_13DA(storage, furi_string_get_cstr(path));
|
||||
}
|
||||
|
||||
string_clear(path);
|
||||
furi_string_free(path);
|
||||
}
|
||||
|
||||
static void storage_dir_remove(Storage* storage, const char* base) {
|
||||
@@ -235,15 +235,15 @@ static void storage_dir_remove(Storage* storage, const char* base) {
|
||||
|
||||
static bool storage_dir_rename_check(Storage* storage, const char* base) {
|
||||
bool result = false;
|
||||
string_t path;
|
||||
string_init(path);
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
|
||||
result = (storage_common_stat(storage, base, NULL) == FSE_OK);
|
||||
|
||||
if(result) {
|
||||
for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) {
|
||||
string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
|
||||
result = (storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK);
|
||||
furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
|
||||
result = (storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK);
|
||||
if(!result) {
|
||||
break;
|
||||
}
|
||||
@@ -252,15 +252,15 @@ static bool storage_dir_rename_check(Storage* storage, const char* base) {
|
||||
|
||||
if(result) {
|
||||
for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) {
|
||||
string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
|
||||
result = check_file_13DA(storage, string_get_cstr(path));
|
||||
furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
|
||||
result = check_file_13DA(storage, furi_string_get_cstr(path));
|
||||
if(!result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string_clear(path);
|
||||
furi_string_free(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ static const char* stream_test_right_data =
|
||||
MU_TEST_1(stream_composite_subtest, Stream* stream) {
|
||||
const size_t data_size = 128;
|
||||
uint8_t data[data_size];
|
||||
string_t string_lee;
|
||||
string_init_set(string_lee, "lee");
|
||||
FuriString* string_lee;
|
||||
string_lee = furi_string_alloc_set("lee");
|
||||
|
||||
// test that stream is empty
|
||||
// "" -> ""
|
||||
@@ -267,7 +267,7 @@ MU_TEST_1(stream_composite_subtest, Stream* stream) {
|
||||
mu_assert_int_eq(9, stream_tell(stream));
|
||||
mu_check(stream_eof(stream));
|
||||
|
||||
string_clear(string_lee);
|
||||
furi_string_free(string_lee);
|
||||
}
|
||||
|
||||
MU_TEST(stream_composite_test) {
|
||||
@@ -416,10 +416,10 @@ MU_TEST(stream_buffered_write_after_read_test) {
|
||||
}
|
||||
|
||||
MU_TEST(stream_buffered_large_file_test) {
|
||||
string_t input_data;
|
||||
string_t output_data;
|
||||
string_init(input_data);
|
||||
string_init(output_data);
|
||||
FuriString* input_data;
|
||||
FuriString* output_data;
|
||||
input_data = furi_string_alloc();
|
||||
output_data = furi_string_alloc();
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
@@ -429,7 +429,7 @@ MU_TEST(stream_buffered_large_file_test) {
|
||||
const size_t rep_count = data_size / line_size + 1;
|
||||
|
||||
for(size_t i = 0; i < rep_count; ++i) {
|
||||
string_cat_printf(input_data, "%s\n", stream_test_data);
|
||||
furi_string_cat_printf(input_data, "%s\n", stream_test_data);
|
||||
}
|
||||
|
||||
// write test data to file
|
||||
@@ -437,8 +437,8 @@ MU_TEST(stream_buffered_large_file_test) {
|
||||
mu_check(buffered_file_stream_open(
|
||||
stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_assert_int_eq(0, stream_size(stream));
|
||||
mu_assert_int_eq(string_size(input_data), stream_write_string(stream, input_data));
|
||||
mu_assert_int_eq(string_size(input_data), stream_size(stream));
|
||||
mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data));
|
||||
mu_assert_int_eq(furi_string_size(input_data), stream_size(stream));
|
||||
|
||||
const size_t substr_start = 8;
|
||||
const size_t substr_len = 11;
|
||||
@@ -475,23 +475,23 @@ MU_TEST(stream_buffered_large_file_test) {
|
||||
|
||||
// read the whole file
|
||||
mu_check(stream_rewind(stream));
|
||||
string_t tmp;
|
||||
string_init(tmp);
|
||||
FuriString* tmp;
|
||||
tmp = furi_string_alloc();
|
||||
while(stream_read_line(stream, tmp)) {
|
||||
string_cat(output_data, tmp);
|
||||
furi_string_cat(output_data, tmp);
|
||||
}
|
||||
string_clear(tmp);
|
||||
furi_string_free(tmp);
|
||||
|
||||
// check against generated data
|
||||
mu_assert_int_eq(string_size(input_data), string_size(output_data));
|
||||
mu_check(string_equal_p(input_data, output_data));
|
||||
mu_assert_int_eq(furi_string_size(input_data), furi_string_size(output_data));
|
||||
mu_check(furi_string_equal(input_data, output_data));
|
||||
mu_check(stream_eof(stream));
|
||||
|
||||
stream_free(stream);
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
string_clear(input_data);
|
||||
string_clear(output_data);
|
||||
furi_string_free(input_data);
|
||||
furi_string_free(output_data);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(stream_suite) {
|
||||
@@ -13,7 +13,7 @@
|
||||
#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
|
||||
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
|
||||
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
|
||||
#define TEST_RANDOM_COUNT_PARSE 232
|
||||
#define TEST_RANDOM_COUNT_PARSE 233
|
||||
#define TEST_TIMEOUT 10000
|
||||
|
||||
static SubGhzEnvironment* environment_handler;
|
||||
@@ -28,12 +28,12 @@ static void subghz_test_rx_callback(
|
||||
void* context) {
|
||||
UNUSED(receiver);
|
||||
UNUSED(context);
|
||||
string_t text;
|
||||
string_init(text);
|
||||
FuriString* text;
|
||||
text = furi_string_alloc();
|
||||
subghz_protocol_decoder_base_get_string(decoder_base, text);
|
||||
subghz_receiver_reset(receiver_handler);
|
||||
FURI_LOG_T(TAG, "\r\n%s", string_get_cstr(text));
|
||||
string_clear(text);
|
||||
FURI_LOG_T(TAG, "\r\n%s", furi_string_get_cstr(text));
|
||||
furi_string_free(text);
|
||||
subghz_test_decoder_count++;
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ static bool subghz_decode_random_test(const char* path) {
|
||||
static bool subghz_encoder_test(const char* path) {
|
||||
subghz_test_decoder_count = 0;
|
||||
uint32_t test_start = furi_get_tick();
|
||||
string_t temp_str;
|
||||
string_init(temp_str);
|
||||
FuriString* temp_str;
|
||||
temp_str = furi_string_alloc();
|
||||
bool file_load = false;
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
@@ -167,11 +167,11 @@ static bool subghz_encoder_test(const char* path) {
|
||||
} while(false);
|
||||
if(file_load) {
|
||||
SubGhzTransmitter* transmitter =
|
||||
subghz_transmitter_alloc_init(environment_handler, string_get_cstr(temp_str));
|
||||
subghz_transmitter_alloc_init(environment_handler, furi_string_get_cstr(temp_str));
|
||||
subghz_transmitter_deserialize(transmitter, fff_data_file);
|
||||
|
||||
SubGhzProtocolDecoderBase* decoder = subghz_receiver_search_decoder_base_by_name(
|
||||
receiver_handler, string_get_cstr(temp_str));
|
||||
receiver_handler, furi_string_get_cstr(temp_str));
|
||||
|
||||
if(decoder) {
|
||||
LevelDuration level_duration;
|
||||
@@ -192,10 +192,11 @@ static bool subghz_encoder_test(const char* path) {
|
||||
flipper_format_free(fff_data_file);
|
||||
FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count);
|
||||
if(furi_get_tick() - test_start > TEST_TIMEOUT) {
|
||||
printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str));
|
||||
printf(
|
||||
"\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", furi_string_get_cstr(temp_str));
|
||||
subghz_test_decoder_count = 0;
|
||||
}
|
||||
string_clear(temp_str);
|
||||
furi_string_free(temp_str);
|
||||
|
||||
return subghz_test_decoder_count ? true : false;
|
||||
}
|
||||
@@ -434,6 +435,13 @@ MU_TEST(subghz_decoder_clemsa_test) {
|
||||
"Test decoder " SUBGHZ_PROTOCOL_CLEMSA_NAME " error\r\n");
|
||||
}
|
||||
|
||||
MU_TEST(subghz_decoder_oregon2_test) {
|
||||
mu_assert(
|
||||
subghz_decoder_test(
|
||||
EXT_PATH("unit_tests/subghz/oregon2_raw.sub"), SUBGHZ_PROTOCOL_OREGON2_NAME),
|
||||
"Test decoder " SUBGHZ_PROTOCOL_OREGON2_NAME " error\r\n");
|
||||
}
|
||||
|
||||
//test encoders
|
||||
MU_TEST(subghz_encoder_princeton_test) {
|
||||
mu_assert(
|
||||
@@ -595,6 +603,7 @@ MU_TEST_SUITE(subghz) {
|
||||
MU_RUN_TEST(subghz_decoder_magellen_test);
|
||||
MU_RUN_TEST(subghz_decoder_intertechno_v3_test);
|
||||
MU_RUN_TEST(subghz_decoder_clemsa_test);
|
||||
MU_RUN_TEST(subghz_decoder_oregon2_test);
|
||||
|
||||
MU_RUN_TEST(subghz_encoder_princeton_test);
|
||||
MU_RUN_TEST(subghz_encoder_came_test);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user