mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
Compare commits
691 Commits
nfc-parser
...
electra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3afee368de | ||
|
|
e8cbce6e1d | ||
|
|
ab2fcaf4ab | ||
|
|
8a58fc1ca7 | ||
|
|
807bec14b1 | ||
|
|
8ba938cec1 | ||
|
|
11070c9e5e | ||
|
|
6a91588f52 | ||
|
|
e0797131ec | ||
|
|
9e42e00ead | ||
|
|
d5339f8270 | ||
|
|
e909818f65 | ||
|
|
e4ed15ba23 | ||
|
|
8275140fe6 | ||
|
|
4f6c98dc0d | ||
|
|
21abcb56fd | ||
|
|
fb6070f29d | ||
|
|
de4b086083 | ||
|
|
7c013c0534 | ||
|
|
23ca7e7b48 | ||
|
|
c4709a5b6b | ||
|
|
276feac73f | ||
|
|
0d456aa550 | ||
|
|
c673b53e21 | ||
|
|
51bb9c0a0a | ||
|
|
217bfac2fc | ||
|
|
603a86dbe6 | ||
|
|
7c5111e29f | ||
|
|
63403bbae2 | ||
|
|
7c63bf7574 | ||
|
|
0ae78dfcdd | ||
|
|
97d5b8b6f6 | ||
|
|
33daa960cf | ||
|
|
5dddb075ac | ||
|
|
6d1a5c71e6 | ||
|
|
50bee67748 | ||
|
|
3005f6cd9a | ||
|
|
fb8f59fa1d | ||
|
|
1d17206e23 | ||
|
|
548d370ab9 | ||
|
|
5efbd36bb8 | ||
|
|
1afa3f7ef3 | ||
|
|
3d3db9f5b0 | ||
|
|
e3f95a326b | ||
|
|
a86aeface5 | ||
|
|
5f9b300ab2 | ||
|
|
a7715704f8 | ||
|
|
98c51d13a1 | ||
|
|
b9966a50d9 | ||
|
|
9648da951a | ||
|
|
8ffee678c6 | ||
|
|
e1cb69d046 | ||
|
|
b60e6042a5 | ||
|
|
96db11a0d6 | ||
|
|
b12d43b765 | ||
|
|
a89a67d103 | ||
|
|
9656331618 | ||
|
|
a8dcec0dad | ||
|
|
d73832a5dd | ||
|
|
a27aa0336a | ||
|
|
887f6a20fc | ||
|
|
786dbfe0c3 | ||
|
|
374e96bb7d | ||
|
|
c9d23a9d1d | ||
|
|
6bfa383cea | ||
|
|
bf721d7a5f | ||
|
|
7077d588c7 | ||
|
|
75ece9b697 | ||
|
|
a57dbe446e | ||
|
|
9b377e6f80 | ||
|
|
1736a8a7c2 | ||
|
|
7414e6d4df | ||
|
|
e7ef923729 | ||
|
|
c157ca9879 | ||
|
|
4965215c8d | ||
|
|
379e8d2a6a | ||
|
|
42c69b076a | ||
|
|
d13017a7fe | ||
|
|
0e3cbb4911 | ||
|
|
f544aa8eb6 | ||
|
|
e5f9af3b43 | ||
|
|
43c4381820 | ||
|
|
1559ee6293 | ||
|
|
34abaa7e27 | ||
|
|
3108f07a4b | ||
|
|
c3b59a9dba | ||
|
|
3269f751cd | ||
|
|
2987a46322 | ||
|
|
fb018ec170 | ||
|
|
85fc0a2dd3 | ||
|
|
83ff6fb8bf | ||
|
|
70cdd26855 | ||
|
|
0a7e258c1a | ||
|
|
f88a916ccc | ||
|
|
6cb9ad12f1 | ||
|
|
5bf16e7e0e | ||
|
|
7b99f0b0bb | ||
|
|
c87683596a | ||
|
|
9bef2aaec6 | ||
|
|
286fd796e7 | ||
|
|
0d73a58123 | ||
|
|
9042009b0b | ||
|
|
8eba6e18ff | ||
|
|
4422a03ae9 | ||
|
|
12112e70bc | ||
|
|
be43e49869 | ||
|
|
00970a4b12 | ||
|
|
94c2d7a4e3 | ||
|
|
4883383b20 | ||
|
|
70f93a48f5 | ||
|
|
7189026335 | ||
|
|
b079b46681 | ||
|
|
1a40fae003 | ||
|
|
f4ffd29bbc | ||
|
|
b299604932 | ||
|
|
6bb605f8ce | ||
|
|
c1e8cbf3fd | ||
|
|
2443a702c9 | ||
|
|
744ef8138e | ||
|
|
b3151c563f | ||
|
|
fb9728d570 | ||
|
|
c144611609 | ||
|
|
95da39ba88 | ||
|
|
db14ca964b | ||
|
|
e3ca293eee | ||
|
|
58da27fa91 | ||
|
|
88a6860913 | ||
|
|
c9909467f9 | ||
|
|
27e61eb808 | ||
|
|
16b34c6e4d | ||
|
|
6b120a3b09 | ||
|
|
c31b60c7b7 | ||
|
|
d1c75dc57b | ||
|
|
52d97b9329 | ||
|
|
294df5d1d4 | ||
|
|
344b624efc | ||
|
|
1e324a7314 | ||
|
|
6e4d32b941 | ||
|
|
22cf19dcef | ||
|
|
7787845479 | ||
|
|
ef29ed149d | ||
|
|
a830d6b511 | ||
|
|
f8d4d9397e | ||
|
|
5ba6e3225b | ||
|
|
ec4b8b8f5e | ||
|
|
45e7913435 | ||
|
|
f5ca3ed2a1 | ||
|
|
7c6541e513 | ||
|
|
5431257470 | ||
|
|
5793d5271c | ||
|
|
3ccb2956f3 | ||
|
|
d32f195557 | ||
|
|
096a26b07d | ||
|
|
f426c44811 | ||
|
|
9f71be6fef | ||
|
|
002e5cd9de | ||
|
|
e436ea275a | ||
|
|
3084469d83 | ||
|
|
64bd2f9c84 | ||
|
|
c353182353 | ||
|
|
538422e2a9 | ||
|
|
74cda02368 | ||
|
|
f02b03172a | ||
|
|
21e7c46033 | ||
|
|
f5dff83595 | ||
|
|
175db7baa3 | ||
|
|
a6aa441edc | ||
|
|
ae84992f25 | ||
|
|
8ec1c74baf | ||
|
|
84beb9b23e | ||
|
|
fda8370255 | ||
|
|
7c0939ad52 | ||
|
|
01f3192957 | ||
|
|
9961dadee7 | ||
|
|
585b7f963d | ||
|
|
bb439a9761 | ||
|
|
8762629276 | ||
|
|
adafe96924 | ||
|
|
6de2934394 | ||
|
|
f633f476c8 | ||
|
|
11d7f53854 | ||
|
|
763e2f5bab | ||
|
|
bf769ee398 | ||
|
|
23940bff81 | ||
|
|
c52f28efa4 | ||
|
|
81a16e5a28 | ||
|
|
8d75af8457 | ||
|
|
aaa7c81f99 | ||
|
|
385c3c1c01 | ||
|
|
c323656037 | ||
|
|
0a48658a9a | ||
|
|
46a90ec97f | ||
|
|
d1d3c43939 | ||
|
|
34fac96ef6 | ||
|
|
c1441b1331 | ||
|
|
6d73b266d5 | ||
|
|
6947d3dea2 | ||
|
|
2aa2dcc71b | ||
|
|
09c46a3381 | ||
|
|
6d9a2cc699 | ||
|
|
760deb66c5 | ||
|
|
e0469ae1ed | ||
|
|
4039ccbcca | ||
|
|
0c465f7eb3 | ||
|
|
1bef579b82 | ||
|
|
702ab672bb | ||
|
|
7d50c4a742 | ||
|
|
139cc3c93d | ||
|
|
3b83d8b825 | ||
|
|
8c0ba4de9f | ||
|
|
ee36c66572 | ||
|
|
4a673397b3 | ||
|
|
a5bb1ead68 | ||
|
|
558f75672f | ||
|
|
7987917d85 | ||
|
|
1c033e2afe | ||
|
|
169522cbe8 | ||
|
|
7c607abfe6 | ||
|
|
6f560ef210 | ||
|
|
71111b0d2f | ||
|
|
8bd984ff81 | ||
|
|
2276432745 | ||
|
|
ff0952d66a | ||
|
|
bcde0aefbd | ||
|
|
acc39a4bc0 | ||
|
|
c541227483 | ||
|
|
a09ec4d976 | ||
|
|
a0dc2b5cfc | ||
|
|
7e9ecdf394 | ||
|
|
ce67472dc4 | ||
|
|
f88da8b0c3 | ||
|
|
d573cc06da | ||
|
|
17dd089b5a | ||
|
|
eb013ab6ec | ||
|
|
d7711d729f | ||
|
|
375eb55d33 | ||
|
|
6e52c591e5 | ||
|
|
c5bf29cb8c | ||
|
|
2aa85347ee | ||
|
|
75432346de | ||
|
|
98c328f93f | ||
|
|
3f7a070397 | ||
|
|
b27066b508 | ||
|
|
5cfc773b7b | ||
|
|
2da05bfa6c | ||
|
|
9050a242e6 | ||
|
|
022fccf0d7 | ||
|
|
adbe4d44f4 | ||
|
|
79a286fe1a | ||
|
|
2f5be8f695 | ||
|
|
e8e596e4c9 | ||
|
|
7b09a22a5c | ||
|
|
c9434492b8 | ||
|
|
1bd56fb190 | ||
|
|
25d4c4f829 | ||
|
|
175f603678 | ||
|
|
df57ecd786 | ||
|
|
58cd56a439 | ||
|
|
b1a9904ea5 | ||
|
|
43d1659200 | ||
|
|
8f9fbc3a79 | ||
|
|
bf97209c9b | ||
|
|
2961ad5ee1 | ||
|
|
4f7eb77071 | ||
|
|
ecab4d53d2 | ||
|
|
4e7f25a539 | ||
|
|
5e47048369 | ||
|
|
a6c5a1ba69 | ||
|
|
7b26dc5ebf | ||
|
|
1070064f89 | ||
|
|
88b354b57e | ||
|
|
4b7ca736d6 | ||
|
|
18ea2371a4 | ||
|
|
78e6c236c7 | ||
|
|
22be2629e0 | ||
|
|
7fc4ba7c1c | ||
|
|
33fe146a57 | ||
|
|
a2739ab0c1 | ||
|
|
bc309cebe6 | ||
|
|
cc937a97ef | ||
|
|
02f8840ac7 | ||
|
|
1c56a30d35 | ||
|
|
b0a741233f | ||
|
|
b29a5896a4 | ||
|
|
dbb81055f2 | ||
|
|
465fcf93a7 | ||
|
|
65b0aa8e99 | ||
|
|
90a8009d43 | ||
|
|
b1ebb142c4 | ||
|
|
ee2c7bed92 | ||
|
|
d4433fabd4 | ||
|
|
10d2911af2 | ||
|
|
b8d5dfdd05 | ||
|
|
c778233223 | ||
|
|
614f9b8705 | ||
|
|
26cb315845 | ||
|
|
e1bc60b7eb | ||
|
|
a88adc2a27 | ||
|
|
aa54a477d8 | ||
|
|
c69ce4c921 | ||
|
|
b77e430df5 | ||
|
|
a64907d84b | ||
|
|
bc98c788fe | ||
|
|
59370e03db | ||
|
|
16d1e71d6e | ||
|
|
111438361d | ||
|
|
113afc0d0f | ||
|
|
21962da715 | ||
|
|
d731918197 | ||
|
|
e143833ee1 | ||
|
|
ee11aca464 | ||
|
|
71e763d9b3 | ||
|
|
02a827da38 | ||
|
|
2d32ea68fe | ||
|
|
66c60e65aa | ||
|
|
b15787053a | ||
|
|
b38d2e8d84 | ||
|
|
9fcf3795ee | ||
|
|
073902f83e | ||
|
|
c7952d57d8 | ||
|
|
e114c01ce2 | ||
|
|
1e473e59f4 | ||
|
|
3e3250ea5f | ||
|
|
a484e42d42 | ||
|
|
c2613c00f1 | ||
|
|
90e60560c7 | ||
|
|
9edf2a7624 | ||
|
|
fb956e2427 | ||
|
|
4e1089ec49 | ||
|
|
2c650b5bc7 | ||
|
|
fcf3b50f69 | ||
|
|
88a3b4593d | ||
|
|
b6a6528526 | ||
|
|
01d937ca0b | ||
|
|
60a9d7e6cf | ||
|
|
ae160efa16 | ||
|
|
33cf554f06 | ||
|
|
200a6138ef | ||
|
|
4adb492e29 | ||
|
|
698d0b4b49 | ||
|
|
f7742c692d | ||
|
|
b8b344c6e1 | ||
|
|
4d73794100 | ||
|
|
913659325b | ||
|
|
d19f8f51ea | ||
|
|
8e4c366f0b | ||
|
|
7b01a33b3f | ||
|
|
11a34e5bc3 | ||
|
|
2c5973be22 | ||
|
|
597d295743 | ||
|
|
62edabe9dd | ||
|
|
890bb9838c | ||
|
|
87804374c5 | ||
|
|
26ac455fb9 | ||
|
|
9298e567d0 | ||
|
|
c3c54f672c | ||
|
|
feb45f6645 | ||
|
|
887083b7f5 | ||
|
|
c061fb1681 | ||
|
|
8dd59a5d9e | ||
|
|
cc457fade2 | ||
|
|
d72c449b13 | ||
|
|
d70bcfdfff | ||
|
|
6d15c23231 | ||
|
|
0397dd0a40 | ||
|
|
dd988ba449 | ||
|
|
a46038acbf | ||
|
|
3f29295380 | ||
|
|
3c77dc7930 | ||
|
|
13493916e2 | ||
|
|
0acd3bfc66 | ||
|
|
3d9a6a41db | ||
|
|
7d7f15bdf1 | ||
|
|
5c88e680a6 | ||
|
|
fdde5856b8 | ||
|
|
949098bbc5 | ||
|
|
4042852825 | ||
|
|
71a93e8cc3 | ||
|
|
d75f2c62ca | ||
|
|
dd87afcbde | ||
|
|
f5cc40af0c | ||
|
|
25a280c818 | ||
|
|
19fe8e8954 | ||
|
|
9d5135daff | ||
|
|
3a847243bc | ||
|
|
a9fb8da642 | ||
|
|
7e7c2b746c | ||
|
|
42d3876d22 | ||
|
|
0f7411d03a | ||
|
|
d61931e69d | ||
|
|
75c7c7473a | ||
|
|
c8e62ba5e8 | ||
|
|
1faeca6e1b | ||
|
|
0fddc8ed60 | ||
|
|
9d1b14effa | ||
|
|
0154018363 | ||
|
|
b904555ebf | ||
|
|
14d3510d8e | ||
|
|
11cfbd1ec8 | ||
|
|
389affd904 | ||
|
|
6d09bebf14 | ||
|
|
b0df852944 | ||
|
|
6836a7b7c5 | ||
|
|
14dabf523a | ||
|
|
809e1b3aff | ||
|
|
a9de06d6f2 | ||
|
|
08f096df24 | ||
|
|
4a382bc1de | ||
|
|
6f71f1113a | ||
|
|
c24625fae8 | ||
|
|
a35159c220 | ||
|
|
2d2fac5045 | ||
|
|
c35f258ab8 | ||
|
|
702e4f39ab | ||
|
|
56875ed9a7 | ||
|
|
1e09034e23 | ||
|
|
8a86571068 | ||
|
|
37708b0e79 | ||
|
|
14ae52f88f | ||
|
|
8584702fd7 | ||
|
|
ed9cb357b5 | ||
|
|
34a1d9eba4 | ||
|
|
357df80642 | ||
|
|
1a02152d03 | ||
|
|
ab609bc294 | ||
|
|
e6935f2a9d | ||
|
|
5b97ddc842 | ||
|
|
7ab888bb98 | ||
|
|
b135c8e792 | ||
|
|
edda4e5508 | ||
|
|
ed055cbdf6 | ||
|
|
cf41c98d66 | ||
|
|
73deff8863 | ||
|
|
4c2e997997 | ||
|
|
ade84ccb9c | ||
|
|
bcdb9cb13c | ||
|
|
afad5e4407 | ||
|
|
962d809ad7 | ||
|
|
3c73123a81 | ||
|
|
f3f3e56c63 | ||
|
|
b2a7bb0696 | ||
|
|
c0db3d541e | ||
|
|
50e0521bf7 | ||
|
|
ebd09a1981 | ||
|
|
6bc63b7734 | ||
|
|
f6eb79e1e5 | ||
|
|
d195de502e | ||
|
|
ec356626fa | ||
|
|
b1674711a1 | ||
|
|
9ceae3a3b2 | ||
|
|
ded9b121ba | ||
|
|
534fe2fb26 | ||
|
|
3cbc68f07a | ||
|
|
26da5f564b | ||
|
|
1ad9bb8caf | ||
|
|
5a92adaefc | ||
|
|
c489c956e7 | ||
|
|
afd41aade1 | ||
|
|
fee6f12684 | ||
|
|
4265b9c28e | ||
|
|
95e653cf76 | ||
|
|
29fa68118d | ||
|
|
4625d6f17c | ||
|
|
dd4f873439 | ||
|
|
4984e9e414 | ||
|
|
3e53e69827 | ||
|
|
8c54c14742 | ||
|
|
e180266c1a | ||
|
|
751cf23410 | ||
|
|
cd8e76bbcd | ||
|
|
2d78e23d25 | ||
|
|
9d6f51484a | ||
|
|
9a77dbec56 | ||
|
|
a83e421d71 | ||
|
|
2c784d3fea | ||
|
|
c736c3f3f0 | ||
|
|
e0782966d4 | ||
|
|
ed34dfa1c6 | ||
|
|
962a7b1ba7 | ||
|
|
2e05489a82 | ||
|
|
ff28c23f64 | ||
|
|
3721a71eab | ||
|
|
6846e808cf | ||
|
|
2f0adf73c7 | ||
|
|
35674a306b | ||
|
|
fb2bff6c4d | ||
|
|
12d70a3c32 | ||
|
|
f9b6d22534 | ||
|
|
c63089a929 | ||
|
|
ebcc317816 | ||
|
|
603421bd8c | ||
|
|
6aa7f2e261 | ||
|
|
1bd42af688 | ||
|
|
398a468fd7 | ||
|
|
90b49926ea | ||
|
|
7caf2bd2ff | ||
|
|
3446b38a06 | ||
|
|
22be06174a | ||
|
|
6bfa591e92 | ||
|
|
4573046df8 | ||
|
|
fe05c678c4 | ||
|
|
5d4dae5fa8 | ||
|
|
89e1620883 | ||
|
|
4fd0ce3eb5 | ||
|
|
28723949c4 | ||
|
|
cbab316607 | ||
|
|
19a5f02d66 | ||
|
|
754fffac6b | ||
|
|
289fbe56be | ||
|
|
c31052848a | ||
|
|
a8651a2861 | ||
|
|
76a5c444fa | ||
|
|
da44d70bf2 | ||
|
|
e702cdedc3 | ||
|
|
67eb679435 | ||
|
|
ed3cd21f5c | ||
|
|
d3dcc1d27d | ||
|
|
e6f078eeb7 | ||
|
|
097632fb7a | ||
|
|
834c2efb8b | ||
|
|
1cb8b0e369 | ||
|
|
100a46d7af | ||
|
|
b0371b3465 | ||
|
|
872987f002 | ||
|
|
51d8b18f3e | ||
|
|
92a25af3c3 | ||
|
|
ce80586822 | ||
|
|
fee4a5a8f7 | ||
|
|
a15312e052 | ||
|
|
d23bc9f58a | ||
|
|
35a93e6eef | ||
|
|
a5b77aa228 | ||
|
|
3612814a18 | ||
|
|
1165e25f00 | ||
|
|
64fe987fb5 | ||
|
|
c8ea167a06 | ||
|
|
653af9a5cd | ||
|
|
16d1c938bf | ||
|
|
1074af905c | ||
|
|
786f3568c0 | ||
|
|
830dbc7a71 | ||
|
|
686c05d20c | ||
|
|
4b786fb77e | ||
|
|
16b8fa4715 | ||
|
|
39055ff701 | ||
|
|
cbc0231461 | ||
|
|
1ceacc6555 | ||
|
|
ae04fc70eb | ||
|
|
acd6445d3b | ||
|
|
7a89789a28 | ||
|
|
63eeb86bc7 | ||
|
|
1e6fe92b44 | ||
|
|
c014491f55 | ||
|
|
5e384ccc43 | ||
|
|
3fce83eb79 | ||
|
|
3f6092d95c | ||
|
|
87f8f1d9c4 | ||
|
|
eb4d0bb737 | ||
|
|
b9498826fd | ||
|
|
2617eccb46 | ||
|
|
aef18f6b2f | ||
|
|
aad9f6be28 | ||
|
|
9fb14704c3 | ||
|
|
1ad17878e3 | ||
|
|
391c32654b | ||
|
|
74023e43ce | ||
|
|
c470748e3f | ||
|
|
84abb53712 | ||
|
|
46eec3f568 | ||
|
|
007e29425d | ||
|
|
41c316d612 | ||
|
|
39e9dd0ab0 | ||
|
|
a989c8adcc | ||
|
|
5f041a22e5 | ||
|
|
ecabcbc58a | ||
|
|
c002684233 | ||
|
|
a4ebbeabd2 | ||
|
|
7db8d5aa82 | ||
|
|
7981cb832e | ||
|
|
c27494ac39 | ||
|
|
f37d00a8ba | ||
|
|
11ecb54576 | ||
|
|
8d60c0ff21 | ||
|
|
a1e62c3e76 | ||
|
|
16a3f4c06a | ||
|
|
b5964b9795 | ||
|
|
eef4574a63 | ||
|
|
e3930a30c0 | ||
|
|
36114de5f7 | ||
|
|
1fd4839bb6 | ||
|
|
a7ab4b9c32 | ||
|
|
51f6dcffa4 | ||
|
|
ab236f3763 | ||
|
|
81e4e94adf | ||
|
|
5655be1b8f | ||
|
|
61067b0984 | ||
|
|
dc8b0b02d8 | ||
|
|
d9e4a60010 | ||
|
|
9e8e5d8ae9 | ||
|
|
bae0baa42f | ||
|
|
027ea9ea36 | ||
|
|
4f50ef9b54 | ||
|
|
a11fcfc72d | ||
|
|
cb0cf7b9e2 | ||
|
|
95737958ad | ||
|
|
f9f67e6d54 | ||
|
|
dd182ab179 | ||
|
|
fc043da9c6 | ||
|
|
f1a972607a | ||
|
|
4b7b0ad6b9 | ||
|
|
ba6b56445d | ||
|
|
be15c5ff4a | ||
|
|
957a89f2b3 | ||
|
|
08a5adf18e | ||
|
|
3a82b3aa3c | ||
|
|
d73d007797 | ||
|
|
3fd5f15e7f | ||
|
|
1f9fd4c42a | ||
|
|
c539cfa5ae | ||
|
|
48e4de1213 | ||
|
|
18ea59051a | ||
|
|
34517ec43e | ||
|
|
9aae348cae | ||
|
|
321a56d934 | ||
|
|
22aba527b7 | ||
|
|
6103de1754 | ||
|
|
8799e1112b | ||
|
|
01d178a1f3 | ||
|
|
685ed6bfad | ||
|
|
d337222cbe | ||
|
|
bfffaf5b53 | ||
|
|
e8b468b492 | ||
|
|
d3c994c403 | ||
|
|
4397e2cff5 | ||
|
|
e9454b629b | ||
|
|
85f437ee22 | ||
|
|
14af1fe022 | ||
|
|
686fd208dc | ||
|
|
cfb974dc1f | ||
|
|
1ea99d119b | ||
|
|
843fa3eecc | ||
|
|
3959827fd4 | ||
|
|
d0c466ccc0 | ||
|
|
18fbe364f2 | ||
|
|
c9ffe4ab4d | ||
|
|
0a44c75b20 | ||
|
|
82ecc8e73f | ||
|
|
e2a7d5f3f4 | ||
|
|
5994c26de3 | ||
|
|
f4e738a9ef | ||
|
|
13fe87259f | ||
|
|
d55652deff | ||
|
|
4b363472dd | ||
|
|
bf78ace9e2 | ||
|
|
cf4b537c37 | ||
|
|
305d5bcc83 | ||
|
|
d65dfe1958 | ||
|
|
3edbf8f538 | ||
|
|
e9e44db964 | ||
|
|
09defbc4d4 | ||
|
|
2b3e12fcb6 | ||
|
|
3ec070313e | ||
|
|
33136b441c | ||
|
|
5bff5ca40d | ||
|
|
d5164c427f | ||
|
|
4a77a236b4 | ||
|
|
cf6829f608 | ||
|
|
69d1d5498e | ||
|
|
d7b54dfa66 | ||
|
|
04e28f3e39 | ||
|
|
1a56ce77e2 | ||
|
|
94e8e5d498 | ||
|
|
f3cbb0363d | ||
|
|
59e94566fd | ||
|
|
fa146d8770 | ||
|
|
064c60e52e | ||
|
|
18ea05edee | ||
|
|
12180ba707 | ||
|
|
278ae51d73 | ||
|
|
d113bbf4dd | ||
|
|
38b65fba3b | ||
|
|
7af6a46c8f | ||
|
|
ff724ce4b5 | ||
|
|
f151d3be01 | ||
|
|
fa04e36df2 | ||
|
|
7554e7bedb | ||
|
|
59e797b312 | ||
|
|
94cdaf20a2 | ||
|
|
f7de65684a | ||
|
|
810dfa1b79 | ||
|
|
f0838dd5fc |
@@ -69,7 +69,7 @@ Min butthurt: 0
|
||||
Max butthurt: 9
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L1_Painting_128x64
|
||||
Min butthurt: 0
|
||||
@@ -85,26 +85,33 @@ Min level: 1
|
||||
Max level: 3
|
||||
Weight: 3
|
||||
|
||||
Name: L1_Senpai_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 5
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 3
|
||||
|
||||
Name: L1_Kaiju_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 10
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L1_My_dude_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 8
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L2_Wake_up_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 12
|
||||
Min level: 2
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L2_Furippa2_128x64
|
||||
Min butthurt: 0
|
||||
@@ -132,7 +139,7 @@ Min butthurt: 0
|
||||
Max butthurt: 8
|
||||
Min level: 2
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L3_Furippa3_128x64
|
||||
Min butthurt: 0
|
||||
@@ -155,30 +162,37 @@ Min level: 3
|
||||
Max level: 3
|
||||
Weight: 3
|
||||
|
||||
Name: L1_Senpai_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 5
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
|
||||
Name: L1_Sad_song_128x64
|
||||
Min butthurt: 8
|
||||
Max butthurt: 13
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L2_Coding_in_the_shell_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 12
|
||||
Min level: 2
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L2_Secret_door_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 12
|
||||
Min level: 2
|
||||
Max level: 3
|
||||
Weight: 4
|
||||
Weight: 3
|
||||
|
||||
Name: L3_Freedom_2_dolphins_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 12
|
||||
Min level: 3
|
||||
Max level: 3
|
||||
Weight: 5
|
||||
|
||||
Name: L1_Akira_128x64
|
||||
Min butthurt: 0
|
||||
Max butthurt: 8
|
||||
Min level: 1
|
||||
Max level: 3
|
||||
Weight: 5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/applications/services/notification/notification_app.c b/applications/services/notification/notification_app.c
|
||||
index 5769ced..c5d3088 100644
|
||||
index 9baa738..91ad7c1 100644
|
||||
--- a/applications/services/notification/notification_app.c
|
||||
+++ b/applications/services/notification/notification_app.c
|
||||
@@ -9,6 +9,7 @@
|
||||
@@ -19,7 +19,7 @@ index 5769ced..c5d3088 100644
|
||||
}
|
||||
|
||||
diff --git a/applications/settings/notification_settings/notification_settings_app.c b/applications/settings/notification_settings/notification_settings_app.c
|
||||
index 1955012..19d953d 100644
|
||||
index 2a1d988..dda86f3 100644
|
||||
--- a/applications/settings/notification_settings/notification_settings_app.c
|
||||
+++ b/applications/settings/notification_settings/notification_settings_app.c
|
||||
@@ -3,6 +3,7 @@
|
||||
@@ -30,16 +30,16 @@ index 1955012..19d953d 100644
|
||||
|
||||
#define MAX_NOTIFICATION_SETTINGS 4
|
||||
|
||||
@@ -20,6 +21,8 @@ static const NotificationSequence sequence_note_c = {
|
||||
NULL,
|
||||
};
|
||||
@@ -13,6 +14,8 @@ typedef struct {
|
||||
VariableItemList* variable_item_list;
|
||||
} NotificationAppSettings;
|
||||
|
||||
+static VariableItem* temp_item;
|
||||
+
|
||||
#define CONTRAST_COUNT 11
|
||||
const char* const contrast_text[CONTRAST_COUNT] = {
|
||||
"-5",
|
||||
@@ -156,6 +159,59 @@ static void vibro_changed(VariableItem* item) {
|
||||
static const NotificationSequence sequence_note_c = {
|
||||
&message_note_c5,
|
||||
&message_delay_100,
|
||||
@@ -168,6 +171,59 @@ static void vibro_changed(VariableItem* item) {
|
||||
notification_message(app->notification, &sequence_single_vibro);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ index 1955012..19d953d 100644
|
||||
static uint32_t notification_app_settings_exit(void* context) {
|
||||
UNUSED(context);
|
||||
return VIEW_NONE;
|
||||
@@ -180,8 +236,40 @@ static NotificationAppSettings* alloc_settings() {
|
||||
@@ -192,8 +248,40 @@ static NotificationAppSettings* alloc_settings() {
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, contrast_text[value_index]);
|
||||
|
||||
@@ -462,54 +462,6 @@ index 0000000..68dacda
|
||||
+ */
|
||||
+const char* rgb_backlight_get_color_text(uint8_t index);
|
||||
\ No newline at end of file
|
||||
diff --git a/targets/f7/furi_hal/furi_hal_light.c b/targets/f7/furi_hal/furi_hal_light.c
|
||||
index 83e1603..45798ca 100644
|
||||
--- a/targets/f7/furi_hal/furi_hal_light.c
|
||||
+++ b/targets/f7/furi_hal/furi_hal_light.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <furi_hal_light.h>
|
||||
#include <lp5562.h>
|
||||
#include <stdint.h>
|
||||
+#include <applications/settings/notification_settings/rgb_backlight.h>
|
||||
|
||||
#define LED_CURRENT_RED 50
|
||||
#define LED_CURRENT_GREEN 50
|
||||
@@ -31,22 +32,21 @@ void furi_hal_light_init() {
|
||||
}
|
||||
|
||||
void furi_hal_light_set(Light light, uint8_t value) {
|
||||
- furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
- if(light & LightRed) {
|
||||
- lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value);
|
||||
- }
|
||||
- if(light & LightGreen) {
|
||||
- lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value);
|
||||
- }
|
||||
- if(light & LightBlue) {
|
||||
- lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value);
|
||||
- }
|
||||
if(light & LightBacklight) {
|
||||
- uint8_t prev = lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite);
|
||||
- lp5562_execute_ramp(
|
||||
- &furi_hal_i2c_handle_power, LP5562Engine1, LP5562ChannelWhite, prev, value, 100);
|
||||
+ rgb_backlight_update(value, false);
|
||||
+ } else {
|
||||
+ furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
+ if(light & LightRed) {
|
||||
+ lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value);
|
||||
+ }
|
||||
+ if(light & LightGreen) {
|
||||
+ lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value);
|
||||
+ }
|
||||
+ if(light & LightBlue) {
|
||||
+ lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value);
|
||||
+ }
|
||||
+ furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||
}
|
||||
- furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||
}
|
||||
|
||||
void furi_hal_light_blink_start(Light light, uint8_t brightness, uint16_t on_time, uint16_t period) {
|
||||
diff --git a/lib/drivers/SK6805.c b/lib/drivers/SK6805.c
|
||||
new file mode 100644
|
||||
index 0000000..572e1df
|
||||
@@ -575,7 +527,7 @@ index 0000000..572e1df
|
||||
+
|
||||
+void SK6805_update(void) {
|
||||
+ SK6805_init();
|
||||
+ furi_kernel_lock();
|
||||
+ FURI_CRITICAL_ENTER();
|
||||
+ uint32_t end;
|
||||
+ /* Последовательная отправка цветов светодиодов */
|
||||
+ for(uint8_t lednumber = 0; lednumber < SK6805_LED_COUNT; lednumber++) {
|
||||
@@ -615,7 +567,7 @@ index 0000000..572e1df
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ furi_kernel_unlock();
|
||||
+ FURI_CRITICAL_EXIT();
|
||||
+}
|
||||
diff --git a/lib/drivers/SK6805.h b/lib/drivers/SK6805.h
|
||||
new file mode 100644
|
||||
@@ -675,3 +627,51 @@ index 0000000..7c58956
|
||||
+
|
||||
+#endif /* SK6805_H_ */
|
||||
\ No newline at end of file
|
||||
diff --git a/targets/f7/furi_hal/furi_hal_light.c b/targets/f7/furi_hal/furi_hal_light.c
|
||||
index 83e1603..45798ca 100644
|
||||
--- a/targets/f7/furi_hal/furi_hal_light.c
|
||||
+++ b/targets/f7/furi_hal/furi_hal_light.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <furi_hal_light.h>
|
||||
#include <lp5562.h>
|
||||
#include <stdint.h>
|
||||
+#include <applications/settings/notification_settings/rgb_backlight.h>
|
||||
|
||||
#define LED_CURRENT_RED (50u)
|
||||
#define LED_CURRENT_GREEN (50u)
|
||||
@@ -31,22 +32,21 @@ void furi_hal_light_init(void) {
|
||||
}
|
||||
|
||||
void furi_hal_light_set(Light light, uint8_t value) {
|
||||
- furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
- if(light & LightRed) {
|
||||
- lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value);
|
||||
- }
|
||||
- if(light & LightGreen) {
|
||||
- lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value);
|
||||
- }
|
||||
- if(light & LightBlue) {
|
||||
- lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value);
|
||||
- }
|
||||
if(light & LightBacklight) {
|
||||
- uint8_t prev = lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite);
|
||||
- lp5562_execute_ramp(
|
||||
- &furi_hal_i2c_handle_power, LP5562Engine1, LP5562ChannelWhite, prev, value, 100);
|
||||
+ rgb_backlight_update(value, false);
|
||||
+ } else {
|
||||
+ furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
+ if(light & LightRed) {
|
||||
+ lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value);
|
||||
+ }
|
||||
+ if(light & LightGreen) {
|
||||
+ lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value);
|
||||
+ }
|
||||
+ if(light & LightBlue) {
|
||||
+ lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value);
|
||||
+ }
|
||||
+ furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||
}
|
||||
- furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||
}
|
||||
|
||||
void furi_hal_light_blink_start(Light light, uint8_t brightness, uint16_t on_time, uint16_t period) {
|
||||
|
||||
@@ -375,7 +375,7 @@ trigger:
|
||||
- tag
|
||||
|
||||
node:
|
||||
typ: haupt
|
||||
typ: dev1
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
@@ -678,4 +678,4 @@ trigger:
|
||||
- push
|
||||
|
||||
node:
|
||||
typ: haupt
|
||||
typ: dev1
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# MLib macros we can't do much about.
|
||||
//-V:M_LET:1048,1044
|
||||
//-V:M_EACH:1048,1044
|
||||
//-V:ARRAY_DEF:760,747,568,776,729,712,654
|
||||
//-V:LIST_DEF:760,747,568,712,729,654,776
|
||||
//-V:ARRAY_DEF:760,747,568,776,729,712,654,1103
|
||||
//-V:LIST_DEF:760,747,568,712,729,654,776,1103
|
||||
//-V:BPTREE_DEF2:779,1086,557,773,512
|
||||
//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685
|
||||
//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685,1103
|
||||
//-V:ALGO_DEF:1048,747,1044
|
||||
//-V:TUPLE_DEF2:524,590,1001,760
|
||||
|
||||
@@ -42,8 +42,5 @@
|
||||
# Model-related warnings
|
||||
//-V:with_view_model:1044,1048
|
||||
|
||||
# Functions that always return the same error code
|
||||
//-V:picopass_device_decrypt:1048
|
||||
|
||||
# Examples
|
||||
//V_EXCLUDE_PATH applications/examples/
|
||||
@@ -1 +1 @@
|
||||
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/*
|
||||
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e lib/mjs -e */arm-none-eabi/*
|
||||
|
||||
2
.vscode/ReadMe.md
vendored
2
.vscode/ReadMe.md
vendored
@@ -1,4 +1,4 @@
|
||||
# Visual Studio Code workspace for Flipper Zero
|
||||
# Visual Studio Code workspace for Flipper Zero {#vscode}
|
||||
|
||||
## Setup
|
||||
|
||||
|
||||
5
.vscode/example/clangd/extensions.json
vendored
5
.vscode/example/clangd/extensions.json
vendored
@@ -8,7 +8,8 @@
|
||||
"amiralizadeh9480.cpp-helper",
|
||||
"marus25.cortex-debug",
|
||||
"zxh404.vscode-proto3",
|
||||
"augustocdias.tasks-shell-input"
|
||||
"augustocdias.tasks-shell-input",
|
||||
"rioj7.command-variable"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": [
|
||||
@@ -16,4 +17,4 @@
|
||||
"ms-vscode.cpptools",
|
||||
"ms-vscode.cmake-tools"
|
||||
]
|
||||
}
|
||||
}
|
||||
21
.vscode/example/cpptools/c_cpp_properties.json
vendored
21
.vscode/example/cpptools/c_cpp_properties.json
vendored
@@ -2,30 +2,27 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"compilerPath": "${workspaceFolder}/toolchain/x86_64-windows/bin/arm-none-eabi-gcc.exe",
|
||||
"compilerPath": "${workspaceFolder}/toolchain/current/bin/arm-none-eabi-gcc.exe",
|
||||
"intelliSenseMode": "gcc-arm",
|
||||
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cpptools",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "c++17"
|
||||
"cStandard": "gnu23",
|
||||
"cppStandard": "c++20"
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"compilerPath": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gcc",
|
||||
"compilerPath": "${workspaceFolder}/toolchain/current/bin/arm-none-eabi-gcc",
|
||||
"intelliSenseMode": "gcc-arm",
|
||||
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cpptools",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "c++17"
|
||||
"cStandard": "gnu23",
|
||||
"cppStandard": "c++20"
|
||||
},
|
||||
{
|
||||
"name": "Mac",
|
||||
"compilerPath": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gcc",
|
||||
"compilerPath": "${workspaceFolder}/toolchain/current/bin/arm-none-eabi-gcc",
|
||||
"intelliSenseMode": "gcc-arm",
|
||||
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cpptools",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "c++17"
|
||||
"cStandard": "gnu23",
|
||||
"cppStandard": "c++20"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
||||
18
.vscode/example/settings.json
vendored
18
.vscode/example/settings.json
vendored
@@ -1,26 +1,20 @@
|
||||
{
|
||||
"C_Cpp.default.cStandard": "gnu17",
|
||||
"C_Cpp.default.cppStandard": "c++17",
|
||||
"C_Cpp.default.cStandard": "gnu23",
|
||||
"C_Cpp.default.cppStandard": "c++20",
|
||||
"python.formatting.provider": "black",
|
||||
"workbench.tree.indent": 12,
|
||||
"cortex-debug.enableTelemetry": false,
|
||||
"cortex-debug.variableUseNaturalFormat": true,
|
||||
"cortex-debug.showRTOS": true,
|
||||
"cortex-debug.armToolchainPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/bin",
|
||||
"cortex-debug.armToolchainPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin",
|
||||
"cortex-debug.armToolchainPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin",
|
||||
"cortex-debug.openocdPath.windows": "${workspaceFolder}/toolchain/x86_64-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/x86_64-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",
|
||||
"cortex-debug.armToolchainPath": "${workspaceFolder}/toolchain/current/bin",
|
||||
"cortex-debug.openocdPath": "${workspaceFolder}/toolchain/current/bin/openocd",
|
||||
"cortex-debug.gdbPath": "${workspaceFolder}/toolchain/current/bin/arm-none-eabi-gdb-py3",
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
"*.scons": "python",
|
||||
"SConscript": "python",
|
||||
"SConstruct": "python",
|
||||
"*.fam": "python",
|
||||
"*.fam": "python"
|
||||
},
|
||||
"clangd.arguments": [
|
||||
// We might be able to tighten this a bit more to only include the correct toolchain.
|
||||
|
||||
2
.vscode/example/tasks.json
vendored
2
.vscode/example/tasks.json
vendored
@@ -91,7 +91,7 @@
|
||||
"label": "[Debug:unit_tests] Flash (USB)",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt FIRMWARE_APP_SET=unit_tests FORCE=1 flash_usb"
|
||||
"command": "./fbt FIRMWARE_APP_SET=unit_tests FORCE=1 flash_usb_full"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Flash (USB, with resources)",
|
||||
|
||||
85
CHANGELOG.md
85
CHANGELOG.md
@@ -1,21 +1,75 @@
|
||||
## New changes
|
||||
* LF RFID: Write T5577 with random password added (clear password via Extra actions) (by @Leptopt1los)
|
||||
* NFC: Add NFC NDEF parser (by @Willy-JL)
|
||||
* LFRFID: **Electra intercom protocol support** (Romania) (by @Leptopt1los | PR #750)
|
||||
* NFC: Temp fix for `iso14443_4_layer_decode_block` crash
|
||||
* NFC: CharlieCard parser (by @zacharyweiss)
|
||||
* SubGHz: FAAC RC XT - add 0xB button code on arrow buttons for programming mode
|
||||
* SubGHz: Add Manually - Sommer FM fixes
|
||||
* SubGHz: Enabled tx-rx state on unused gpio pin by default (**external amp option was removed and is enabled by default now**)
|
||||
* SubGHz: **Status output !TX/RX on the GDO2 CC1101 pin** (by @quen0n | PR #742)
|
||||
* SubGHz: Reworked saved settings (by @xMasterX and @Willy-JL)
|
||||
* Desktop: Fixes for animation unload (by @Willy-JL)
|
||||
* iButton: Updated DS1420 for latest ibutton changes
|
||||
* Misc: Allow no prefix usage of name_generator_make_detailed_datetime
|
||||
* Misc: Allow setting view dispatcher callbacks to NULL
|
||||
* Misc: Added `void` due to `-Wstrict-prototypes`
|
||||
* Misc: Some code cleanup and proper log levels in nfc parsers
|
||||
* Infrared: Allow external apps to use infrared settings (by @Willy-JL)
|
||||
* JS & HAL: Various fixes and FURI_HAL_RANDOM_MAX define added (by @Willy-JL)
|
||||
* JS: **BadUSB layout support** (by @Willy-JL)
|
||||
* JS: New Modules `widget`, `vgm` and path globals (by @jamisonderek)
|
||||
* Apps: Enhance Random Interval and Movement Functionality in HID Mouse Jiggler for Improved Stealth and Human-Like Behavior (by @gushmazuko | PR #746)
|
||||
* Apps: NFC Magic - **Gen2 writing support, Gen4 NTAG password and PACK fixes** (by @Astrrra)
|
||||
* Apps: MFKey - **fixed crashes**, add more free ram (by @noproto & @Willy-JL)
|
||||
* Apps: **Check out Apps updates by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev)
|
||||
* OFW: assets: checking limits on image size; ufbt: cdb target
|
||||
* OFW: NFC: system dict skip when user dict is skipped fix (replaces our fix)
|
||||
* OFW: FuriHal: fix start duration furi_hal_subghz_async_tx
|
||||
* OFW: NFC: parsers minor cleanup
|
||||
* OFW: NFC Ntag success write freeze when not saved card
|
||||
* OFW: ufbt: fixed generated project paths on Windows
|
||||
* OFW PR 3616: NFC: Mf Desfire fix reading big files (by gornekich)
|
||||
* OFW: iButton: fix crash when deleting some keys
|
||||
* OFW: Desktop: cleanup error popups
|
||||
* OFW: Troika parser visual fixes
|
||||
* OFW: Fix the retry/exit confirmation prompts in iButton
|
||||
* OFW: nfc app: add legacy keys for plantain cards
|
||||
* OFW: GUI: Fix array out of bounds in menu exit
|
||||
* OFW: add support for S(WTX) request in iso14443_4a_poller
|
||||
* OFW: Mosgortrans parser output fixes
|
||||
* OFW: BLE: Add GapPairingNone support
|
||||
* OFW: iButton new UI
|
||||
* OFW: FuriHal: add ADC API
|
||||
* OFW: Mf Desfire multiple file rights support
|
||||
* OFW: **Felica poller** (NFC-F)
|
||||
* OFW: Desktop/Loader: Unload animations before loading FAPs
|
||||
* OFW: JS Documentation
|
||||
* OFW: **Update radio stack to v1.19.0**
|
||||
* OFW: **Move crypto1 to helpers, add it to the public API**
|
||||
* OFW: Explain RNG differences, add FURI_HAL_RANDOM_MAX
|
||||
* OFW: Furi: Add "out of memory" and "malloc(0)" crash messages
|
||||
* OFW: IR: Fix crash on duty_cycle=1
|
||||
* OFW: **Desktop: ensure that animation is unloaded before app start (fixes some out of memory crashes)**
|
||||
* OFW: Hide unlock with reader for MFU-C
|
||||
* OFW: fbt: fixed missing FBT_FAP_DEBUG_ELF_ROOT to dist env
|
||||
* OFW: fbt: added -Wstrict-prototypes for main firmware
|
||||
* OFW: Mifare Ultralight naming fix
|
||||
* OFW: IR: Remember OTG state
|
||||
* OFW: Bad USB: fix crash when selecting a keyboard layout
|
||||
* OFW: L1_Mods animation update : adding VGM visual
|
||||
* OFW: RFID Improvements
|
||||
* OFW: Fixed plugins and UI
|
||||
* OFW: **NFC: Fix mf desfire detect**
|
||||
* OFW: infrared_transmit.h was missing `#pragma once`
|
||||
* OFW: Show the wrong PIN Attempt count on the login screen
|
||||
* OFW: SavedStruct: Introduce saved_struct_get_metadata
|
||||
* OFW: JS CLI command
|
||||
* OFW: Add ChromeOS Bad USB demo
|
||||
* OFW: **Configurable Infrared TX output** (previous UL version is replaced with OFW version, new features added "AutoDetect" and saving settings)
|
||||
* OFW: BadUSB: BLE, media keys, Fn/Globe key commands
|
||||
* OFW: NFC: Slix privacy password reveal ->(was included in previous UL release) and **Desfire detect fix**
|
||||
* OFW: github: additional pre-upload checks for doxygen workflow
|
||||
* OFW: NFC UI fixes
|
||||
* OFW: Gui: unicode support, new canvas API
|
||||
* OFW: **Api Symbols: replace asserts with checks**
|
||||
<br><br>
|
||||
#### Known NFC post-refactor regressions list:
|
||||
- Mifare Mini clones reading is broken (original mini working fine) (OFW)
|
||||
- EMV simple data parser was removed with protocol with refactoring (OFW)
|
||||
- Option to unlock Slix-L (NFC V) with preset or custom password was removed with refactoring (OFW)
|
||||
- NFC CLI was removed with refactoring (OFW)
|
||||
- Current list of affected apps: https://github.com/xMasterX/all-the-plugins/tree/dev/apps_broken_by_last_refactors
|
||||
- Also in app **Enhanced Sub-GHz Chat** - NFC part was temporarily removed to make app usable, NFC part of the app requires remaking it with new nfc stack
|
||||
- NFC CLI was removed with refactoring (OFW) (will be back soon)
|
||||
- Mifare Nested not ported to latest API yet, `unlshd-065` is the latest version on old NFC API that works with "nested app"
|
||||
|
||||
----
|
||||
|
||||
@@ -31,13 +85,14 @@
|
||||
|cloudtips|only RU payments accepted|https://pay.cloudtips.ru/p/7b3e9d65|
|
||||
|YooMoney|only RU payments accepted|https://yoomoney.ru/fundraise/XA49mgQLPA0.221209|
|
||||
|USDT|(TRC20)|`TSXcitMSnWXUFqiUfEXrTVpVewXy2cYhrs`|
|
||||
|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`|
|
||||
|ETH|(BSC/ERC20-Tokens)|`darkflippers.eth` (or `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`)|
|
||||
|BTC||`bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`|
|
||||
|SOL|(Solana/Tokens)|`DSgwouAEgu8iP5yr7EHHDqMNYWZxAqXWsTEeqCAXGLj8`|
|
||||
|DOGE||`D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`|
|
||||
|LTC||`ltc1q3ex4ejkl0xpx3znwrmth4lyuadr5qgv8tmq8z9`|
|
||||
|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`|
|
||||
|XMR|(Monero)| `41xUz92suUu1u5Mu4qkrcs52gtfpu9rnZRdBpCJ244KRHf6xXSvVFevdf2cnjS7RAeYr5hn9MsEfxKoFDRSctFjG5fv1Mhn`|
|
||||
|TON||`EQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmpGf`|
|
||||
|TON||`UQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmsxa`|
|
||||
|
||||
#### Thanks to our sponsors who supported project in the past and special thanks to sponsors who supports us on regular basis:
|
||||
ClaraCrazy, Pathfinder [Count Zero cDc], callmezimbra, Quen0n, MERRON, grvpvl (lvpvrg), art_col, ThurstonWaffles, Moneron, UterGrooll, LUCFER, Northpirate, zloepuzo, T.Rat, Alexey B., ionelife, ...
|
||||
|
||||
72
ReadMe.md
72
ReadMe.md
@@ -1,6 +1,6 @@
|
||||
<h3 align="center">
|
||||
<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">
|
||||
<img src="https://user-images.githubusercontent.com/10697207/186202043-26947e28-b1cc-459a-8f20-ffcc7fc0c71c.png" align="center" alt="Unleashed Firmware Logo" border="0">
|
||||
</a>
|
||||
</h3>
|
||||
<div align="center" id="badges">
|
||||
@@ -20,15 +20,15 @@
|
||||
|
||||
### Welcome to the Flipper Zero Unleashed Firmware repo!
|
||||
|
||||
#### **This firmware is a fork from** [flipperdevices/flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware)
|
||||
#### **This firmware is a fork from original (OFW) firmware** [flipperdevices/flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware)
|
||||
|
||||
<br>
|
||||
|
||||
### Most stable custom firmware focused on new features and improvements of original firmware components, with almost no UI changes
|
||||
### Most stable custom firmware focused on new features and improvements of original firmware components, keeping compatibility with original firmware API and Apps
|
||||
|
||||
<br>
|
||||
|
||||
##### This software is for experimental purposes only and is not meant for any illegal activity/purposes. <br> We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law. <br> Also, this software is made without any support from Flipper Devices and is in no way related to the official devs.
|
||||
##### This software is for experimental purposes only and is not meant for any illegal activity/purposes. <br> We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law. <br> Also, this software is made without any support from Flipper Devices and is in no way related to the official team.
|
||||
|
||||
|
||||
<br>
|
||||
@@ -36,7 +36,7 @@
|
||||
## FAQ (frequently asked questions)
|
||||
[Follow this link to find answers to most asked questions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/FAQ.md)
|
||||
|
||||
## Dev builds (unstable)
|
||||
## Dev builds (unstable) (built automatically from dev branch)
|
||||
- https://dev.unleashedflip.com/
|
||||
- https://t.me/kotnehleb
|
||||
## Releases in Telegram
|
||||
@@ -45,23 +45,24 @@
|
||||
# What's changed
|
||||
- **Sub-GHz** *lib & hal*
|
||||
- Regional TX restrictions removed
|
||||
- Extra Sub-GHz frequencies
|
||||
- Extra Sub-GHz frequencies added
|
||||
- Frequency range can be extended in settings file (Warning: It can damage Flipper's hardware)
|
||||
- Many rolling code [protocols](https://github.com/DarkFlippers/unleashed-firmware#current-modified-and-new-sub-ghz-protocols-list) now have the ability to save & send captured signals
|
||||
- FAAC SLH (Spa) & BFT Mitto (keeloq secure with seed) manual creation
|
||||
- External CC1101 module support [(by quen0n)](https://github.com/DarkFlippers/unleashed-firmware/pull/307)
|
||||
- **Sub-GHz** *Main App*
|
||||
- Save last used frequency [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
|
||||
- Save last used settings [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
|
||||
- New frequency analyzer [(by ClusterM)](https://github.com/DarkFlippers/unleashed-firmware/pull/43)
|
||||
- Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
|
||||
- Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79)
|
||||
- New option to use timestamps + protocol name when you saving file, instead of random name or timestamp only - Enable in `Radio Settings -> Protocol Names = ON`
|
||||
- Read mode UI improvements (shows time when signal was received) (by @wosk)
|
||||
- External CC1101 module support (Hardware SPI used)
|
||||
- External CC1101 module amplifier control (or LED control) support (enabled by default)
|
||||
- **Hold right in received signal list to delete selected signal**
|
||||
- **Custom buttons for Keeloq / Alutech AT4N / Nice Flor S / Somfy Telis / Security+ 2.0 / CAME Atomo** - now you can use arrow buttons to send signal with different button code
|
||||
- `Add manually` menu extended with new protocols
|
||||
- FAAC SLH, BFT Mitto / Somfy Telis / Nice Flor S / CAME Atomo, etc.. manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis)
|
||||
- FAAC SLH, BFT Mitto / Somfy Telis / Nice Flor S / CAME Atomo, etc.. manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis, (right arrow button for other protocols))
|
||||
- Debug mode counter increase settings (+1 -> +5, +10, default: +1)
|
||||
- Debug PIN output settings for protocol development
|
||||
|
||||
@@ -75,22 +76,22 @@
|
||||
- Recompiled IR TV Universal Remote for ALL buttons
|
||||
- Universal remotes for Projectors, Fans, A/Cs and Audio(soundbars, etc.) -> Also always updated and verified by our team
|
||||
- Infrared -> `RCA` Protocol
|
||||
- Infrared -> Debug TX PIN output settings
|
||||
- Infrared -> External IR modules support (with autodetect by OFW)
|
||||
- **NFC/RFID/iButton**
|
||||
* LFRFID/iButton Fuzzer plugins
|
||||
* Extra Mifare Classic keys
|
||||
* LFRFID and iButton Fuzzer plugins
|
||||
* Extra Mifare Classic keys in system dict
|
||||
* EMV Protocol + Public data parser (by @Leptopt1los and @wosk)
|
||||
* NFC `Add manually` -> Mifare Classic with custom UID
|
||||
* NFC parsers: Umarsh, Zolotaya Korona, Kazan, Metromoney, Moscow Social Card, Troika (reworked) and [many others](https://github.com/DarkFlippers/unleashed-firmware/tree/dev/applications/main/nfc/plugins/supported_cards)
|
||||
* Picopass/iClass plugin (now with emulation support!) included in releases
|
||||
* NFC parsers: Umarsh, Zolotaya Korona, Kazan, Metromoney, Moscow Social Card, Troika (reworked) and [many others](https://github.com/DarkFlippers/unleashed-firmware/tree/dev/applications/main/nfc/plugins/supported_cards) (by @Leptopt1los and @assasinfil)
|
||||
- **Quality of life & other features**
|
||||
- Customizable Flipper name **Update! Now can be changed in Settings->Desktop** (by @xMasterX and @Willy-JL)
|
||||
- Text Input UI element -> Cursor feature (by @Willy-JL)
|
||||
- Byte Input Mini editor -> **Press UP** multiple times until the nibble editor appears
|
||||
- Clock on Desktop -> `Settings -> Desktop -> Show Clock`
|
||||
- Byte Input Mini editor -> **Press UP** multiple times until the nibble editor appears (by @gid9798)
|
||||
- Clock on Desktop -> `Settings -> Desktop -> Show Clock` (by @gid9798)
|
||||
- Battery percentage display with different styles `Settings -> Desktop -> Battery View`
|
||||
- More games in Dummy Mode -> click or hold any of arrow buttons
|
||||
- Lock device with pin(or regular lock if pin not set) by holding UP button on main screen [(by an4tur0r)](https://github.com/DarkFlippers/unleashed-firmware/pull/107)
|
||||
- **BadBT** plugin (BT version of BadKB) [(by Willy-JL, ClaraCrazy, XFW contributors)](https://github.com/ClaraCrazy/Flipper-Xtreme/tree/dev/applications/main/bad_kb) - (See in Applications->Tools) - (aka BadUSB via Bluetooth)
|
||||
- **BadKB** plugin [(by Willy-JL, ClaraCrazy, XFW contributors)](https://github.com/Flipper-XFW/Xtreme-Firmware/tree/dev/applications/main/bad_kb) - (See in Applications->Tools) - (aka BadUSB via Bluetooth)
|
||||
- BadUSB -> Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout)
|
||||
- Custom community plugins and games added + all known working apps can be downloaded in extra pack in every release
|
||||
- Other small fixes and changes throughout
|
||||
@@ -99,16 +100,16 @@
|
||||
Also check the [changelog in releases](https://github.com/DarkFlippers/unleashed-firmware/releases) for latest updates!
|
||||
|
||||
### Current modified and new Sub-GHz protocols list:
|
||||
Thanks to Official team (to their SubGHz Developer, Skorp) for implementing decoders for these protocols in OFW.
|
||||
Thanks to Official team (to their SubGHz Developer, Skorp) for implementing support (decoder + encoder / or decode only) for these protocols in OFW.
|
||||
|
||||
Keeloq [Not ALL systems supported for decode or emulation!] - [Supported manufacturers list](https://pastes.io/raw/unuj9bhe4m)
|
||||
|
||||
Encoders or sending made by @xMasterX:
|
||||
- Nero Radio 57bit (+ 56bit encoder improvements)
|
||||
- CAME 12bit/24bit encoder fixes (Fixes now merged in OFW)
|
||||
- Keeloq: HCS101, AN-Motors, JCM Tech, MHouse, Nice Smilo, DTM Neo, FAAC RC,XT, Mutancode, Normstahl, Beninca + Allmatic, Stilmatic, CAME Space, Aprimatic (model TR and similar), Centurion Nova (thanks Carlos !)
|
||||
Encoders or emulation support made by @xMasterX:
|
||||
- Nero Radio 57bit (+ 56bit support)
|
||||
- CAME 12bit/24bit encoder fixes (Fixes are now merged in OFW)
|
||||
- Keeloq: Dea Mio, Genius Bravo, GSN, HCS101, AN-Motors, JCM Tech, MHouse, Nice Smilo, DTM Neo, FAAC RC,XT, Mutancode, Normstahl, Beninca + Allmatic, Stilmatic, CAME Space, Aprimatic (model TR and similar), Centurion Nova (thanks Carlos !)
|
||||
|
||||
Encoders or sending made by @Eng1n33r(first implementation in Q2 2022) & @xMasterX (current version):
|
||||
Encoders or emulation made by @Eng1n33r(first implementation in Q2 2022) and @xMasterX (current version):
|
||||
- CAME Atomo -> Update! check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
- Nice Flor S -> How to create new remote - [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
- FAAC SLH (Spa) -> Update!!! Check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
@@ -116,7 +117,7 @@ Encoders or sending made by @Eng1n33r(first implementation in Q2 2022) & @xMaste
|
||||
- Star Line
|
||||
- Security+ v1 & v2 (encoders was made in OFW)
|
||||
|
||||
Encoders made by @assasinfil & @xMasterX:
|
||||
Encoders made by @assasinfil and @xMasterX:
|
||||
- Somfy Telis -> How to create new remote - [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
- Somfy Keytis
|
||||
- KingGates Stylo 4k
|
||||
@@ -125,12 +126,12 @@ Encoders made by @assasinfil & @xMasterX:
|
||||
|
||||
## Please support development of the project
|
||||
The majority of this project is developed and maintained by me, @xMasterX.
|
||||
I'm unemployed, and the only income I receive is from your donations.
|
||||
Our team is small and the guys are working on this project as much as they can solely based on the enthusiasm they have for this project and the community.
|
||||
- @gid9798 - SubGHz, Plugins, many other things
|
||||
- @assasinfil - SubGHz protocols, NFC parsers (working with @Leptopt1los)
|
||||
- @Leptopt1los - NFC, RFID, Plugins, and many other things
|
||||
- @gid9798 - SubGHz, Plugins, many other things - currently offline :(
|
||||
- @assasinfil - SubGHz protocols, NFC parsers
|
||||
- @Svaarich - UI design and animations
|
||||
- @amec0e & @Leptopt1los (only ACs) - Infrared assets
|
||||
- @amec0e - Infrared assets
|
||||
- Community moderators in Telegram, Discord, and Reddit
|
||||
- And of course our GitHub community. Your PRs are a very important part of this firmware and open-source development.
|
||||
|
||||
@@ -144,13 +145,14 @@ You can support us by using links or addresses below:
|
||||
|cloudtips|only RU payments accepted|https://pay.cloudtips.ru/p/7b3e9d65|
|
||||
|YooMoney|only RU payments accepted|https://yoomoney.ru/fundraise/XA49mgQLPA0.221209|
|
||||
|USDT|(TRC20)|`TSXcitMSnWXUFqiUfEXrTVpVewXy2cYhrs`|
|
||||
|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`|
|
||||
|ETH|(BSC/ERC20-Tokens)|`darkflippers.eth` (or `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`)|
|
||||
|BTC||`bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`|
|
||||
|SOL|(Solana/Tokens)|`DSgwouAEgu8iP5yr7EHHDqMNYWZxAqXWsTEeqCAXGLj8`|
|
||||
|DOGE||`D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`|
|
||||
|LTC||`ltc1q3ex4ejkl0xpx3znwrmth4lyuadr5qgv8tmq8z9`|
|
||||
|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`|
|
||||
|XMR|(Monero)| `41xUz92suUu1u5Mu4qkrcs52gtfpu9rnZRdBpCJ244KRHf6xXSvVFevdf2cnjS7RAeYr5hn9MsEfxKoFDRSctFjG5fv1Mhn`|
|
||||
|TON||`EQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmpGf`|
|
||||
|TON||`UQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmsxa`|
|
||||
|
||||
## Community apps included
|
||||
|
||||
@@ -166,6 +168,8 @@ See full list and sources here: [xMasterX/all-the-plugins](https://github.com/xM
|
||||
## [How to install](/documentation/HowToInstall.md) - [versions info](/CHANGELOG.md#recommended-update-option---web-updater): `n`,` `,`e`...
|
||||
## Firmware & Development
|
||||
|
||||
### - **Developer Documentation** - [developer.flipper.net](https://developer.flipper.net/flipperzero/doxygen)
|
||||
|
||||
### - **[How to build](/documentation/HowToBuild.md#how-to-build-by-yourself) | [Project-structure](#project-structure)**
|
||||
|
||||
### - **CLion IDE** - How to setup workspace for flipper firmware development [by Savely Krasovsky](https://krasovs.ky/2022/11/01/flipper-zero-clion.html)
|
||||
@@ -184,22 +188,20 @@ See full list and sources here: [xMasterX/all-the-plugins](https://github.com/xM
|
||||
|
||||
## **Sub-GHz**
|
||||
|
||||
### - [How to use Flipper as new remote (Nice FlorS, BFT Mitto, Somfy Telis, Aprimatic, AN-Motors, etc..)](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
|
||||
### - External Radio: [How to connect CC1101 module](https://github.com/quen0n/flipperzero-ext-cc1101)
|
||||
|
||||
### - Transmission is blocked? [How to extend Sub-GHz frequency range](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/DangerousSettings.md)
|
||||
|
||||
### - [How to add extra Sub-GHz frequencies](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md)
|
||||
|
||||
### - [How to use Flipper as new remote (Nice FlorS, BFT Mitto, Somfy Telis, Aprimatic, AN-Motors, etc..)](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
|
||||
### - [~~Configure Sub-GHz Remote App~~](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemotePlugin.md) Not recomeded, please use embedded configurator
|
||||
### - [~~Configure Sub-GHz Remote App~~](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemotePlugin.md) Not recommended, please use embedded configurator
|
||||
|
||||
## **Plugins**
|
||||
|
||||
### - TOTP (Authenticator): [config description](https://github.com/akopachov/flipper-zero_authenticator/blob/master/docs/conf-file_description.md)
|
||||
|
||||
### - Mifare Nested plugin: [How to recover keys](https://github.com/AloneLiberty/FlipperNested#how-to-use-it)
|
||||
|
||||
### - Barcode Generator: [How to use](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/BarcodeGenerator.md)
|
||||
|
||||
### - Multi Converter: [How to use](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/MultiConverter.md)
|
||||
@@ -246,6 +248,8 @@ See full list and sources here: [xMasterX/all-the-plugins](https://github.com/xM
|
||||
* Official Docs: [docs.flipper.net](https://docs.flipper.net/)
|
||||
* Official Forum: [forum.flipperzero.one](https://forum.flipperzero.one/)
|
||||
|
||||
* Update! Developer Documentation [developer.flipper.net](https://developer.flipper.net/flipperzero/doxygen)
|
||||
|
||||
# Project structure
|
||||
|
||||
- `applications` - Applications and services used in firmware
|
||||
|
||||
83
SConstruct
83
SConstruct
@@ -7,7 +7,7 @@
|
||||
# construction of certain targets behind command-line options.
|
||||
|
||||
import os
|
||||
from fbt.util import path_as_posix
|
||||
from fbt.util import open_browser_action
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
|
||||
@@ -42,6 +42,7 @@ distenv = coreenv.Clone(
|
||||
"openocd",
|
||||
"blackmagic",
|
||||
"jflash",
|
||||
"doxygen",
|
||||
],
|
||||
ENV=os.environ,
|
||||
UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
|
||||
@@ -66,6 +67,7 @@ if GetOption("fullenv") or any(
|
||||
|
||||
# Target for self-update package
|
||||
dist_basic_arguments = [
|
||||
"${ARGS}",
|
||||
"--bundlever",
|
||||
"${UPDATE_VERSION_STRING}",
|
||||
]
|
||||
@@ -182,6 +184,7 @@ fap_deploy = distenv.PhonyTarget(
|
||||
"send",
|
||||
"${SOURCE}",
|
||||
"/ext/apps",
|
||||
"${ARGS}",
|
||||
]
|
||||
]
|
||||
),
|
||||
@@ -208,7 +211,7 @@ distenv.Alias("jflash", firmware_jflash)
|
||||
|
||||
distenv.PhonyTarget(
|
||||
"gdb_trace_all",
|
||||
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
|
||||
[["${GDB}", "${GDBOPTS}", "${SOURCES}", "${GDBFLASH}"]],
|
||||
source=firmware_env["FW_ELF"],
|
||||
GDBOPTS="${GDBOPTS_BASE}",
|
||||
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
||||
@@ -227,7 +230,7 @@ firmware_debug = distenv.PhonyTarget(
|
||||
source=firmware_env["FW_ELF"],
|
||||
GDBOPTS="${GDBOPTS_BASE}",
|
||||
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
||||
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
|
||||
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
|
||||
)
|
||||
distenv.Depends(firmware_debug, firmware_flash)
|
||||
|
||||
@@ -237,7 +240,7 @@ distenv.PhonyTarget(
|
||||
source=firmware_env["FW_ELF"],
|
||||
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
||||
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
||||
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
|
||||
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
|
||||
)
|
||||
|
||||
# Debug alien elf
|
||||
@@ -272,19 +275,35 @@ distenv.PhonyTarget(
|
||||
# Just start OpenOCD
|
||||
distenv.PhonyTarget(
|
||||
"openocd",
|
||||
"${OPENOCDCOM}",
|
||||
[["${OPENOCDCOM}", "${ARGS}"]],
|
||||
)
|
||||
|
||||
# Linter
|
||||
distenv.PhonyTarget(
|
||||
"lint",
|
||||
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]],
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${FBT_SCRIPT_DIR}/lint.py",
|
||||
"check",
|
||||
"${LINT_SOURCES}",
|
||||
"${ARGS}",
|
||||
]
|
||||
],
|
||||
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
||||
)
|
||||
|
||||
distenv.PhonyTarget(
|
||||
"format",
|
||||
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]],
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${FBT_SCRIPT_DIR}/lint.py",
|
||||
"format",
|
||||
"${LINT_SOURCES}",
|
||||
"${ARGS}",
|
||||
]
|
||||
],
|
||||
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
|
||||
)
|
||||
|
||||
@@ -307,7 +326,16 @@ firmware_env.Append(
|
||||
)
|
||||
|
||||
|
||||
black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}"
|
||||
black_commandline = [
|
||||
[
|
||||
"@${PYTHON3}",
|
||||
"-m",
|
||||
"black",
|
||||
"${PY_BLACK_ARGS}",
|
||||
"${PY_LINT_SOURCES}",
|
||||
"${ARGS}",
|
||||
]
|
||||
]
|
||||
black_base_args = [
|
||||
"--include",
|
||||
'"(\\.scons|\\.py|SConscript|SConstruct|\\.fam)$"',
|
||||
@@ -333,12 +361,28 @@ distenv.PhonyTarget(
|
||||
|
||||
# Start Flipper CLI via PySerial's miniterm
|
||||
distenv.PhonyTarget(
|
||||
"cli", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]]
|
||||
"cli",
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${FBT_SCRIPT_DIR}/serial_cli.py",
|
||||
"-p",
|
||||
"${FLIP_PORT}",
|
||||
"${ARGS}",
|
||||
]
|
||||
],
|
||||
)
|
||||
|
||||
# Update WiFi devboard firmware
|
||||
# Update WiFi devboard firmware with release channel
|
||||
distenv.PhonyTarget(
|
||||
"devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]]
|
||||
"devboard_flash",
|
||||
[
|
||||
[
|
||||
"${PYTHON3}",
|
||||
"${FBT_SCRIPT_DIR}/wifi_board.py",
|
||||
"${ARGS}",
|
||||
]
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -353,7 +397,7 @@ distenv.PhonyTarget(
|
||||
distenv.PhonyTarget(
|
||||
"get_stlink",
|
||||
distenv.Action(
|
||||
lambda **kw: distenv.GetDevices(),
|
||||
lambda **_: distenv.GetDevices(),
|
||||
None,
|
||||
),
|
||||
)
|
||||
@@ -376,3 +420,18 @@ distenv.PhonyTarget(
|
||||
"env",
|
||||
"@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)",
|
||||
)
|
||||
|
||||
doxy_build = distenv.DoxyBuild(
|
||||
"documentation/doxygen/build/html/index.html",
|
||||
"documentation/doxygen/Doxyfile-awesome.cfg",
|
||||
doxy_env_variables={
|
||||
"DOXY_SRC_ROOT": Dir(".").abspath,
|
||||
"DOXY_BUILD_DIR": Dir("documentation/doxygen/build").abspath,
|
||||
"DOXY_CONFIG_DIR": "documentation/doxygen",
|
||||
},
|
||||
)
|
||||
distenv.Alias("doxygen", doxy_build)
|
||||
distenv.AlwaysBuild(doxy_build)
|
||||
|
||||
# Open generated documentation in browser
|
||||
distenv.PhonyTarget("doxy", open_browser_action, source=doxy_build)
|
||||
|
||||
@@ -71,7 +71,10 @@ Small applications providing configuration for basic firmware and its services.
|
||||
|
||||
## system
|
||||
|
||||
Utility apps not visible in other menus.
|
||||
Utility apps not visible in other menus, plus few external apps pre-packaged with the firmware.
|
||||
|
||||
- `hid_app` - BLE & USB HID remote
|
||||
- `js_app` - JS engine runner
|
||||
- `snake_game` - Snake game
|
||||
- `storage_move_to_sd` - Data migration tool for internal storage
|
||||
- `updater` - Update service & application
|
||||
|
||||
@@ -11,29 +11,29 @@ class AccessorApp {
|
||||
public:
|
||||
void run(void);
|
||||
|
||||
AccessorApp();
|
||||
~AccessorApp();
|
||||
AccessorApp(void);
|
||||
~AccessorApp(void);
|
||||
|
||||
enum class Scene : uint8_t {
|
||||
Exit,
|
||||
Start,
|
||||
};
|
||||
|
||||
AccessorAppViewManager* get_view_manager();
|
||||
AccessorAppViewManager* get_view_manager(void);
|
||||
void switch_to_next_scene(Scene index);
|
||||
void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list);
|
||||
bool switch_to_previous_scene(uint8_t count = 1);
|
||||
Scene get_previous_scene();
|
||||
Scene get_previous_scene(void);
|
||||
|
||||
void notify_green_blink();
|
||||
void notify_success();
|
||||
void notify_green_blink(void);
|
||||
void notify_success(void);
|
||||
|
||||
char* get_text_store();
|
||||
uint8_t get_text_store_size();
|
||||
char* get_text_store(void);
|
||||
uint8_t get_text_store_size(void);
|
||||
void set_text_store(const char* text...);
|
||||
|
||||
WIEGAND* get_wiegand();
|
||||
OneWireHost* get_one_wire();
|
||||
WIEGAND* get_wiegand(void);
|
||||
OneWireHost* get_one_wire(void);
|
||||
|
||||
private:
|
||||
std::list<Scene> previous_scenes_list = {Scene::Exit};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "accessor_view_manager.h"
|
||||
#include "accessor_event.h"
|
||||
#include <callback-connector.h>
|
||||
#include "callback_connector.h"
|
||||
|
||||
AccessorAppViewManager::AccessorAppViewManager() {
|
||||
event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent));
|
||||
|
||||
@@ -15,16 +15,16 @@ public:
|
||||
|
||||
FuriMessageQueue* event_queue;
|
||||
|
||||
AccessorAppViewManager();
|
||||
~AccessorAppViewManager();
|
||||
AccessorAppViewManager(void);
|
||||
~AccessorAppViewManager(void);
|
||||
|
||||
void switch_to(ViewType type);
|
||||
|
||||
void receive_event(AccessorEvent* event);
|
||||
void send_event(AccessorEvent* event);
|
||||
|
||||
Submenu* get_submenu();
|
||||
Popup* get_popup();
|
||||
Submenu* get_submenu(void);
|
||||
Popup* get_popup(void);
|
||||
|
||||
private:
|
||||
ViewDispatcher* view_dispatcher;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#ifndef CALLBACKCONNECTOR_H
|
||||
#define CALLBACKCONNECTOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <functional>
|
||||
namespace cbc {
|
||||
namespace Details {
|
||||
|
||||
template <std::size_t Tag, typename T, typename Ret, typename... Args> class FuncMemberWrapper {
|
||||
template <std::size_t Tag, typename T, typename Ret, typename... Args>
|
||||
class FuncMemberWrapper {
|
||||
public:
|
||||
FuncMemberWrapper() = delete;
|
||||
using member_fun_t = Ret (T::*)(Args...);
|
||||
@@ -43,7 +46,8 @@ template <std::size_t Tag, typename T, typename Ret, typename... Args>
|
||||
typename FuncMemberWrapper<Tag, T, Ret, Args...>::const_member_fun_t
|
||||
FuncMemberWrapper<Tag, T, Ret, Args...>::const_member{};
|
||||
|
||||
template <typename Functor, typename Ret, typename... Args> struct FunctorWrapper {
|
||||
template <typename Functor, typename Ret, typename... Args>
|
||||
struct FunctorWrapper {
|
||||
public:
|
||||
static std::function<Ret(Args...)> functor;
|
||||
static auto instatiate(Functor fn) {
|
||||
@@ -75,7 +79,8 @@ auto const_instantiate(T* t, Ret (T::*ptr)(Args...) const) {
|
||||
return FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
|
||||
}
|
||||
|
||||
template <std::size_t tag, typename T, typename Func> auto const_instantiate(T* t, Func ptr) {
|
||||
template <std::size_t tag, typename T, typename Func>
|
||||
auto const_instantiate(T* t, Func ptr) {
|
||||
return const_instantiate(t, ptr);
|
||||
}
|
||||
|
||||
@@ -91,9 +96,11 @@ auto obtain_connector(T* t, Ret (T::*ptr)(Args...) const) {
|
||||
return Details::FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
|
||||
}
|
||||
|
||||
template <typename Functor> auto obtain_connector(Functor functor) {
|
||||
template <typename Functor>
|
||||
auto obtain_connector(Functor functor) {
|
||||
return Details::deducer(std::move(functor), &Functor::operator());
|
||||
}
|
||||
} //end of cbc scope
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // CALLBACKCONNECTOR_H
|
||||
@@ -2,12 +2,12 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
volatile unsigned long WIEGAND::_cardTempHigh = 0;
|
||||
volatile unsigned long WIEGAND::_cardTemp = 0;
|
||||
volatile unsigned long WIEGAND::_lastWiegand = 0;
|
||||
unsigned long WIEGAND::_cardTempHigh = 0;
|
||||
unsigned long WIEGAND::_cardTemp = 0;
|
||||
unsigned long WIEGAND::_lastWiegand = 0;
|
||||
unsigned long WIEGAND::_code = 0;
|
||||
unsigned long WIEGAND::_codeHigh = 0;
|
||||
volatile int WIEGAND::_bitCount = 0;
|
||||
int WIEGAND::_bitCount = 0;
|
||||
int WIEGAND::_wiegandType = 0;
|
||||
|
||||
constexpr uint32_t clocks_in_ms = 64 * 1000;
|
||||
@@ -98,10 +98,7 @@ void WIEGAND::ReadD1() {
|
||||
_lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received
|
||||
}
|
||||
|
||||
unsigned long WIEGAND::GetCardId(
|
||||
volatile unsigned long* codehigh,
|
||||
volatile unsigned long* codelow,
|
||||
char bitlength) {
|
||||
unsigned long WIEGAND::GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength) {
|
||||
if(bitlength == 26) // EM tag
|
||||
return (*codelow & 0x1FFFFFE) >> 1;
|
||||
|
||||
|
||||
@@ -2,28 +2,26 @@
|
||||
|
||||
class WIEGAND {
|
||||
public:
|
||||
WIEGAND();
|
||||
void begin();
|
||||
void end();
|
||||
bool available();
|
||||
unsigned long getCode();
|
||||
unsigned long getCodeHigh();
|
||||
int getWiegandType();
|
||||
WIEGAND(void);
|
||||
void begin(void);
|
||||
void end(void);
|
||||
bool available(void);
|
||||
unsigned long getCode(void);
|
||||
unsigned long getCodeHigh(void);
|
||||
int getWiegandType(void);
|
||||
|
||||
static void ReadD0();
|
||||
static void ReadD1();
|
||||
static void ReadD0(void);
|
||||
static void ReadD1(void);
|
||||
|
||||
private:
|
||||
static bool DoWiegandConversion();
|
||||
static unsigned long GetCardId(
|
||||
volatile unsigned long* codehigh,
|
||||
volatile unsigned long* codelow,
|
||||
char bitlength);
|
||||
static bool DoWiegandConversion(void);
|
||||
static unsigned long
|
||||
GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength);
|
||||
|
||||
static volatile unsigned long _cardTempHigh;
|
||||
static volatile unsigned long _cardTemp;
|
||||
static volatile unsigned long _lastWiegand;
|
||||
static volatile int _bitCount;
|
||||
static unsigned long _cardTempHigh;
|
||||
static unsigned long _cardTemp;
|
||||
static unsigned long _lastWiegand;
|
||||
static int _bitCount;
|
||||
static int _wiegandType;
|
||||
static unsigned long _code;
|
||||
static unsigned long _codeHigh;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "../accessor_app.h"
|
||||
#include "../accessor_view_manager.h"
|
||||
#include "../accessor_event.h"
|
||||
#include <callback-connector.h>
|
||||
#include "callback_connector.h"
|
||||
#include "accessor_scene_start.h"
|
||||
|
||||
void AccessorSceneStart::on_enter(AccessorApp* app) {
|
||||
|
||||
@@ -12,7 +12,8 @@ void battery_test_dialog_callback(DialogExResult result, void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t battery_test_exit_confirm_view() {
|
||||
uint32_t battery_test_exit_confirm_view(void* context) {
|
||||
UNUSED(context);
|
||||
return BatteryTestAppViewExitDialog;
|
||||
}
|
||||
|
||||
@@ -31,7 +32,7 @@ static void battery_test_battery_info_update_model(void* context) {
|
||||
notification_message(app->notifications, &sequence_display_backlight_on);
|
||||
}
|
||||
|
||||
BatteryTestApp* battery_test_alloc() {
|
||||
BatteryTestApp* battery_test_alloc(void) {
|
||||
BatteryTestApp* app = malloc(sizeof(BatteryTestApp));
|
||||
|
||||
// Records
|
||||
|
||||
@@ -116,7 +116,7 @@ static void battery_info_draw_callback(Canvas* canvas, void* context) {
|
||||
draw_stat(canvas, 104, 42, &I_Health_16x16, health);
|
||||
}
|
||||
|
||||
BatteryInfo* battery_info_alloc() {
|
||||
BatteryInfo* battery_info_alloc(void) {
|
||||
BatteryInfo* battery_info = malloc(sizeof(BatteryInfo));
|
||||
battery_info->view = view_alloc();
|
||||
view_set_context(battery_info->view, battery_info);
|
||||
|
||||
@@ -14,7 +14,7 @@ typedef struct {
|
||||
uint8_t health;
|
||||
} BatteryInfoModel;
|
||||
|
||||
BatteryInfo* battery_info_alloc();
|
||||
BatteryInfo* battery_info_alloc(void);
|
||||
|
||||
void battery_info_free(BatteryInfo* battery_info);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ uint32_t bt_debug_start_view(void* context) {
|
||||
return BtDebugAppViewSubmenu;
|
||||
}
|
||||
|
||||
BtDebugApp* bt_debug_app_alloc() {
|
||||
BtDebugApp* bt_debug_app_alloc(void) {
|
||||
BtDebugApp* app = malloc(sizeof(BtDebugApp));
|
||||
|
||||
// Gui
|
||||
|
||||
@@ -129,7 +129,7 @@ static void bt_test_carrier_timer_callback(void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
BtCarrierTest* bt_carrier_test_alloc() {
|
||||
BtCarrierTest* bt_carrier_test_alloc(void) {
|
||||
BtCarrierTest* bt_carrier_test = malloc(sizeof(BtCarrierTest));
|
||||
bt_carrier_test->bt_test = bt_test_alloc();
|
||||
bt_test_set_context(bt_carrier_test->bt_test, bt_carrier_test);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct BtCarrierTest BtCarrierTest;
|
||||
|
||||
BtCarrierTest* bt_carrier_test_alloc();
|
||||
BtCarrierTest* bt_carrier_test_alloc(void);
|
||||
|
||||
void bt_carrier_test_free(BtCarrierTest* bt_carrier_test);
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ static void bt_test_packet_timer_callback(void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
BtPacketTest* bt_packet_test_alloc() {
|
||||
BtPacketTest* bt_packet_test_alloc(void) {
|
||||
BtPacketTest* bt_packet_test = malloc(sizeof(BtPacketTest));
|
||||
bt_packet_test->bt_test = bt_test_alloc();
|
||||
bt_test_set_context(bt_packet_test->bt_test, bt_packet_test);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct BtPacketTest BtPacketTest;
|
||||
|
||||
BtPacketTest* bt_packet_test_alloc();
|
||||
BtPacketTest* bt_packet_test_alloc(void);
|
||||
|
||||
void bt_packet_test_free(BtPacketTest* bt_packet_test);
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ void bt_test_process_back(BtTest* bt_test) {
|
||||
}
|
||||
}
|
||||
|
||||
BtTest* bt_test_alloc() {
|
||||
BtTest* bt_test_alloc(void) {
|
||||
BtTest* bt_test = malloc(sizeof(BtTest));
|
||||
bt_test->view = view_alloc();
|
||||
view_set_context(bt_test->view, bt_test);
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef void (*BtTestBackCallback)(void* context);
|
||||
typedef struct BtTestParam BtTestParam;
|
||||
typedef void (*BtTestParamChangeCallback)(BtTestParam* param);
|
||||
|
||||
BtTest* bt_test_alloc();
|
||||
BtTest* bt_test_alloc(void);
|
||||
|
||||
void bt_test_free(BtTest* bt_test);
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ uint32_t ccid_test_exit(void* context) {
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
CcidTestApp* ccid_test_app_alloc() {
|
||||
CcidTestApp* ccid_test_app_alloc(void) {
|
||||
CcidTestApp* app = malloc(sizeof(CcidTestApp));
|
||||
|
||||
// Gui
|
||||
|
||||
@@ -50,7 +50,7 @@ static void crash_test_submenu_callback(void* context, uint32_t index) {
|
||||
furi_halt("Crash test: furi_halt");
|
||||
break;
|
||||
default:
|
||||
furi_crash("Programming error");
|
||||
furi_crash();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ static uint32_t crash_test_exit_callback(void* context) {
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
CrashTest* crash_test_alloc() {
|
||||
CrashTest* crash_test_alloc(void) {
|
||||
CrashTest* instance = malloc(sizeof(CrashTest));
|
||||
|
||||
View* view = NULL;
|
||||
|
||||
@@ -26,7 +26,7 @@ static void gui_input_events_callback(const void* value, void* ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
static DirectDraw* direct_draw_alloc() {
|
||||
static DirectDraw* direct_draw_alloc(void) {
|
||||
DirectDraw* instance = malloc(sizeof(DirectDraw));
|
||||
|
||||
instance->input = furi_record_open(RECORD_INPUT_EVENTS);
|
||||
|
||||
@@ -121,7 +121,7 @@ static void display_config_set_contrast(VariableItem* item) {
|
||||
display_test_reload_config(instance);
|
||||
}
|
||||
|
||||
DisplayTest* display_test_alloc() {
|
||||
DisplayTest* display_test_alloc(void) {
|
||||
DisplayTest* instance = malloc(sizeof(DisplayTest));
|
||||
|
||||
View* view = NULL;
|
||||
|
||||
@@ -154,7 +154,7 @@ static void view_display_test_timer_callback(void* context) {
|
||||
instance->view, ViewDisplayTestModel * model, { model->counter++; }, true);
|
||||
}
|
||||
|
||||
ViewDisplayTest* view_display_test_alloc() {
|
||||
ViewDisplayTest* view_display_test_alloc(void) {
|
||||
ViewDisplayTest* instance = malloc(sizeof(ViewDisplayTest));
|
||||
|
||||
instance->view = view_alloc();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
typedef struct ViewDisplayTest ViewDisplayTest;
|
||||
|
||||
ViewDisplayTest* view_display_test_alloc();
|
||||
ViewDisplayTest* view_display_test_alloc(void);
|
||||
|
||||
void view_display_test_free(ViewDisplayTest* instance);
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
|
||||
//This arrays contains the font itself. You can use any u8g2 font you want
|
||||
|
||||
/*
|
||||
Fontname: -Raccoon-Fixed4x6-Medium-R-Normal--6-60-75-75-P-40-ISO10646-1
|
||||
Copyright:
|
||||
Glyphs: 95/203
|
||||
BBX Build Mode: 0
|
||||
*/
|
||||
const uint8_t u8g2_font_tom_thumb_4x6_tr[725] =
|
||||
"_\0\2\2\2\3\3\4\4\3\6\0\377\5\377\5\0\0\352\1\330\2\270 \5\340\315\0!\6\265\310"
|
||||
"\254\0\42\6\213\313$\25#\10\227\310\244\241\206\12$\10\227\310\215\70b\2%\10\227\310d\324F\1"
|
||||
"&\10\227\310(\65R\22'\5\251\313\10(\6\266\310\251\62)\10\226\310\304\224\24\0*\6\217\312\244"
|
||||
"\16+\7\217\311\245\225\0,\6\212\310)\0-\5\207\312\14.\5\245\310\4/\7\227\310Ve\4\60"
|
||||
"\7\227\310-k\1\61\6\226\310\255\6\62\10\227\310h\220\312\1\63\11\227\310h\220\62X\0\64\10\227"
|
||||
"\310$\65b\1\65\10\227\310\214\250\301\2\66\10\227\310\315\221F\0\67\10\227\310\314TF\0\70\10\227"
|
||||
"\310\214\64\324\10\71\10\227\310\214\64\342\2:\6\255\311\244\0;\7\222\310e\240\0<\10\227\310\246\32"
|
||||
"d\20=\6\217\311l\60>\11\227\310d\220A*\1\77\10\227\310\314\224a\2@\10\227\310UC\3"
|
||||
"\1A\10\227\310UC\251\0B\10\227\310\250\264\322\2C\7\227\310\315\32\10D\10\227\310\250d-\0"
|
||||
"E\10\227\310\214\70\342\0F\10\227\310\214\70b\4G\10\227\310\315\221\222\0H\10\227\310$\65\224\12"
|
||||
"I\7\227\310\254X\15J\7\227\310\226\252\2K\10\227\310$\265\222\12L\7\227\310\304\346\0M\10\227"
|
||||
"\310\244\61\224\12N\10\227\310\244q\250\0O\7\227\310UV\5P\10\227\310\250\264b\4Q\10\227\310"
|
||||
"Uj$\1R\10\227\310\250\64V\1S\10\227\310m\220\301\2T\7\227\310\254\330\2U\7\227\310$"
|
||||
"W\22V\10\227\310$\253L\0W\10\227\310$\65\206\12X\10\227\310$\325R\1Y\10\227\310$U"
|
||||
"V\0Z\7\227\310\314T\16[\7\227\310\214X\16\134\10\217\311d\220A\0]\7\227\310\314r\4^"
|
||||
"\5\213\313\65_\5\207\310\14`\6\212\313\304\0a\7\223\310\310\65\2b\10\227\310D\225\324\2c\7"
|
||||
"\223\310\315\14\4d\10\227\310\246\245\222\0e\6\223\310\235\2f\10\227\310\246\264b\2g\10\227\307\35"
|
||||
"\61%\0h\10\227\310D\225\254\0i\6\265\310\244\1j\10\233\307f\30U\5k\10\227\310\304\264T"
|
||||
"\1l\7\227\310\310\326\0m\7\223\310<R\0n\7\223\310\250d\5o\7\223\310U\252\2p\10\227"
|
||||
"\307\250\244V\4q\10\227\307-\225d\0r\6\223\310\315\22s\10\223\310\215\70\22\0t\10\227\310\245"
|
||||
"\25\243\0u\7\223\310$+\11v\10\223\310$\65R\2w\7\223\310\244q\4x\7\223\310\244\62\25"
|
||||
"y\11\227\307$\225dJ\0z\7\223\310\254\221\6{\10\227\310\251\32D\1|\6\265\310(\1}\11"
|
||||
"\227\310\310\14RR\0~\6\213\313\215\4\0\0\0\4\377\377\0";
|
||||
|
||||
// Screen is 128x64 px
|
||||
static void app_draw_callback(Canvas* canvas, void* ctx) {
|
||||
UNUSED(ctx);
|
||||
|
||||
canvas_clear(canvas);
|
||||
|
||||
canvas_set_custom_u8g2_font(canvas, u8g2_font_tom_thumb_4x6_tr);
|
||||
|
||||
canvas_draw_str(canvas, 0, 6, "This is a tiny custom font");
|
||||
canvas_draw_str(canvas, 0, 12, "012345.?! ,:;\"\'@#$%");
|
||||
}
|
||||
|
||||
static void app_input_callback(InputEvent* input_event, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
|
||||
}
|
||||
|
||||
int32_t example_custom_font_main(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||
|
||||
// Configure view port
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, app_draw_callback, view_port);
|
||||
view_port_input_callback_set(view_port, app_input_callback, event_queue);
|
||||
|
||||
// Register view port in GUI
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
InputEvent event;
|
||||
|
||||
bool running = true;
|
||||
|
||||
while(running) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
if((event.type == InputTypePress) || (event.type == InputTypeRepeat)) {
|
||||
switch(event.key) {
|
||||
case InputKeyBack:
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
applications/debug/expansion_test/application.fam
Normal file
12
applications/debug/expansion_test/application.fam
Normal file
@@ -0,0 +1,12 @@
|
||||
App(
|
||||
appid="expansion_test",
|
||||
name="Expansion Module Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="expansion_test_app",
|
||||
requires=["expansion_start"],
|
||||
fap_libs=["assets"],
|
||||
stack_size=1 * 1024,
|
||||
order=20,
|
||||
fap_category="Debug",
|
||||
fap_file_assets="assets",
|
||||
)
|
||||
9
applications/debug/expansion_test/assets/test.txt
Normal file
9
applications/debug/expansion_test/assets/test.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
"Did you ever hear the tragedy of Darth Plagueis the Wise?"
|
||||
"No."
|
||||
"I thought not. It's not a story the Jedi would tell you. It's a Sith legend. Darth Plagueis... was a Dark Lord of the Sith so powerful and so wise, he could use the Force to influence the midi-chlorians... to create... life. He had such a knowledge of the dark side, he could even keep the ones he cared about... from dying."
|
||||
"He could actually... save people from death?"
|
||||
"The dark side of the Force is a pathway to many abilities... some consider to be unnatural."
|
||||
"Wh– What happened to him?"
|
||||
"He became so powerful, the only thing he was afraid of was... losing his power. Which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew. Then his apprentice killed him in his sleep. It's ironic. He could save others from death, but not himself."
|
||||
"Is it possible to learn this power?"
|
||||
"Not from a Jedi."
|
||||
457
applications/debug/expansion_test/expansion_test.c
Normal file
457
applications/debug/expansion_test/expansion_test.c
Normal file
@@ -0,0 +1,457 @@
|
||||
/**
|
||||
* @file expansion_test.c
|
||||
* @brief Expansion module support testing application.
|
||||
*
|
||||
* Before running, connect pins using the following scheme:
|
||||
* 13 -> 16 (USART TX to LPUART RX)
|
||||
* 14 -> 15 (USART RX to LPUART TX)
|
||||
*
|
||||
* What this application does:
|
||||
*
|
||||
* - Enables module support and emulates the module on a single device
|
||||
* (hence the above connection),
|
||||
* - Connects to the expansion module service, sets baud rate,
|
||||
* - Starts the RPC session,
|
||||
* - Creates a directory at `/ext/ExpansionTest` and writes a file
|
||||
* named `test.txt` under it,
|
||||
* - Plays an audiovisual alert (sound and blinking display),
|
||||
* - Waits 10 cycles of idle loop,
|
||||
* - Stops the RPC session,
|
||||
* - Waits another 10 cycles of idle loop,
|
||||
* - Exits (plays a sound if any of the above steps failed).
|
||||
*/
|
||||
#include <furi.h>
|
||||
|
||||
#include <furi_hal_resources.h>
|
||||
|
||||
#include <furi_hal_serial.h>
|
||||
#include <furi_hal_serial_control.h>
|
||||
|
||||
#include <pb.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
|
||||
#include <flipper.pb.h>
|
||||
|
||||
#include <storage/storage.h>
|
||||
#include <expansion/expansion.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <expansion/expansion_protocol.h>
|
||||
|
||||
#define TAG "ExpansionTest"
|
||||
|
||||
#define TEST_DIR_PATH EXT_PATH(TAG)
|
||||
#define TEST_FILE_NAME "test.txt"
|
||||
#define TEST_FILE_PATH EXT_PATH(TAG "/" TEST_FILE_NAME)
|
||||
|
||||
#define HOST_SERIAL_ID (FuriHalSerialIdLpuart)
|
||||
#define MODULE_SERIAL_ID (FuriHalSerialIdUsart)
|
||||
|
||||
#define RECEIVE_BUFFER_SIZE (sizeof(ExpansionFrame) + sizeof(ExpansionFrameChecksum))
|
||||
|
||||
typedef enum {
|
||||
ExpansionTestAppFlagData = 1U << 0,
|
||||
ExpansionTestAppFlagExit = 1U << 1,
|
||||
} ExpansionTestAppFlag;
|
||||
|
||||
#define EXPANSION_TEST_APP_ALL_FLAGS (ExpansionTestAppFlagData | ExpansionTestAppFlagExit)
|
||||
|
||||
typedef struct {
|
||||
FuriThreadId thread_id;
|
||||
Expansion* expansion;
|
||||
FuriHalSerialHandle* handle;
|
||||
FuriStreamBuffer* buf;
|
||||
ExpansionFrame frame;
|
||||
PB_Main msg;
|
||||
Storage* storage;
|
||||
} ExpansionTestApp;
|
||||
|
||||
static void expansion_test_app_serial_rx_callback(
|
||||
FuriHalSerialHandle* handle,
|
||||
FuriHalSerialRxEvent event,
|
||||
void* context) {
|
||||
furi_assert(handle);
|
||||
furi_assert(context);
|
||||
ExpansionTestApp* app = context;
|
||||
|
||||
if(event == FuriHalSerialRxEventData) {
|
||||
const uint8_t data = furi_hal_serial_async_rx(handle);
|
||||
furi_stream_buffer_send(app->buf, &data, sizeof(data), 0);
|
||||
furi_thread_flags_set(app->thread_id, ExpansionTestAppFlagData);
|
||||
}
|
||||
}
|
||||
|
||||
static ExpansionTestApp* expansion_test_app_alloc(void) {
|
||||
ExpansionTestApp* instance = malloc(sizeof(ExpansionTestApp));
|
||||
instance->buf = furi_stream_buffer_alloc(RECEIVE_BUFFER_SIZE, 1);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void expansion_test_app_free(ExpansionTestApp* instance) {
|
||||
furi_stream_buffer_free(instance->buf);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
static void expansion_test_app_start(ExpansionTestApp* instance) {
|
||||
instance->thread_id = furi_thread_get_current_id();
|
||||
instance->expansion = furi_record_open(RECORD_EXPANSION);
|
||||
instance->handle = furi_hal_serial_control_acquire(MODULE_SERIAL_ID);
|
||||
furi_check(instance->handle);
|
||||
// Configure the serial port
|
||||
furi_hal_serial_init(instance->handle, EXPANSION_PROTOCOL_DEFAULT_BAUD_RATE);
|
||||
// Start waiting for the initial pulse
|
||||
expansion_set_listen_serial(instance->expansion, HOST_SERIAL_ID);
|
||||
|
||||
furi_hal_serial_async_rx_start(
|
||||
instance->handle, expansion_test_app_serial_rx_callback, instance, false);
|
||||
}
|
||||
|
||||
static void expansion_test_app_stop(ExpansionTestApp* instance) {
|
||||
// Disable expansion module support
|
||||
expansion_disable(instance->expansion);
|
||||
// Give back the module handle
|
||||
furi_hal_serial_control_release(instance->handle);
|
||||
// Restore expansion user settings
|
||||
expansion_enable(instance->expansion);
|
||||
furi_record_close(RECORD_EXPANSION);
|
||||
}
|
||||
|
||||
static inline bool expansion_test_app_is_success_response(const ExpansionFrame* response) {
|
||||
return response->header.type == ExpansionFrameTypeStatus &&
|
||||
response->content.status.error == ExpansionFrameErrorNone;
|
||||
}
|
||||
|
||||
static inline bool expansion_test_app_is_success_rpc_message(const PB_Main* message) {
|
||||
return (message->command_status == PB_CommandStatus_OK ||
|
||||
message->command_status == PB_CommandStatus_ERROR_STORAGE_EXIST) &&
|
||||
(message->which_content == PB_Main_empty_tag);
|
||||
}
|
||||
|
||||
static size_t expansion_test_app_receive_callback(uint8_t* data, size_t data_size, void* context) {
|
||||
ExpansionTestApp* instance = context;
|
||||
|
||||
size_t received_size = 0;
|
||||
|
||||
while(true) {
|
||||
received_size += furi_stream_buffer_receive(
|
||||
instance->buf, data + received_size, data_size - received_size, 0);
|
||||
if(received_size == data_size) break;
|
||||
|
||||
const uint32_t flags = furi_thread_flags_wait(
|
||||
EXPANSION_TEST_APP_ALL_FLAGS, FuriFlagWaitAny, EXPANSION_PROTOCOL_TIMEOUT_MS);
|
||||
|
||||
// Exit on any error
|
||||
if(flags & FuriFlagError) break;
|
||||
}
|
||||
|
||||
return received_size;
|
||||
}
|
||||
|
||||
static size_t
|
||||
expansion_test_app_send_callback(const uint8_t* data, size_t data_size, void* context) {
|
||||
ExpansionTestApp* instance = context;
|
||||
|
||||
furi_hal_serial_tx(instance->handle, data, data_size);
|
||||
furi_hal_serial_tx_wait_complete(instance->handle);
|
||||
|
||||
return data_size;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_receive_frame(ExpansionTestApp* instance, ExpansionFrame* frame) {
|
||||
return expansion_protocol_decode(frame, expansion_test_app_receive_callback, instance) ==
|
||||
ExpansionProtocolStatusOk;
|
||||
}
|
||||
|
||||
static bool
|
||||
expansion_test_app_send_status_response(ExpansionTestApp* instance, ExpansionFrameError error) {
|
||||
ExpansionFrame frame = {
|
||||
.header.type = ExpansionFrameTypeStatus,
|
||||
.content.status.error = error,
|
||||
};
|
||||
return expansion_protocol_encode(&frame, expansion_test_app_send_callback, instance) ==
|
||||
ExpansionProtocolStatusOk;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_send_heartbeat(ExpansionTestApp* instance) {
|
||||
ExpansionFrame frame = {
|
||||
.header.type = ExpansionFrameTypeHeartbeat,
|
||||
.content.heartbeat = {},
|
||||
};
|
||||
return expansion_protocol_encode(&frame, expansion_test_app_send_callback, instance) ==
|
||||
ExpansionProtocolStatusOk;
|
||||
}
|
||||
|
||||
static bool
|
||||
expansion_test_app_send_baud_rate_request(ExpansionTestApp* instance, uint32_t baud_rate) {
|
||||
ExpansionFrame frame = {
|
||||
.header.type = ExpansionFrameTypeBaudRate,
|
||||
.content.baud_rate.baud = baud_rate,
|
||||
};
|
||||
return expansion_protocol_encode(&frame, expansion_test_app_send_callback, instance) ==
|
||||
ExpansionProtocolStatusOk;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_send_control_request(
|
||||
ExpansionTestApp* instance,
|
||||
ExpansionFrameControlCommand command) {
|
||||
ExpansionFrame frame = {
|
||||
.header.type = ExpansionFrameTypeControl,
|
||||
.content.control.command = command,
|
||||
};
|
||||
return expansion_protocol_encode(&frame, expansion_test_app_send_callback, instance) ==
|
||||
ExpansionProtocolStatusOk;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_send_data_request(
|
||||
ExpansionTestApp* instance,
|
||||
const uint8_t* data,
|
||||
size_t data_size) {
|
||||
furi_assert(data_size <= EXPANSION_PROTOCOL_MAX_DATA_SIZE);
|
||||
|
||||
ExpansionFrame frame = {
|
||||
.header.type = ExpansionFrameTypeData,
|
||||
.content.data.size = data_size,
|
||||
};
|
||||
|
||||
memcpy(frame.content.data.bytes, data, data_size);
|
||||
return expansion_protocol_encode(&frame, expansion_test_app_send_callback, instance) ==
|
||||
ExpansionProtocolStatusOk;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_rpc_encode_callback(
|
||||
pb_ostream_t* stream,
|
||||
const pb_byte_t* data,
|
||||
size_t data_size) {
|
||||
ExpansionTestApp* instance = stream->state;
|
||||
|
||||
size_t size_sent = 0;
|
||||
|
||||
while(size_sent < data_size) {
|
||||
const size_t current_size = MIN(data_size - size_sent, EXPANSION_PROTOCOL_MAX_DATA_SIZE);
|
||||
if(!expansion_test_app_send_data_request(instance, data + size_sent, current_size)) break;
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(!expansion_test_app_is_success_response(&instance->frame)) break;
|
||||
size_sent += current_size;
|
||||
}
|
||||
|
||||
return size_sent == data_size;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_send_rpc_request(ExpansionTestApp* instance, PB_Main* message) {
|
||||
pb_ostream_t stream = {
|
||||
.callback = expansion_test_app_rpc_encode_callback,
|
||||
.state = instance,
|
||||
.max_size = SIZE_MAX,
|
||||
.bytes_written = 0,
|
||||
.errmsg = NULL,
|
||||
};
|
||||
|
||||
const bool success = pb_encode_ex(&stream, &PB_Main_msg, message, PB_ENCODE_DELIMITED);
|
||||
pb_release(&PB_Main_msg, message);
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_receive_rpc_request(ExpansionTestApp* instance, PB_Main* message) {
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(!expansion_test_app_send_status_response(instance, ExpansionFrameErrorNone)) break;
|
||||
if(instance->frame.header.type != ExpansionFrameTypeData) break;
|
||||
pb_istream_t stream = pb_istream_from_buffer(
|
||||
instance->frame.content.data.bytes, instance->frame.content.data.size);
|
||||
if(!pb_decode_ex(&stream, &PB_Main_msg, message, PB_DECODE_DELIMITED)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_send_presence(ExpansionTestApp* instance) {
|
||||
// Send pulses to emulate module insertion
|
||||
const uint8_t init = 0xAA;
|
||||
furi_hal_serial_tx(instance->handle, &init, sizeof(init));
|
||||
furi_hal_serial_tx_wait_complete(instance->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_wait_ready(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(instance->frame.header.type != ExpansionFrameTypeHeartbeat) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_handshake(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_baud_rate_request(instance, 230400)) break;
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(!expansion_test_app_is_success_response(&instance->frame)) break;
|
||||
furi_hal_serial_set_br(instance->handle, 230400);
|
||||
furi_delay_ms(EXPANSION_PROTOCOL_BAUD_CHANGE_DT_MS);
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_start_rpc(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_control_request(instance, ExpansionFrameControlCommandStartRpc))
|
||||
break;
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(!expansion_test_app_is_success_response(&instance->frame)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_rpc_mkdir(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
instance->msg.command_id++;
|
||||
instance->msg.command_status = PB_CommandStatus_OK;
|
||||
instance->msg.which_content = PB_Main_storage_mkdir_request_tag;
|
||||
instance->msg.has_next = false;
|
||||
instance->msg.content.storage_mkdir_request.path = TEST_DIR_PATH;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_rpc_request(instance, &instance->msg)) break;
|
||||
if(!expansion_test_app_receive_rpc_request(instance, &instance->msg)) break;
|
||||
if(!expansion_test_app_is_success_rpc_message(&instance->msg)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_rpc_write(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
File* file = storage_file_alloc(storage);
|
||||
|
||||
do {
|
||||
if(!storage_file_open(file, APP_ASSETS_PATH(TEST_FILE_NAME), FSAM_READ, FSOM_OPEN_EXISTING))
|
||||
break;
|
||||
|
||||
const uint64_t file_size = storage_file_size(file);
|
||||
|
||||
instance->msg.command_id++;
|
||||
instance->msg.command_status = PB_CommandStatus_OK;
|
||||
instance->msg.which_content = PB_Main_storage_write_request_tag;
|
||||
instance->msg.has_next = false;
|
||||
instance->msg.content.storage_write_request.path = TEST_FILE_PATH;
|
||||
instance->msg.content.storage_write_request.has_file = true;
|
||||
instance->msg.content.storage_write_request.file.data =
|
||||
malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(file_size));
|
||||
instance->msg.content.storage_write_request.file.data->size = file_size;
|
||||
|
||||
const size_t bytes_read = storage_file_read(
|
||||
file, instance->msg.content.storage_write_request.file.data->bytes, file_size);
|
||||
|
||||
if(bytes_read != file_size) {
|
||||
pb_release(&PB_Main_msg, &instance->msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!expansion_test_app_send_rpc_request(instance, &instance->msg)) break;
|
||||
if(!expansion_test_app_receive_rpc_request(instance, &instance->msg)) break;
|
||||
if(!expansion_test_app_is_success_rpc_message(&instance->msg)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
storage_file_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_rpc_alert(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
instance->msg.command_id++;
|
||||
instance->msg.command_status = PB_CommandStatus_OK;
|
||||
instance->msg.which_content = PB_Main_system_play_audiovisual_alert_request_tag;
|
||||
instance->msg.has_next = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_rpc_request(instance, &instance->msg)) break;
|
||||
if(!expansion_test_app_receive_rpc_request(instance, &instance->msg)) break;
|
||||
if(instance->msg.which_content != PB_Main_empty_tag) break;
|
||||
if(instance->msg.command_status != PB_CommandStatus_OK) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_idle(ExpansionTestApp* instance, uint32_t num_cycles) {
|
||||
uint32_t num_cycles_done;
|
||||
for(num_cycles_done = 0; num_cycles_done < num_cycles; ++num_cycles_done) {
|
||||
if(!expansion_test_app_send_heartbeat(instance)) break;
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(instance->frame.header.type != ExpansionFrameTypeHeartbeat) break;
|
||||
furi_delay_ms(EXPANSION_PROTOCOL_TIMEOUT_MS - 50);
|
||||
}
|
||||
|
||||
return num_cycles_done == num_cycles;
|
||||
}
|
||||
|
||||
static bool expansion_test_app_stop_rpc(ExpansionTestApp* instance) {
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_control_request(instance, ExpansionFrameControlCommandStopRpc))
|
||||
break;
|
||||
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
|
||||
if(!expansion_test_app_is_success_response(&instance->frame)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int32_t expansion_test_app(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
ExpansionTestApp* instance = expansion_test_app_alloc();
|
||||
expansion_test_app_start(instance);
|
||||
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
if(!expansion_test_app_send_presence(instance)) break;
|
||||
if(!expansion_test_app_wait_ready(instance)) break;
|
||||
if(!expansion_test_app_handshake(instance)) break;
|
||||
if(!expansion_test_app_start_rpc(instance)) break;
|
||||
if(!expansion_test_app_rpc_mkdir(instance)) break;
|
||||
if(!expansion_test_app_rpc_write(instance)) break;
|
||||
if(!expansion_test_app_rpc_alert(instance)) break;
|
||||
if(!expansion_test_app_idle(instance, 10)) break;
|
||||
if(!expansion_test_app_stop_rpc(instance)) break;
|
||||
if(!expansion_test_app_idle(instance, 10)) break;
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
expansion_test_app_stop(instance);
|
||||
expansion_test_app_free(instance);
|
||||
|
||||
if(!success) {
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
notification_message(notification, &sequence_error);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -12,7 +12,7 @@ static bool lfrfid_debug_back_event_callback(void* context) {
|
||||
return scene_manager_handle_back_event(app->scene_manager);
|
||||
}
|
||||
|
||||
static LfRfidDebug* lfrfid_debug_alloc() {
|
||||
static LfRfidDebug* lfrfid_debug_alloc(void) {
|
||||
LfRfidDebug* app = malloc(sizeof(LfRfidDebug));
|
||||
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
|
||||
@@ -170,7 +170,7 @@ static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* conte
|
||||
return consumed;
|
||||
}
|
||||
|
||||
LfRfidTuneView* lfrfid_debug_view_tune_alloc() {
|
||||
LfRfidTuneView* lfrfid_debug_view_tune_alloc(void) {
|
||||
LfRfidTuneView* tune_view = malloc(sizeof(LfRfidTuneView));
|
||||
tune_view->view = view_alloc();
|
||||
view_set_context(tune_view->view, tune_view);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct LfRfidTuneView LfRfidTuneView;
|
||||
|
||||
LfRfidTuneView* lfrfid_debug_view_tune_alloc();
|
||||
LfRfidTuneView* lfrfid_debug_view_tune_alloc(void);
|
||||
|
||||
void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ static void locale_test_view_draw_callback(Canvas* canvas, void* _model) {
|
||||
}
|
||||
canvas_draw_str(canvas, 0, 10, furi_string_get_cstr(tmp_string));
|
||||
|
||||
FuriHalRtcDateTime datetime;
|
||||
DateTime datetime;
|
||||
furi_hal_rtc_get_datetime(&datetime);
|
||||
|
||||
locale_format_time(tmp_string, &datetime, locale_get_time_format(), false);
|
||||
@@ -53,7 +53,7 @@ static uint32_t locale_test_exit(void* context) {
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
static LocaleTestApp* locale_test_alloc() {
|
||||
static LocaleTestApp* locale_test_alloc(void) {
|
||||
LocaleTestApp* app = malloc(sizeof(LocaleTestApp));
|
||||
|
||||
// Gui
|
||||
|
||||
@@ -83,7 +83,7 @@ static bool rpc_debug_app_rpc_init_rpc(RpcDebugApp* app, const char* args) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RpcDebugApp* rpc_debug_app_alloc() {
|
||||
static RpcDebugApp* rpc_debug_app_alloc(void) {
|
||||
RpcDebugApp* app = malloc(sizeof(RpcDebugApp));
|
||||
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
|
||||
@@ -21,7 +21,7 @@ typedef struct {
|
||||
Cli* cli;
|
||||
} SpeakerDebugApp;
|
||||
|
||||
static SpeakerDebugApp* speaker_app_alloc() {
|
||||
static SpeakerDebugApp* speaker_app_alloc(void) {
|
||||
SpeakerDebugApp* app = (SpeakerDebugApp*)malloc(sizeof(SpeakerDebugApp));
|
||||
app->music_worker = music_worker_alloc();
|
||||
app->message_queue = furi_message_queue_alloc(8, sizeof(SpeakerDebugAppMessage));
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef enum {
|
||||
PrincetonDecoderStepCheckDuration,
|
||||
} PrincetonDecoderStep;
|
||||
|
||||
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc() {
|
||||
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void) {
|
||||
SubGhzEncoderPrinceton* instance = malloc(sizeof(SubGhzEncoderPrinceton));
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ typedef void (*SubGhzDecoderPrincetonCallback)(SubGhzDecoderPrinceton* parser, v
|
||||
* Allocate SubGhzEncoderPrinceton
|
||||
* @return pointer to SubGhzEncoderPrinceton instance
|
||||
*/
|
||||
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc();
|
||||
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void);
|
||||
|
||||
/**
|
||||
* Free SubGhzEncoderPrinceton instance
|
||||
@@ -69,7 +69,7 @@ LevelDuration subghz_encoder_princeton_for_testing_yield(void* context);
|
||||
* Allocate SubGhzDecoderPrinceton
|
||||
* @return SubGhzDecoderPrinceton*
|
||||
*/
|
||||
SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc();
|
||||
SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(void);
|
||||
|
||||
/**
|
||||
* Free SubGhzDecoderPrinceton
|
||||
|
||||
@@ -12,7 +12,7 @@ void subghz_test_scene_show_only_rx_on_enter(void* context) {
|
||||
// Setup view
|
||||
Popup* popup = app->popup;
|
||||
|
||||
const char* header_text = "Transmission is blocked";
|
||||
const char* header_text = "Transmission is Blocked";
|
||||
const char* message_text = "Transmission on\nthis frequency is\nrestricted in\nyour region";
|
||||
if(!furi_hal_region_is_provisioned()) {
|
||||
header_text = "Firmware update needed";
|
||||
|
||||
@@ -21,7 +21,7 @@ static void subghz_test_app_tick_event_callback(void* context) {
|
||||
scene_manager_handle_tick_event(app->scene_manager);
|
||||
}
|
||||
|
||||
SubGhzTestApp* subghz_test_app_alloc() {
|
||||
SubGhzTestApp* subghz_test_app_alloc(void) {
|
||||
SubGhzTestApp* app = malloc(sizeof(SubGhzTestApp));
|
||||
|
||||
// GUI
|
||||
|
||||
@@ -219,7 +219,7 @@ void subghz_test_carrier_rssi_timer_callback(void* context) {
|
||||
false);
|
||||
}
|
||||
|
||||
SubGhzTestCarrier* subghz_test_carrier_alloc() {
|
||||
SubGhzTestCarrier* subghz_test_carrier_alloc(void) {
|
||||
SubGhzTestCarrier* subghz_test_carrier = malloc(sizeof(SubGhzTestCarrier));
|
||||
|
||||
// View allocation and configuration
|
||||
|
||||
@@ -16,7 +16,7 @@ void subghz_test_carrier_set_callback(
|
||||
SubGhzTestCarrierCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzTestCarrier* subghz_test_carrier_alloc();
|
||||
SubGhzTestCarrier* subghz_test_carrier_alloc(void);
|
||||
|
||||
void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier);
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ void subghz_test_packet_exit(void* context) {
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
SubGhzTestPacket* subghz_test_packet_alloc() {
|
||||
SubGhzTestPacket* subghz_test_packet_alloc(void) {
|
||||
SubGhzTestPacket* instance = malloc(sizeof(SubGhzTestPacket));
|
||||
|
||||
// View allocation and configuration
|
||||
|
||||
@@ -15,7 +15,7 @@ void subghz_test_packet_set_callback(
|
||||
SubGhzTestPacketCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzTestPacket* subghz_test_packet_alloc();
|
||||
SubGhzTestPacket* subghz_test_packet_alloc(void);
|
||||
|
||||
void subghz_test_packet_free(SubGhzTestPacket* subghz_test_packet);
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ void subghz_test_static_exit(void* context) {
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
SubGhzTestStatic* subghz_test_static_alloc() {
|
||||
SubGhzTestStatic* subghz_test_static_alloc(void) {
|
||||
SubGhzTestStatic* instance = malloc(sizeof(SubGhzTestStatic));
|
||||
|
||||
// View allocation and configuration
|
||||
|
||||
@@ -15,7 +15,7 @@ void subghz_test_static_set_callback(
|
||||
SubGhzTestStaticCallback callback,
|
||||
void* context);
|
||||
|
||||
SubGhzTestStatic* subghz_test_static_alloc();
|
||||
SubGhzTestStatic* subghz_test_static_alloc(void);
|
||||
|
||||
void subghz_test_static_free(SubGhzTestStatic* subghz_static);
|
||||
|
||||
|
||||
10
applications/debug/text_box_element_test/application.fam
Normal file
10
applications/debug/text_box_element_test/application.fam
Normal file
@@ -0,0 +1,10 @@
|
||||
App(
|
||||
appid="text_box_element_test",
|
||||
name="Text Box Element Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="text_box_element_test_app",
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=140,
|
||||
fap_category="Debug",
|
||||
)
|
||||
@@ -71,7 +71,7 @@ static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
|
||||
}
|
||||
|
||||
int32_t text_box_test_app(void* p) {
|
||||
int32_t text_box_element_test_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||
furi_check(event_queue);
|
||||
@@ -1,8 +1,8 @@
|
||||
App(
|
||||
appid="text_box_test",
|
||||
name="Text Box Test",
|
||||
appid="text_box_view_test",
|
||||
name="Text Box View Test",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="text_box_test_app",
|
||||
entry_point="text_box_view_test_app",
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=140,
|
||||
161
applications/debug/text_box_view_test/text_box_view_test.c
Normal file
161
applications/debug/text_box_view_test/text_box_view_test.c
Normal file
@@ -0,0 +1,161 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/text_box.h>
|
||||
#include <gui/view_stack.h>
|
||||
|
||||
#define TAG "TextBoxViewTest"
|
||||
|
||||
typedef struct {
|
||||
TextBoxFont font;
|
||||
TextBoxFocus focus;
|
||||
const char* text;
|
||||
} TextBoxViewTestContent;
|
||||
|
||||
static const TextBoxViewTestContent text_box_view_test_content_arr[] = {
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusStart,
|
||||
.text = "Hello, let's test text box. Press Right and Left to switch content",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text = "First test to add dynamically lines with EndFocus set\nLine 0",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text = "First test to add dynamically lines with EndFocus set\nLine 0\nLine 1",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text = "First test to add dynamically lines with EndFocus set\nLine 0\nLine 1\nLine 2",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text =
|
||||
"First test to add dynamically lines with EndFocus set\nLine 0\nLine 1\nLine 2\nLine 3",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text =
|
||||
"First test to add dynamically lines with EndFocus set\nLine 0\nLine 1\nLine 2\nLine 3\nLine 4",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusStart,
|
||||
.text =
|
||||
"Verify that symbols don't overlap borders: llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllend",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusStart,
|
||||
.text =
|
||||
"\n\n\n Start from several newline chars. Verify that scrolling doesn't break.\n\n\n\n\nThe end",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusStart,
|
||||
.text =
|
||||
"Let's test big text.\n\n The ARM Cortex-M is a group of 32-bit RISC ARM processor cores licensed by ARM Limited. These cores are optimized for low-cost and energy-efficient integrated circuits, which have been embedded in tens of billions of consumer devices.[1] Though they are most often the main component of microcontroller chips, sometimes they are embedded inside other types of chips too. The Cortex-M family consists of Cortex-M0,[2] Cortex-M0+,[3] Cortex-M1,[4] Cortex-M3,[5] Cortex-M4,[6] Cortex-M7,[7] Cortex-M23,[8] Cortex-M33,[9] Cortex-M35P,[10] Cortex-M52,[11] Cortex-M55,[12] Cortex-M85.[13] A floating-point unit (FPU) option is available for Cortex-M4 / M7 / M33 / M35P / M52 / M55 / M85 cores, and when included in the silicon these cores are sometimes known as \"Cortex-MxF\", where 'x' is the core variant.\n\nThe ARM Cortex-M family are ARM microprocessor cores that are designed for use in microcontrollers, ASICs, ASSPs, FPGAs, and SoCs. Cortex-M cores are commonly used as dedicated microcontroller chips, but also are hidden inside of SoC chips as power management controllers, I/O controllers, system controllers, touch screen controllers, smart battery controllers, and sensor controllers. The main difference from Cortex-A cores is that Cortex-M cores have no memory management unit (MMU) for virtual memory, considered essential for full-fledged operating systems. Cortex-M programs instead run bare metal or on one of the many real-time operating systems which support a Cortex-M.Though 8-bit microcontrollers were very popular in the past, Cortex-M has slowly been chipping away at the 8-bit market as the prices of low-end Cortex-M chips have moved downward. Cortex-M have become a popular replacements for 8-bit chips in applications that benefit from 32-bit math operations, and replacing older legacy ARM cores such as ARM7 and ARM9.",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontText,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text =
|
||||
"The same but with EndFocus\n\n The ARM Cortex-M is a group of 32-bit RISC ARM processor cores licensed by ARM Limited. These cores are optimized for low-cost and energy-efficient integrated circuits, which have been embedded in tens of billions of consumer devices.[1] Though they are most often the main component of microcontroller chips, sometimes they are embedded inside other types of chips too. The Cortex-M family consists of Cortex-M0,[2] Cortex-M0+,[3] Cortex-M1,[4] Cortex-M3,[5] Cortex-M4,[6] Cortex-M7,[7] Cortex-M23,[8] Cortex-M33,[9] Cortex-M35P,[10] Cortex-M52,[11] Cortex-M55,[12] Cortex-M85.[13] A floating-point unit (FPU) option is available for Cortex-M4 / M7 / M33 / M35P / M52 / M55 / M85 cores, and when included in the silicon these cores are sometimes known as \"Cortex-MxF\", where 'x' is the core variant.\n\nThe ARM Cortex-M family are ARM microprocessor cores that are designed for use in microcontrollers, ASICs, ASSPs, FPGAs, and SoCs. Cortex-M cores are commonly used as dedicated microcontroller chips, but also are hidden inside of SoC chips as power management controllers, I/O controllers, system controllers, touch screen controllers, smart battery controllers, and sensor controllers. The main difference from Cortex-A cores is that Cortex-M cores have no memory management unit (MMU) for virtual memory, considered essential for full-fledged operating systems. Cortex-M programs instead run bare metal or on one of the many real-time operating systems which support a Cortex-M.Though 8-bit microcontrollers were very popular in the past, Cortex-M has slowly been chipping away at the 8-bit market as the prices of low-end Cortex-M chips have moved downward. Cortex-M have become a popular replacements for 8-bit chips in applications that benefit from 32-bit math operations, and replacing older legacy ARM cores such as ARM7 and ARM9.",
|
||||
},
|
||||
{
|
||||
.font = TextBoxFontHex,
|
||||
.focus = TextBoxFocusEnd,
|
||||
.text =
|
||||
"0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999\n0000 0000 0000 0000\n1111 1111 1111 1111\n2222 2222 2222 2222\n3333 3333 3333 3333\n4444 4444 4444 4444\n5555 5555 5555 5555\n6666 6666 6666 6666\n7777 7777 7777 7777\n8888 8888 8888 8888\n9999 9999 9999 9999",
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
TextBox* text_box;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
size_t current_content_i;
|
||||
} TextBoxViewTest;
|
||||
|
||||
static void text_box_update_view(TextBoxViewTest* instance) {
|
||||
// Intentional incorrect way to reset text box to verify that state resets if text changes
|
||||
text_box_set_text(instance->text_box, "");
|
||||
|
||||
const TextBoxViewTestContent* content =
|
||||
&text_box_view_test_content_arr[instance->current_content_i];
|
||||
text_box_set_font(instance->text_box, content->font);
|
||||
text_box_set_focus(instance->text_box, content->focus);
|
||||
text_box_set_text(instance->text_box, content->text);
|
||||
}
|
||||
|
||||
static bool text_box_switch_view_input_callback(InputEvent* event, void* context) {
|
||||
bool consumed = false;
|
||||
TextBoxViewTest* instance = context;
|
||||
size_t contents_cnt = COUNT_OF(text_box_view_test_content_arr);
|
||||
|
||||
if(event->type == InputTypeShort) {
|
||||
if(event->key == InputKeyRight) {
|
||||
if(instance->current_content_i < contents_cnt - 1) {
|
||||
instance->current_content_i++;
|
||||
text_box_update_view(instance);
|
||||
consumed = true;
|
||||
}
|
||||
} else if(event->key == InputKeyLeft) {
|
||||
if(instance->current_content_i > 0) {
|
||||
instance->current_content_i--;
|
||||
text_box_update_view(instance);
|
||||
consumed = true;
|
||||
}
|
||||
} else if(event->key == InputKeyBack) {
|
||||
view_dispatcher_stop(instance->view_dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
int32_t text_box_view_test_app(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
|
||||
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
||||
view_dispatcher_enable_queue(view_dispatcher);
|
||||
|
||||
TextBoxViewTest instance = {
|
||||
.text_box = text_box_alloc(),
|
||||
.current_content_i = 0,
|
||||
.view_dispatcher = view_dispatcher,
|
||||
};
|
||||
|
||||
text_box_update_view(&instance);
|
||||
|
||||
View* text_box_switch_view = view_alloc();
|
||||
view_set_input_callback(text_box_switch_view, text_box_switch_view_input_callback);
|
||||
view_set_context(text_box_switch_view, &instance);
|
||||
|
||||
ViewStack* view_stack = view_stack_alloc();
|
||||
view_stack_add_view(view_stack, text_box_switch_view);
|
||||
view_stack_add_view(view_stack, text_box_get_view(instance.text_box));
|
||||
|
||||
view_dispatcher_add_view(view_dispatcher, 0, view_stack_get_view(view_stack));
|
||||
view_dispatcher_switch_to_view(view_dispatcher, 0);
|
||||
|
||||
view_dispatcher_run(view_dispatcher);
|
||||
|
||||
view_dispatcher_remove_view(view_dispatcher, 0);
|
||||
view_dispatcher_free(view_dispatcher);
|
||||
view_stack_free(view_stack);
|
||||
view_free(text_box_switch_view);
|
||||
text_box_free(instance.text_box);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <gui/elements.h>
|
||||
#include <furi_hal_uart.h>
|
||||
#include <furi_hal_console.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/dialog_ex.h>
|
||||
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#define LINES_ON_SCREEN 6
|
||||
#define COLUMNS_ON_SCREEN 21
|
||||
#define TAG "UartEcho"
|
||||
@@ -22,6 +23,7 @@ typedef struct {
|
||||
View* view;
|
||||
FuriThread* worker_thread;
|
||||
FuriStreamBuffer* rx_stream;
|
||||
FuriHalSerialHandle* serial_handle;
|
||||
} UartEchoApp;
|
||||
|
||||
typedef struct {
|
||||
@@ -39,10 +41,16 @@ struct UartDumpModel {
|
||||
typedef enum {
|
||||
WorkerEventReserved = (1 << 0), // Reserved for StreamBuffer internal event
|
||||
WorkerEventStop = (1 << 1),
|
||||
WorkerEventRx = (1 << 2),
|
||||
WorkerEventRxData = (1 << 2),
|
||||
WorkerEventRxIdle = (1 << 3),
|
||||
WorkerEventRxOverrunError = (1 << 4),
|
||||
WorkerEventRxFramingError = (1 << 5),
|
||||
WorkerEventRxNoiseError = (1 << 6),
|
||||
} WorkerEventFlags;
|
||||
|
||||
#define WORKER_EVENTS_MASK (WorkerEventStop | WorkerEventRx)
|
||||
#define WORKER_EVENTS_MASK \
|
||||
(WorkerEventStop | WorkerEventRxData | WorkerEventRxIdle | WorkerEventRxOverrunError | \
|
||||
WorkerEventRxFramingError | WorkerEventRxNoiseError)
|
||||
|
||||
const NotificationSequence sequence_notification = {
|
||||
&message_display_backlight_on,
|
||||
@@ -91,14 +99,39 @@ static uint32_t uart_echo_exit(void* context) {
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
|
||||
static void
|
||||
uart_echo_on_irq_cb(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
UNUSED(handle);
|
||||
UartEchoApp* app = context;
|
||||
volatile FuriHalSerialRxEvent event_copy = event;
|
||||
UNUSED(event_copy);
|
||||
|
||||
if(ev == UartIrqEventRXNE) {
|
||||
WorkerEventFlags flag = 0;
|
||||
|
||||
if(event & FuriHalSerialRxEventData) {
|
||||
uint8_t data = furi_hal_serial_async_rx(handle);
|
||||
furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
|
||||
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx);
|
||||
flag |= WorkerEventRxData;
|
||||
}
|
||||
|
||||
if(event & FuriHalSerialRxEventIdle) {
|
||||
//idle line detected, packet transmission may have ended
|
||||
flag |= WorkerEventRxIdle;
|
||||
}
|
||||
|
||||
//error detected
|
||||
if(event & FuriHalSerialRxEventFrameError) {
|
||||
flag |= WorkerEventRxFramingError;
|
||||
}
|
||||
if(event & FuriHalSerialRxEventNoiseError) {
|
||||
flag |= WorkerEventRxNoiseError;
|
||||
}
|
||||
if(event & FuriHalSerialRxEventOverrunError) {
|
||||
flag |= WorkerEventRxOverrunError;
|
||||
}
|
||||
|
||||
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), flag);
|
||||
}
|
||||
|
||||
static void uart_echo_push_to_list(UartDumpModel* model, const char data) {
|
||||
@@ -153,13 +186,13 @@ static int32_t uart_echo_worker(void* context) {
|
||||
furi_check((events & FuriFlagError) == 0);
|
||||
|
||||
if(events & WorkerEventStop) break;
|
||||
if(events & WorkerEventRx) {
|
||||
if(events & WorkerEventRxData) {
|
||||
size_t length = 0;
|
||||
do {
|
||||
uint8_t data[64];
|
||||
length = furi_stream_buffer_receive(app->rx_stream, data, 64, 0);
|
||||
if(length > 0) {
|
||||
furi_hal_uart_tx(FuriHalUartIdUSART1, data, length);
|
||||
furi_hal_serial_tx(app->serial_handle, data, length);
|
||||
with_view_model(
|
||||
app->view,
|
||||
UartDumpModel * model,
|
||||
@@ -176,6 +209,23 @@ static int32_t uart_echo_worker(void* context) {
|
||||
with_view_model(
|
||||
app->view, UartDumpModel * model, { UNUSED(model); }, true);
|
||||
}
|
||||
|
||||
if(events & WorkerEventRxIdle) {
|
||||
furi_hal_serial_tx(app->serial_handle, (uint8_t*)"\r\nDetect IDLE\r\n", 15);
|
||||
}
|
||||
|
||||
if(events &
|
||||
(WorkerEventRxOverrunError | WorkerEventRxFramingError | WorkerEventRxNoiseError)) {
|
||||
if(events & WorkerEventRxOverrunError) {
|
||||
furi_hal_serial_tx(app->serial_handle, (uint8_t*)"\r\nDetect ORE\r\n", 14);
|
||||
}
|
||||
if(events & WorkerEventRxFramingError) {
|
||||
furi_hal_serial_tx(app->serial_handle, (uint8_t*)"\r\nDetect FE\r\n", 13);
|
||||
}
|
||||
if(events & WorkerEventRxNoiseError) {
|
||||
furi_hal_serial_tx(app->serial_handle, (uint8_t*)"\r\nDetect NE\r\n", 13);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -221,9 +271,11 @@ static UartEchoApp* uart_echo_app_alloc(uint32_t baudrate) {
|
||||
furi_thread_start(app->worker_thread);
|
||||
|
||||
// Enable uart listener
|
||||
furi_hal_console_disable();
|
||||
furi_hal_uart_set_br(FuriHalUartIdUSART1, baudrate);
|
||||
furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, uart_echo_on_irq_cb, app);
|
||||
app->serial_handle = furi_hal_serial_control_acquire(FuriHalSerialIdUsart);
|
||||
furi_check(app->serial_handle);
|
||||
furi_hal_serial_init(app->serial_handle, baudrate);
|
||||
|
||||
furi_hal_serial_async_rx_start(app->serial_handle, uart_echo_on_irq_cb, app, true);
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -231,7 +283,9 @@ static UartEchoApp* uart_echo_app_alloc(uint32_t baudrate) {
|
||||
static void uart_echo_app_free(UartEchoApp* app) {
|
||||
furi_assert(app);
|
||||
|
||||
furi_hal_console_enable(); // this will also clear IRQ callback so thread is no longer referenced
|
||||
furi_hal_serial_async_rx_stop(app->serial_handle);
|
||||
furi_hal_serial_deinit(app->serial_handle);
|
||||
furi_hal_serial_control_release(app->serial_handle);
|
||||
|
||||
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventStop);
|
||||
furi_thread_join(app->worker_thread);
|
||||
|
||||
@@ -2,8 +2,9 @@ App(
|
||||
appid="unit_tests",
|
||||
apptype=FlipperAppType.STARTUP,
|
||||
entry_point="unit_tests_on_system_start",
|
||||
sources=["unit_tests.c", "test_runner.c", "unit_test_api_table.cpp"],
|
||||
cdefines=["APP_UNIT_TESTS"],
|
||||
requires=["system_settings"],
|
||||
requires=["system_settings", "subghz_start"],
|
||||
provides=["delay_test"],
|
||||
resources="resources",
|
||||
order=100,
|
||||
@@ -12,9 +13,210 @@ App(
|
||||
App(
|
||||
appid="delay_test",
|
||||
name="Delay Test",
|
||||
sources=["tests/common/*.c", "tests/rpc/*.c"],
|
||||
apptype=FlipperAppType.SYSTEM,
|
||||
entry_point="delay_test_app",
|
||||
stack_size=1 * 1024,
|
||||
requires=["unit_tests"],
|
||||
order=110,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_varint",
|
||||
sources=["tests/common/*.c", "tests/varint/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_furi",
|
||||
sources=["tests/common/*.c", "tests/furi/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_furi_hal",
|
||||
sources=["tests/common/*.c", "tests/furi_hal/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_furi_hal_crypto",
|
||||
sources=["tests/common/*.c", "tests/furi_hal_crypto/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_furi_string",
|
||||
sources=["tests/common/*.c", "tests/furi_string/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_storage",
|
||||
sources=["tests/common/*.c", "tests/storage/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_stream",
|
||||
sources=["tests/common/*.c", "tests/stream/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_dirwalk",
|
||||
sources=["tests/common/*.c", "tests/dirwalk/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_manifest",
|
||||
sources=["tests/common/*.c", "tests/manifest/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_flipper_format",
|
||||
sources=["tests/common/*.c", "tests/flipper_format/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_flipper_format_string",
|
||||
sources=["tests/common/*.c", "tests/flipper_format_string/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_rpc",
|
||||
sources=["tests/common/*.c", "tests/rpc/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_subghz",
|
||||
sources=["tests/common/*.c", "tests/subghz/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_infrared",
|
||||
sources=["tests/common/*.c", "tests/infrared/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_nfc",
|
||||
sources=["tests/common/*.c", "tests/nfc/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_power",
|
||||
sources=["tests/common/*.c", "tests/power/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_protocol_dict",
|
||||
sources=["tests/common/*.c", "tests/protocol_dict/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_lfrfid",
|
||||
sources=["tests/common/*.c", "tests/lfrfid/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_bit_lib",
|
||||
sources=["tests/common/*.c", "tests/bit_lib/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_datetime",
|
||||
sources=["tests/common/*.c", "tests/datetime/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_float_tools",
|
||||
sources=["tests/common/*.c", "tests/float_tools/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_bt",
|
||||
sources=["tests/common/*.c", "tests/bt/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_dialogs_file_browser_options",
|
||||
sources=["tests/common/*.c", "tests/dialogs_file_browser_options/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_expansion",
|
||||
sources=["tests/common/*.c", "tests/expansion/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
App(
|
||||
appid="test_compress",
|
||||
sources=["tests/common/*.c", "tests/compress/*.c"],
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="get_api",
|
||||
requires=["unit_tests"],
|
||||
)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,205 @@
|
||||
Filetype: IR tests file
|
||||
Version: 1
|
||||
#
|
||||
name: decoder_input1
|
||||
type: raw
|
||||
data: 25557 8437 4188 571 1538 595 1514 567 1542 570 1539 573 501 565 1544 568 506 571 1539 573 501 565 509 568 508 569 506 571 1538 574 501 565 1543 569 506 571 504 573 1536 566 1544 568 506 592 1517 574 1535 567 507 570 505 572 1537 575 500 566 508 600 1509 572 503 574 501 565 1544 568 1540 593
|
||||
#
|
||||
name: decoder_expected1
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AF 00 00 00
|
||||
command: 36 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input2
|
||||
type: raw
|
||||
data: 25609 8444 4152 564 1568 544 1565 547 1561 541 1568 544 530 547 1536 566 510 567 1567 545 529 548 526 540 535 542 508 569 1539 573 527 539 1543 569 506 571 504 573 1561 541 508 569 507 570 1538 564 1545 567 507 570 505 572 1537 565 509 568 1541 571 1538 564 511 566 509 568 1539 573 1537 596
|
||||
#
|
||||
name: decoder_expected2
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AF 00 00 00
|
||||
command: 32 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input3
|
||||
type: raw
|
||||
data: 25582 8448 4176 571 1537 565 1544 568 1540 572 1537 575 500 566 1542 570 505 572 1537 575 500 566 508 569 506 571 504 573 1536 565 510 567 1542 570 504 573 1536 566 1543 569 506 571 504 573 1536 566 1543 569 506 571 504 573 502 575 500 566 1542 570 1539 573 502 575 500 566 1542 570 1540 572
|
||||
#
|
||||
name: decoder_expected3
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AF 00 00 00
|
||||
command: 33 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input4
|
||||
type: raw
|
||||
data: 25594 8443 4181 568 1542 570 505 572 1538 564 1545 567 508 569 1540 572 504 573 1536 566 510 567 1542 571 505 572 504 573 1562 540 510 567 1543 570 506 571 504 573 503 574 501 565 510 567 509 568 507 570 1539 573 502 565 1545 568 1542 571 1539 573 1536 566 1544 569 1541 572 503 574 1537 565
|
||||
#
|
||||
name: decoder_expected4
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 40 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input5
|
||||
type: raw
|
||||
data: 25556 8475 4150 597 1512 600 476 601 1509 603 1506 595 480 597 1512 600 476 601 1508 594 482 595 1515 597 478 599 477 600 1510 602 473 604 1506 595 480 597 1513 599 476 601 475 602 474 603 472 594 482 595 1514 598 477 600 476 601 1508 594 1516 596 1513 599 1510 602 1507 595 480 597 1513 599
|
||||
#
|
||||
name: decoder_expected5
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 41 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input6
|
||||
type: raw
|
||||
data: 25567 8471 4155 604 1506 596 480 597 1513 599 1510 603 473 594 1515 597 478 599 1511 602 474 603 1507 595 480 597 479 598 1511 602 474 603 1506 596 480 597 478 599 1511 602 474 603 472 594 481 596 479 598 1512 601 474 603 1506 596 479 598 1511 602 1508 594 1515 598 1512 600 475 602 1507 595
|
||||
#
|
||||
name: decoder_expected6
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 42 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input7
|
||||
type: raw
|
||||
data: 25584 8444 4180 569 1541 572 504 573 1536 566 1544 569 507 570 1539 574 501 566 1569 596 455 570 1540 573 502 575 501 565 1544 569 507 570 1565 548 503 574 1535 567 1543 570 506 571 529 548 502 565 511 566 1543 601 475 571 504 573 503 574 1536 566 1543 570 1539 574 1536 566 509 568 1541 572
|
||||
#
|
||||
name: decoder_expected7
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 43 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input8
|
||||
type: raw
|
||||
data: 25562 8445 4181 568 1543 570 505 572 1538 575 1535 567 508 569 1539 573 503 595 1514 567 508 600 1509 572 503 595 481 596 1513 568 507 601 1508 573 502 575 501 566 1543 570 506 571 504 573 1536 566 510 567 508 600 475 571 1539 573 502 575 1534 568 1542 571 505 572 1537 575 1534 568 1542 571
|
||||
#
|
||||
name: decoder_expected8
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 12 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input9
|
||||
type: raw
|
||||
data: 25558 8470 4152 597 1513 600 476 601 1508 594 1515 598 478 599 1509 593 483 594 1515 598 478 599 1510 603 474 592 482 595 1514 599 477 600 1509 593 483 594 481 596 1513 600 476 601 1508 594 1515 598 478 599 476 601 474 593 1517 596 479 598 1512 601 474 603 472 594 1515 598 1511 602 1508 594
|
||||
#
|
||||
name: decoder_expected9
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 1A 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input10
|
||||
type: raw
|
||||
data: 25587 8442 4179 601 1507 595 481 565 1544 600 1509 593 482 595 1513 568 507 570 1539 594 481 565 1544 600 476 570 505 593 1516 597 479 598 1511 591 484 593 481 575 1534 600 476 570 1539 595 480 597 478 599 476 570 505 593 1517 564 511 597 1511 602 474 572 1537 597 1513 600 1509 572 1537 565
|
||||
#
|
||||
name: decoder_expected10
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 0A 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: decoder_input11
|
||||
type: raw
|
||||
data: 25554 8474 4149 600 1510 603 472 594 1515 597 1512 601 475 602 1507 595 480 597 1513 599 475 602 1508 594 481 596 479 598 1512 601 474 603 1506 596 479 598 1512 601 1508 594 481 596 1513 599 476 601 474 603 472 594 481 596 480 597 478 599 1510 603 473 593 1515 597 1512 601 1509 603 1506 596
|
||||
#
|
||||
name: decoder_expected11
|
||||
type: parsed_array
|
||||
count: 1
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 0B 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
name: encoder_decoder_input1
|
||||
type: parsed_array
|
||||
count: 11
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AF 00 00 00
|
||||
command: 36 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AF 00 00 00
|
||||
command: 32 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AF 00 00 00
|
||||
command: 33 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 40 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 41 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 42 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 43 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 12 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 1A 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 0A 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
protocol: Pioneer
|
||||
address: AD 00 00 00
|
||||
command: 0B 00 00 00
|
||||
repeat: false
|
||||
#
|
||||
@@ -0,0 +1,41 @@
|
||||
Filetype: Flipper NFC device
|
||||
Version: 4
|
||||
# Device type can be ISO14443-3A, ISO14443-3B, ISO14443-4A, ISO14443-4B, ISO15693-3, FeliCa, NTAG/Ultralight, Mifare Classic, Mifare DESFire, SLIX, ST25TB
|
||||
Device type: SLIX
|
||||
# UID is common for all formats
|
||||
UID: E0 04 01 08 49 D0 DC 81
|
||||
# ISO15693-3 specific data
|
||||
# Data Storage Format Identifier
|
||||
DSFID: 01
|
||||
# Application Family Identifier
|
||||
AFI: 3D
|
||||
# IC Reference - Vendor specific meaning
|
||||
IC Reference: 01
|
||||
# Lock Bits
|
||||
Lock DSFID: true
|
||||
Lock AFI: true
|
||||
# Number of memory blocks, valid range = 1..256
|
||||
Block Count: 80
|
||||
# Size of a single memory block, valid range = 01...20 (hex)
|
||||
Block Size: 04
|
||||
Data Content: 03 0A 82 ED 86 39 61 D2 03 14 1E 32 B6 CA 00 3C 36 42 0C 33 53 30 37 32 32 34 30 30 00 00 00 00 00 FF 04 01 01 00 00 00 A3 03 1E 00 26 00 00 00 00 00 0F 00 76 03 65 01 00 00 00 00 85 01 34 00 75 09 05 00 01 00 00 00 00 00 00 00 00 00 00 00 D7 FA 00 1C 9E 1C 67 27 00 30 30 30 30 30 30 30 30 30 30 00 00 00 97 25 55 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 8C 00 30 53 48 80 DE 00 00 00 00 F4 C3 58 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 F3 00 2C DD C3 3E 91 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 FF 00 01
|
||||
# Block Security Status: 01 = locked, 00 = not locked
|
||||
Security Status: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
# SLIX specific data
|
||||
# SLIX capabilities field affects emulation modes. Possible options: Default, AcceptAllPasswords
|
||||
Capabilities: AcceptAllPasswords
|
||||
# Passwords are optional. If a password is omitted, a default value will be used
|
||||
Password Read: 00 00 00 00
|
||||
Password Write: 00 00 00 00
|
||||
Password Privacy: 0F 0F 0F 0F
|
||||
Password Destroy: 0F 0F 0F 0F
|
||||
Password EAS: 00 00 00 00
|
||||
# This is the card's secp128r1 elliptic curve signature. It can not be calculated without knowing NXP's private key.
|
||||
Signature: A6 25 54 03 74 24 C4 38 36 F4 89 70 76 1A 72 27 54 D9 E7 3D 38 CB 4C 1B 3E FD 0E DF 8A F6 7E 3D
|
||||
Privacy Mode: false
|
||||
# Protection pointer configuration
|
||||
Protection Pointer: 32
|
||||
Protection Condition: 02
|
||||
# SLIX Lock Bits
|
||||
Lock EAS: true
|
||||
Lock PPL: true
|
||||
@@ -0,0 +1,41 @@
|
||||
Filetype: Flipper NFC device
|
||||
Version: 4
|
||||
# Device type can be ISO14443-3A, ISO14443-3B, ISO14443-4A, ISO14443-4B, ISO15693-3, FeliCa, NTAG/Ultralight, Mifare Classic, Mifare DESFire, SLIX, ST25TB
|
||||
Device type: SLIX
|
||||
# UID is common for all formats
|
||||
UID: E0 04 01 08 49 D0 DC 81
|
||||
# ISO15693-3 specific data
|
||||
# Data Storage Format Identifier
|
||||
DSFID: 01
|
||||
# Application Family Identifier
|
||||
AFI: 3D
|
||||
# IC Reference - Vendor specific meaning
|
||||
IC Reference: 01
|
||||
# Lock Bits
|
||||
Lock DSFID: true
|
||||
Lock AFI: true
|
||||
# Number of memory blocks, valid range = 1..256
|
||||
Block Count: 80
|
||||
# Size of a single memory block, valid range = 01...20 (hex)
|
||||
Block Size: 04
|
||||
Data Content: 03 0A 82 ED 86 39 61 D2 03 14 1E 32 B6 CA 00 3C 36 42 0C 33 53 30 37 32 32 34 30 30 00 00 00 00 00 FF 04 01 01 00 00 00 A3 03 1E 00 26 00 00 00 00 00 0F 00 76 03 65 01 00 00 00 00 85 01 34 00 75 09 05 00 01 00 00 00 00 00 00 00 00 00 00 00 D7 FA 00 1C 9E 1C 67 27 00 30 30 30 30 30 30 30 30 30 30 00 00 00 97 25 55 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 8C 00 30 53 48 80 DE 00 00 00 00 F4 C3 58 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 F3 00 2C DD C3 3E 91 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 FF 00 01
|
||||
# Block Security Status: 01 = locked, 00 = not locked
|
||||
Security Status: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
# SLIX specific data
|
||||
# SLIX capabilities field affects emulation modes. Possible options: Default, AcceptAllPasswords
|
||||
Capabilities: Default
|
||||
# Passwords are optional. If a password is omitted, a default value will be used
|
||||
Password Read: 00 00 00 00
|
||||
Password Write: 00 00 00 00
|
||||
Password Privacy: 0F 0F 0F 0F
|
||||
Password Destroy: 0F 0F 0F 0F
|
||||
Password EAS: 00 00 00 00
|
||||
# This is the card's secp128r1 elliptic curve signature. It can not be calculated without knowing NXP's private key.
|
||||
Signature: A6 25 54 03 74 24 C4 38 36 F4 89 70 76 1A 72 27 54 D9 E7 3D 38 CB 4C 1B 3E FD 0E DF 8A F6 7E 3D
|
||||
Privacy Mode: false
|
||||
# Protection pointer configuration
|
||||
Protection Pointer: 32
|
||||
Protection Condition: 02
|
||||
# SLIX Lock Bits
|
||||
Lock EAS: true
|
||||
Lock PPL: true
|
||||
@@ -0,0 +1,39 @@
|
||||
Filetype: Flipper NFC device
|
||||
Version: 4
|
||||
# Device type can be ISO14443-3A, ISO14443-3B, ISO14443-4A, ISO14443-4B, ISO15693-3, FeliCa, NTAG/Ultralight, Mifare Classic, Mifare DESFire, SLIX, ST25TB
|
||||
Device type: SLIX
|
||||
# UID is common for all formats
|
||||
UID: E0 04 01 08 49 D0 DC 81
|
||||
# ISO15693-3 specific data
|
||||
# Data Storage Format Identifier
|
||||
DSFID: 01
|
||||
# Application Family Identifier
|
||||
AFI: 3D
|
||||
# IC Reference - Vendor specific meaning
|
||||
IC Reference: 01
|
||||
# Lock Bits
|
||||
Lock DSFID: true
|
||||
Lock AFI: true
|
||||
# Number of memory blocks, valid range = 1..256
|
||||
Block Count: 80
|
||||
# Size of a single memory block, valid range = 01...20 (hex)
|
||||
Block Size: 04
|
||||
Data Content: 03 0A 82 ED 86 39 61 D2 03 14 1E 32 B6 CA 00 3C 36 42 0C 33 53 30 37 32 32 34 30 30 00 00 00 00 00 FF 04 01 01 00 00 00 A3 03 1E 00 26 00 00 00 00 00 0F 00 76 03 65 01 00 00 00 00 85 01 34 00 75 09 05 00 01 00 00 00 00 00 00 00 00 00 00 00 D7 FA 00 1C 9E 1C 67 27 00 30 30 30 30 30 30 30 30 30 30 00 00 00 97 25 55 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 8C 00 30 53 48 80 DE 00 00 00 00 F4 C3 58 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 F3 00 2C DD C3 3E 91 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 FF 00 01
|
||||
# Block Security Status: 01 = locked, 00 = not locked
|
||||
Security Status: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
# SLIX specific data
|
||||
# Passwords are optional. If a password is omitted, a default value will be used
|
||||
Password Read: 00 00 00 00
|
||||
Password Write: 00 00 00 00
|
||||
Password Privacy: 0F 0F 0F 0F
|
||||
Password Destroy: 0F 0F 0F 0F
|
||||
Password EAS: 00 00 00 00
|
||||
# This is the card's secp128r1 elliptic curve signature. It can not be calculated without knowing NXP's private key.
|
||||
Signature: A6 25 54 03 74 24 C4 38 36 F4 89 70 76 1A 72 27 54 D9 E7 3D 38 CB 4C 1B 3E FD 0E DF 8A F6 7E 3D
|
||||
Privacy Mode: false
|
||||
# Protection pointer configuration
|
||||
Protection Pointer: 32
|
||||
Protection Condition: 02
|
||||
# SLIX Lock Bits
|
||||
Lock EAS: true
|
||||
Lock PPL: true
|
||||
@@ -1,164 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "minunit_vars.h"
|
||||
#include <notification/notification_messages.h>
|
||||
#include <cli/cli.h>
|
||||
#include <loader/loader.h>
|
||||
|
||||
#define TAG "UnitTests"
|
||||
|
||||
int run_minunit_test_furi();
|
||||
int run_minunit_test_furi_hal();
|
||||
int run_minunit_test_furi_hal_crypto();
|
||||
int run_minunit_test_furi_string();
|
||||
int run_minunit_test_infrared();
|
||||
int run_minunit_test_rpc();
|
||||
int run_minunit_test_manifest();
|
||||
int run_minunit_test_flipper_format();
|
||||
int run_minunit_test_flipper_format_string();
|
||||
int run_minunit_test_stream();
|
||||
int run_minunit_test_storage();
|
||||
int run_minunit_test_subghz();
|
||||
int run_minunit_test_dirwalk();
|
||||
int run_minunit_test_power();
|
||||
int run_minunit_test_protocol_dict();
|
||||
int run_minunit_test_lfrfid_protocols();
|
||||
int run_minunit_test_nfc();
|
||||
int run_minunit_test_bit_lib();
|
||||
int run_minunit_test_float_tools();
|
||||
int run_minunit_test_bt();
|
||||
int run_minunit_test_dialogs_file_browser_options();
|
||||
|
||||
typedef int (*UnitTestEntry)();
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const UnitTestEntry entry;
|
||||
} UnitTest;
|
||||
|
||||
const UnitTest unit_tests[] = {
|
||||
{.name = "furi", .entry = run_minunit_test_furi},
|
||||
{.name = "furi_hal", .entry = run_minunit_test_furi_hal},
|
||||
{.name = "furi_hal_crypto", .entry = run_minunit_test_furi_hal_crypto},
|
||||
{.name = "furi_string", .entry = run_minunit_test_furi_string},
|
||||
{.name = "storage", .entry = run_minunit_test_storage},
|
||||
{.name = "stream", .entry = run_minunit_test_stream},
|
||||
{.name = "dirwalk", .entry = run_minunit_test_dirwalk},
|
||||
{.name = "manifest", .entry = run_minunit_test_manifest},
|
||||
{.name = "flipper_format", .entry = run_minunit_test_flipper_format},
|
||||
{.name = "flipper_format_string", .entry = run_minunit_test_flipper_format_string},
|
||||
{.name = "rpc", .entry = run_minunit_test_rpc},
|
||||
{.name = "subghz", .entry = run_minunit_test_subghz},
|
||||
{.name = "infrared", .entry = run_minunit_test_infrared},
|
||||
{.name = "nfc", .entry = run_minunit_test_nfc},
|
||||
{.name = "power", .entry = run_minunit_test_power},
|
||||
{.name = "protocol_dict", .entry = run_minunit_test_protocol_dict},
|
||||
{.name = "lfrfid", .entry = run_minunit_test_lfrfid_protocols},
|
||||
{.name = "bit_lib", .entry = run_minunit_test_bit_lib},
|
||||
{.name = "float_tools", .entry = run_minunit_test_float_tools},
|
||||
{.name = "bt", .entry = run_minunit_test_bt},
|
||||
{.name = "dialogs_file_browser_options",
|
||||
.entry = run_minunit_test_dialogs_file_browser_options},
|
||||
};
|
||||
|
||||
void minunit_print_progress() {
|
||||
static const char progress[] = {'\\', '|', '/', '-'};
|
||||
static uint8_t progress_counter = 0;
|
||||
static uint32_t last_tick = 0;
|
||||
uint32_t current_tick = furi_get_tick();
|
||||
if(current_tick - last_tick > 20) {
|
||||
last_tick = current_tick;
|
||||
printf("[%c]\033[3D", progress[++progress_counter % COUNT_OF(progress)]);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void minunit_print_fail(const char* str) {
|
||||
printf(_FURI_LOG_CLR_E "%s\r\n" _FURI_LOG_CLR_RESET, str);
|
||||
}
|
||||
|
||||
void minunit_printf_warning(const char* format, ...) {
|
||||
FuriString* str = furi_string_alloc();
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
furi_string_vprintf(str, format, args);
|
||||
va_end(args);
|
||||
printf(_FURI_LOG_CLR_W "%s\r\n" _FURI_LOG_CLR_RESET, furi_string_get_cstr(str));
|
||||
furi_string_free(str);
|
||||
}
|
||||
|
||||
void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
|
||||
UNUSED(cli);
|
||||
UNUSED(args);
|
||||
UNUSED(context);
|
||||
minunit_run = 0;
|
||||
minunit_assert = 0;
|
||||
minunit_fail = 0;
|
||||
minunit_status = 0;
|
||||
|
||||
Loader* loader = furi_record_open(RECORD_LOADER);
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
// TODO FL-3491: lock device while test running
|
||||
if(loader_is_locked(loader)) {
|
||||
printf("RPC: stop all applications to run tests\r\n");
|
||||
notification_message(notification, &sequence_blink_magenta_100);
|
||||
} else {
|
||||
notification_message_block(notification, &sequence_set_only_blue_255);
|
||||
|
||||
uint32_t heap_before = memmgr_get_free_heap();
|
||||
uint32_t cycle_counter = furi_get_tick();
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(unit_tests); i++) {
|
||||
if(cli_cmd_interrupt_received(cli)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(furi_string_size(args)) {
|
||||
if(furi_string_cmp_str(args, unit_tests[i].name) == 0) {
|
||||
unit_tests[i].entry();
|
||||
} else {
|
||||
printf("Skipping %s\r\n", unit_tests[i].name);
|
||||
}
|
||||
} else {
|
||||
unit_tests[i].entry();
|
||||
}
|
||||
}
|
||||
|
||||
if(minunit_run != 0) {
|
||||
printf("\r\nFailed tests: %u\r\n", minunit_fail);
|
||||
|
||||
// Time report
|
||||
cycle_counter = (furi_get_tick() - cycle_counter);
|
||||
printf("Consumed: %lu ms\r\n", cycle_counter);
|
||||
|
||||
// Wait for tested services and apps to deallocate memory
|
||||
furi_delay_ms(200);
|
||||
uint32_t heap_after = memmgr_get_free_heap();
|
||||
printf("Leaked: %ld\r\n", heap_before - heap_after);
|
||||
|
||||
// Final Report
|
||||
if(minunit_fail == 0) {
|
||||
notification_message(notification, &sequence_success);
|
||||
printf("Status: PASSED\r\n");
|
||||
} else {
|
||||
notification_message(notification, &sequence_error);
|
||||
printf("Status: FAILED\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_LOADER);
|
||||
}
|
||||
|
||||
void unit_tests_on_system_start() {
|
||||
#ifdef SRV_CLI
|
||||
Cli* cli = furi_record_open(RECORD_CLI);
|
||||
|
||||
// We need to launch apps from tests, so we cannot lock loader
|
||||
cli_add_command(cli, "unit_tests", CliCommandFlagParallelSafe, unit_tests_cli, NULL);
|
||||
furi_record_close(RECORD_CLI);
|
||||
#endif
|
||||
}
|
||||
216
applications/debug/unit_tests/test_runner.c
Normal file
216
applications/debug/unit_tests/test_runner.c
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "test_runner.h"
|
||||
|
||||
#include "tests/test_api.h"
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include <toolbox/path.h>
|
||||
#include <loader/loader.h>
|
||||
#include <storage/storage.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#include <loader/firmware_api/firmware_api.h>
|
||||
#include <flipper_application/flipper_application.h>
|
||||
#include <flipper_application/api_hashtable/api_hashtable.h>
|
||||
#include <flipper_application/plugins/composite_resolver.h>
|
||||
|
||||
extern const ElfApiInterface* const unit_tests_api_interface;
|
||||
|
||||
#define TAG "TestRunner"
|
||||
|
||||
#define PLUGINS_PATH "/ext/apps_data/unit_tests/plugins"
|
||||
|
||||
struct TestRunner {
|
||||
Storage* storage;
|
||||
Loader* loader;
|
||||
NotificationApp* notification;
|
||||
|
||||
// Temporary used things
|
||||
Cli* cli;
|
||||
FuriString* args;
|
||||
|
||||
// ELF related stuff
|
||||
CompositeApiResolver* composite_resolver;
|
||||
|
||||
// Report data
|
||||
int minunit_run;
|
||||
int minunit_assert;
|
||||
int minunit_fail;
|
||||
int minunit_status;
|
||||
};
|
||||
|
||||
TestRunner* test_runner_alloc(Cli* cli, FuriString* args) {
|
||||
TestRunner* instance = malloc(sizeof(TestRunner));
|
||||
|
||||
instance->storage = furi_record_open(RECORD_STORAGE);
|
||||
instance->loader = furi_record_open(RECORD_LOADER);
|
||||
instance->notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
instance->cli = cli;
|
||||
instance->args = args;
|
||||
|
||||
instance->composite_resolver = composite_api_resolver_alloc();
|
||||
composite_api_resolver_add(instance->composite_resolver, firmware_api_interface);
|
||||
composite_api_resolver_add(instance->composite_resolver, unit_tests_api_interface);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void test_runner_free(TestRunner* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
composite_api_resolver_free(instance->composite_resolver);
|
||||
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
instance->notification = NULL;
|
||||
|
||||
furi_record_close(RECORD_LOADER);
|
||||
instance->loader = NULL;
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
instance->storage = NULL;
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
static bool test_runner_run_plugin(TestRunner* instance, const char* path) {
|
||||
furi_assert(instance);
|
||||
|
||||
FURI_LOG_D(TAG, "Loading %s", path);
|
||||
FlipperApplication* lib = flipper_application_alloc(
|
||||
instance->storage, composite_api_resolver_get(instance->composite_resolver));
|
||||
|
||||
bool result = false;
|
||||
instance->minunit_fail = -1;
|
||||
do {
|
||||
FlipperApplicationPreloadStatus preload_res = flipper_application_preload(lib, path);
|
||||
|
||||
if(preload_res != FlipperApplicationPreloadStatusSuccess) {
|
||||
FURI_LOG_E(TAG, "Failed to preload %s, %d", path, preload_res);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_application_is_plugin(lib)) {
|
||||
FURI_LOG_E(TAG, "Not a plugin %s", path);
|
||||
break;
|
||||
}
|
||||
|
||||
FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(lib);
|
||||
if(load_status != FlipperApplicationLoadStatusSuccess) {
|
||||
FURI_LOG_E(TAG, "Failed to load %s", path);
|
||||
break;
|
||||
}
|
||||
|
||||
const FlipperAppPluginDescriptor* app_descriptor =
|
||||
flipper_application_plugin_get_descriptor(lib);
|
||||
|
||||
const TestApi* test = app_descriptor->entry_point;
|
||||
|
||||
instance->minunit_fail = test->run();
|
||||
|
||||
instance->minunit_run += test->get_minunit_run();
|
||||
instance->minunit_assert += test->get_minunit_assert();
|
||||
instance->minunit_status += test->get_minunit_status();
|
||||
|
||||
result = (instance->minunit_fail == 0);
|
||||
} while(false);
|
||||
|
||||
flipper_application_free(lib);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void test_runner_run_internal(TestRunner* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
char file_name_buffer[256];
|
||||
FuriString* file_name = furi_string_alloc();
|
||||
FuriString* file_basename = furi_string_alloc();
|
||||
File* directory = storage_file_alloc(instance->storage);
|
||||
|
||||
do {
|
||||
if(!storage_dir_open(directory, PLUGINS_PATH)) {
|
||||
FURI_LOG_E(TAG, "Failed to open directory %s", PLUGINS_PATH);
|
||||
break;
|
||||
}
|
||||
|
||||
while(true) {
|
||||
if(cli_cmd_interrupt_received(instance->cli)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!storage_dir_read(directory, NULL, file_name_buffer, sizeof(file_name_buffer))) {
|
||||
break;
|
||||
}
|
||||
|
||||
furi_string_set(file_name, file_name_buffer);
|
||||
if(!furi_string_end_with_str(file_name, ".fal")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
path_concat(PLUGINS_PATH, file_name_buffer, file_name);
|
||||
|
||||
path_extract_filename(file_name, file_basename, true);
|
||||
const char* file_basename_cstr = furi_string_get_cstr(file_basename);
|
||||
|
||||
bool result = true;
|
||||
if(furi_string_size(instance->args)) {
|
||||
if(furi_string_cmp_str(instance->args, file_basename_cstr) == 0) {
|
||||
result = test_runner_run_plugin(instance, furi_string_get_cstr(file_name));
|
||||
} else {
|
||||
printf("Skipping %s\r\n", file_basename_cstr);
|
||||
}
|
||||
} else {
|
||||
result = test_runner_run_plugin(instance, furi_string_get_cstr(file_name));
|
||||
}
|
||||
|
||||
if(!result) {
|
||||
printf("Failed to execute test: %s\r\n", file_basename_cstr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(false);
|
||||
|
||||
storage_dir_close(directory);
|
||||
storage_file_free(directory);
|
||||
furi_string_free(file_name);
|
||||
furi_string_free(file_basename);
|
||||
}
|
||||
|
||||
void test_runner_run(TestRunner* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
// TODO FL-3491: lock device while test running
|
||||
if(loader_is_locked(instance->loader)) {
|
||||
printf("RPC: stop all applications to run tests\r\n");
|
||||
notification_message(instance->notification, &sequence_blink_magenta_100);
|
||||
} else {
|
||||
notification_message_block(instance->notification, &sequence_set_only_blue_255);
|
||||
|
||||
uint32_t heap_before = memmgr_get_free_heap();
|
||||
uint32_t cycle_counter = furi_get_tick();
|
||||
|
||||
test_runner_run_internal(instance);
|
||||
|
||||
if(instance->minunit_run != 0) {
|
||||
printf("\r\nFailed tests: %d\r\n", instance->minunit_fail);
|
||||
|
||||
// Time report
|
||||
cycle_counter = (furi_get_tick() - cycle_counter);
|
||||
printf("Consumed: %lu ms\r\n", cycle_counter);
|
||||
|
||||
// Wait for tested services and apps to deallocate memory
|
||||
furi_delay_ms(200);
|
||||
uint32_t heap_after = memmgr_get_free_heap();
|
||||
printf("Leaked: %ld\r\n", heap_before - heap_after);
|
||||
|
||||
// Final Report
|
||||
if(instance->minunit_fail == 0) {
|
||||
notification_message(instance->notification, &sequence_success);
|
||||
printf("Status: PASSED\r\n");
|
||||
} else {
|
||||
notification_message(instance->notification, &sequence_error);
|
||||
printf("Status: FAILED\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
applications/debug/unit_tests/test_runner.h
Normal file
12
applications/debug/unit_tests/test_runner.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
typedef struct TestRunner TestRunner;
|
||||
typedef struct Cli Cli;
|
||||
|
||||
TestRunner* test_runner_alloc(Cli* cli, FuriString* args);
|
||||
|
||||
void test_runner_free(TestRunner* isntance);
|
||||
|
||||
void test_runner_run(TestRunner* isntance);
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include <lfrfid/tools/bit_lib.h>
|
||||
#include "../test.h"
|
||||
#include <bit_lib/bit_lib.h>
|
||||
|
||||
MU_TEST(test_bit_lib_increment_index) {
|
||||
uint32_t index = 0;
|
||||
@@ -218,6 +218,178 @@ MU_TEST(test_bit_lib_get_bits_32) {
|
||||
mu_assert_int_eq(0b00001001101100011000110001100010, bit_lib_get_bits_32(value, 0, 32));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_get_bits_64) {
|
||||
uint8_t value[8] = {
|
||||
0b00001001,
|
||||
0b10110001,
|
||||
0b10001100,
|
||||
0b01100010,
|
||||
0b00001001,
|
||||
0b10110001,
|
||||
0b10001100,
|
||||
0b01100010};
|
||||
mu_assert_int_eq(0b0, bit_lib_get_bits_64(value, 0, 1));
|
||||
mu_assert_int_eq(0b00, bit_lib_get_bits_64(value, 0, 2));
|
||||
mu_assert_int_eq(0b000, bit_lib_get_bits_64(value, 0, 3));
|
||||
mu_assert_int_eq(0b0000, bit_lib_get_bits_64(value, 0, 4));
|
||||
mu_assert_int_eq(0b00001, bit_lib_get_bits_64(value, 0, 5));
|
||||
mu_assert_int_eq(0b000010, bit_lib_get_bits_64(value, 0, 6));
|
||||
mu_assert_int_eq(0b0000100, bit_lib_get_bits_64(value, 0, 7));
|
||||
mu_assert_int_eq(0b00001001, bit_lib_get_bits_64(value, 0, 8));
|
||||
mu_assert_int_eq(0b000010011, bit_lib_get_bits_64(value, 0, 9));
|
||||
mu_assert_int_eq(0b0000100110, bit_lib_get_bits_64(value, 0, 10));
|
||||
mu_assert_int_eq(0b00001001101, bit_lib_get_bits_64(value, 0, 11));
|
||||
mu_assert_int_eq(0b000010011011, bit_lib_get_bits_64(value, 0, 12));
|
||||
mu_assert_int_eq(0b0000100110110, bit_lib_get_bits_64(value, 0, 13));
|
||||
mu_assert_int_eq(0b00001001101100, bit_lib_get_bits_64(value, 0, 14));
|
||||
mu_assert_int_eq(0b000010011011000, bit_lib_get_bits_64(value, 0, 15));
|
||||
mu_assert_int_eq(0b0000100110110001, bit_lib_get_bits_64(value, 0, 16));
|
||||
mu_assert_int_eq(0b00001001101100011, bit_lib_get_bits_64(value, 0, 17));
|
||||
mu_assert_int_eq(0b000010011011000110, bit_lib_get_bits_64(value, 0, 18));
|
||||
mu_assert_int_eq(0b0000100110110001100, bit_lib_get_bits_64(value, 0, 19));
|
||||
mu_assert_int_eq(0b00001001101100011000, bit_lib_get_bits_64(value, 0, 20));
|
||||
mu_assert_int_eq(0b000010011011000110001, bit_lib_get_bits_64(value, 0, 21));
|
||||
mu_assert_int_eq(0b0000100110110001100011, bit_lib_get_bits_64(value, 0, 22));
|
||||
mu_assert_int_eq(0b00001001101100011000110, bit_lib_get_bits_64(value, 0, 23));
|
||||
mu_assert_int_eq(0b000010011011000110001100, bit_lib_get_bits_64(value, 0, 24));
|
||||
mu_assert_int_eq(0b0000100110110001100011000, bit_lib_get_bits_64(value, 0, 25));
|
||||
mu_assert_int_eq(0b00001001101100011000110001, bit_lib_get_bits_64(value, 0, 26));
|
||||
mu_assert_int_eq(0b000010011011000110001100011, bit_lib_get_bits_64(value, 0, 27));
|
||||
mu_assert_int_eq(0b0000100110110001100011000110, bit_lib_get_bits_64(value, 0, 28));
|
||||
mu_assert_int_eq(0b00001001101100011000110001100, bit_lib_get_bits_64(value, 0, 29));
|
||||
mu_assert_int_eq(0b000010011011000110001100011000, bit_lib_get_bits_64(value, 0, 30));
|
||||
mu_assert_int_eq(0b0000100110110001100011000110001, bit_lib_get_bits_64(value, 0, 31));
|
||||
mu_assert_int_eq(0b00001001101100011000110001100010, bit_lib_get_bits_64(value, 0, 32));
|
||||
|
||||
uint64_t res = bit_lib_get_bits_64(value, 0, 33);
|
||||
uint64_t expected = 0b000010011011000110001100011000100;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 34);
|
||||
expected = 0b0000100110110001100011000110001000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 35);
|
||||
expected = 0b00001001101100011000110001100010000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 36);
|
||||
expected = 0b000010011011000110001100011000100000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 37);
|
||||
expected = 0b0000100110110001100011000110001000001;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 38);
|
||||
expected = 0b00001001101100011000110001100010000010;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 39);
|
||||
expected = 0b000010011011000110001100011000100000100;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 40);
|
||||
expected = 0b0000100110110001100011000110001000001001;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 41);
|
||||
expected = 0b00001001101100011000110001100010000010011;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 42);
|
||||
expected = 0b000010011011000110001100011000100000100110;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 43);
|
||||
expected = 0b0000100110110001100011000110001000001001101;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 44);
|
||||
expected = 0b00001001101100011000110001100010000010011011;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 45);
|
||||
expected = 0b000010011011000110001100011000100000100110110;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 46);
|
||||
expected = 0b0000100110110001100011000110001000001001101100;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 47);
|
||||
expected = 0b00001001101100011000110001100010000010011011000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 48);
|
||||
expected = 0b000010011011000110001100011000100000100110110001;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 49);
|
||||
expected = 0b0000100110110001100011000110001000001001101100011;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 50);
|
||||
expected = 0b00001001101100011000110001100010000010011011000110;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 51);
|
||||
expected = 0b000010011011000110001100011000100000100110110001100;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 52);
|
||||
expected = 0b0000100110110001100011000110001000001001101100011000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 53);
|
||||
expected = 0b00001001101100011000110001100010000010011011000110001;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 54);
|
||||
expected = 0b000010011011000110001100011000100000100110110001100011;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 55);
|
||||
expected = 0b0000100110110001100011000110001000001001101100011000110;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 56);
|
||||
expected = 0b00001001101100011000110001100010000010011011000110001100;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 57);
|
||||
expected = 0b000010011011000110001100011000100000100110110001100011000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 58);
|
||||
expected = 0b0000100110110001100011000110001000001001101100011000110001;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 59);
|
||||
expected = 0b00001001101100011000110001100010000010011011000110001100011;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 60);
|
||||
expected = 0b000010011011000110001100011000100000100110110001100011000110;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 61);
|
||||
expected = 0b0000100110110001100011000110001000001001101100011000110001100;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 62);
|
||||
expected = 0b00001001101100011000110001100010000010011011000110001100011000;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 63);
|
||||
expected = 0b000010011011000110001100011000100000100110110001100011000110001;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
|
||||
res = bit_lib_get_bits_64(value, 0, 64);
|
||||
expected = 0b0000100110110001100011000110001000001001101100011000110001100010;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_test_parity_u32) {
|
||||
// test even parity
|
||||
mu_assert_int_eq(bit_lib_test_parity_32(0b00000000, BitLibParityEven), 0);
|
||||
@@ -447,6 +619,95 @@ MU_TEST(test_bit_lib_crc16) {
|
||||
mu_assert_int_eq(0x31C3, bit_lib_crc16(data, data_size, 0x1021, 0x0000, false, false, 0x0000));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_num_to_bytes_be) {
|
||||
uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
uint8_t dest[8];
|
||||
|
||||
bit_lib_num_to_bytes_be(0x01, 1, dest);
|
||||
mu_assert_mem_eq(src, dest, sizeof(src[0]));
|
||||
|
||||
bit_lib_num_to_bytes_be(0x0123456789ABCDEF, 4, dest);
|
||||
mu_assert_mem_eq(src + 4, dest, 4 * sizeof(src[0]));
|
||||
|
||||
bit_lib_num_to_bytes_be(0x0123456789ABCDEF, 8, dest);
|
||||
mu_assert_mem_eq(src, dest, 8 * sizeof(src[0]));
|
||||
|
||||
bit_lib_num_to_bytes_be(bit_lib_bytes_to_num_be(src, 8), 8, dest);
|
||||
mu_assert_mem_eq(src, dest, 8 * sizeof(src[0]));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_num_to_bytes_le) {
|
||||
uint8_t dest[8];
|
||||
|
||||
uint8_t n2b_le_expected_1[] = {0x01};
|
||||
bit_lib_num_to_bytes_le(0x01, 1, dest);
|
||||
mu_assert_mem_eq(n2b_le_expected_1, dest, sizeof(n2b_le_expected_1[0]));
|
||||
|
||||
uint8_t n2b_le_expected_2[] = {0xEF, 0xCD, 0xAB, 0x89};
|
||||
bit_lib_num_to_bytes_le(0x0123456789ABCDEF, 4, dest);
|
||||
mu_assert_mem_eq(n2b_le_expected_2, dest, 4 * sizeof(n2b_le_expected_2[0]));
|
||||
|
||||
uint8_t n2b_le_expected_3[] = {0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01};
|
||||
bit_lib_num_to_bytes_le(0x0123456789ABCDEF, 8, dest);
|
||||
mu_assert_mem_eq(n2b_le_expected_3, dest, 8 * sizeof(n2b_le_expected_3[0]));
|
||||
|
||||
bit_lib_num_to_bytes_le(bit_lib_bytes_to_num_le(n2b_le_expected_3, 8), 8, dest);
|
||||
mu_assert_mem_eq(n2b_le_expected_3, dest, 8 * sizeof(n2b_le_expected_3[0]));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_bytes_to_num_be) {
|
||||
uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
uint64_t res;
|
||||
|
||||
res = bit_lib_bytes_to_num_be(src, 1);
|
||||
mu_assert_int_eq(0x01, res);
|
||||
|
||||
res = bit_lib_bytes_to_num_be(src, 4);
|
||||
mu_assert_int_eq(0x01234567, res);
|
||||
|
||||
res = bit_lib_bytes_to_num_be(src, 8);
|
||||
uint64_t expected = 0x0123456789ABCDEF;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_bytes_to_num_le) {
|
||||
uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
uint64_t res;
|
||||
|
||||
res = bit_lib_bytes_to_num_le(src, 1);
|
||||
mu_assert_int_eq(0x01, res);
|
||||
|
||||
res = bit_lib_bytes_to_num_le(src, 4);
|
||||
mu_assert_int_eq(0x67452301, res);
|
||||
|
||||
res = bit_lib_bytes_to_num_le(src, 8);
|
||||
uint64_t expected = 0xEFCDAB8967452301;
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
}
|
||||
|
||||
MU_TEST(test_bit_lib_bytes_to_num_bcd) {
|
||||
uint8_t src[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
uint64_t res;
|
||||
bool is_bcd_res;
|
||||
|
||||
res = bit_lib_bytes_to_num_bcd(src, 1, &is_bcd_res);
|
||||
mu_assert_int_eq(01, res);
|
||||
mu_assert_int_eq(true, is_bcd_res);
|
||||
|
||||
res = bit_lib_bytes_to_num_bcd(src, 4, &is_bcd_res);
|
||||
mu_assert_int_eq(1234567, res);
|
||||
mu_assert_int_eq(true, is_bcd_res);
|
||||
|
||||
uint8_t digits[5] = {0x98, 0x76, 0x54, 0x32, 0x10};
|
||||
uint64_t expected = 9876543210;
|
||||
res = bit_lib_bytes_to_num_bcd(digits, 5, &is_bcd_res);
|
||||
mu_assert_mem_eq(&expected, &res, sizeof(expected));
|
||||
mu_assert_int_eq(true, is_bcd_res);
|
||||
|
||||
res = bit_lib_bytes_to_num_bcd(src, 8, &is_bcd_res);
|
||||
mu_assert_int_eq(false, is_bcd_res);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_bit_lib) {
|
||||
MU_RUN_TEST(test_bit_lib_increment_index);
|
||||
MU_RUN_TEST(test_bit_lib_is_set);
|
||||
@@ -457,6 +718,7 @@ MU_TEST_SUITE(test_bit_lib) {
|
||||
MU_RUN_TEST(test_bit_lib_get_bits);
|
||||
MU_RUN_TEST(test_bit_lib_get_bits_16);
|
||||
MU_RUN_TEST(test_bit_lib_get_bits_32);
|
||||
MU_RUN_TEST(test_bit_lib_get_bits_64);
|
||||
MU_RUN_TEST(test_bit_lib_test_parity_u32);
|
||||
MU_RUN_TEST(test_bit_lib_test_parity);
|
||||
MU_RUN_TEST(test_bit_lib_remove_bit_every_nth);
|
||||
@@ -465,9 +727,16 @@ MU_TEST_SUITE(test_bit_lib) {
|
||||
MU_RUN_TEST(test_bit_lib_get_bit_count);
|
||||
MU_RUN_TEST(test_bit_lib_reverse_16_fast);
|
||||
MU_RUN_TEST(test_bit_lib_crc16);
|
||||
MU_RUN_TEST(test_bit_lib_num_to_bytes_be);
|
||||
MU_RUN_TEST(test_bit_lib_num_to_bytes_le);
|
||||
MU_RUN_TEST(test_bit_lib_bytes_to_num_be);
|
||||
MU_RUN_TEST(test_bit_lib_bytes_to_num_le);
|
||||
MU_RUN_TEST(test_bit_lib_bytes_to_num_bcd);
|
||||
}
|
||||
|
||||
int run_minunit_test_bit_lib() {
|
||||
int run_minunit_test_bit_lib(void) {
|
||||
MU_RUN_SUITE(test_bit_lib);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_bit_lib)
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
#include <bt/bt_service/bt_keys_storage.h>
|
||||
#include <storage/storage.h>
|
||||
@@ -17,7 +17,7 @@ typedef struct {
|
||||
|
||||
BtTest* bt_test = NULL;
|
||||
|
||||
void bt_test_alloc() {
|
||||
void bt_test_alloc(void) {
|
||||
bt_test = malloc(sizeof(BtTest));
|
||||
bt_test->storage = furi_record_open(RECORD_STORAGE);
|
||||
bt_test->nvm_ram_buff_dut = malloc(BT_TEST_NVM_RAM_BUFF_SIZE);
|
||||
@@ -27,7 +27,7 @@ void bt_test_alloc() {
|
||||
bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, BT_TEST_NVM_RAM_BUFF_SIZE);
|
||||
}
|
||||
|
||||
void bt_test_free() {
|
||||
void bt_test_free(void) {
|
||||
furi_check(bt_test);
|
||||
free(bt_test->nvm_ram_buff_ref);
|
||||
free(bt_test->nvm_ram_buff_dut);
|
||||
@@ -37,7 +37,7 @@ void bt_test_free() {
|
||||
bt_test = NULL;
|
||||
}
|
||||
|
||||
static void bt_test_keys_storage_profile() {
|
||||
static void bt_test_keys_storage_profile(void) {
|
||||
// Emulate nvm change on initial connection
|
||||
const int nvm_change_size_on_connection = 88;
|
||||
for(size_t i = 0; i < nvm_change_size_on_connection; i++) {
|
||||
@@ -82,7 +82,7 @@ static void bt_test_keys_storage_profile() {
|
||||
"Wrong buffer loaded");
|
||||
}
|
||||
|
||||
static void bt_test_keys_remove_test_file() {
|
||||
static void bt_test_keys_remove_test_file(void) {
|
||||
mu_assert(
|
||||
storage_simply_remove(bt_test->storage, BT_TEST_KEY_STORAGE_FILE_PATH),
|
||||
"Can't remove test file");
|
||||
@@ -104,7 +104,9 @@ MU_TEST_SUITE(test_bt) {
|
||||
bt_test_free();
|
||||
}
|
||||
|
||||
int run_minunit_test_bt() {
|
||||
int run_minunit_test_bt(void) {
|
||||
MU_RUN_SUITE(test_bt);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_bt)
|
||||
42
applications/debug/unit_tests/tests/common/common.c
Normal file
42
applications/debug/unit_tests/tests/common/common.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "../test.h"
|
||||
#include "../minunit_vars.h"
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
void minunit_print_progress(void) {
|
||||
static const char progress[] = {'\\', '|', '/', '-'};
|
||||
static uint8_t progress_counter = 0;
|
||||
static uint32_t last_tick = 0;
|
||||
uint32_t current_tick = furi_get_tick();
|
||||
if(current_tick - last_tick > 20) {
|
||||
last_tick = current_tick;
|
||||
printf("[%c]\033[3D", progress[++progress_counter % COUNT_OF(progress)]);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void minunit_print_fail(const char* str) {
|
||||
printf(_FURI_LOG_CLR_E "%s\r\n" _FURI_LOG_CLR_RESET, str);
|
||||
}
|
||||
|
||||
void minunit_printf_warning(const char* format, ...) {
|
||||
FuriString* str = furi_string_alloc();
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
furi_string_vprintf(str, format, args);
|
||||
va_end(args);
|
||||
printf(_FURI_LOG_CLR_W "%s\r\n" _FURI_LOG_CLR_RESET, furi_string_get_cstr(str));
|
||||
furi_string_free(str);
|
||||
}
|
||||
|
||||
int get_minunit_run(void) {
|
||||
return minunit_run;
|
||||
}
|
||||
|
||||
int get_minunit_assert(void) {
|
||||
return minunit_assert;
|
||||
}
|
||||
|
||||
int get_minunit_status(void) {
|
||||
return minunit_status;
|
||||
}
|
||||
159
applications/debug/unit_tests/tests/compress/compress_test.c
Normal file
159
applications/debug/unit_tests/tests/compress/compress_test.c
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "../test.h"
|
||||
|
||||
#include <toolbox/compress.h>
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <furi_hal_random.h>
|
||||
|
||||
#include <storage/storage.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define COMPRESS_UNIT_TESTS_PATH(path) EXT_PATH("unit_tests/compress/" path)
|
||||
|
||||
static void compress_test_reference_comp_decomp() {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
File* compressed_file = storage_file_alloc(storage);
|
||||
File* decompressed_file = storage_file_alloc(storage);
|
||||
|
||||
mu_assert(
|
||||
storage_file_open(
|
||||
compressed_file,
|
||||
COMPRESS_UNIT_TESTS_PATH("compressed.bin"),
|
||||
FSAM_READ,
|
||||
FSOM_OPEN_EXISTING),
|
||||
"Failed to open compressed file");
|
||||
mu_assert(
|
||||
storage_file_open(
|
||||
decompressed_file,
|
||||
COMPRESS_UNIT_TESTS_PATH("uncompressed.bin"),
|
||||
FSAM_READ,
|
||||
FSOM_OPEN_EXISTING),
|
||||
"Failed to open decompressed file");
|
||||
|
||||
uint64_t compressed_ref_size = storage_file_size(compressed_file);
|
||||
uint64_t decompressed_ref_size = storage_file_size(decompressed_file);
|
||||
|
||||
mu_assert(compressed_ref_size > 0 && decompressed_ref_size > 0, "Invalid file sizes");
|
||||
|
||||
uint8_t* compressed_ref_buff = malloc(compressed_ref_size);
|
||||
uint8_t* decompressed_ref_buff = malloc(decompressed_ref_size);
|
||||
|
||||
mu_assert(
|
||||
storage_file_read(compressed_file, compressed_ref_buff, compressed_ref_size) ==
|
||||
compressed_ref_size,
|
||||
"Failed to read compressed file");
|
||||
|
||||
mu_assert(
|
||||
storage_file_read(decompressed_file, decompressed_ref_buff, decompressed_ref_size) ==
|
||||
decompressed_ref_size,
|
||||
"Failed to read decompressed file");
|
||||
|
||||
storage_file_free(compressed_file);
|
||||
storage_file_free(decompressed_file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
uint8_t* temp_buffer = malloc(1024);
|
||||
Compress* comp = compress_alloc(1024);
|
||||
|
||||
size_t encoded_size = 0;
|
||||
mu_assert(
|
||||
compress_encode(
|
||||
comp, decompressed_ref_buff, decompressed_ref_size, temp_buffer, 1024, &encoded_size),
|
||||
"Compress failed");
|
||||
|
||||
mu_assert(encoded_size == compressed_ref_size, "Encoded size is not equal to reference size");
|
||||
|
||||
mu_assert(
|
||||
memcmp(temp_buffer, compressed_ref_buff, compressed_ref_size) == 0,
|
||||
"Encoded buffer is not equal to reference");
|
||||
|
||||
size_t decoded_size = 0;
|
||||
mu_assert(
|
||||
compress_decode(
|
||||
comp, compressed_ref_buff, compressed_ref_size, temp_buffer, 1024, &decoded_size),
|
||||
"Decompress failed");
|
||||
|
||||
mu_assert(
|
||||
decoded_size == decompressed_ref_size, "Decoded size is not equal to reference size");
|
||||
|
||||
mu_assert(
|
||||
memcmp(temp_buffer, decompressed_ref_buff, decompressed_ref_size) == 0,
|
||||
"Decoded buffer is not equal to reference");
|
||||
|
||||
compress_free(comp);
|
||||
|
||||
free(temp_buffer);
|
||||
free(compressed_ref_buff);
|
||||
free(decompressed_ref_buff);
|
||||
}
|
||||
|
||||
static void compress_test_random_comp_decomp() {
|
||||
static const size_t src_buffer_size = 1024;
|
||||
static const size_t encoded_buffer_size = 1024;
|
||||
static const size_t small_buffer_size = src_buffer_size / 32;
|
||||
|
||||
// We only fill half of the buffer with random data, so if anything goes wrong, there's no overflow
|
||||
static const size_t src_data_size = src_buffer_size / 2;
|
||||
|
||||
Compress* comp = compress_alloc(src_buffer_size);
|
||||
uint8_t* src_buff = malloc(src_buffer_size);
|
||||
uint8_t* encoded_buff = malloc(encoded_buffer_size);
|
||||
uint8_t* decoded_buff = malloc(src_buffer_size);
|
||||
uint8_t* small_buff = malloc(small_buffer_size);
|
||||
|
||||
furi_hal_random_fill_buf(src_buff, src_data_size);
|
||||
|
||||
size_t encoded_size = 0;
|
||||
|
||||
mu_assert(
|
||||
compress_encode(
|
||||
comp, src_buff, src_data_size, encoded_buff, encoded_buffer_size, &encoded_size),
|
||||
"Compress failed");
|
||||
|
||||
mu_assert(encoded_size > 0, "Encoded size is zero");
|
||||
|
||||
size_t small_enc_dec_size = 0;
|
||||
mu_assert(
|
||||
compress_encode(
|
||||
comp, src_buff, src_data_size, small_buff, small_buffer_size, &small_enc_dec_size) ==
|
||||
false,
|
||||
"Compress to small buffer failed");
|
||||
|
||||
size_t decoded_size = 0;
|
||||
mu_assert(
|
||||
compress_decode(
|
||||
comp, encoded_buff, encoded_size, decoded_buff, src_buffer_size, &decoded_size),
|
||||
"Decompress failed");
|
||||
mu_assert(decoded_size == src_data_size, "Decoded size is not equal to source size");
|
||||
|
||||
mu_assert(
|
||||
memcmp(src_buff, decoded_buff, src_data_size) == 0,
|
||||
"Decoded buffer is not equal to source");
|
||||
|
||||
mu_assert(
|
||||
compress_decode(
|
||||
comp, encoded_buff, encoded_size, small_buff, small_buffer_size, &small_enc_dec_size) ==
|
||||
false,
|
||||
"Decompress to small buffer failed");
|
||||
|
||||
free(small_buff);
|
||||
free(src_buff);
|
||||
free(encoded_buff);
|
||||
free(decoded_buff);
|
||||
compress_free(comp);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_compress) {
|
||||
MU_RUN_TEST(compress_test_random_comp_decomp);
|
||||
MU_RUN_TEST(compress_test_reference_comp_decomp);
|
||||
}
|
||||
|
||||
int run_minunit_test_compress(void) {
|
||||
MU_RUN_SUITE(test_compress);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_compress)
|
||||
193
applications/debug/unit_tests/tests/datetime/datetimelib_test.c
Normal file
193
applications/debug/unit_tests/tests/datetime/datetimelib_test.c
Normal file
@@ -0,0 +1,193 @@
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
|
||||
#include <datetime/datetime.h>
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_correct_min) {
|
||||
DateTime correct_min = {0, 0, 0, 1, 1, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&correct_min);
|
||||
|
||||
mu_assert_int_eq(true, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_correct_max) {
|
||||
DateTime correct_max = {23, 59, 59, 31, 12, 2099, 7};
|
||||
bool result = datetime_validate_datetime(&correct_max);
|
||||
|
||||
mu_assert_int_eq(true, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_second) {
|
||||
DateTime incorrect_sec = {0, 0, 60, 1, 1, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_sec);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_minute) {
|
||||
DateTime incorrect_min = {0, 60, 0, 1, 1, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_min);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_hour) {
|
||||
DateTime incorrect_hour = {24, 0, 0, 1, 1, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_hour);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_day_min) {
|
||||
DateTime incorrect_day_min = {0, 0, 0, 0, 1, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_day_min);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_day_max) {
|
||||
DateTime incorrect_day_max = {0, 0, 0, 32, 1, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_day_max);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_month_min) {
|
||||
DateTime incorrect_month_min = {0, 0, 0, 1, 0, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_month_min);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_month_max) {
|
||||
DateTime incorrect_month_max = {0, 0, 0, 1, 13, 2000, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_month_max);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_year_min) {
|
||||
DateTime incorrect_year_min = {0, 0, 0, 1, 1, 1999, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_year_min);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_year_max) {
|
||||
DateTime incorrect_year_max = {0, 0, 0, 1, 1, 2100, 1};
|
||||
bool result = datetime_validate_datetime(&incorrect_year_max);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_weekday_min) {
|
||||
DateTime incorrect_weekday_min = {0, 0, 0, 1, 1, 2000, 0};
|
||||
bool result = datetime_validate_datetime(&incorrect_weekday_min);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_validate_datetime_incorrect_weekday_max) {
|
||||
DateTime incorrect_weekday_max = {0, 0, 0, 1, 1, 2000, 8};
|
||||
bool result = datetime_validate_datetime(&incorrect_weekday_max);
|
||||
|
||||
mu_assert_int_eq(false, result);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_datetime_validate_datetime) {
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_correct_min);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_correct_max);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_second);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_minute);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_hour);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_day_min);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_day_max);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_month_min);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_month_max);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_year_min);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_year_max);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_weekday_min);
|
||||
MU_RUN_TEST(test_datetime_validate_datetime_incorrect_weekday_max);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_timestamp_to_datetime_min) {
|
||||
uint32_t test_value = 0;
|
||||
DateTime min_datetime_expected = {0, 0, 0, 1, 1, 1970, 4};
|
||||
|
||||
DateTime result = {0};
|
||||
datetime_timestamp_to_datetime(test_value, &result);
|
||||
|
||||
mu_assert_mem_eq(&min_datetime_expected, &result, sizeof(result));
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_timestamp_to_datetime_max) {
|
||||
uint32_t test_value = UINT32_MAX;
|
||||
DateTime max_datetime_expected = {6, 28, 15, 7, 2, 2106, 7};
|
||||
|
||||
DateTime result = {0};
|
||||
datetime_timestamp_to_datetime(test_value, &result);
|
||||
|
||||
mu_assert_mem_eq(&max_datetime_expected, &result, sizeof(result));
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_timestamp_to_datetime_to_timestamp) {
|
||||
uint32_t test_value = random();
|
||||
|
||||
DateTime datetime = {0};
|
||||
datetime_timestamp_to_datetime(test_value, &datetime);
|
||||
|
||||
uint32_t result = datetime_datetime_to_timestamp(&datetime);
|
||||
|
||||
mu_assert_int_eq(test_value, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_timestamp_to_datetime_weekday) {
|
||||
uint32_t test_value = 1709748421; // Wed Mar 06 18:07:01 2024 UTC
|
||||
|
||||
DateTime datetime = {0};
|
||||
datetime_timestamp_to_datetime(test_value, &datetime);
|
||||
|
||||
mu_assert_int_eq(datetime.hour, 18);
|
||||
mu_assert_int_eq(datetime.minute, 7);
|
||||
mu_assert_int_eq(datetime.second, 1);
|
||||
mu_assert_int_eq(datetime.day, 6);
|
||||
mu_assert_int_eq(datetime.month, 3);
|
||||
mu_assert_int_eq(datetime.weekday, 3);
|
||||
mu_assert_int_eq(datetime.year, 2024);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_datetime_timestamp_to_datetime_suite) {
|
||||
MU_RUN_TEST(test_datetime_timestamp_to_datetime_min);
|
||||
MU_RUN_TEST(test_datetime_timestamp_to_datetime_max);
|
||||
MU_RUN_TEST(test_datetime_timestamp_to_datetime_to_timestamp);
|
||||
MU_RUN_TEST(test_datetime_timestamp_to_datetime_weekday);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_datetime_to_timestamp_min) {
|
||||
DateTime min_datetime = {0, 0, 0, 1, 1, 1970, 0};
|
||||
|
||||
uint32_t result = datetime_datetime_to_timestamp(&min_datetime);
|
||||
mu_assert_int_eq(0, result);
|
||||
}
|
||||
|
||||
MU_TEST(test_datetime_datetime_to_timestamp_max) {
|
||||
DateTime max_datetime = {6, 28, 15, 7, 2, 2106, 0};
|
||||
|
||||
uint32_t result = datetime_datetime_to_timestamp(&max_datetime);
|
||||
mu_assert_int_eq(UINT32_MAX, result);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_datetime_datetime_to_timestamp_suite) {
|
||||
MU_RUN_TEST(test_datetime_datetime_to_timestamp_min);
|
||||
MU_RUN_TEST(test_datetime_datetime_to_timestamp_max);
|
||||
}
|
||||
|
||||
int run_minunit_test_datetime(void) {
|
||||
MU_RUN_SUITE(test_datetime_timestamp_to_datetime_suite);
|
||||
MU_RUN_SUITE(test_datetime_datetime_to_timestamp_suite);
|
||||
MU_RUN_SUITE(test_datetime_validate_datetime);
|
||||
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_datetime)
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
MU_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields) {
|
||||
mu_assert(
|
||||
@@ -25,8 +25,10 @@ MU_TEST_SUITE(dialogs_file_browser_options) {
|
||||
MU_RUN_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields);
|
||||
}
|
||||
|
||||
int run_minunit_test_dialogs_file_browser_options() {
|
||||
int run_minunit_test_dialogs_file_browser_options(void) {
|
||||
MU_RUN_SUITE(dialogs_file_browser_options);
|
||||
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_dialogs_file_browser_options)
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
#include <furi.h>
|
||||
#include <m-dict.h>
|
||||
#include <toolbox/dir_walk.h>
|
||||
@@ -266,7 +266,9 @@ MU_TEST_SUITE(test_dirwalk_suite) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
int run_minunit_test_dirwalk() {
|
||||
int run_minunit_test_dirwalk(void) {
|
||||
MU_RUN_SUITE(test_dirwalk_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_dirwalk)
|
||||
202
applications/debug/unit_tests/tests/expansion/expansion_test.c
Normal file
202
applications/debug/unit_tests/tests/expansion/expansion_test.c
Normal file
@@ -0,0 +1,202 @@
|
||||
#include "../test.h"
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal_random.h>
|
||||
|
||||
#include <expansion/expansion_protocol.h>
|
||||
|
||||
#define EXPANSION_TEST_GARBAGE_MAGIC (0xB19AF)
|
||||
#define EXPANSION_TEST_GARBAGE_BUF_SIZE (0x100U)
|
||||
#define EXPANSION_TEST_GARBAGE_ITERATIONS (100U)
|
||||
|
||||
MU_TEST(test_expansion_encoded_size) {
|
||||
ExpansionFrame frame = {};
|
||||
|
||||
frame.header.type = ExpansionFrameTypeHeartbeat;
|
||||
mu_assert_int_eq(1, expansion_frame_get_encoded_size(&frame));
|
||||
|
||||
frame.header.type = ExpansionFrameTypeStatus;
|
||||
mu_assert_int_eq(2, expansion_frame_get_encoded_size(&frame));
|
||||
|
||||
frame.header.type = ExpansionFrameTypeBaudRate;
|
||||
mu_assert_int_eq(5, expansion_frame_get_encoded_size(&frame));
|
||||
|
||||
frame.header.type = ExpansionFrameTypeControl;
|
||||
mu_assert_int_eq(2, expansion_frame_get_encoded_size(&frame));
|
||||
|
||||
frame.header.type = ExpansionFrameTypeData;
|
||||
for(size_t i = 0; i <= EXPANSION_PROTOCOL_MAX_DATA_SIZE; ++i) {
|
||||
frame.content.data.size = i;
|
||||
mu_assert_int_eq(i + 2, expansion_frame_get_encoded_size(&frame));
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(test_expansion_remaining_size) {
|
||||
ExpansionFrame frame = {};
|
||||
|
||||
size_t remaining_size;
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 0, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
|
||||
frame.header.type = ExpansionFrameTypeHeartbeat;
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 0, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 1, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 100, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
|
||||
frame.header.type = ExpansionFrameTypeStatus;
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 0, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 1, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 2, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 100, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
|
||||
frame.header.type = ExpansionFrameTypeBaudRate;
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 0, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 1, &remaining_size));
|
||||
mu_assert_int_eq(4, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 5, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 100, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
|
||||
frame.header.type = ExpansionFrameTypeControl;
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 0, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 1, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 2, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 100, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
|
||||
frame.header.type = ExpansionFrameTypeData;
|
||||
frame.content.data.size = EXPANSION_PROTOCOL_MAX_DATA_SIZE;
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 0, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 1, &remaining_size));
|
||||
mu_assert_int_eq(1, remaining_size);
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 2, &remaining_size));
|
||||
mu_assert_int_eq(EXPANSION_PROTOCOL_MAX_DATA_SIZE, remaining_size);
|
||||
for(size_t i = 0; i <= EXPANSION_PROTOCOL_MAX_DATA_SIZE; ++i) {
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, i + 2, &remaining_size));
|
||||
mu_assert_int_eq(EXPANSION_PROTOCOL_MAX_DATA_SIZE - i, remaining_size);
|
||||
}
|
||||
mu_check(expansion_frame_get_remaining_size(&frame, 100, &remaining_size));
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
void* data_out;
|
||||
size_t size_available;
|
||||
size_t size_sent;
|
||||
} TestExpansionSendStream;
|
||||
|
||||
static size_t test_expansion_send_callback(const uint8_t* data, size_t data_size, void* context) {
|
||||
TestExpansionSendStream* stream = context;
|
||||
const size_t size_sent = MIN(data_size, stream->size_available);
|
||||
|
||||
memcpy(stream->data_out + stream->size_sent, data, size_sent);
|
||||
|
||||
stream->size_available -= size_sent;
|
||||
stream->size_sent += size_sent;
|
||||
|
||||
return size_sent;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const void* data_in;
|
||||
size_t size_available;
|
||||
size_t size_received;
|
||||
} TestExpansionReceiveStream;
|
||||
|
||||
static size_t test_expansion_receive_callback(uint8_t* data, size_t data_size, void* context) {
|
||||
TestExpansionReceiveStream* stream = context;
|
||||
const size_t size_received = MIN(data_size, stream->size_available);
|
||||
|
||||
memcpy(data, stream->data_in + stream->size_received, size_received);
|
||||
|
||||
stream->size_available -= size_received;
|
||||
stream->size_received += size_received;
|
||||
|
||||
return size_received;
|
||||
}
|
||||
|
||||
MU_TEST(test_expansion_encode_decode_frame) {
|
||||
const ExpansionFrame frame_in = {
|
||||
.header.type = ExpansionFrameTypeData,
|
||||
.content.data.size = 8,
|
||||
.content.data.bytes = {0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xca, 0xfe},
|
||||
};
|
||||
|
||||
uint8_t encoded_data[sizeof(ExpansionFrame) + sizeof(ExpansionFrameChecksum)];
|
||||
memset(encoded_data, 0, sizeof(encoded_data));
|
||||
|
||||
TestExpansionSendStream send_stream = {
|
||||
.data_out = &encoded_data,
|
||||
.size_available = sizeof(encoded_data),
|
||||
.size_sent = 0,
|
||||
};
|
||||
|
||||
const size_t encoded_size = expansion_frame_get_encoded_size(&frame_in);
|
||||
|
||||
mu_assert_int_eq(
|
||||
expansion_protocol_encode(&frame_in, test_expansion_send_callback, &send_stream),
|
||||
ExpansionProtocolStatusOk);
|
||||
mu_assert_int_eq(encoded_size + sizeof(ExpansionFrameChecksum), send_stream.size_sent);
|
||||
mu_assert_int_eq(
|
||||
expansion_protocol_get_checksum((const uint8_t*)&frame_in, encoded_size),
|
||||
encoded_data[encoded_size]);
|
||||
mu_assert_mem_eq(&frame_in, &encoded_data, encoded_size);
|
||||
|
||||
TestExpansionReceiveStream stream = {
|
||||
.data_in = encoded_data,
|
||||
.size_available = send_stream.size_sent,
|
||||
.size_received = 0,
|
||||
};
|
||||
|
||||
ExpansionFrame frame_out;
|
||||
|
||||
mu_assert_int_eq(
|
||||
expansion_protocol_decode(&frame_out, test_expansion_receive_callback, &stream),
|
||||
ExpansionProtocolStatusOk);
|
||||
mu_assert_int_eq(encoded_size + sizeof(ExpansionFrameChecksum), stream.size_received);
|
||||
mu_assert_mem_eq(&frame_in, &frame_out, encoded_size);
|
||||
}
|
||||
|
||||
MU_TEST(test_expansion_garbage_input) {
|
||||
uint8_t garbage_data[EXPANSION_TEST_GARBAGE_BUF_SIZE];
|
||||
for(uint32_t i = 0; i < EXPANSION_TEST_GARBAGE_ITERATIONS; ++i) {
|
||||
furi_hal_random_fill_buf(garbage_data, sizeof(garbage_data));
|
||||
size_t remaining_size = EXPANSION_TEST_GARBAGE_MAGIC;
|
||||
if(expansion_frame_get_remaining_size(
|
||||
(ExpansionFrame*)garbage_data, sizeof(garbage_data), &remaining_size)) {
|
||||
// If by chance the garbage data is a valid frame, then the result
|
||||
// must be 0 because the amount of data provided is more than enough
|
||||
mu_assert_int_eq(0, remaining_size);
|
||||
} else {
|
||||
// If the frame is invalid, the remaining_size parameter should be untouched
|
||||
mu_assert_int_eq(EXPANSION_TEST_GARBAGE_MAGIC, remaining_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_expansion_suite) {
|
||||
MU_RUN_TEST(test_expansion_encoded_size);
|
||||
MU_RUN_TEST(test_expansion_remaining_size);
|
||||
MU_RUN_TEST(test_expansion_encode_decode_frame);
|
||||
MU_RUN_TEST(test_expansion_garbage_input);
|
||||
}
|
||||
|
||||
int run_minunit_test_expansion(void) {
|
||||
MU_RUN_SUITE(test_expansion_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_expansion)
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <flipper_format/flipper_format.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
#define TEST_DIR TEST_DIR_NAME "/"
|
||||
#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp")
|
||||
@@ -103,14 +103,14 @@ static bool storage_write_string(const char* path, const char* data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static void tests_setup() {
|
||||
static void tests_setup(void) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data");
|
||||
mu_assert(storage_simply_mkdir(storage, TEST_DIR_NAME), "Cannot create dir");
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
static void tests_teardown() {
|
||||
static void tests_teardown(void) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data");
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
@@ -545,7 +545,9 @@ MU_TEST_SUITE(flipper_format) {
|
||||
tests_teardown();
|
||||
}
|
||||
|
||||
int run_minunit_test_flipper_format() {
|
||||
int run_minunit_test_flipper_format(void) {
|
||||
MU_RUN_SUITE(flipper_format);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_flipper_format)
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include <storage/storage.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
static const char* test_filetype = "Flipper Format test";
|
||||
static const uint32_t test_version = 666;
|
||||
@@ -331,7 +331,9 @@ MU_TEST_SUITE(flipper_format_string_suite) {
|
||||
MU_RUN_TEST(flipper_format_file_test);
|
||||
}
|
||||
|
||||
int run_minunit_test_flipper_format_string() {
|
||||
int run_minunit_test_flipper_format_string(void) {
|
||||
MU_RUN_SUITE(flipper_format_string_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_flipper_format_string)
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <float.h>
|
||||
#include <float_tools.h>
|
||||
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
MU_TEST(float_tools_equal_test) {
|
||||
mu_check(float_is_equal(FLT_MAX, FLT_MAX));
|
||||
@@ -54,7 +54,9 @@ MU_TEST_SUITE(float_tools_suite) {
|
||||
MU_RUN_TEST(float_tools_equal_test);
|
||||
}
|
||||
|
||||
int run_minunit_test_float_tools() {
|
||||
int run_minunit_test_float_tools(void) {
|
||||
MU_RUN_SUITE(float_tools_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_float_tools)
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void test_furi_memmgr() {
|
||||
void test_furi_memmgr(void) {
|
||||
void* ptr;
|
||||
|
||||
// allocate memory case
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
const uint32_t context_value = 0xdeadbeef;
|
||||
const uint32_t notify_value_0 = 0x12345678;
|
||||
@@ -15,7 +15,7 @@ void test_pubsub_handler(const void* arg, void* ctx) {
|
||||
pubsub_context_value = *(uint32_t*)ctx;
|
||||
}
|
||||
|
||||
void test_furi_pubsub() {
|
||||
void test_furi_pubsub(void) {
|
||||
FuriPubSub* test_pubsub = NULL;
|
||||
FuriPubSubSubscription* test_pubsub_subscription = NULL;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
#define TEST_RECORD_NAME "test/holding"
|
||||
|
||||
void test_furi_create_open() {
|
||||
void test_furi_create_open(void) {
|
||||
// Test that record does not exist
|
||||
mu_check(furi_record_exists(TEST_RECORD_NAME) == false);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
// v2 tests
|
||||
void test_furi_create_open();
|
||||
void test_furi_concurrent_access();
|
||||
void test_furi_pubsub();
|
||||
void test_furi_create_open(void);
|
||||
void test_furi_concurrent_access(void);
|
||||
void test_furi_pubsub(void);
|
||||
|
||||
void test_furi_memmgr();
|
||||
void test_furi_memmgr(void);
|
||||
|
||||
static int foo = 0;
|
||||
|
||||
@@ -50,8 +50,10 @@ MU_TEST_SUITE(test_suite) {
|
||||
MU_RUN_TEST(mu_test_furi_memmgr);
|
||||
}
|
||||
|
||||
int run_minunit_test_furi() {
|
||||
int run_minunit_test_furi(void) {
|
||||
MU_RUN_SUITE(test_suite);
|
||||
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_furi)
|
||||
@@ -1,8 +1,11 @@
|
||||
#include "furi_hal_rtc.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <lp5562_reg.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DATA_SIZE 4
|
||||
#define EEPROM_ADDRESS 0b10101000
|
||||
@@ -11,19 +14,19 @@
|
||||
#define EEPROM_PAGE_SIZE 16
|
||||
#define EEPROM_WRITE_DELAY_MS 6
|
||||
|
||||
static void furi_hal_i2c_int_setup() {
|
||||
static void furi_hal_i2c_int_setup(void) {
|
||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
}
|
||||
|
||||
static void furi_hal_i2c_int_teardown() {
|
||||
static void furi_hal_i2c_int_teardown(void) {
|
||||
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||
}
|
||||
|
||||
static void furi_hal_i2c_ext_setup() {
|
||||
static void furi_hal_i2c_ext_setup(void) {
|
||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
|
||||
}
|
||||
|
||||
static void furi_hal_i2c_ext_teardown() {
|
||||
static void furi_hal_i2c_ext_teardown(void) {
|
||||
furi_hal_i2c_release(&furi_hal_i2c_handle_external);
|
||||
}
|
||||
|
||||
@@ -224,8 +227,10 @@ MU_TEST_SUITE(furi_hal_i2c_ext_suite) {
|
||||
MU_RUN_TEST(furi_hal_i2c_ext_eeprom);
|
||||
}
|
||||
|
||||
int run_minunit_test_furi_hal() {
|
||||
int run_minunit_test_furi_hal(void) {
|
||||
MU_RUN_SUITE(furi_hal_i2c_int_suite);
|
||||
MU_RUN_SUITE(furi_hal_i2c_ext_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_furi_hal)
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
static const uint8_t key_ctr_1[32] = {
|
||||
0x77, 0x6B, 0xEF, 0xF2, 0x85, 0x1D, 0xB0, 0x6F, 0x4C, 0x8A, 0x05, 0x42, 0xC8, 0x69, 0x6F, 0x6C,
|
||||
@@ -409,16 +409,16 @@ static const uint8_t tv_gcm_tag_4[16] = {
|
||||
0x1B,
|
||||
};
|
||||
|
||||
static void furi_hal_crypto_ctr_setup() {
|
||||
static void furi_hal_crypto_ctr_setup(void) {
|
||||
}
|
||||
|
||||
static void furi_hal_crypto_ctr_teardown() {
|
||||
static void furi_hal_crypto_ctr_teardown(void) {
|
||||
}
|
||||
|
||||
static void furi_hal_crypto_gcm_setup() {
|
||||
static void furi_hal_crypto_gcm_setup(void) {
|
||||
}
|
||||
|
||||
static void furi_hal_crypto_gcm_teardown() {
|
||||
static void furi_hal_crypto_gcm_teardown(void) {
|
||||
}
|
||||
|
||||
MU_TEST(furi_hal_crypto_ctr_1) {
|
||||
@@ -595,8 +595,10 @@ MU_TEST_SUITE(furi_hal_crypto_gcm_test) {
|
||||
MU_RUN_TEST(furi_hal_crypto_gcm_4);
|
||||
}
|
||||
|
||||
int run_minunit_test_furi_hal_crypto() {
|
||||
int run_minunit_test_furi_hal_crypto(void) {
|
||||
MU_RUN_SUITE(furi_hal_crypto_ctr_test);
|
||||
MU_RUN_SUITE(furi_hal_crypto_gcm_test);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_furi_hal_crypto)
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
static void test_setup(void) {
|
||||
}
|
||||
@@ -462,8 +462,10 @@ MU_TEST_SUITE(test_suite) {
|
||||
MU_RUN_TEST(mu_test_furi_string_utf8);
|
||||
}
|
||||
|
||||
int run_minunit_test_furi_string() {
|
||||
int run_minunit_test_furi_string(void) {
|
||||
MU_RUN_SUITE(test_suite);
|
||||
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_furi_string)
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <flipper_format.h>
|
||||
#include <infrared.h>
|
||||
#include <common/infrared_common_i.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
#define IR_TEST_FILES_DIR EXT_PATH("unit_tests/infrared/")
|
||||
#define IR_TEST_FILE_PREFIX "test_"
|
||||
@@ -17,7 +17,7 @@ typedef struct {
|
||||
|
||||
static InfraredTest* test;
|
||||
|
||||
static void infrared_test_alloc() {
|
||||
static void infrared_test_alloc(void) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
test = malloc(sizeof(InfraredTest));
|
||||
test->decoder_handler = infrared_alloc_decoder();
|
||||
@@ -26,7 +26,7 @@ static void infrared_test_alloc() {
|
||||
test->file_path = furi_string_alloc();
|
||||
}
|
||||
|
||||
static void infrared_test_free() {
|
||||
static void infrared_test_free(void) {
|
||||
furi_check(test);
|
||||
infrared_free_decoder(test->decoder_handler);
|
||||
infrared_free_encoder(test->encoder_handler);
|
||||
@@ -426,53 +426,53 @@ MU_TEST(infrared_test_decoder_mixed) {
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 3);
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolPioneer, 6);
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_nec) {
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 2);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 3);
|
||||
for(uint32_t i = 1; i <= 3; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_unexpected_end_in_sequence) {
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 2);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, 2);
|
||||
for(uint32_t i = 1; i <= 2; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, i);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_necext1) {
|
||||
infrared_test_run_decoder(InfraredProtocolNECext, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolNECext, 1);
|
||||
for(uint32_t i = 0; i < 2; ++i) {
|
||||
UNUSED(i);
|
||||
infrared_test_run_decoder(InfraredProtocolNECext, 1);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_long_packets_with_nec_start) {
|
||||
infrared_test_run_decoder(InfraredProtocolNEC42ext, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolNEC42ext, 2);
|
||||
for(uint32_t i = 1; i <= 2; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolNEC42ext, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_encoder_sirc) {
|
||||
infrared_test_run_encoder(InfraredProtocolSIRC, 1);
|
||||
infrared_test_run_encoder(InfraredProtocolSIRC, 2);
|
||||
for(uint32_t i = 1; i <= 2; ++i) {
|
||||
infrared_test_run_encoder(InfraredProtocolSIRC, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_sirc) {
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 3);
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 2);
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 4);
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 5);
|
||||
for(uint32_t i = 1; i <= 5; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolSIRC, 5);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_rc5) {
|
||||
infrared_test_run_decoder(InfraredProtocolRC5X, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 2);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 3);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 4);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 5);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 6);
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, 7);
|
||||
|
||||
for(uint32_t i = 1; i <= 7; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolRC5, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_encoder_rc5x) {
|
||||
@@ -492,21 +492,21 @@ MU_TEST(infrared_test_encoder_rc6) {
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_kaseikyo) {
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 2);
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 3);
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 4);
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 5);
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, 6);
|
||||
for(uint32_t i = 1; i <= 6; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolKaseikyo, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_rca) {
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 1);
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 2);
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 3);
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 4);
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 5);
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, 6);
|
||||
for(uint32_t i = 1; i <= 6; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolRCA, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_decoder_pioneer) {
|
||||
for(uint32_t i = 1; i <= 11; ++i) {
|
||||
infrared_test_run_decoder(InfraredProtocolPioneer, i);
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(infrared_test_encoder_decoder_all) {
|
||||
@@ -520,6 +520,7 @@ MU_TEST(infrared_test_encoder_decoder_all) {
|
||||
infrared_test_run_encoder_decoder(InfraredProtocolSIRC, 1);
|
||||
infrared_test_run_encoder_decoder(InfraredProtocolKaseikyo, 1);
|
||||
infrared_test_run_encoder_decoder(InfraredProtocolRCA, 1);
|
||||
infrared_test_run_encoder_decoder(InfraredProtocolPioneer, 1);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(infrared_test) {
|
||||
@@ -539,11 +540,14 @@ MU_TEST_SUITE(infrared_test) {
|
||||
MU_RUN_TEST(infrared_test_decoder_necext1);
|
||||
MU_RUN_TEST(infrared_test_decoder_kaseikyo);
|
||||
MU_RUN_TEST(infrared_test_decoder_rca);
|
||||
MU_RUN_TEST(infrared_test_decoder_pioneer);
|
||||
MU_RUN_TEST(infrared_test_decoder_mixed);
|
||||
MU_RUN_TEST(infrared_test_encoder_decoder_all);
|
||||
}
|
||||
|
||||
int run_minunit_test_infrared() {
|
||||
int run_minunit_test_infrared(void) {
|
||||
MU_RUN_SUITE(infrared_test);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_infrared)
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
#include <toolbox/protocols/protocol_dict.h>
|
||||
#include <lfrfid/protocols/lfrfid_protocols.h>
|
||||
#include <toolbox/pulse_protocols/pulse_glue.h>
|
||||
@@ -209,6 +209,25 @@ const int8_t indala26_test_timings[INDALA26_EMULATION_TIMINGS_COUNT] = {
|
||||
-1, 1, -1, 1, -1, 1, -1, 1,
|
||||
};
|
||||
|
||||
#define FDXB_TEST_DATA \
|
||||
{ 0x44, 0x88, 0x23, 0xF2, 0x5A, 0x6F, 0x00, 0x01, 0x00, 0x00, 0x00 }
|
||||
#define FDXB_TEST_DATA_SIZE 11
|
||||
#define FDXB_TEST_EMULATION_TIMINGS_COUNT (206)
|
||||
|
||||
const int8_t fdxb_test_timings[FDXB_TEST_EMULATION_TIMINGS_COUNT] = {
|
||||
32, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16,
|
||||
-16, 16, -32, 16, -16, 32, -16, 16, -16, 16, -16, 16, -32, 16, -16, 16, -16, 32, -32,
|
||||
16, -16, 16, -16, 16, -16, 32, -16, 16, -16, 16, -16, 16, -32, 16, -16, 16, -16, 32,
|
||||
-16, 16, -16, 16, -16, 16, -32, 32, -32, 32, -32, 32, -32, 16, -16, 16, -16, 32, -16,
|
||||
16, -32, 16, -16, 32, -16, 16, -32, 32, -16, 16, -32, 16, -16, 32, -16, 16, -32, 32,
|
||||
-16, 16, -32, 32, -32, 32, -32, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16,
|
||||
16, -16, 16, -16, 32, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16,
|
||||
-32, 32, -32, 32, -32, 32, -32, 16, -16, 32, -32, 32, -16, 16, -16, 16, -32, 32, -32,
|
||||
32, -32, 32, -32, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16,
|
||||
-16, 32, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -32,
|
||||
16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16, 16, -16,
|
||||
};
|
||||
|
||||
MU_TEST(test_lfrfid_protocol_em_read_simple) {
|
||||
ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
|
||||
mu_assert_int_eq(EM_TEST_DATA_SIZE, protocol_dict_get_data_size(dict, LFRFIDProtocolEM4100));
|
||||
@@ -445,6 +464,73 @@ MU_TEST(test_lfrfid_protocol_inadala26_emulate_simple) {
|
||||
protocol_dict_free(dict);
|
||||
}
|
||||
|
||||
MU_TEST(test_lfrfid_protocol_fdxb_emulate_simple) {
|
||||
ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
|
||||
mu_assert_int_eq(FDXB_TEST_DATA_SIZE, protocol_dict_get_data_size(dict, LFRFIDProtocolFDXB));
|
||||
mu_assert_string_eq("FDX-B", protocol_dict_get_name(dict, LFRFIDProtocolFDXB));
|
||||
mu_assert_string_eq("ISO", protocol_dict_get_manufacturer(dict, LFRFIDProtocolFDXB));
|
||||
|
||||
const uint8_t data[FDXB_TEST_DATA_SIZE] = FDXB_TEST_DATA;
|
||||
|
||||
protocol_dict_set_data(dict, LFRFIDProtocolFDXB, data, FDXB_TEST_DATA_SIZE);
|
||||
mu_check(protocol_dict_encoder_start(dict, LFRFIDProtocolFDXB));
|
||||
|
||||
for(size_t i = 0; i < FDXB_TEST_EMULATION_TIMINGS_COUNT; i++) {
|
||||
LevelDuration level_duration = protocol_dict_encoder_yield(dict, LFRFIDProtocolFDXB);
|
||||
|
||||
if(level_duration_get_level(level_duration)) {
|
||||
mu_assert_int_eq(fdxb_test_timings[i], level_duration_get_duration(level_duration));
|
||||
} else {
|
||||
mu_assert_int_eq(fdxb_test_timings[i], -level_duration_get_duration(level_duration));
|
||||
}
|
||||
}
|
||||
|
||||
protocol_dict_free(dict);
|
||||
}
|
||||
|
||||
MU_TEST(test_lfrfid_protocol_fdxb_read_simple) {
|
||||
ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
|
||||
mu_assert_int_eq(FDXB_TEST_DATA_SIZE, protocol_dict_get_data_size(dict, LFRFIDProtocolFDXB));
|
||||
mu_assert_string_eq("FDX-B", protocol_dict_get_name(dict, LFRFIDProtocolFDXB));
|
||||
mu_assert_string_eq("ISO", protocol_dict_get_manufacturer(dict, LFRFIDProtocolFDXB));
|
||||
|
||||
const uint8_t data[FDXB_TEST_DATA_SIZE] = FDXB_TEST_DATA;
|
||||
|
||||
protocol_dict_decoders_start(dict);
|
||||
|
||||
ProtocolId protocol = PROTOCOL_NO;
|
||||
PulseGlue* pulse_glue = pulse_glue_alloc();
|
||||
|
||||
for(size_t i = 0; i < FDXB_TEST_EMULATION_TIMINGS_COUNT * 10; i++) {
|
||||
bool pulse_pop = pulse_glue_push(
|
||||
pulse_glue,
|
||||
fdxb_test_timings[i % FDXB_TEST_EMULATION_TIMINGS_COUNT] >= 0,
|
||||
abs(fdxb_test_timings[i % FDXB_TEST_EMULATION_TIMINGS_COUNT]) *
|
||||
LF_RFID_READ_TIMING_MULTIPLIER);
|
||||
|
||||
if(pulse_pop) {
|
||||
uint32_t length, period;
|
||||
pulse_glue_pop(pulse_glue, &length, &period);
|
||||
|
||||
protocol = protocol_dict_decoders_feed(dict, true, period);
|
||||
if(protocol != PROTOCOL_NO) break;
|
||||
|
||||
protocol = protocol_dict_decoders_feed(dict, false, length - period);
|
||||
if(protocol != PROTOCOL_NO) break;
|
||||
}
|
||||
}
|
||||
|
||||
pulse_glue_free(pulse_glue);
|
||||
|
||||
mu_assert_int_eq(LFRFIDProtocolFDXB, protocol);
|
||||
uint8_t received_data[FDXB_TEST_DATA_SIZE] = {0};
|
||||
protocol_dict_get_data(dict, protocol, received_data, FDXB_TEST_DATA_SIZE);
|
||||
|
||||
mu_assert_mem_eq(data, received_data, FDXB_TEST_DATA_SIZE);
|
||||
|
||||
protocol_dict_free(dict);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_lfrfid_protocols_suite) {
|
||||
MU_RUN_TEST(test_lfrfid_protocol_em_read_simple);
|
||||
MU_RUN_TEST(test_lfrfid_protocol_em_emulate_simple);
|
||||
@@ -456,9 +542,14 @@ MU_TEST_SUITE(test_lfrfid_protocols_suite) {
|
||||
MU_RUN_TEST(test_lfrfid_protocol_ioprox_xsf_emulate_simple);
|
||||
|
||||
MU_RUN_TEST(test_lfrfid_protocol_inadala26_emulate_simple);
|
||||
|
||||
MU_RUN_TEST(test_lfrfid_protocol_fdxb_read_simple);
|
||||
MU_RUN_TEST(test_lfrfid_protocol_fdxb_emulate_simple);
|
||||
}
|
||||
|
||||
int run_minunit_test_lfrfid_protocols() {
|
||||
int run_minunit_test_lfrfid_protocols(void) {
|
||||
MU_RUN_SUITE(test_lfrfid_protocols_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_lfrfid_protocols)
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.c>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
#include <update_util/resources/manifest.h>
|
||||
|
||||
#define TAG "Manifest"
|
||||
@@ -69,7 +69,9 @@ MU_TEST_SUITE(manifest_suite) {
|
||||
MU_RUN_TEST(manifest_iteration_test);
|
||||
}
|
||||
|
||||
int run_minunit_test_manifest() {
|
||||
int run_minunit_test_manifest(void) {
|
||||
MU_RUN_SUITE(manifest_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_manifest)
|
||||
@@ -7,33 +7,72 @@
|
||||
#include <nfc/nfc_poller.h>
|
||||
#include <nfc/nfc_listener.h>
|
||||
#include <nfc/protocols/iso14443_3a/iso14443_3a.h>
|
||||
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
|
||||
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.h>
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight.h>
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller_sync.h>
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller.h>
|
||||
#include <nfc/protocols/iso15693_3/iso15693_3_poller.h>
|
||||
#include <nfc/protocols/slix/slix.h>
|
||||
#include <nfc/protocols/slix/slix_i.h>
|
||||
#include <nfc/protocols/slix/slix_poller.h>
|
||||
#include <nfc/protocols/slix/slix_poller_i.h>
|
||||
|
||||
#include <nfc/nfc_poller.h>
|
||||
|
||||
#include <toolbox/keys_dict.h>
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
#define TAG "NfcTest"
|
||||
|
||||
#define NFC_TEST_NFC_DEV_PATH EXT_PATH("unit_tests/nfc/nfc_device_test.nfc")
|
||||
#define NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH EXT_PATH("unit_tests/mf_dict.nfc")
|
||||
|
||||
#define NFC_TEST_FLAG_WORKER_DONE (1)
|
||||
|
||||
typedef enum {
|
||||
NfcTestMfClassicSendFrameTestStateAuth,
|
||||
NfcTestMfClassicSendFrameTestStateReadBlock,
|
||||
|
||||
NfcTestMfClassicSendFrameTestStateFail,
|
||||
NfcTestMfClassicSendFrameTestStateSuccess,
|
||||
} NfcTestMfClassicSendFrameTestState;
|
||||
|
||||
typedef struct {
|
||||
NfcTestMfClassicSendFrameTestState state;
|
||||
BitBuffer* tx_buf;
|
||||
BitBuffer* rx_buf;
|
||||
FuriThreadId thread_id;
|
||||
} NfcTestMfClassicSendFrameTest;
|
||||
|
||||
typedef enum {
|
||||
NfcTestSlixPollerSetPasswordStateGetRandomNumber,
|
||||
NfcTestSlixPollerSetPasswordStateSetPassword,
|
||||
} NfcTestSlixPollerSetPasswordState;
|
||||
|
||||
typedef struct {
|
||||
FuriThreadId thread_id;
|
||||
NfcTestSlixPollerSetPasswordState state;
|
||||
SlixRandomNumber random_number;
|
||||
SlixPassword password;
|
||||
SlixError error;
|
||||
} NfcTestSlixPollerSetPasswordContext;
|
||||
|
||||
typedef struct {
|
||||
Storage* storage;
|
||||
} NfcTest;
|
||||
|
||||
static NfcTest* nfc_test = NULL;
|
||||
|
||||
static void nfc_test_alloc() {
|
||||
static void nfc_test_alloc(void) {
|
||||
nfc_test = malloc(sizeof(NfcTest));
|
||||
nfc_test->storage = furi_record_open(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
static void nfc_test_free() {
|
||||
static void nfc_test_free(void) {
|
||||
furi_check(nfc_test);
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
@@ -292,7 +331,7 @@ MU_TEST(ntag_213_locked_reader) {
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
static void mf_ultralight_write() {
|
||||
static void mf_ultralight_write(void) {
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
|
||||
@@ -342,7 +381,7 @@ static void mf_ultralight_write() {
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
static void mf_classic_reader() {
|
||||
static void mf_classic_reader(void) {
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
|
||||
@@ -368,7 +407,7 @@ static void mf_classic_reader() {
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
static void mf_classic_write() {
|
||||
static void mf_classic_write(void) {
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
|
||||
@@ -396,7 +435,7 @@ static void mf_classic_write() {
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
static void mf_classic_value_block() {
|
||||
static void mf_classic_value_block(void) {
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
|
||||
@@ -435,6 +474,109 @@ static void mf_classic_value_block() {
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
NfcCommand mf_classic_poller_send_frame_callback(NfcGenericEventEx event, void* context) {
|
||||
furi_check(event.poller);
|
||||
furi_check(event.parent_event_data);
|
||||
furi_check(context);
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
MfClassicPoller* instance = event.poller;
|
||||
NfcTestMfClassicSendFrameTest* frame_test = context;
|
||||
Iso14443_3aPollerEvent* iso3_event = event.parent_event_data;
|
||||
|
||||
MfClassicError error = MfClassicErrorNone;
|
||||
if(iso3_event->type == Iso14443_3aPollerEventTypeReady) {
|
||||
if(frame_test->state == NfcTestMfClassicSendFrameTestStateAuth) {
|
||||
MfClassicKey key = {
|
||||
.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
};
|
||||
error = mf_classic_poller_auth(instance, 0, &key, MfClassicKeyTypeA, NULL);
|
||||
frame_test->state = (error == MfClassicErrorNone) ?
|
||||
NfcTestMfClassicSendFrameTestStateReadBlock :
|
||||
NfcTestMfClassicSendFrameTestStateFail;
|
||||
} else if(frame_test->state == NfcTestMfClassicSendFrameTestStateReadBlock) {
|
||||
do {
|
||||
const uint8_t read_block_cmd[] = {
|
||||
0x30,
|
||||
0x01,
|
||||
0x8b,
|
||||
0xb9,
|
||||
};
|
||||
bit_buffer_copy_bytes(frame_test->tx_buf, read_block_cmd, sizeof(read_block_cmd));
|
||||
|
||||
error = mf_classic_poller_send_encrypted_frame(
|
||||
instance, frame_test->tx_buf, frame_test->rx_buf, 200000);
|
||||
if(error != MfClassicErrorNone) break;
|
||||
if(bit_buffer_get_size_bytes(frame_test->rx_buf) != 18) {
|
||||
error = MfClassicErrorProtocol;
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t* rx_data = bit_buffer_get_data(frame_test->rx_buf);
|
||||
const uint8_t rx_data_ref[16] = {0};
|
||||
if(memcmp(rx_data, rx_data_ref, sizeof(rx_data_ref)) != 0) {
|
||||
error = MfClassicErrorProtocol;
|
||||
break;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
frame_test->state = (error == MfClassicErrorNone) ?
|
||||
NfcTestMfClassicSendFrameTestStateSuccess :
|
||||
NfcTestMfClassicSendFrameTestStateFail;
|
||||
} else if(frame_test->state == NfcTestMfClassicSendFrameTestStateSuccess) {
|
||||
command = NfcCommandStop;
|
||||
} else if(frame_test->state == NfcTestMfClassicSendFrameTestStateFail) {
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
} else {
|
||||
frame_test->state = NfcTestMfClassicSendFrameTestStateFail;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_thread_flags_set(frame_test->thread_id, NFC_TEST_FLAG_WORKER_DONE);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
MU_TEST(mf_classic_send_frame_test) {
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
|
||||
NfcDevice* nfc_device = nfc_device_alloc();
|
||||
nfc_data_generator_fill_data(NfcDataGeneratorTypeMfClassic4k_7b, nfc_device);
|
||||
NfcListener* mfc_listener = nfc_listener_alloc(
|
||||
listener, NfcProtocolMfClassic, nfc_device_get_data(nfc_device, NfcProtocolMfClassic));
|
||||
nfc_listener_start(mfc_listener, NULL, NULL);
|
||||
|
||||
NfcPoller* mfc_poller = nfc_poller_alloc(poller, NfcProtocolMfClassic);
|
||||
NfcTestMfClassicSendFrameTest context = {
|
||||
.state = NfcTestMfClassicSendFrameTestStateAuth,
|
||||
.thread_id = furi_thread_get_current_id(),
|
||||
.tx_buf = bit_buffer_alloc(32),
|
||||
.rx_buf = bit_buffer_alloc(32),
|
||||
};
|
||||
nfc_poller_start_ex(mfc_poller, mf_classic_poller_send_frame_callback, &context);
|
||||
|
||||
uint32_t flag =
|
||||
furi_thread_flags_wait(NFC_TEST_FLAG_WORKER_DONE, FuriFlagWaitAny, FuriWaitForever);
|
||||
mu_assert(flag == NFC_TEST_FLAG_WORKER_DONE, "Wrong thread flag");
|
||||
nfc_poller_stop(mfc_poller);
|
||||
nfc_poller_free(mfc_poller);
|
||||
|
||||
mu_assert(
|
||||
context.state == NfcTestMfClassicSendFrameTestStateSuccess, "Wrong test state at the end");
|
||||
|
||||
bit_buffer_free(context.tx_buf);
|
||||
bit_buffer_free(context.rx_buf);
|
||||
nfc_listener_stop(mfc_listener);
|
||||
nfc_listener_free(mfc_listener);
|
||||
nfc_device_free(nfc_device);
|
||||
nfc_free(listener);
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
MU_TEST(mf_classic_dict_test) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
if(storage_common_stat(storage, NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, NULL) == FSE_OK) {
|
||||
@@ -504,6 +646,127 @@ MU_TEST(mf_classic_dict_test) {
|
||||
"Remove test dict failed");
|
||||
}
|
||||
|
||||
MU_TEST(slix_file_with_capabilities_test) {
|
||||
NfcDevice* nfc_device_missed_cap = nfc_device_alloc();
|
||||
mu_assert(
|
||||
nfc_device_load(nfc_device_missed_cap, EXT_PATH("unit_tests/nfc/Slix_cap_missed.nfc")),
|
||||
"nfc_device_load() failed\r\n");
|
||||
|
||||
NfcDevice* nfc_device_default_cap = nfc_device_alloc();
|
||||
mu_assert(
|
||||
nfc_device_load(nfc_device_default_cap, EXT_PATH("unit_tests/nfc/Slix_cap_default.nfc")),
|
||||
"nfc_device_load() failed\r\n");
|
||||
|
||||
mu_assert(
|
||||
nfc_device_is_equal(nfc_device_missed_cap, nfc_device_default_cap),
|
||||
"nfc_device_is_equal() failed\r\n");
|
||||
|
||||
nfc_device_free(nfc_device_default_cap);
|
||||
nfc_device_free(nfc_device_missed_cap);
|
||||
}
|
||||
|
||||
NfcCommand slix_poller_set_password_callback(NfcGenericEventEx event, void* context) {
|
||||
furi_check(event.poller);
|
||||
furi_check(event.parent_event_data);
|
||||
furi_check(context);
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
Iso15693_3PollerEvent* iso15_event = event.parent_event_data;
|
||||
SlixPoller* poller = event.poller;
|
||||
NfcTestSlixPollerSetPasswordContext* slix_ctx = context;
|
||||
|
||||
if(iso15_event->type == Iso15693_3PollerEventTypeReady) {
|
||||
iso15693_3_copy(
|
||||
poller->data->iso15693_3_data, iso15693_3_poller_get_data(poller->iso15693_3_poller));
|
||||
|
||||
if(slix_ctx->state == NfcTestSlixPollerSetPasswordStateGetRandomNumber) {
|
||||
slix_ctx->error = slix_poller_get_random_number(poller, &slix_ctx->random_number);
|
||||
if(slix_ctx->error != SlixErrorNone) {
|
||||
furi_thread_flags_set(slix_ctx->thread_id, NFC_TEST_FLAG_WORKER_DONE);
|
||||
command = NfcCommandStop;
|
||||
} else {
|
||||
slix_ctx->state = NfcTestSlixPollerSetPasswordStateSetPassword;
|
||||
}
|
||||
} else if(slix_ctx->state == NfcTestSlixPollerSetPasswordStateSetPassword) {
|
||||
slix_ctx->error = slix_poller_set_password(
|
||||
poller, SlixPasswordTypeRead, slix_ctx->password, slix_ctx->random_number);
|
||||
furi_thread_flags_set(slix_ctx->thread_id, NFC_TEST_FLAG_WORKER_DONE);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
} else {
|
||||
slix_ctx->error = slix_process_iso15693_3_error(iso15_event->data->error);
|
||||
furi_thread_flags_set(slix_ctx->thread_id, NFC_TEST_FLAG_WORKER_DONE);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void slix_set_password_test(const char* file_path, SlixPassword pass, bool correct_pass) {
|
||||
FURI_LOG_I(TAG, "Testing file: %s", file_path);
|
||||
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
|
||||
NfcDevice* nfc_device = nfc_device_alloc();
|
||||
mu_assert(nfc_device_load(nfc_device, file_path), "nfc_device_load() failed\r\n");
|
||||
|
||||
const SlixData* slix_data = nfc_device_get_data(nfc_device, NfcProtocolSlix);
|
||||
NfcListener* slix_listener = nfc_listener_alloc(listener, NfcProtocolSlix, slix_data);
|
||||
nfc_listener_start(slix_listener, NULL, NULL);
|
||||
|
||||
SlixCapabilities slix_capabilities = slix_data->capabilities;
|
||||
|
||||
NfcPoller* slix_poller = nfc_poller_alloc(poller, NfcProtocolSlix);
|
||||
|
||||
NfcTestSlixPollerSetPasswordContext slix_poller_context = {
|
||||
.thread_id = furi_thread_get_current_id(),
|
||||
.state = NfcTestSlixPollerSetPasswordStateGetRandomNumber,
|
||||
.password = pass,
|
||||
.error = SlixErrorNone,
|
||||
};
|
||||
|
||||
nfc_poller_start_ex(slix_poller, slix_poller_set_password_callback, &slix_poller_context);
|
||||
|
||||
uint32_t flag =
|
||||
furi_thread_flags_wait(NFC_TEST_FLAG_WORKER_DONE, FuriFlagWaitAny, FuriWaitForever);
|
||||
mu_assert(flag == NFC_TEST_FLAG_WORKER_DONE, "Wrong thread flag\r\n");
|
||||
|
||||
nfc_poller_stop(slix_poller);
|
||||
nfc_poller_free(slix_poller);
|
||||
nfc_listener_stop(slix_listener);
|
||||
nfc_listener_free(slix_listener);
|
||||
|
||||
mu_assert(
|
||||
slix_poller_context.state == NfcTestSlixPollerSetPasswordStateSetPassword,
|
||||
"Poller failed before setting password\r\n");
|
||||
|
||||
if((slix_capabilities == SlixCapabilitiesAcceptAllPasswords) || (correct_pass)) {
|
||||
mu_assert(slix_poller_context.error == SlixErrorNone, "Failed to set password\r\n");
|
||||
} else {
|
||||
mu_assert(
|
||||
slix_poller_context.error == SlixErrorTimeout,
|
||||
"Must have received SlixErrorTimeout\r\n");
|
||||
}
|
||||
|
||||
nfc_device_free(nfc_device);
|
||||
nfc_free(listener);
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
MU_TEST(slix_set_password_default_cap_correct_pass) {
|
||||
slix_set_password_test(EXT_PATH("unit_tests/nfc/Slix_cap_default.nfc"), 0x00000000, true);
|
||||
}
|
||||
|
||||
MU_TEST(slix_set_password_default_cap_incorrect_pass) {
|
||||
slix_set_password_test(EXT_PATH("unit_tests/nfc/Slix_cap_default.nfc"), 0x12341234, false);
|
||||
}
|
||||
|
||||
MU_TEST(slix_set_password_access_all_passwords_cap) {
|
||||
slix_set_password_test(
|
||||
EXT_PATH("unit_tests/nfc/Slix_cap_accept_all_pass.nfc"), 0x12341234, false);
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(nfc) {
|
||||
nfc_test_alloc();
|
||||
|
||||
@@ -538,17 +801,24 @@ MU_TEST_SUITE(nfc) {
|
||||
MU_RUN_TEST(mf_classic_1k_7b_file_test);
|
||||
MU_RUN_TEST(mf_classic_4k_4b_file_test);
|
||||
MU_RUN_TEST(mf_classic_4k_7b_file_test);
|
||||
MU_RUN_TEST(mf_classic_reader);
|
||||
|
||||
MU_RUN_TEST(mf_classic_reader);
|
||||
MU_RUN_TEST(mf_classic_write);
|
||||
MU_RUN_TEST(mf_classic_value_block);
|
||||
|
||||
MU_RUN_TEST(mf_classic_send_frame_test);
|
||||
MU_RUN_TEST(mf_classic_dict_test);
|
||||
|
||||
MU_RUN_TEST(slix_file_with_capabilities_test);
|
||||
MU_RUN_TEST(slix_set_password_default_cap_correct_pass);
|
||||
MU_RUN_TEST(slix_set_password_default_cap_incorrect_pass);
|
||||
MU_RUN_TEST(slix_set_password_access_all_passwords_cap);
|
||||
|
||||
nfc_test_free();
|
||||
}
|
||||
|
||||
int run_minunit_test_nfc() {
|
||||
int run_minunit_test_nfc(void) {
|
||||
MU_RUN_SUITE(nfc);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_nfc)
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
static void power_test_deinit(void) {
|
||||
// Try to reset to default charge voltage limit
|
||||
@@ -63,7 +63,9 @@ MU_TEST_SUITE(test_power_suite) {
|
||||
power_test_deinit();
|
||||
}
|
||||
|
||||
int run_minunit_test_power() {
|
||||
int run_minunit_test_power(void) {
|
||||
MU_RUN_SUITE(test_power_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_power)
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
#include <toolbox/protocols/protocol_dict.h>
|
||||
|
||||
typedef enum {
|
||||
@@ -18,7 +18,7 @@ typedef struct {
|
||||
|
||||
static const uint32_t protocol_0_decoder_result = 0xDEADBEEF;
|
||||
|
||||
static void* protocol_0_alloc() {
|
||||
static void* protocol_0_alloc(void) {
|
||||
void* data = malloc(sizeof(Protocol0Data));
|
||||
return data;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ typedef struct {
|
||||
|
||||
static const uint64_t protocol_1_decoder_result = 0x1234567890ABCDEF;
|
||||
|
||||
static void* protocol_1_alloc() {
|
||||
static void* protocol_1_alloc(void) {
|
||||
void* data = malloc(sizeof(Protocol1Data));
|
||||
return data;
|
||||
}
|
||||
@@ -216,7 +216,9 @@ MU_TEST_SUITE(test_protocol_dict_suite) {
|
||||
MU_RUN_TEST(test_protocol_dict);
|
||||
}
|
||||
|
||||
int run_minunit_test_protocol_dict() {
|
||||
int run_minunit_test_protocol_dict(void) {
|
||||
MU_RUN_SUITE(test_protocol_dict_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_protocol_dict)
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <lib/toolbox/path.h>
|
||||
|
||||
#include <m-list.h>
|
||||
#include "../minunit.h"
|
||||
#include "../test.h"
|
||||
|
||||
#include <protobuf_version.h>
|
||||
#include <pb.h>
|
||||
@@ -1840,7 +1840,7 @@ MU_TEST_SUITE(test_rpc_session) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
int run_minunit_test_rpc() {
|
||||
int run_minunit_test_rpc(void) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
if(storage_sd_status(storage) != FSE_OK) {
|
||||
FURI_LOG_E(TAG, "SD card not mounted - skip storage tests");
|
||||
@@ -1864,3 +1864,5 @@ int32_t delay_test_app(void* p) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_API_DEFINE(run_minunit_test_rpc)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user