Compare commits

...

219 Commits

Author SHA1 Message Date
Aleksandr Kutuzov
d1832d5e90 Merge remote-tracking branch 'origin/release-candidate' into release 2023-12-23 11:08:50 +00:00
Aleksandr Kutuzov
ad66d3b3c6 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-12-22 11:10:18 +00:00
あく
531ba24e9a
Rollback #3305 and #3297 fix various rendering issues (#3307)
* Revert "[FL-3729, FL-3730] Gui: fix string width calculation (#3305)"
* Revert "Added UTF-8 support to Flipper Zero canvas API (#3297)"
2023-12-22 11:08:46 +00:00
あく
1543170f4c
[FL-3729, FL-3730] Gui: fix string width calculation (#3305) 2023-12-21 16:43:11 +00:00
Aleksandr Kutuzov
c0be669a30 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-12-19 14:17:20 +00:00
Skorpionm
17b122990f
USART Bridge: added support for software control of DE/RE pins (#3280)
* USART Bridge: added support for software control of DE/RE pins
* USART Bridge: fix syntax
* UsbUsartBridge: add TODO ticket
* UsbUsartBridge: add second TODO ticket
* GpioUartBridge: human readable configuration
* GpioUartBridge: rename `Soft DE/RE` to `DE/RE Pin`
* GpioUartBridge: push pull for DE/RE pin

Co-authored-by: あく <alleteam@gmail.com>
2023-12-19 14:13:37 +00:00
hedger
1e1d9fcb69
ufbt: changed toolchain environment invocation; updated .gitignore for app template (#3300) 2023-12-19 12:43:06 +00:00
gornekich
6f6074dc01
Keys Dict: fix PVS warnings (#3299)
* keys dict: fix PVS warnings
* nfc app: suppress PVS warning
2023-12-19 12:11:35 +00:00
Evgeny Stepanischev
25d24f1e4c
Added UTF-8 support to Flipper Zero canvas API (#3297)
* Added UTF-8 support to Flipper Zero canvas API
* Add unicode example

Co-authored-by: あく <alleteam@gmail.com>
2023-12-18 18:36:50 +00:00
Andrea Maugeri
7642d67cae
NfcDict Refactoring (#3271)
* toolbox(keys_dict): generalize nfc_dict
* nfc: rework nfc app and tests
* toolbox(keys_dict): improve code readability
2023-12-18 14:30:56 +00:00
Aleksandr Kutuzov
5dbe1cf0bc Merge remote-tracking branch 'origin/release-candidate' into release 2023-12-08 16:08:51 +09:00
Aleksandr Kutuzov
8a3142da04 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-12-05 22:43:06 +09:00
Aleksandr Kutuzov
b0dc8a3940 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-12-04 15:35:41 +09:00
Aleksandr Kutuzov
f711b3f929 Merge remote-tracking branch 'origin/release-candidate' into release 2023-11-22 04:49:24 +09:00
Aleksandr Kutuzov
9524a5ef74 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-11-16 01:53:37 +09:00
Aleksandr Kutuzov
e487bcd2f8 Merge remote-tracking branch 'origin/release-candidate' into release 2023-11-01 15:48:39 +09:00
Aleksandr Kutuzov
880e7bb1a8 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-10-28 23:47:59 +09:00
Aleksandr Kutuzov
fa2d516017 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-10-24 12:14:29 +09:00
Aleksandr Kutuzov
e8c6e70a5f Merge remote-tracking branch 'origin/release-candidate' into release 2023-10-12 10:42:41 +09:00
Aleksandr Kutuzov
333f45d2c6 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-10-10 07:01:58 +09:00
Aleksandr Kutuzov
4fc6f3b245 Merge remote-tracking branch 'origin/release-candidate' into release 2023-09-26 23:24:34 +09:00
Aleksandr Kutuzov
a3e07586ee Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-26 16:29:58 +09:00
Aleksandr Kutuzov
9fd8d30b6f Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-25 17:31:33 +09:00
Aleksandr Kutuzov
81e490117a Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-21 23:35:58 +09:00
Aleksandr Kutuzov
176c3618b1 Merge remote-tracking branch 'origin/release-candidate' into release 2023-09-15 19:44:19 +09:00
Aleksandr Kutuzov
dba34f25fe Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-14 18:35:28 +09:00
Aleksandr Kutuzov
6ceb71e327 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-12 10:21:06 +09:00
Aleksandr Kutuzov
60c96b97c6 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-12 01:36:34 +09:00
Aleksandr Kutuzov
ff41b65077 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-12 01:18:41 +09:00
Aleksandr Kutuzov
fe637da8fc Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-12 00:40:01 +09:00
Aleksandr Kutuzov
baf661d47d Merge remote-tracking branch 'origin/dev' into release-candidate 2023-09-11 22:37:30 +09:00
Aleksandr Kutuzov
384e950ab3 Merge remote-tracking branch 'origin/release-candidate' into release 2023-08-31 14:49:45 +09:00
Aleksandr Kutuzov
0d991e6960 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-08-29 21:19:47 +09:00
Aleksandr Kutuzov
d874fcd5cb Merge remote-tracking branch 'origin/dev' into release-candidate 2023-08-24 05:53:38 +09:00
Aleksandr Kutuzov
5a58004bbb Merge remote-tracking branch 'origin/release-candidate' into release 2023-08-16 21:53:56 +09:00
Aleksandr Kutuzov
4b5f829375 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-08-11 03:09:30 +09:00
Aleksandr Kutuzov
357fbfe63b Merge remote-tracking branch 'origin/release-candidate' into release 2023-08-04 22:29:19 +09:00
Aleksandr Kutuzov
45e78fbdc2 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-08-03 16:29:04 +09:00
Aleksandr Kutuzov
bf262efed5 Merge remote-tracking branch 'origin/release-candidate' into release 2023-07-20 15:21:02 +04:00
Aleksandr Kutuzov
12f898f0ff Merge remote-tracking branch 'origin/dev' into release-candidate 2023-07-18 15:05:17 +04:00
Aleksandr Kutuzov
c29941aefb Merge remote-tracking branch 'origin/release-candidate' into release 2023-07-12 18:24:01 +04:00
Skorpionm
06b8b9bf1e SubGhz: fix check connect cc1101_ext (#2857)
* SubGhz: fix check connect cc1101_ext
* SubGhz: fix syntax
* SubGhz: enable interface pin pullups
* SubGhz: fix syntax
* SubGhz: fix CLI check connect CC1101_ext
* SubGhz: fix CLI display of the selected device

Co-authored-by: あく <alleteam@gmail.com>
2023-07-12 15:09:55 +04:00
Aleksandr Kutuzov
3991db4b36 Merge remote-tracking branch 'origin/release-candidate' into release 2023-07-06 21:01:41 +09:00
Aleksandr Kutuzov
279a33dc8c Merge remote-tracking branch 'origin/dev' into release-candidate 2023-07-06 02:01:48 +09:00
Aleksandr Kutuzov
948dafc434 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-07-02 04:43:52 +09:00
Aleksandr Kutuzov
27a8f29a68 Merge remote-tracking branch 'origin/release-candidate' into release 2023-06-16 16:28:58 +09:00
Aleksandr Kutuzov
7081d76e7b Merge remote-tracking branch 'origin/dev' into release-candidate 2023-06-15 21:27:44 +09:00
Aleksandr Kutuzov
60baf2a608 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-06-14 20:50:13 +09:00
Aleksandr Kutuzov
1ac1f0b441 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-06-09 22:22:59 +09:00
Aleksandr Kutuzov
406cb8b711 Merge remote-tracking branch 'origin/release-candidate' into release 2023-06-03 06:21:05 +09:00
Aleksandr Kutuzov
dc3d56523a Merge remote-tracking branch 'origin/dev' into release-candidate 2023-06-03 06:03:02 +09:00
Aleksandr Kutuzov
e4830a6ebc Merge remote-tracking branch 'origin/release-candidate' into release 2023-06-03 01:14:42 +09:00
Aleksandr Kutuzov
2d8f262dd4 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-06-01 21:50:05 +09:00
Aleksandr Kutuzov
96d97af4e6 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-05-30 01:48:41 +09:00
Aleksandr Kutuzov
16b976478c Merge remote-tracking branch 'origin/release-candidate' into release 2023-05-17 18:28:55 +09:00
Aleksandr Kutuzov
9cedac9adf Merge remote-tracking branch 'origin/dev' into release-candidate 2023-05-15 20:55:58 +09:00
Aleksandr Kutuzov
508dbe4984 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-05-11 19:13:36 +09:00
Aleksandr Kutuzov
b7f406d43b Merge branch 'release-candidate' into release 2023-04-28 00:46:14 +09:00
Aleksandr Kutuzov
849aa0f784 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-04-27 23:01:55 +09:00
Aleksandr Kutuzov
df78ba8e09 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-04-26 15:39:56 +09:00
Aleksandr Kutuzov
31e47e97bd Merge remote-tracking branch 'origin/dev' into release-candidate 2023-04-24 16:39:53 +09:00
Aleksandr Kutuzov
085c8008db Merge remote-tracking branch 'origin/dev' into release-candidate 2023-04-20 22:10:24 +09:00
Aleksandr Kutuzov
376319cbc8 Merge remote-tracking branch 'origin/release-candidate' into release 2023-04-12 23:13:23 +09:00
Aleksandr Kutuzov
728320b713 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-04-12 15:12:01 +09:00
Aleksandr Kutuzov
b55677673f Merge remote-tracking branch 'origin/dev' into release-candidate 2023-04-07 11:05:52 +08:00
Aleksandr Kutuzov
c41fe8e4e4 Merge remote-tracking branch 'origin/release-candidate' into release 2023-03-28 14:13:19 +09:00
Aleksandr Kutuzov
9b9dce3676 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-03-27 16:42:32 +09:00
Aleksandr Kutuzov
e52e30c56d Merge remote-tracking branch 'origin/dev' into release-candidate 2023-03-23 05:27:22 +09:00
Aleksandr Kutuzov
b698126c36 Merge remote-tracking branch 'origin/release-candidate' into release 2023-03-13 16:04:36 +09:00
Aleksandr Kutuzov
f141a67788 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-03-10 20:15:19 +09:00
Aleksandr Kutuzov
dec00feb7b Merge remote-tracking branch 'origin/dev' into release-candidate 2023-03-10 18:26:49 +09:00
Aleksandr Kutuzov
61744b8d01 Merge remote-tracking branch 'origin/release-candidate' into release 2023-02-28 00:59:33 +09:00
Aleksandr Kutuzov
119c7fe5f1 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-02-27 23:59:52 +09:00
Aleksandr Kutuzov
e9984f8b4c Merge branch 'dev' into release-candidate 2023-02-27 15:25:21 +09:00
Aleksandr Kutuzov
a38a62fe79 Merge remote-tracking branch 'origin/release-candidate' into release 2023-02-14 18:53:04 +09:00
Aleksandr Kutuzov
e2e4dcc2f8 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-02-14 00:44:31 +09:00
Aleksandr Kutuzov
ea5fe0ec86 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-02-09 14:45:49 +09:00
Aleksandr Kutuzov
8a08fd5da9 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-02-09 14:10:01 +09:00
Aleksandr Kutuzov
13a0a92f0d Merge branch 'release-candidate' into release 2023-02-02 21:22:44 +07:00
Aleksandr Kutuzov
48eb15c79c Merge remote-tracking branch 'origin/dev' into release-candidate 2023-01-30 16:57:20 +07:00
Aleksandr Kutuzov
8ee66c3e9b Merge remote-tracking branch 'origin/release-candidate' into release 2023-01-09 02:02:31 +09:00
Aleksandr Kutuzov
e18056ba78 Merge remote-tracking branch 'origin/dev' into release-candidate 2023-01-08 20:19:22 +09:00
Aleksandr Kutuzov
b60ba76551 Merge remote-tracking branch 'origin/release-candidate' into release 2022-12-24 00:34:50 +09:00
Aleksandr Kutuzov
5670397c3b Merge remote-tracking branch 'origin/dev' into release-candidate 2022-12-23 22:47:02 +09:00
Aleksandr Kutuzov
6ff3f821b2 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-12-23 19:37:55 +09:00
Aleksandr Kutuzov
8bc7723faa Merge remote-tracking branch 'origin/dev' into release-candidate 2022-12-21 00:08:55 +09:00
Aleksandr Kutuzov
09f3dc74bc Merge remote-tracking branch 'origin/release-candidate' into release 2022-12-10 04:43:41 +09:00
Aleksandr Kutuzov
0d7f305da1 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-12-10 04:32:10 +09:00
Aleksandr Kutuzov
c7bf3d3066 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-12-08 18:32:17 +09:00
Aleksandr Kutuzov
579e3b5f26 Merge remote-tracking branch 'origin/release-candidate' into release 2022-12-02 23:19:51 +09:00
gornekich
a74bcbaeb6 NFC: fix NTAG203 info scene #2078 2022-12-02 21:44:23 +09:00
Aleksandr Kutuzov
3c1d59f152 Merge remote-tracking branch 'origin/release-candidate' into release 2022-12-01 05:17:10 +09:00
Aleksandr Kutuzov
ec218060ac Merge remote-tracking branch 'origin/dev' into release-candidate 2022-11-30 20:42:10 +09:00
Aleksandr Kutuzov
303c266eba Merge branch 'release-candidate' into release 2022-11-14 21:01:50 +09:00
Aleksandr Kutuzov
f3904dc5a4 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-11-14 17:12:42 +09:00
Aleksandr Kutuzov
04c780f48a Merge branch 'dev' into release-candidate 2022-11-11 02:54:41 +09:00
Aleksandr Kutuzov
8d0faae820 Merge remote-tracking branch 'origin/release-candidate' into release 2022-11-01 23:20:27 +09:00
Aleksandr Kutuzov
a50fb2ac5e Merge remote-tracking branch 'origin/dev' into release-candidate 2022-11-01 19:28:10 +09:00
Aleksandr Kutuzov
fd0dd34a03 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-10-29 04:00:13 +09:00
Aleksandr Kutuzov
3ab17e596b Merge branch 'release-candidate' into release 2022-10-19 20:32:45 +09:00
hedger
33a7478b0a scripts: fixed c2 bundle format (#1889)
* scripts: fixed c2 bundle format
* scripts: copro.py: small refactoring

Co-authored-by: あく <alleteam@gmail.com>
2022-10-18 21:14:25 +09:00
Aleksandr Kutuzov
747e81fe1e Merge remote-tracking branch 'origin/release-candidate' into release 2022-10-18 01:19:05 +09:00
Aleksandr Kutuzov
cfde6350a6 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-10-15 03:27:47 +09:00
Aleksandr Kutuzov
5c52bb7621 Merge remote-tracking branch 'origin/release-candidate' into release 2022-10-03 00:45:53 +09:00
Aleksandr Kutuzov
e40349350d Merge branch 'dev' into release-candidate 2022-09-30 22:06:09 +09:00
Aleksandr Kutuzov
a0f6a23062 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-09-29 20:02:13 +09:00
Aleksandr Kutuzov
3481252ef7 Merge remote-tracking branch 'origin/release-candidate' into release 2022-09-24 01:17:00 +09:00
Aleksandr Kutuzov
14a180975a Merge remote-tracking branch 'origin/dev' into release-candidate 2022-09-23 02:53:12 +09:00
Aleksandr Kutuzov
bb9b52ad3e Merge remote-tracking branch 'origin/dev' into release-candidate 2022-09-22 01:57:30 +09:00
Aleksandr Kutuzov
7e86f634ba Merge remote-tracking branch 'origin/dev' into release-candidate 2022-09-20 14:44:52 +09:00
Aleksandr Kutuzov
55b463248c Merge remote-tracking branch 'origin/release-candidate' into release 2022-09-07 00:06:42 +09:00
Aleksandr Kutuzov
09148b2d6e Merge branch 'dev' into release-candidate 2022-09-05 22:47:13 +09:00
Aleksandr Kutuzov
3d9efa98d4 Merge branch 'dev' into release-candidate 2022-09-05 20:45:58 +09:00
Aleksandr Kutuzov
ae9038da36 Merge remote-tracking branch 'origin/release-candidate' into release 2022-08-25 19:26:42 +09:00
Aleksandr Kutuzov
8fb679e098 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-08-25 01:26:34 +09:00
Aleksandr Kutuzov
af891bdd4a Merge branch 'dev' into release-candidate 2022-08-24 02:58:31 +09:00
Aleksandr Kutuzov
f6d6a626ea Merge branch 'dev' into release-candidate 2022-08-24 01:21:50 +09:00
Aleksandr Kutuzov
bf236f5e15 Merge branch 'release-candidate' into release 2022-08-16 21:39:00 +09:00
Aleksandr Kutuzov
2fc2486b91 Merge branch 'dev' into release-candidate 2022-08-16 00:54:27 +09:00
Aleksandr Kutuzov
7a6720384f Merge branch 'release-candidate' into release 2022-08-13 18:21:46 +09:00
Aleksandr Kutuzov
be0aa536ba Merge remote-tracking branch 'origin/dev' into release-candidate 2022-08-13 18:12:26 +09:00
Aleksandr Kutuzov
df6b81274b Merge remote-tracking branch 'origin/dev' into release-candidate 2022-08-12 22:50:53 +09:00
Aleksandr Kutuzov
f785ce1f91 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-08-12 01:11:41 +09:00
Aleksandr Kutuzov
0c592ff84a Merge branch 'release-candidate' into release 2022-08-03 08:50:08 +09:00
Aleksandr Kutuzov
8bcd76636e Merge remote-tracking branch 'origin/dev' into release-candidate 2022-08-02 23:12:13 +09:00
Aleksandr Kutuzov
86c9b0077c Merge remote-tracking branch 'origin/dev' into release-candidate 2022-07-28 21:36:31 +09:00
Aleksandr Kutuzov
e28446de49 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-07-27 02:29:17 +09:00
Aleksandr Kutuzov
52434f77a3 Merge remote-tracking branch 'origin/dev' into release-candidate 2022-07-27 00:45:52 +09:00
Aleksandr Kutuzov
3e5d499b44
Merge branch 'release-candidate' into release 2022-07-13 18:49:21 +09:00
Aleksandr Kutuzov
577a4ba5a5
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-07-12 23:57:39 +09:00
Aleksandr Kutuzov
996b15e204
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-07-10 21:53:42 +09:00
Aleksandr Kutuzov
fc15d5ccce
Merge branch 'release-candidate' into release 2022-06-28 23:47:38 +09:00
Aleksandr Kutuzov
1edc74acff
Merge branch 'dev' into release-candidate 2022-06-28 22:06:48 +09:00
Aleksandr Kutuzov
c5fd214f80
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-06-26 21:18:09 +09:00
Aleksandr Kutuzov
e82001aaa6
Merge branch 'release-candidate' into release 2022-06-15 20:00:39 +09:00
Aleksandr Kutuzov
e682e02bca
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-06-14 12:08:22 +09:00
Aleksandr Kutuzov
ae95d75d2e
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-06-13 11:45:08 +09:00
Aleksandr Kutuzov
84cc3816c4
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-06-10 11:15:08 +09:00
Aleksandr Kutuzov
94bb1ad354
Merge branch 'release-candidate' into release 2022-06-03 23:03:06 +09:00
Aleksandr Kutuzov
be4dec77da
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-06-03 16:49:35 +09:00
Aleksandr Kutuzov
287defdfc5
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-06-01 04:44:44 +09:00
Aleksandr Kutuzov
cb6cf95714
Merge branch 'release-candidate' into release 2022-05-12 17:45:25 +03:00
Aleksandr Kutuzov
f82484d447
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-05-12 17:00:05 +03:00
Aleksandr Kutuzov
e64de44b73
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-05-11 19:42:05 +03:00
Aleksandr Kutuzov
d3c0618699
Merge branch 'release-candidate' into release 2022-05-05 00:41:18 +03:00
Aleksandr Kutuzov
b501d47943
Merge branch 'dev' into release-candidate 2022-04-29 17:27:23 +03:00
Aleksandr Kutuzov
d21e5bd56e
Merge branch 'release-candidate' into release 2022-04-25 15:50:08 +03:00
Aleksandr Kutuzov
1ad81aaf1f
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-04-24 01:12:36 +03:00
Aleksandr Kutuzov
5435679420
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-04-21 19:26:45 +03:00
Aleksandr Kutuzov
d294b5e256
Merge branch 'release-candidate' into release 2022-04-18 16:21:59 +03:00
Aleksandr Kutuzov
bc77681e65
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-04-15 21:00:34 +03:00
Aleksandr Kutuzov
460f573446
Merge branch 'dev' into release-candidate 2022-04-14 20:46:46 +03:00
Aleksandr Kutuzov
215466e2d6
Merge branch 'release-candidate' into release 2022-04-08 20:17:00 +03:00
Aleksandr Kutuzov
625eb0a4a5
Merge branch 'dev' into release-candidate 2022-04-07 18:48:44 +03:00
Aleksandr Kutuzov
5f582abfe0
Merge branch 'release-candidate' into release 2022-04-01 16:41:50 +03:00
Aleksandr Kutuzov
5c58faa3f5
Merge branch 'dev' into release-candidate 2022-03-31 17:58:25 +03:00
Aleksandr Kutuzov
28d9b21483
Merge branch 'release-candidate' into release 2022-03-29 15:30:57 +03:00
Aleksandr Kutuzov
0d35596d96
Merge branch 'dev' into release-candidate 2022-03-28 17:31:20 +03:00
Aleksandr Kutuzov
631e532245
Merge branch 'release-candidate' into release 2022-03-25 21:19:30 +03:00
Aleksandr Kutuzov
b29c0d3fb5
Merge branch 'dev' into release-candidate 2022-03-25 19:08:49 +03:00
Aleksandr Kutuzov
e74aa2d042
Merge branch 'dev' into release-candidate 2022-03-25 14:11:17 +03:00
Aleksandr Kutuzov
e1ff6da6cd
Merge branch 'dev' into release-candidate 2022-03-24 18:45:41 +03:00
Aleksandr Kutuzov
c02d8beed9
Merge branch 'dev' into release-candidate 2022-03-24 16:59:28 +03:00
Aleksandr Kutuzov
f2a8485176
Merge branch 'release-candidate' into release 2022-03-23 12:19:26 +03:00
Aleksandr Kutuzov
dc6da827fa
Merge branch 'dev' into release-candidate 2022-03-17 18:55:11 +07:00
Aleksandr Kutuzov
3f164ef30d
Merge branch 'release-candidate' into release 2022-03-03 20:33:15 +07:00
Aleksandr Kutuzov
afa46b0855
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-02-24 15:45:28 +03:00
Aleksandr Kutuzov
e69875954b
Merge branch 'release-candidate' into release 2022-02-19 02:47:11 +03:00
Aleksandr Kutuzov
57689a1e0f
Merge branch 'dev' into release-candidate 2022-02-16 20:53:12 +03:00
Aleksandr Kutuzov
f8c8e63adf
Merge branch 'release-candidate' into release 2022-02-14 17:37:24 +03:00
Aleksandr Kutuzov
d4aeee64fa
Merge branch 'dev' into release-candidate 2022-02-14 13:30:17 +03:00
Aleksandr Kutuzov
661b4b181a
Merge branch 'dev' into release-candidate 2022-02-10 22:11:05 +03:00
Aleksandr Kutuzov
bb81e86495
Merge branch 'release-candidate' into release 2022-02-07 14:44:23 +03:00
Aleksandr Kutuzov
3cdcd644fe
Merge branch 'dev' into release-candidate 2022-02-04 00:31:46 +03:00
Aleksandr Kutuzov
fffacfbe26
Merge branch 'release-candidate' into release 2022-02-01 16:07:34 +03:00
Aleksandr Kutuzov
1d5ca45675
Merge remote-tracking branch 'origin/dev' into release-candidate 2022-02-01 10:44:21 +03:00
Aleksandr Kutuzov
983537996c
Merge branch 'dev' into release-candidate 2022-01-29 14:40:14 +03:00
Aleksandr Kutuzov
3e04b73c1e
Merge branch 'release-candidate' into release 2022-01-21 17:12:55 +03:00
Aleksandr Kutuzov
830daa8b51
Merge branch 'dev' into release-candidate 2022-01-16 18:43:41 +03:00
Aleksandr Kutuzov
543402f64a
Merge branch 'dev' into release-candidate 2022-01-14 17:10:12 +03:00
Aleksandr Kutuzov
24e7bda854
Merge branch 'dev' into release-candidate 2022-01-14 14:08:42 +03:00
Aleksandr Kutuzov
8042f94570
Merge branch 'release-candidate' into release 2021-12-28 18:02:40 +03:00
Aleksandr Kutuzov
bb650c4e87
Merge branch 'dev' into release-candidate 2021-12-24 18:01:54 +03:00
Aleksandr Kutuzov
208ea6fbb0
Merge branch 'dev' into release-candidate 2021-12-23 21:17:20 +03:00
Aleksandr Kutuzov
a426762605
Merge branch 'release-candidate' into release 2021-12-21 00:08:22 +03:00
Aleksandr Kutuzov
2ee2e8f4ba
Merge branch 'dev' into release-candidate 2021-12-17 16:41:21 +03:00
DrZlo13
cc285ab05e Merge branch 'dev' into release-candidate 2021-12-16 05:24:32 +10:00
Aleksandr Kutuzov
06ad32109d Merge branch 'release-candidate' into release 2021-12-15 17:17:33 +03:00
Aleksandr Kutuzov
5a0f7e20ba Merge remote-tracking branch 'origin/dev' into release-candidate 2021-12-12 14:33:17 +03:00
Aleksandr Kutuzov
cf6a1a7301 Merge branch 'dev' into release-candidate 2021-12-09 14:06:47 +03:00
Aleksandr Kutuzov
3a70d3b7f6 Merge branch 'dev' into release-candidate 2021-12-08 18:03:54 +03:00
Aleksandr Kutuzov
1060f7b037 Merge branch 'release-candidate' into release 2021-12-01 13:43:37 +03:00
Albert Kharisov
5352e4eb63 Fix butthurt and battery (#850)
* Fix butthurt and battery
2021-11-29 15:53:21 +03:00
Aleksandr Kutuzov
b0b20392a5 Merge remote-tracking branch 'origin/dev' into release-candidate 2021-11-26 17:20:35 +03:00
Aleksandr Kutuzov
14777a7585 Merge remote-tracking branch 'origin/release-candidate' into release 2021-11-25 00:08:19 +03:00
Aleksandr Kutuzov
a5fa342ffa Merge remote-tracking branch 'origin/dev' into release-candidate 2021-11-21 18:22:17 +03:00
Aleksandr Kutuzov
90eb608f08 Merge branch 'release-candidate' into release 2021-11-16 20:26:37 +03:00
Aleksandr Kutuzov
be02738c4a Merge remote-tracking branch 'origin/dev' into release-candidate 2021-11-15 23:38:06 +03:00
Aleksandr Kutuzov
dad1b0622b Merge branch 'dev' into release-candidate 2021-11-14 18:31:48 +03:00
Aleksandr Kutuzov
cb227dafd1 Merge branch 'dev' into release-candidate 2021-11-04 22:44:46 +03:00
Aleksandr Kutuzov
f3603e3c04 Merge branch 'dev' into release-candidate 2021-10-28 17:24:03 +03:00
Aleksandr Kutuzov
eb74bcd41b Merge branch 'release-candidate' into release 2021-10-28 12:57:49 +03:00
Aleksandr Kutuzov
7b730dd08a Merge branch 'dev' into release-candidate 2021-10-25 03:41:13 +03:00
Aleksandr Kutuzov
ce74a35066 Merge branch 'release-candidate' into release 2021-10-21 21:19:16 +03:00
Aleksandr Kutuzov
55692ee82f Merge branch 'dev' into release-candidate 2021-10-13 22:38:50 +03:00
Aleksandr Kutuzov
20deb6458a Merge branch 'release-candidate' into release 2021-10-04 05:28:46 +03:00
Aleksandr Kutuzov
cca004a42d Merge branch 'dev' into release-candidate 2021-09-29 17:21:03 +03:00
Aleksandr Kutuzov
6c60c96d7c Merge branch 'release-candidate' into release 2021-09-28 12:54:44 +03:00
Aleksandr Kutuzov
b3f1db8f9e Merge branch 'dev' into release-candidate 2021-09-17 12:21:33 +03:00
Aleksandr Kutuzov
badf87fe67 Merge branch 'dev' into release-candidate 2021-09-16 19:13:52 +03:00
Aleksandr Kutuzov
dc622321b9 Merge branch 'dev' into release-candidate 2021-09-15 20:31:28 +03:00
Aleksandr Kutuzov
fd29e190b7 Merge branch 'release-candidate' into release 2021-09-15 20:27:06 +03:00
あく
3db456da98 [FL-1811] FuriHal: move core2 startup to hal init stage, prevent working with flash controller till core2 startup finish. #704 2021-09-15 17:40:52 +03:00
Aleksandr Kutuzov
44d7b5b1ce Merge branch 'release-candidate' into release 2021-09-10 03:59:09 +03:00
Aleksandr Kutuzov
97e0a3026f Merge branch 'release-candidate' into release 2021-09-03 01:45:03 +03:00
Aleksandr Kutuzov
3773428a21 Merge branch 'release-candidate' into release 2021-08-29 16:14:45 +03:00
Aleksandr Kutuzov
b629ae18f2 Merge branch 'release-candidate' into release 2021-08-17 19:35:03 +03:00
Aleksandr Kutuzov
073c87f37d Merge remote-tracking branch 'origin/release-candidate' into release 2021-08-12 00:18:56 +03:00
あく
0bc3828fd9 [FL-1590] SubGhz: fix incorrect limits on frequency that were causing crashes #607 2021-07-30 14:15:01 +03:00
24 changed files with 635 additions and 502 deletions

View File

@ -12,7 +12,7 @@
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller_sync.h>
#include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
#include <nfc/helpers/nfc_dict.h>
#include <toolbox/keys_dict.h>
#include <nfc/nfc.h>
#include "../minunit.h"
@ -443,36 +443,36 @@ MU_TEST(mf_classic_dict_test) {
"Remove test dict failed");
}
NfcDict* dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
mu_assert(dict != NULL, "nfc_dict_alloc() failed");
KeysDict* dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
mu_assert(dict != NULL, "keys_dict_alloc() failed");
size_t dict_keys_total = nfc_dict_get_total_keys(dict);
mu_assert(dict_keys_total == 0, "nfc_dict_keys_total() failed");
size_t dict_keys_total = keys_dict_get_total_keys(dict);
mu_assert(dict_keys_total == 0, "keys_dict_keys_total() failed");
const uint32_t test_key_num = 30;
MfClassicKey* key_arr_ref = malloc(test_key_num * sizeof(MfClassicKey));
for(size_t i = 0; i < test_key_num; i++) {
furi_hal_random_fill_buf(key_arr_ref[i].data, sizeof(MfClassicKey));
mu_assert(
nfc_dict_add_key(dict, key_arr_ref[i].data, sizeof(MfClassicKey)), "add key failed");
keys_dict_add_key(dict, key_arr_ref[i].data, sizeof(MfClassicKey)), "add key failed");
size_t dict_keys_total = nfc_dict_get_total_keys(dict);
mu_assert(dict_keys_total == (i + 1), "nfc_dict_keys_total() failed");
size_t dict_keys_total = keys_dict_get_total_keys(dict);
mu_assert(dict_keys_total == (i + 1), "keys_dict_keys_total() failed");
}
nfc_dict_free(dict);
keys_dict_free(dict);
dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
mu_assert(dict != NULL, "nfc_dict_alloc() failed");
dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
mu_assert(dict != NULL, "keys_dict_alloc() failed");
dict_keys_total = nfc_dict_get_total_keys(dict);
mu_assert(dict_keys_total == test_key_num, "nfc_dict_keys_total() failed");
dict_keys_total = keys_dict_get_total_keys(dict);
mu_assert(dict_keys_total == test_key_num, "keys_dict_keys_total() failed");
MfClassicKey key_dut = {};
size_t key_idx = 0;
while(nfc_dict_get_next_key(dict, key_dut.data, sizeof(MfClassicKey))) {
while(keys_dict_get_next_key(dict, key_dut.data, sizeof(MfClassicKey))) {
mu_assert(
memcmp(key_arr_ref[key_idx].data, key_dut.data, sizeof(MfClassicKey)) == 0,
"Loaded key data mismatch");
@ -484,19 +484,19 @@ MU_TEST(mf_classic_dict_test) {
for(size_t i = 0; i < COUNT_OF(delete_keys_idx); i++) {
MfClassicKey* key = &key_arr_ref[delete_keys_idx[i]];
mu_assert(
nfc_dict_is_key_present(dict, key->data, sizeof(MfClassicKey)),
"nfc_dict_is_key_present() failed");
keys_dict_is_key_present(dict, key->data, sizeof(MfClassicKey)),
"keys_dict_is_key_present() failed");
mu_assert(
nfc_dict_delete_key(dict, key->data, sizeof(MfClassicKey)),
"nfc_dict_delete_key() failed");
keys_dict_delete_key(dict, key->data, sizeof(MfClassicKey)),
"keys_dict_delete_key() failed");
}
dict_keys_total = nfc_dict_get_total_keys(dict);
dict_keys_total = keys_dict_get_total_keys(dict);
mu_assert(
dict_keys_total == test_key_num - COUNT_OF(delete_keys_idx),
"nfc_dict_keys_total() failed");
"keys_dict_keys_total() failed");
nfc_dict_free(dict);
keys_dict_free(dict);
free(key_arr_ref);
mu_assert(

View File

@ -27,6 +27,7 @@ static const uint32_t baudrate_list[] = {
460800,
921600,
};
static const char* software_de_re[] = {"None", "4"};
bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) {
GpioApp* app = context;
@ -84,6 +85,17 @@ static void line_port_cb(VariableItem* item) {
view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet);
}
static void line_software_de_re_cb(VariableItem* item) {
GpioApp* app = variable_item_get_context(item);
furi_assert(app);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, software_de_re[index]);
app->usb_uart_cfg->software_de_re = index;
view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet);
}
static void line_flow_cb(VariableItem* item) {
GpioApp* app = variable_item_get_context(item);
furi_assert(app);
@ -155,6 +167,11 @@ void gpio_scene_usb_uart_cfg_on_enter(void* context) {
app->var_item_flow = item;
line_ensure_flow_invariant(app);
item = variable_item_list_add(
var_item_list, "DE/RE Pin", COUNT_OF(software_de_re), line_software_de_re_cb, app);
variable_item_set_current_value_index(item, app->usb_uart_cfg->software_de_re);
variable_item_set_current_value_text(item, software_de_re[app->usb_uart_cfg->software_de_re]);
variable_item_list_set_selected_item(
var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg));

View File

@ -6,11 +6,16 @@
#include <furi_hal.h>
#include <furi_hal_usb_cdc.h>
//TODO: FL-3276 port to new USART API
#include <stm32wbxx_ll_lpuart.h>
#include <stm32wbxx_ll_usart.h>
#define USB_CDC_PKT_LEN CDC_DATA_SZ
#define USB_UART_RX_BUF_SIZE (USB_CDC_PKT_LEN * 5)
#define USB_CDC_BIT_DTR (1 << 0)
#define USB_CDC_BIT_RTS (1 << 1)
#define USB_USART_DE_RE_PIN &gpio_ext_pa4
static const GpioPin* flow_pins[][2] = {
{&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3
@ -247,6 +252,17 @@ static int32_t usb_uart_worker(void* context) {
usb_uart->cfg.flow_pins = usb_uart->cfg_new.flow_pins;
events |= WorkerEvtCtrlLineSet;
}
if(usb_uart->cfg.software_de_re != usb_uart->cfg_new.software_de_re) {
usb_uart->cfg.software_de_re = usb_uart->cfg_new.software_de_re;
if(usb_uart->cfg.software_de_re != 0) {
furi_hal_gpio_write(USB_USART_DE_RE_PIN, true);
furi_hal_gpio_init(
USB_USART_DE_RE_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedMedium);
} else {
furi_hal_gpio_init(
USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
}
}
api_lock_unlock(usb_uart->cfg_lock);
}
if(events & WorkerEvtLineCfgSet) {
@ -260,6 +276,8 @@ static int32_t usb_uart_worker(void* context) {
usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch);
usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch);
furi_hal_gpio_init(USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
if(usb_uart->cfg.flow_pins != 0) {
furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog);
furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog);
@ -298,7 +316,24 @@ static int32_t usb_uart_tx_thread(void* context) {
if(len > 0) {
usb_uart->st.tx_cnt += len;
if(usb_uart->cfg.software_de_re != 0)
furi_hal_gpio_write(USB_USART_DE_RE_PIN, false);
furi_hal_uart_tx(usb_uart->cfg.uart_ch, data, len);
if(usb_uart->cfg.software_de_re != 0) {
//TODO: FL-3276 port to new USART API
if(usb_uart->cfg.uart_ch == FuriHalUartIdUSART1) {
while(!LL_USART_IsActiveFlag_TC(USART1))
;
} else if(usb_uart->cfg.uart_ch == FuriHalUartIdLPUART1) {
while(!LL_LPUART_IsActiveFlag_TC(LPUART1))
;
}
furi_hal_gpio_write(USB_USART_DE_RE_PIN, true);
}
}
}
}

View File

@ -11,6 +11,7 @@ typedef struct {
uint8_t flow_pins;
uint8_t baudrate_mode;
uint32_t baudrate;
uint8_t software_de_re;
} UsbUartConfig;
typedef struct {

View File

@ -1,6 +1,6 @@
#include "mf_user_dict.h"
#include <nfc/helpers/nfc_dict.h>
#include <toolbox/keys_dict.h>
#include <nfc/protocols/mf_classic/mf_classic.h>
#include <furi/furi.h>
@ -15,22 +15,22 @@ struct MfUserDict {
MfUserDict* mf_user_dict_alloc(size_t max_keys_to_load) {
MfUserDict* instance = malloc(sizeof(MfUserDict));
NfcDict* dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
KeysDict* dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
furi_assert(dict);
size_t dict_keys_num = nfc_dict_get_total_keys(dict);
size_t dict_keys_num = keys_dict_get_total_keys(dict);
instance->keys_num = MIN(max_keys_to_load, dict_keys_num);
if(instance->keys_num > 0) {
instance->keys_arr = malloc(instance->keys_num * sizeof(MfClassicKey));
for(size_t i = 0; i < instance->keys_num; i++) {
bool key_loaded =
nfc_dict_get_next_key(dict, instance->keys_arr[i].data, sizeof(MfClassicKey));
keys_dict_get_next_key(dict, instance->keys_arr[i].data, sizeof(MfClassicKey));
furi_assert(key_loaded);
}
}
nfc_dict_free(dict);
keys_dict_free(dict);
return instance;
}
@ -67,13 +67,13 @@ bool mf_user_dict_delete_key(MfUserDict* instance, uint32_t index) {
furi_assert(index < instance->keys_num);
furi_assert(instance->keys_arr);
NfcDict* dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
KeysDict* dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
furi_assert(dict);
bool key_delete_success =
nfc_dict_delete_key(dict, instance->keys_arr[index].data, sizeof(MfClassicKey));
nfc_dict_free(dict);
keys_dict_delete_key(dict, instance->keys_arr[index].data, sizeof(MfClassicKey));
keys_dict_free(dict);
if(key_delete_success) {
instance->keys_num--;

View File

@ -343,7 +343,7 @@ bool nfc_load_file(NfcApp* instance, FuriString* path, bool show_dialog) {
nfc_supported_cards_load_cache(instance->nfc_supported_cards);
FuriString* load_path = furi_string_alloc();
if(nfc_has_shadow_file_internal(instance, path)) {
if(nfc_has_shadow_file_internal(instance, path)) { //-V1051
nfc_set_shadow_file_path(path, load_path);
} else if(furi_string_end_with(path, NFC_APP_SHADOW_EXTENSION)) {
size_t path_len = furi_string_size(path);

View File

@ -52,7 +52,7 @@
#include <nfc/nfc_device.h>
#include <nfc/helpers/nfc_data_generator.h>
#include <nfc/helpers/nfc_dict.h>
#include <toolbox/keys_dict.h>
#include <gui/modules/validators.h>
#include <toolbox/path.h>
@ -80,7 +80,7 @@ typedef enum {
} NfcRpcState;
typedef struct {
NfcDict* dict;
KeysDict* dict;
uint8_t sectors_total;
uint8_t sectors_read;
uint8_t current_sector;

View File

@ -41,7 +41,8 @@ NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context)
instance->view_dispatcher, NfcCustomEventDictAttackDataUpdate);
} else if(mfc_event->type == MfClassicPollerEventTypeRequestKey) {
MfClassicKey key = {};
if(nfc_dict_get_next_key(instance->nfc_dict_context.dict, key.data, sizeof(MfClassicKey))) {
if(keys_dict_get_next_key(
instance->nfc_dict_context.dict, key.data, sizeof(MfClassicKey))) {
mfc_event->data->key_request_data.key = key;
mfc_event->data->key_request_data.key_provided = true;
instance->nfc_dict_context.dict_keys_current++;
@ -60,7 +61,7 @@ NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context)
view_dispatcher_send_custom_event(
instance->view_dispatcher, NfcCustomEventDictAttackDataUpdate);
} else if(mfc_event->type == MfClassicPollerEventTypeNextSector) {
nfc_dict_rewind(instance->nfc_dict_context.dict);
keys_dict_rewind(instance->nfc_dict_context.dict);
instance->nfc_dict_context.dict_keys_current = 0;
instance->nfc_dict_context.current_sector =
mfc_event->data->next_sector_data.current_sector;
@ -79,7 +80,7 @@ NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context)
view_dispatcher_send_custom_event(
instance->view_dispatcher, NfcCustomEventDictAttackDataUpdate);
} else if(mfc_event->type == MfClassicPollerEventTypeKeyAttackStop) {
nfc_dict_rewind(instance->nfc_dict_context.dict);
keys_dict_rewind(instance->nfc_dict_context.dict);
instance->nfc_dict_context.is_key_attack = false;
instance->nfc_dict_context.dict_keys_current = 0;
view_dispatcher_send_custom_event(
@ -124,15 +125,15 @@ static void nfc_scene_mf_classic_dict_attack_prepare_view(NfcApp* instance) {
scene_manager_get_scene_state(instance->scene_manager, NfcSceneMfClassicDictAttack);
if(state == DictAttackStateUserDictInProgress) {
do {
if(!nfc_dict_check_presence(NFC_APP_MF_CLASSIC_DICT_USER_PATH)) {
if(!keys_dict_check_presence(NFC_APP_MF_CLASSIC_DICT_USER_PATH)) {
state = DictAttackStateSystemDictInProgress;
break;
}
instance->nfc_dict_context.dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
if(nfc_dict_get_total_keys(instance->nfc_dict_context.dict) == 0) {
nfc_dict_free(instance->nfc_dict_context.dict);
instance->nfc_dict_context.dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
if(keys_dict_get_total_keys(instance->nfc_dict_context.dict) == 0) {
keys_dict_free(instance->nfc_dict_context.dict);
state = DictAttackStateSystemDictInProgress;
break;
}
@ -141,13 +142,13 @@ static void nfc_scene_mf_classic_dict_attack_prepare_view(NfcApp* instance) {
} while(false);
}
if(state == DictAttackStateSystemDictInProgress) {
instance->nfc_dict_context.dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, NfcDictModeOpenExisting, sizeof(MfClassicKey));
instance->nfc_dict_context.dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, KeysDictModeOpenExisting, sizeof(MfClassicKey));
dict_attack_set_header(instance->dict_attack, "MF Classic System Dictionary");
}
instance->nfc_dict_context.dict_keys_total =
nfc_dict_get_total_keys(instance->nfc_dict_context.dict);
keys_dict_get_total_keys(instance->nfc_dict_context.dict);
dict_attack_set_total_dict_keys(
instance->dict_attack, instance->nfc_dict_context.dict_keys_total);
instance->nfc_dict_context.dict_keys_current = 0;
@ -185,7 +186,7 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent
if(state == DictAttackStateUserDictInProgress) {
nfc_poller_stop(instance->poller);
nfc_poller_free(instance->poller);
nfc_dict_free(instance->nfc_dict_context.dict);
keys_dict_free(instance->nfc_dict_context.dict);
scene_manager_set_scene_state(
instance->scene_manager,
NfcSceneMfClassicDictAttack,
@ -215,7 +216,7 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent
if(instance->nfc_dict_context.is_card_present) {
nfc_poller_stop(instance->poller);
nfc_poller_free(instance->poller);
nfc_dict_free(instance->nfc_dict_context.dict);
keys_dict_free(instance->nfc_dict_context.dict);
scene_manager_set_scene_state(
instance->scene_manager,
NfcSceneMfClassicDictAttack,
@ -253,7 +254,7 @@ void nfc_scene_mf_classic_dict_attack_on_exit(void* context) {
scene_manager_set_scene_state(
instance->scene_manager, NfcSceneMfClassicDictAttack, DictAttackStateUserDictInProgress);
nfc_dict_free(instance->nfc_dict_context.dict);
keys_dict_free(instance->nfc_dict_context.dict);
instance->nfc_dict_context.current_sector = 0;
instance->nfc_dict_context.sectors_total = 0;

View File

@ -14,20 +14,20 @@ void nfc_scene_mf_classic_keys_on_enter(void* context) {
// Load flipper dict keys total
uint32_t flipper_dict_keys_total = 0;
NfcDict* dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, NfcDictModeOpenExisting, sizeof(MfClassicKey));
KeysDict* dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, KeysDictModeOpenExisting, sizeof(MfClassicKey));
if(dict) {
flipper_dict_keys_total = nfc_dict_get_total_keys(dict);
nfc_dict_free(dict);
flipper_dict_keys_total = keys_dict_get_total_keys(dict);
keys_dict_free(dict);
}
// Load user dict keys total
uint32_t user_dict_keys_total = 0;
dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
if(dict) {
user_dict_keys_total = nfc_dict_get_total_keys(dict);
nfc_dict_free(dict);
user_dict_keys_total = keys_dict_get_total_keys(dict);
keys_dict_free(dict);
}
FuriString* temp_str = furi_string_alloc();

View File

@ -29,23 +29,23 @@ bool nfc_scene_mf_classic_keys_add_on_event(void* context, SceneManagerEvent eve
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventByteInputDone) {
// Add key to dict
NfcDict* dict = nfc_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, NfcDictModeOpenAlways, sizeof(MfClassicKey));
KeysDict* dict = keys_dict_alloc(
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
furi_assert(dict);
MfClassicKey key = {};
memcpy(key.data, instance->byte_input_store, sizeof(MfClassicKey));
if(nfc_dict_is_key_present(dict, key.data, sizeof(MfClassicKey))) {
if(keys_dict_is_key_present(dict, key.data, sizeof(MfClassicKey))) {
scene_manager_next_scene(
instance->scene_manager, NfcSceneMfClassicKeysWarnDuplicate);
} else if(nfc_dict_add_key(dict, key.data, sizeof(MfClassicKey))) {
} else if(keys_dict_add_key(dict, key.data, sizeof(MfClassicKey))) {
scene_manager_next_scene(instance->scene_manager, NfcSceneSaveSuccess);
dolphin_deed(DolphinDeedNfcMfcAdd);
} else {
scene_manager_previous_scene(instance->scene_manager);
}
nfc_dict_free(dict);
keys_dict_free(dict);
consumed = true;
}
}

View File

@ -48,7 +48,6 @@ env.Append(
File("helpers/iso14443_crc.h"),
File("helpers/iso13239_crc.h"),
File("helpers/nfc_data_generator.h"),
File("helpers/nfc_dict.h"),
],
)

View File

@ -1,270 +0,0 @@
#include "nfc_dict.h"
#include <storage/storage.h>
#include <flipper_format/flipper_format.h>
#include <toolbox/stream/file_stream.h>
#include <toolbox/stream/buffered_file_stream.h>
#include <toolbox/args.h>
#include <nfc/helpers/nfc_util.h>
#define TAG "NfcDict"
struct NfcDict {
Stream* stream;
size_t key_size;
size_t key_size_symbols;
uint32_t total_keys;
};
typedef struct {
const char* path;
FS_OpenMode open_mode;
} NfcDictFile;
bool nfc_dict_check_presence(const char* path) {
furi_assert(path);
Storage* storage = furi_record_open(RECORD_STORAGE);
bool dict_present = storage_common_stat(storage, path, NULL) == FSE_OK;
furi_record_close(RECORD_STORAGE);
return dict_present;
}
NfcDict* nfc_dict_alloc(const char* path, NfcDictMode mode, size_t key_size) {
furi_assert(path);
NfcDict* instance = malloc(sizeof(NfcDict));
Storage* storage = furi_record_open(RECORD_STORAGE);
instance->stream = buffered_file_stream_alloc(storage);
furi_record_close(RECORD_STORAGE);
FS_OpenMode open_mode = FSOM_OPEN_EXISTING;
if(mode == NfcDictModeOpenAlways) {
open_mode = FSOM_OPEN_ALWAYS;
}
instance->key_size = key_size;
// Byte = 2 symbols + 1 end of line
instance->key_size_symbols = key_size * 2 + 1;
bool dict_loaded = false;
do {
if(!buffered_file_stream_open(instance->stream, path, FSAM_READ_WRITE, open_mode)) {
buffered_file_stream_close(instance->stream);
break;
}
// Check for new line ending
if(!stream_eof(instance->stream)) {
if(!stream_seek(instance->stream, -1, StreamOffsetFromEnd)) break;
uint8_t last_char = 0;
if(stream_read(instance->stream, &last_char, 1) != 1) break;
if(last_char != '\n') {
FURI_LOG_D(TAG, "Adding new line ending");
if(stream_write_char(instance->stream, '\n') != 1) break;
}
if(!stream_rewind(instance->stream)) break;
}
// Read total amount of keys
FuriString* next_line;
next_line = furi_string_alloc();
while(true) {
if(!stream_read_line(instance->stream, next_line)) {
FURI_LOG_T(TAG, "No keys left in dict");
break;
}
FURI_LOG_T(
TAG,
"Read line: %s, len: %zu",
furi_string_get_cstr(next_line),
furi_string_size(next_line));
if(furi_string_get_char(next_line, 0) == '#') continue;
if(furi_string_size(next_line) != instance->key_size_symbols) continue;
instance->total_keys++;
}
furi_string_free(next_line);
stream_rewind(instance->stream);
dict_loaded = true;
FURI_LOG_I(TAG, "Loaded dictionary with %lu keys", instance->total_keys);
} while(false);
if(!dict_loaded) {
buffered_file_stream_close(instance->stream);
free(instance);
instance = NULL;
}
return instance;
}
void nfc_dict_free(NfcDict* instance) {
furi_assert(instance);
furi_assert(instance->stream);
buffered_file_stream_close(instance->stream);
stream_free(instance->stream);
free(instance);
}
static void nfc_dict_int_to_str(NfcDict* instance, const uint8_t* key_int, FuriString* key_str) {
furi_string_reset(key_str);
for(size_t i = 0; i < instance->key_size; i++) {
furi_string_cat_printf(key_str, "%02X", key_int[i]);
}
}
static void nfc_dict_str_to_int(NfcDict* instance, FuriString* key_str, uint64_t* key_int) {
uint8_t key_byte_tmp;
*key_int = 0ULL;
for(uint8_t i = 0; i < instance->key_size * 2; i += 2) {
args_char_to_hex(
furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp);
*key_int |= (uint64_t)key_byte_tmp << (8 * (instance->key_size - 1 - i / 2));
}
}
uint32_t nfc_dict_get_total_keys(NfcDict* instance) {
furi_assert(instance);
return instance->total_keys;
}
bool nfc_dict_rewind(NfcDict* instance) {
furi_assert(instance);
furi_assert(instance->stream);
return stream_rewind(instance->stream);
}
static bool nfc_dict_get_next_key_str(NfcDict* instance, FuriString* key) {
furi_assert(instance);
furi_assert(instance->stream);
bool key_read = false;
furi_string_reset(key);
while(!key_read) {
if(!stream_read_line(instance->stream, key)) break;
if(furi_string_get_char(key, 0) == '#') continue;
if(furi_string_size(key) != instance->key_size_symbols) continue;
furi_string_left(key, instance->key_size_symbols - 1);
key_read = true;
}
return key_read;
}
bool nfc_dict_get_next_key(NfcDict* instance, uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
FuriString* temp_key = furi_string_alloc();
uint64_t key_int = 0;
bool key_read = nfc_dict_get_next_key_str(instance, temp_key);
if(key_read) {
nfc_dict_str_to_int(instance, temp_key, &key_int);
nfc_util_num2bytes(key_int, key_size, key);
}
furi_string_free(temp_key);
return key_read;
}
static bool nfc_dict_is_key_present_str(NfcDict* instance, FuriString* key) {
furi_assert(instance);
furi_assert(instance->stream);
FuriString* next_line;
next_line = furi_string_alloc();
bool key_found = false;
stream_rewind(instance->stream);
while(!key_found) { //-V654
if(!stream_read_line(instance->stream, next_line)) break;
if(furi_string_get_char(next_line, 0) == '#') continue;
if(furi_string_size(next_line) != instance->key_size_symbols) continue;
furi_string_left(next_line, instance->key_size_symbols - 1);
if(!furi_string_equal(key, next_line)) continue;
key_found = true;
}
furi_string_free(next_line);
return key_found;
}
bool nfc_dict_is_key_present(NfcDict* instance, const uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(key);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
FuriString* temp_key = furi_string_alloc();
nfc_dict_int_to_str(instance, key, temp_key);
bool key_found = nfc_dict_is_key_present_str(instance, temp_key);
furi_string_free(temp_key);
return key_found;
}
static bool nfc_dict_add_key_str(NfcDict* instance, FuriString* key) {
furi_assert(instance);
furi_assert(instance->stream);
furi_string_cat_printf(key, "\n");
bool key_added = false;
do {
if(!stream_seek(instance->stream, 0, StreamOffsetFromEnd)) break;
if(!stream_insert_string(instance->stream, key)) break;
instance->total_keys++;
key_added = true;
} while(false);
furi_string_left(key, instance->key_size_symbols - 1);
return key_added;
}
bool nfc_dict_add_key(NfcDict* instance, const uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(key);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
FuriString* temp_key = furi_string_alloc();
nfc_dict_int_to_str(instance, key, temp_key);
bool key_added = nfc_dict_add_key_str(instance, temp_key);
furi_string_free(temp_key);
return key_added;
}
bool nfc_dict_delete_key(NfcDict* instance, const uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(key);
furi_assert(instance->key_size == key_size);
bool key_removed = false;
uint8_t* temp_key = malloc(key_size);
nfc_dict_rewind(instance);
while(!key_removed) {
if(!nfc_dict_get_next_key(instance, temp_key, key_size)) break;
if(memcmp(temp_key, key, key_size) == 0) {
int32_t offset = (-1) * (instance->key_size_symbols);
stream_seek(instance->stream, offset, StreamOffsetFromCurrent);
if(!stream_delete(instance->stream, instance->key_size_symbols)) break;
instance->total_keys--;
key_removed = true;
}
}
nfc_dict_rewind(instance);
free(temp_key);
return key_removed;
}

View File

@ -1,103 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
NfcDictModeOpenExisting,
NfcDictModeOpenAlways,
} NfcDictMode;
typedef struct NfcDict NfcDict;
/** Check dictionary presence
*
* @param path - dictionary path
*
* @return true if dictionary exists, false otherwise
*/
bool nfc_dict_check_presence(const char* path);
/** Open or create dictionary
* Depending on mode, dictionary will be opened or created.
*
* @param path - dictionary path
* @param mode - NfcDictMode value
* @param key_size - size of dictionary keys in bytes
*
* @return NfcDict dictionary instance
*/
NfcDict* nfc_dict_alloc(const char* path, NfcDictMode mode, size_t key_size);
/** Close dictionary
*
* @param instance - NfcDict dictionary instance
*/
void nfc_dict_free(NfcDict* instance);
/** Get total number of keys in dictionary
*
* @param instance - NfcDict dictionary instance
*
* @return total number of keys in dictionary
*/
uint32_t nfc_dict_get_total_keys(NfcDict* instance);
/** Rewind dictionary
*
* @param instance - NfcDict dictionary instance
*
* @return true if rewind was successful, false otherwise
*/
bool nfc_dict_rewind(NfcDict* instance);
/** Check if key is present in dictionary
*
* @param instance - NfcDict dictionary instance
* @param key - key to check
* @param key_size - size of key in bytes
*
* @return true if key is present, false otherwise
*/
bool nfc_dict_is_key_present(NfcDict* instance, const uint8_t* key, size_t key_size);
/** Get next key from dictionary
* This function will return next key from dictionary. If there are no more
* keys, it will return false, and nfc_dict_rewind() should be called.
*
* @param instance - NfcDict dictionary instance
* @param key - buffer to store key
* @param key_size - size of key in bytes
*
* @return true if key was successfully retrieved, false otherwise
*/
bool nfc_dict_get_next_key(NfcDict* instance, uint8_t* key, size_t key_size);
/** Add key to dictionary
*
* @param instance - NfcDict dictionary instance
* @param key - key to add
* @param key_size - size of key in bytes
*
* @return true if key was successfully added, false otherwise
*/
bool nfc_dict_add_key(NfcDict* instance, const uint8_t* key, size_t key_size);
/** Delete key from dictionary
*
* @param instance - NfcDict dictionary instance
* @param key - key to delete
* @param key_size - size of key in bytes
*
* @return true if key was successfully deleted, false otherwise
*/
bool nfc_dict_delete_key(NfcDict* instance, const uint8_t* key, size_t key_size);
#ifdef __cplusplus
}
#endif

View File

@ -34,6 +34,7 @@ env.Append(
File("hex.h"),
File("simple_array.h"),
File("bit_buffer.h"),
File("keys_dict.h"),
],
)

334
lib/toolbox/keys_dict.c Normal file
View File

@ -0,0 +1,334 @@
#include "keys_dict.h"
#include <storage/storage.h>
#include <flipper_format/flipper_format.h>
#include <toolbox/stream/file_stream.h>
#include <toolbox/stream/buffered_file_stream.h>
#include <toolbox/args.h>
#define TAG "KeysDict"
struct KeysDict {
Stream* stream;
size_t key_size;
size_t key_size_symbols;
size_t total_keys;
};
static inline void keys_dict_add_ending_new_line(KeysDict* instance) {
if(stream_seek(instance->stream, -1, StreamOffsetFromEnd)) {
uint8_t last_char = 0;
// Check if the last char is new line or add a new line
if(stream_read(instance->stream, &last_char, 1) == 1 && last_char != '\n') {
FURI_LOG_D(TAG, "Adding new line ending");
stream_write_char(instance->stream, '\n');
}
stream_rewind(instance->stream);
}
}
static bool keys_dict_read_key_line(KeysDict* instance, FuriString* line, bool* is_endfile) {
if(stream_read_line(instance->stream, line) == false) {
*is_endfile = true;
}
else {
FURI_LOG_T(
TAG, "Read line: %s, len: %zu", furi_string_get_cstr(line), furi_string_size(line));
bool is_comment = furi_string_get_char(line, 0) == '#';
if(!is_comment) {
furi_string_left(line, instance->key_size_symbols - 1);
}
bool is_correct_size = furi_string_size(line) == instance->key_size_symbols - 1;
return !is_comment && is_correct_size;
}
return false;
}
bool keys_dict_check_presence(const char* path) {
furi_assert(path);
Storage* storage = furi_record_open(RECORD_STORAGE);
bool dict_present = storage_common_stat(storage, path, NULL) == FSE_OK;
furi_record_close(RECORD_STORAGE);
return dict_present;
}
KeysDict* keys_dict_alloc(const char* path, KeysDictMode mode, size_t key_size) {
furi_assert(path);
furi_assert(key_size > 0);
KeysDict* instance = malloc(sizeof(KeysDict));
Storage* storage = furi_record_open(RECORD_STORAGE);
furi_assert(storage);
instance->stream = buffered_file_stream_alloc(storage);
furi_assert(instance->stream);
FS_OpenMode open_mode = (mode == KeysDictModeOpenAlways) ? FSOM_OPEN_ALWAYS :
FSOM_OPEN_EXISTING;
// Byte = 2 symbols + 1 end of line
instance->key_size = key_size;
instance->key_size_symbols = key_size * 2 + 1;
instance->total_keys = 0;
bool file_exists =
buffered_file_stream_open(instance->stream, path, FSAM_READ_WRITE, open_mode);
if(!file_exists) {
buffered_file_stream_close(instance->stream);
} else {
// Eventually add new line character in the last line to avoid skipping keys
keys_dict_add_ending_new_line(instance);
}
FuriString* line = furi_string_alloc();
bool is_endfile = false;
// In this loop we only count the entries in the file
// We prefer not to load the whole file in memory for space reasons
while(file_exists && !is_endfile) {
bool read_key = keys_dict_read_key_line(instance, line, &is_endfile);
if(read_key) {
instance->total_keys++;
}
}
stream_rewind(instance->stream);
FURI_LOG_I(TAG, "Loaded dictionary with %zu keys", instance->total_keys);
furi_string_free(line);
return instance;
}
void keys_dict_free(KeysDict* instance) {
furi_assert(instance);
furi_assert(instance->stream);
buffered_file_stream_close(instance->stream);
stream_free(instance->stream);
free(instance);
furi_record_close(RECORD_STORAGE);
}
static void keys_dict_int_to_str(KeysDict* instance, const uint8_t* key_int, FuriString* key_str) {
furi_assert(instance);
furi_assert(key_str);
furi_assert(key_int);
furi_string_reset(key_str);
for(size_t i = 0; i < instance->key_size; i++)
furi_string_cat_printf(key_str, "%02X", key_int[i]);
}
static void keys_dict_str_to_int(KeysDict* instance, FuriString* key_str, uint64_t* key_int) {
furi_assert(instance);
furi_assert(key_str);
furi_assert(key_int);
uint8_t key_byte_tmp;
char h, l;
*key_int = 0ULL;
for(size_t i = 0; i < instance->key_size_symbols - 1; i += 2) {
h = furi_string_get_char(key_str, i);
l = furi_string_get_char(key_str, i + 1);
args_char_to_hex(h, l, &key_byte_tmp);
*key_int |= (uint64_t)key_byte_tmp << (8 * (instance->key_size - 1 - i / 2));
}
}
size_t keys_dict_get_total_keys(KeysDict* instance) {
furi_assert(instance);
return instance->total_keys;
}
bool keys_dict_rewind(KeysDict* instance) {
furi_assert(instance);
furi_assert(instance->stream);
return stream_rewind(instance->stream);
}
static bool keys_dict_get_next_key_str(KeysDict* instance, FuriString* key) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(key);
bool key_read = false;
bool is_endfile = false;
furi_string_reset(key);
while(!key_read && !is_endfile) key_read = keys_dict_read_key_line(instance, key, &is_endfile);
return key_read;
}
bool keys_dict_get_next_key(KeysDict* instance, uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
furi_assert(key);
FuriString* temp_key = furi_string_alloc();
bool key_read = keys_dict_get_next_key_str(instance, temp_key);
if(key_read) {
size_t tmp_len = key_size;
uint64_t key_int = 0;
keys_dict_str_to_int(instance, temp_key, &key_int);
while(tmp_len--) {
key[tmp_len] = (uint8_t)key_int;
key_int >>= 8;
}
}
furi_string_free(temp_key);
return key_read;
}
static bool keys_dict_is_key_present_str(KeysDict* instance, FuriString* key) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(key);
FuriString* line = furi_string_alloc();
bool is_endfile = false;
bool line_found = false;
uint32_t actual_pos = stream_tell(instance->stream);
stream_rewind(instance->stream);
while(!line_found && !is_endfile)
line_found = // The line is found if the line was read and the key is equal to the line
(keys_dict_read_key_line(instance, line, &is_endfile)) &&
(furi_string_equal(key, line));
furi_string_free(line);
// Restore the position of the stream
stream_seek(instance->stream, actual_pos, StreamOffsetFromStart);
return line_found;
}
bool keys_dict_is_key_present(KeysDict* instance, const uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
furi_assert(key);
FuriString* temp_key = furi_string_alloc();
keys_dict_int_to_str(instance, key, temp_key);
bool key_found = keys_dict_is_key_present_str(instance, temp_key);
furi_string_free(temp_key);
return key_found;
}
static bool keys_dict_add_key_str(KeysDict* instance, FuriString* key) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(key);
furi_string_cat_str(key, "\n");
bool key_added = false;
uint32_t actual_pos = stream_tell(instance->stream);
if(stream_seek(instance->stream, 0, StreamOffsetFromEnd) &&
stream_insert_string(instance->stream, key)) {
instance->total_keys++;
key_added = true;
}
stream_seek(instance->stream, actual_pos, StreamOffsetFromStart);
return key_added;
}
bool keys_dict_add_key(KeysDict* instance, const uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
furi_assert(key);
FuriString* temp_key = furi_string_alloc();
furi_assert(temp_key);
keys_dict_int_to_str(instance, key, temp_key);
bool key_added = keys_dict_add_key_str(instance, temp_key);
FURI_LOG_I(TAG, "Added key %s", furi_string_get_cstr(temp_key));
furi_string_free(temp_key);
return key_added;
}
bool keys_dict_delete_key(KeysDict* instance, const uint8_t* key, size_t key_size) {
furi_assert(instance);
furi_assert(instance->stream);
furi_assert(instance->key_size == key_size);
furi_assert(key);
bool key_removed = false;
uint8_t* temp_key = malloc(key_size);
stream_rewind(instance->stream);
while(!key_removed) {
if(!keys_dict_get_next_key(instance, temp_key, key_size)) {
break;
}
if(memcmp(temp_key, key, key_size) == 0) {
stream_seek(instance->stream, -instance->key_size_symbols, StreamOffsetFromCurrent);
if(stream_delete(instance->stream, instance->key_size_symbols) == false) {
break;
}
instance->total_keys--;
key_removed = true;
}
}
FuriString* tmp = furi_string_alloc();
keys_dict_int_to_str(instance, key, tmp);
FURI_LOG_I(TAG, "Removed key %s", furi_string_get_cstr(tmp));
furi_string_free(tmp);
stream_rewind(instance->stream);
free(temp_key);
return key_removed;
}

103
lib/toolbox/keys_dict.h Normal file
View File

@ -0,0 +1,103 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
KeysDictModeOpenExisting,
KeysDictModeOpenAlways,
} KeysDictMode;
typedef struct KeysDict KeysDict;
/** Check if the file list exists
*
* @param path - list path
*
* @return true if list exists, false otherwise
*/
bool keys_dict_check_presence(const char* path);
/** Open or create list
* Depending on mode, list will be opened or created.
*
* @param path - Path of the file that contain the list
* @param mode - ListKeysMode value
* @param key_size - Size of each key in bytes
*
* @return Returns KeysDict list instance
*/
KeysDict* keys_dict_alloc(const char* path, KeysDictMode mode, size_t key_size);
/** Close list
*
* @param instance - KeysDict list instance
*/
void keys_dict_free(KeysDict* instance);
/** Get total number of keys in list
*
* @param instance - KeysDict list instance
*
* @return Returns total number of keys in list
*/
size_t keys_dict_get_total_keys(KeysDict* instance);
/** Rewind list
*
* @param instance - KeysDict list instance
*
* @return Returns true if rewind was successful, false otherwise
*/
bool keys_dict_rewind(KeysDict* instance);
/** Check if key is present in list
*
* @param instance - KeysDict list instance
* @param key - key to check
* @param key_size - Size of the key in bytes
*
* @return Returns true if key is present, false otherwise
*/
bool keys_dict_is_key_present(KeysDict* instance, const uint8_t* key, size_t key_size);
/** Get next key from the list
* This function will return next key from list. If there are no more
* keys, it will return false, and keys_dict_rewind() should be called.
*
* @param instance - KeysDict list instance
* @param key - Array where to store key
* @param key_size - Size of key in bytes
*
* @return Returns true if key was successfully retrieved, false otherwise
*/
bool keys_dict_get_next_key(KeysDict* instance, uint8_t* key, size_t key_size);
/** Add key to list
*
* @param instance - KeysDict list instance
* @param key - Key to add
* @param key_size - Size of the key in bytes
*
* @return Returns true if key was successfully added, false otherwise
*/
bool keys_dict_add_key(KeysDict* instance, const uint8_t* key, size_t key_size);
/** Delete key from list
*
* @param instance - KeysDict list instance
* @param key - Key to delete
* @param key_size - Size of the key in bytes
*
* @return Returns true if key was successfully deleted, false otherwise
*/
bool keys_dict_delete_key(KeysDict* instance, const uint8_t* key, size_t key_size);
#ifdef __cplusplus
}
#endif

View File

@ -11,6 +11,27 @@ WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
# Excludes all files ending with ~, usually created by editors as backup files
GLOB_FILE_EXCLUSION = ["*~"]
# List of environment variables to proxy to child processes
FORWARDED_ENV_VARIABLES = [
# CI/CD variables
"WORKFLOW_BRANCH_OR_TAG",
"DIST_SUFFIX",
# Python & other tools
"HOME",
"APPDATA",
"PYTHONHOME",
"PYTHONNOUSERSITE",
"TMP",
"TEMP",
# ccache
"CCACHE_DISABLE",
# Colors for tools
"TERM",
# Toolchain
"FBT_TOOLCHAIN_PATH",
"UFBT_HOME",
]
def tempfile_arg_esc_func(arg):
arg = quote_spaces(arg)

View File

@ -25,33 +25,10 @@ forward_os_env = {
"PATH": os.environ["PATH"],
}
# Proxying environment to child processes & scripts
variables_to_forward = [
# CI/CD variables
"WORKFLOW_BRANCH_OR_TAG",
"DIST_SUFFIX",
# Python & other tools
"HOME",
"APPDATA",
"PYTHONHOME",
"PYTHONNOUSERSITE",
"TMP",
"TEMP",
# Colors for tools
"TERM",
]
if proxy_env := GetOption("proxy_env"):
variables_to_forward.extend(proxy_env.split(","))
for env_value_name in variables_to_forward:
if environ_value := os.environ.get(env_value_name, None):
forward_os_env[env_value_name] = environ_value
# Core environment init - loads SDK state, sets up paths, etc.
core_env = Environment(
variables=ufbt_variables,
ENV=forward_os_env,
UFBT_STATE_DIR=ufbt_state_dir,
UFBT_CURRENT_SDK_DIR=ufbt_current_sdk_dir,
UFBT_SCRIPT_DIR=ufbt_script_dir,
@ -69,6 +46,7 @@ core_env.Append(CPPDEFINES=GetOption("extra_defines"))
from fbt.appmanifest import FlipperApplication, FlipperAppType
from fbt.sdk.cache import SdkCache
from fbt.util import (
FORWARDED_ENV_VARIABLES,
path_as_posix,
resolve_real_dir_node,
single_quote,
@ -76,8 +54,19 @@ from fbt.util import (
wrap_tempfile,
)
variables_to_forward = list(FORWARDED_ENV_VARIABLES)
if proxy_env := GetOption("proxy_env"):
variables_to_forward.extend(proxy_env.split(","))
for env_value_name in variables_to_forward:
if environ_value := os.environ.get(env_value_name, None):
forward_os_env[env_value_name] = environ_value
# Base environment with all tools loaded from SDK
env = core_env.Clone(
ENV=forward_os_env,
toolpath=[core_env["FBT_SCRIPT_DIR"].Dir("fbt_tools")],
tools=[
"fbt_tweaks",
@ -477,9 +466,12 @@ else:
dist_env.PhonyTarget("dolphin_ext", Action(missing_dolphin_folder, None))
# print(env.Dump())
dist_env.PhonyTarget(
"env",
"@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)",
'@echo "FBT_TOOLCHAIN_PATH='
+ forward_os_env["FBT_TOOLCHAIN_PATH"]
+ '" source $( "${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh" $)',
)
dist_env.PostConfigureUfbtEnvionment()

View File

@ -1,4 +1,6 @@
dist/*
.vscode
.clang-format
.editorconfig
.editorconfig
.env
.ufbt

View File

@ -44,7 +44,11 @@ How to create a new application:
4. Run `ufbt launch` to build and upload your application.
How to open a shell with toolchain environment and other build tools:
In your shell, type "source `ufbt -s env`". You can also use "." instead of "source".
In your shell, type "eval `ufbt -s env`".
How to update uFBT SDK:
Run "ufbt update" to fetch latest SDK.
You can also specify branch, target and/or channel options. See "ufbt update -h" for details.
"""

View File

@ -1,6 +1,5 @@
import json
import os
import pathlib
import sys
from functools import reduce

View File

@ -1,13 +1,14 @@
from SCons.Platform import TempFileMunge
from fbt.util import (
tempfile_arg_esc_func,
single_quote,
wrap_tempfile,
resolve_real_dir_node,
)
import os
import multiprocessing
import os
from fbt.util import (
FORWARDED_ENV_VARIABLES,
resolve_real_dir_node,
single_quote,
tempfile_arg_esc_func,
wrap_tempfile,
)
from SCons.Platform import TempFileMunge
Import("VAR_ENV")
@ -15,23 +16,9 @@ forward_os_env = {
# Import PATH from OS env - scons doesn't do that by default
"PATH": os.environ["PATH"],
}
# Proxying CI environment to child processes & scripts
variables_to_forward = [
# CI/CD variables
"WORKFLOW_BRANCH_OR_TAG",
"DIST_SUFFIX",
# Python & other tools
"HOME",
"APPDATA",
"PYTHONHOME",
"PYTHONNOUSERSITE",
"TMP",
"TEMP",
# ccache
"CCACHE_DISABLE",
# Colors for tools
"TERM",
]
variables_to_forward = list(FORWARDED_ENV_VARIABLES)
if proxy_env := GetOption("proxy_env"):
variables_to_forward.extend(proxy_env.split(","))

View File

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,49.3,,
Version,+,50.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@ -139,6 +139,7 @@ Header,+,lib/toolbox/crc32_calc.h,,
Header,+,lib/toolbox/dir_walk.h,,
Header,+,lib/toolbox/float_tools.h,,
Header,+,lib/toolbox/hex.h,,
Header,+,lib/toolbox/keys_dict.h,,
Header,+,lib/toolbox/manchester_decoder.h,,
Header,+,lib/toolbox/manchester_encoder.h,,
Header,+,lib/toolbox/name_generator.h,,
@ -1592,6 +1593,15 @@ Function,-,j1f,float,float
Function,-,jn,double,"int, double"
Function,-,jnf,float,"int, float"
Function,-,jrand48,long,unsigned short[3]
Function,+,keys_dict_add_key,_Bool,"KeysDict*, const uint8_t*, size_t"
Function,+,keys_dict_alloc,KeysDict*,"const char*, KeysDictMode, size_t"
Function,+,keys_dict_check_presence,_Bool,const char*
Function,+,keys_dict_delete_key,_Bool,"KeysDict*, const uint8_t*, size_t"
Function,+,keys_dict_free,void,KeysDict*
Function,+,keys_dict_get_next_key,_Bool,"KeysDict*, uint8_t*, size_t"
Function,+,keys_dict_get_total_keys,size_t,KeysDict*
Function,+,keys_dict_is_key_present,_Bool,"KeysDict*, const uint8_t*, size_t"
Function,+,keys_dict_rewind,_Bool,KeysDict*
Function,-,l64a,char*,long
Function,-,labs,long,long
Function,-,lcong48,void,unsigned short[7]

1 entry status name type params
2 Version + 49.3 50.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
139 Header + lib/toolbox/dir_walk.h
140 Header + lib/toolbox/float_tools.h
141 Header + lib/toolbox/hex.h
142 Header + lib/toolbox/keys_dict.h
143 Header + lib/toolbox/manchester_decoder.h
144 Header + lib/toolbox/manchester_encoder.h
145 Header + lib/toolbox/name_generator.h
1593 Function - jn double int, double
1594 Function - jnf float int, float
1595 Function - jrand48 long unsigned short[3]
1596 Function + keys_dict_add_key _Bool KeysDict*, const uint8_t*, size_t
1597 Function + keys_dict_alloc KeysDict* const char*, KeysDictMode, size_t
1598 Function + keys_dict_check_presence _Bool const char*
1599 Function + keys_dict_delete_key _Bool KeysDict*, const uint8_t*, size_t
1600 Function + keys_dict_free void KeysDict*
1601 Function + keys_dict_get_next_key _Bool KeysDict*, uint8_t*, size_t
1602 Function + keys_dict_get_total_keys size_t KeysDict*
1603 Function + keys_dict_is_key_present _Bool KeysDict*, const uint8_t*, size_t
1604 Function + keys_dict_rewind _Bool KeysDict*
1605 Function - l64a char* long
1606 Function - labs long long
1607 Function - lcong48 void unsigned short[7]

View File

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,49.3,,
Version,+,50.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
@ -114,7 +114,6 @@ Header,+,lib/nanopb/pb_encode.h,,
Header,+,lib/nfc/helpers/iso13239_crc.h,,
Header,+,lib/nfc/helpers/iso14443_crc.h,,
Header,+,lib/nfc/helpers/nfc_data_generator.h,,
Header,+,lib/nfc/helpers/nfc_dict.h,,
Header,+,lib/nfc/helpers/nfc_util.h,,
Header,+,lib/nfc/nfc.h,,
Header,+,lib/nfc/nfc_device.h,,
@ -204,6 +203,7 @@ Header,+,lib/toolbox/crc32_calc.h,,
Header,+,lib/toolbox/dir_walk.h,,
Header,+,lib/toolbox/float_tools.h,,
Header,+,lib/toolbox/hex.h,,
Header,+,lib/toolbox/keys_dict.h,,
Header,+,lib/toolbox/manchester_decoder.h,,
Header,+,lib/toolbox/manchester_encoder.h,,
Header,+,lib/toolbox/name_generator.h,,
@ -1967,6 +1967,15 @@ Function,-,j1f,float,float
Function,-,jn,double,"int, double"
Function,-,jnf,float,"int, float"
Function,-,jrand48,long,unsigned short[3]
Function,+,keys_dict_add_key,_Bool,"KeysDict*, const uint8_t*, size_t"
Function,+,keys_dict_alloc,KeysDict*,"const char*, KeysDictMode, size_t"
Function,+,keys_dict_check_presence,_Bool,const char*
Function,+,keys_dict_delete_key,_Bool,"KeysDict*, const uint8_t*, size_t"
Function,+,keys_dict_free,void,KeysDict*
Function,+,keys_dict_get_next_key,_Bool,"KeysDict*, uint8_t*, size_t"
Function,+,keys_dict_get_total_keys,size_t,KeysDict*
Function,+,keys_dict_is_key_present,_Bool,"KeysDict*, const uint8_t*, size_t"
Function,+,keys_dict_rewind,_Bool,KeysDict*
Function,-,l64a,char*,long
Function,-,labs,long,long
Function,-,lcong48,void,unsigned short[7]
@ -2441,15 +2450,6 @@ Function,+,nfc_device_save,_Bool,"NfcDevice*, const char*"
Function,+,nfc_device_set_data,void,"NfcDevice*, NfcProtocol, const NfcDeviceData*"
Function,+,nfc_device_set_loading_callback,void,"NfcDevice*, NfcLoadingCallback, void*"
Function,+,nfc_device_set_uid,_Bool,"NfcDevice*, const uint8_t*, size_t"
Function,+,nfc_dict_add_key,_Bool,"NfcDict*, const uint8_t*, size_t"
Function,+,nfc_dict_alloc,NfcDict*,"const char*, NfcDictMode, size_t"
Function,+,nfc_dict_check_presence,_Bool,const char*
Function,+,nfc_dict_delete_key,_Bool,"NfcDict*, const uint8_t*, size_t"
Function,+,nfc_dict_free,void,NfcDict*
Function,+,nfc_dict_get_next_key,_Bool,"NfcDict*, uint8_t*, size_t"
Function,+,nfc_dict_get_total_keys,uint32_t,NfcDict*
Function,+,nfc_dict_is_key_present,_Bool,"NfcDict*, const uint8_t*, size_t"
Function,+,nfc_dict_rewind,_Bool,NfcDict*
Function,+,nfc_felica_listener_set_sensf_res_data,NfcError,"Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t"
Function,+,nfc_free,void,Nfc*
Function,+,nfc_iso14443a_listener_set_col_res_data,NfcError,"Nfc*, uint8_t*, uint8_t, uint8_t*, uint8_t"

1 entry status name type params
2 Version + 49.3 50.0
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/cli/cli.h
114 Header + lib/nfc/helpers/iso13239_crc.h
115 Header + lib/nfc/helpers/iso14443_crc.h
116 Header + lib/nfc/helpers/nfc_data_generator.h
Header + lib/nfc/helpers/nfc_dict.h
117 Header + lib/nfc/helpers/nfc_util.h
118 Header + lib/nfc/nfc.h
119 Header + lib/nfc/nfc_device.h
203 Header + lib/toolbox/dir_walk.h
204 Header + lib/toolbox/float_tools.h
205 Header + lib/toolbox/hex.h
206 Header + lib/toolbox/keys_dict.h
207 Header + lib/toolbox/manchester_decoder.h
208 Header + lib/toolbox/manchester_encoder.h
209 Header + lib/toolbox/name_generator.h
1967 Function - jn double int, double
1968 Function - jnf float int, float
1969 Function - jrand48 long unsigned short[3]
1970 Function + keys_dict_add_key _Bool KeysDict*, const uint8_t*, size_t
1971 Function + keys_dict_alloc KeysDict* const char*, KeysDictMode, size_t
1972 Function + keys_dict_check_presence _Bool const char*
1973 Function + keys_dict_delete_key _Bool KeysDict*, const uint8_t*, size_t
1974 Function + keys_dict_free void KeysDict*
1975 Function + keys_dict_get_next_key _Bool KeysDict*, uint8_t*, size_t
1976 Function + keys_dict_get_total_keys size_t KeysDict*
1977 Function + keys_dict_is_key_present _Bool KeysDict*, const uint8_t*, size_t
1978 Function + keys_dict_rewind _Bool KeysDict*
1979 Function - l64a char* long
1980 Function - labs long long
1981 Function - lcong48 void unsigned short[7]
2450 Function + nfc_device_set_data void NfcDevice*, NfcProtocol, const NfcDeviceData*
2451 Function + nfc_device_set_loading_callback void NfcDevice*, NfcLoadingCallback, void*
2452 Function + nfc_device_set_uid _Bool NfcDevice*, const uint8_t*, size_t
Function + nfc_dict_add_key _Bool NfcDict*, const uint8_t*, size_t
Function + nfc_dict_alloc NfcDict* const char*, NfcDictMode, size_t
Function + nfc_dict_check_presence _Bool const char*
Function + nfc_dict_delete_key _Bool NfcDict*, const uint8_t*, size_t
Function + nfc_dict_free void NfcDict*
Function + nfc_dict_get_next_key _Bool NfcDict*, uint8_t*, size_t
Function + nfc_dict_get_total_keys uint32_t NfcDict*
Function + nfc_dict_is_key_present _Bool NfcDict*, const uint8_t*, size_t
Function + nfc_dict_rewind _Bool NfcDict*
2453 Function + nfc_felica_listener_set_sensf_res_data NfcError Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t
2454 Function + nfc_free void Nfc*
2455 Function + nfc_iso14443a_listener_set_col_res_data NfcError Nfc*, uint8_t*, uint8_t, uint8_t*, uint8_t