1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-13 13:09:49 +04:00

Compare commits

...

252 Commits

Author SHA1 Message Date
MX
dbf4b65d84 update changelog 2022-10-06 19:18:09 +03:00
MX
2ffb246e69 Merge branch 'fz-dev' into dev 2022-10-06 19:17:56 +03:00
Sergey Gavrilov
e3a5df5959 CLI: log command argument (#1817)
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2022-10-07 01:13:02 +09:00
MX
90eefeb2ed Merge pull request #88 from jd-raymaker/dev
Added norwegian keyboard layout
2022-10-06 18:56:33 +03:00
MX
fda541c7fb update changelog 2022-10-06 18:45:53 +03:00
MX
42494d801f fix merge issue 2022-10-06 18:42:59 +03:00
MX
1253a78dba Merge branch 'fz-dev' into dev 2022-10-06 18:41:48 +03:00
Max Andreev
d07c2dbe54 ".fap" extention in file browser and archive tab (#1812)
* Add .fap extention, and Applications tab
* Using new icon, renaming tab to Apps
* Change tabs order
* Add first ugly implementation of in-app icons in archive browser
* Starting using FAPLoader callback
* Getting all metafata from fap
* add app filename fallback
* using fap_loader_item_callback in archive_list_item_cb
* FAP-Loader: removed minimal allocation
* Removed strange code

Co-authored-by: SG <who.just.the.doctor@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
2022-10-07 00:37:53 +09:00
nminaylov
8f1812655e CLI loader shows app name, rfid edit fix 2022-10-06 18:26:15 +03:00
MX
3802171009 Revert "Merge branch 'fz-dev' into dev"
This reverts commit 03ad1770f8.
2022-10-06 18:23:50 +03:00
MX
03ad1770f8 Merge branch 'fz-dev' into dev 2022-10-06 18:23:44 +03:00
MX
b86756b581 don't include example app in releases 2022-10-06 17:58:18 +03:00
Skorpionm
11681d8ee8 [FL-2866, FL-2865] SubGhz: add frequency analyzer history (#1810)
* SubGhz: frequency analyzer history
* SubGhz: add vibro
* SubGhz: turn on the display when receiving a signal
* SubGhz: add signal reception indicator
* SubGhz: fix indicator
* SubGhz: fix FA history

Co-authored-by: あく <alleteam@gmail.com>
2022-10-06 23:48:29 +09:00
Skorpionm
061f53cd3c [FL-2849] SubGhz: read RAW auto generation of names (#1772)
* SubGhz: read RAW auto auto generation of names depending on the date of the entry
* SubGhz: name generation modification RAW-YYYYMMDD-HHMMSS
* SubGhz: replace m-string with FuriString

Co-authored-by: あく <alleteam@gmail.com>
2022-10-06 23:43:17 +09:00
MX
4bbeeb19e2 Merge branch 'fz-dev' into dev 2022-10-06 17:31:43 +03:00
Georgii Surkov
61189c3c82 [FL-2847] FFF trailing space fix (#1811)
* Improve whitespace handlilng in FFF
* Add tests for odd fff user input
* Adjust formatting

Co-authored-by: あく <alleteam@gmail.com>
2022-10-06 23:18:20 +09:00
hedger
9bf11d9fd2 [FL-2859,2838] fbt: improvements for FAPs (#1813)
* fbt: assets builder for apps WIP
* fbt: automatically building private fap assets
* docs: details on how to use image assets
* fbt: renamed fap_assets -> fap_icons
* fbt: support for fap_extbuild field
* docs: info on fap_extbuild
* fbt: added --proxy-env parame ter
* fbt: made firmware_cdb & updater_cdb targets always available
* fbt: renamed fap_icons -> fap_icon_assets
* fbt: deprecated firmware_* target names for faps; new alias is "fap_APPID"
* fbt: changed intermediate file locations for external apps
* fbt: support for fap_private_libs; docs: updates
* restored mbedtls as global lib
* scripts: lint.py: skip "lib" subfolder
* fbt: Sanity checks for building advanced faps as part of fw
* docs: info on fap_private_libs; fbt: optimized *.fam indexing
* fbt: cleanup; samples: added sample_icons app
* fbt: moved example app to applications/examples
* linter fix
* docs: readme fixes
* added applications/examples/application.fam stub
* docs: more info on private libs

Co-authored-by: あく <alleteam@gmail.com>
2022-10-06 22:55:57 +09:00
MX
c76fcf5072 Merge branch 'fz-dev' into dev 2022-10-06 15:50:59 +03:00
MX
007a11d70d upd ofw pr 1832 2022-10-06 15:26:23 +03:00
MX
b61e41163b fix subghz double click after delete, fix rename bug, fix unirf 2022-10-06 15:10:08 +03:00
Nikolay Minaylov
a69e150e2f [FL-2812] RFID: write fix for some protocols #1828
Co-authored-by: あく <alleteam@gmail.com>
2022-10-06 20:36:21 +09:00
Matvey Gerasimov
f16cdd1477 fix: typo badusb demo windows (#1824)
Fix a typo in the badusb demo script for Windows.

Co-authored-by: あく <alleteam@gmail.com>
2022-10-06 20:18:40 +09:00
MX
ac286dfed8 fix subghz bruteforcer, change subghz raw naming 2022-10-06 14:10:56 +03:00
MX
a93008b218 fix rfid fuzzer 2022-10-06 03:09:20 +03:00
MX
31aaa593fc fixes, rfid fuzzer still crashes 2022-10-06 02:30:40 +03:00
MX
5a2719663f fix archive, update changelog 2022-10-06 00:55:26 +03:00
JayDee Raymaker
adccb87499 Added norwegian keyboard layout 2022-10-05 23:26:24 +02:00
MX
693f78e501 update icon naming
OFW PR 1829 by nminaylov
2022-10-05 23:15:14 +03:00
MX
6eb610762e bump api version 2022-10-05 21:40:06 +03:00
MX
3e4d8a41e0 Remove string_push_uint64
OFW PR 1832 by Astrrra
2022-10-05 21:39:40 +03:00
MX
c60bfbf271 oh no 2022-10-05 21:27:13 +03:00
MX
0796263e81 Merge branch 'fz-dev' into dev 2022-10-05 19:27:46 +03:00
Sergey Gavrilov
4bf29827f8 M*LIB: non-inlined strings, FuriString primitive (#1795)
* Quicksave 1
* Header stage complete
* Source stage complete
* Lint & merge fixes
* Includes
* Documentation step 1
* FBT: output free size considering BT STACK
* Documentation step 2
* py lint
* Fix music player plugin
* unit test stage 1: string allocator, mem, getters, setters, appends, compare, search.
* unit test: string equality
* unit test: string replace
* unit test: string start_with, end_with
* unit test: string trim
* unit test: utf-8
* Rename
* Revert fw_size changes
* Simplify CLI backspace handling
* Simplify CLI character insert
* Merge fixes
* Furi: correct filenaming and spelling
* Bt: remove furi string include

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2022-10-06 00:15:23 +09:00
MX
baf5034817 Merge pull request #87 from derskythe/feat-add-subbrute-frequency
Add CAME 12bit 303MHz to SubBrute
2022-10-05 17:26:02 +03:00
derskythe
04e16970db Add CAME 12bit 303MHz to SubBrute 2022-10-05 17:45:45 +04:00
MX
a8b48771e4 rfid fuzzer, ability to change time delay 2022-10-04 23:43:15 +03:00
MX
1424878d65 update assets and changelog 2022-10-04 21:40:07 +03:00
MX
a37b0d464c Signal Generator app: UI update
OFW PR 1829 by nminaylov
2022-10-04 21:07:10 +03:00
MX
96502e21ae RFID: write fix for some protocols
OFW PR 1828 by nminaylov
2022-10-04 21:06:16 +03:00
MX
b5d6d60535 New notification sequence for Frequency Analyser
PR #86 by @BastienB3
2022-10-04 21:05:09 +03:00
MX
32e64fd29e update changelog 2022-10-04 18:40:57 +03:00
MX
8f9d81b972 Merge pull request #84 from colingrady/wrap_rfid_fuzzer_menu
Allow the RFID protocol menu to wrap
2022-10-04 18:25:29 +03:00
MX
23e0566273 Merge pull request #85 from mvanzanten/adding-on-the-fly-changes-ui-addition
Improve UI for added on-the-fly feature
2022-10-04 18:25:07 +03:00
MX
4141483147 NFC update detect reader
OFW PR 1820 by gornekich
2022-10-04 18:23:11 +03:00
Matt Van Zanten
30e005d5c4 improve UI for added on the fly feature 2022-10-04 08:07:53 -07:00
MX
e3a2711eb3 Remove bank card uid emulation & fix emv info
OFW PR 1823 by gornekich
2022-10-04 18:05:57 +03:00
MX
8569641ce6 Infrared error message
OFW PR 1827 by gsurkov
2022-10-04 18:02:21 +03:00
MX
cafd06c71b Don't turn off the backlight on MFC dict attack
OFW PR 1826 by Astrrra
2022-10-04 17:59:22 +03:00
MX
06a7bda69b block hopping and detect raw at same time
and fix freq analyzer feedback display backlight
2022-10-04 17:58:12 +03:00
Colin Grady
c43ce93936 Allow the RFID protocol menu to wrap 2022-10-04 08:53:58 -06:00
MX
2288855163 update assets and changelog 2022-10-04 03:29:02 +03:00
MX
c0765c1114 rfid fuzzer H10301 support and bug fixes 2022-10-04 03:15:28 +03:00
MX
683c6254da Merge remote-tracking branch 'origin/dev' into dev 2022-10-04 02:36:19 +03:00
MX
2ef515ef56 Merge pull request #83 from mvanzanten/adding-on-the-fly-changes-2
Adding on the fly bit changes
2022-10-04 02:35:57 +03:00
MX
667be798fc rfid fuzzer, fix bugs, improve gui, add PAC/Stanley support
add more example files
2022-10-04 02:33:39 +03:00
MX
0f9598099a fix rfid fuzzer crash, fix bug when dict attack can't be restarted 2022-10-04 01:15:15 +03:00
MX
0d6f729386 CLI: log command argument (log level)
OFW PR 1817 by DrZlo13
2022-10-04 00:48:25 +03:00
MX
b452b6fd32 FFF trailing space fix
OFW PR 1811 by gsurkov
2022-10-04 00:45:09 +03:00
Matt Van Zanten
9403128a03 moving to center nicer 2022-10-03 11:32:10 -07:00
Matt Van Zanten
71589b28a7 removing debug logs 2022-10-03 11:09:51 -07:00
Matt Van Zanten
8b0fa6d0b1 running fbt format 2022-10-03 11:07:16 -07:00
Matt Van Zanten
cf47da0ff4 Merge branch 'dev' into adding-on-the-fly-changes-2 2022-10-03 10:47:17 -07:00
Matt Van Zanten
d6b7fae7e4 working version of the on the fly bit switcher 2022-10-03 10:29:04 -07:00
MX
110dc48b96 Merge remote-tracking branch 'origin/dev' into dev 2022-10-03 18:42:52 +03:00
MX
37c666ddf5 Merge pull request #82 from TQMatvey/pr_temp
SubGhz: Enable backlight on new signal
2022-10-03 18:42:18 +03:00
MX
6ddca568b9 correct notification sequence 2022-10-03 18:41:37 +03:00
MX
8993db56b8 this was not part of previous change 2022-10-03 18:40:22 +03:00
MX
3c1efda1db return carrier test included with non debug builds 2022-10-03 18:36:06 +03:00
MX
b62b7956a6 Merge pull request #80 from derskythe/fix-read-in-readraw-crash
Fix-read-in-readraw-crash
2022-10-03 18:27:54 +03:00
MX
dce5af5c2e hmm 2022-10-03 18:22:09 +03:00
MX
fbacdc5b7b fix critical bug with subghz rpc 2022-10-03 18:21:18 +03:00
MX
8dba4f25ae unused 2022-10-03 18:20:49 +03:00
derskythe
43ef4046ed Add stubs for split 2022-10-03 19:00:35 +04:00
mvanzanten
1e63f57bf7 working version, change bits on the fly 2022-10-02 12:06:06 -07:00
Matt Van Zanten
649887fe0f progress, adding on the fly 2022-10-02 08:18:01 -07:00
derskythe
be42c390f2 Save on SD Card only RAW files 2022-10-02 16:57:32 +04:00
derskythe
cbda5d996f Fix uncommited merge 2022-10-02 16:50:03 +04:00
derskythe
de1ec97512 Merge remote-tracking branch 'refs/remotes/origin/fix-read-in-readraw-crash' into fix-read-in-readraw-crash 2022-10-02 16:20:18 +04:00
MX
8af749c965 enable saving detect raw state via define 2022-10-02 13:50:29 +03:00
MX
4d3f45e911 Don’t show temp history dir in filebrowser 2022-10-02 10:18:31 +03:00
MX
63fee41a1f enable worker back 2022-10-02 09:51:27 +03:00
TQMatvey
f441fed68d SubGhz: Follow system backlight timer 2022-10-02 13:48:06 +07:00
TQMatvey
6e0eeed773 SubGhz: turn on display for new signal 2022-10-02 13:29:16 +07:00
MX
6bf306200e make loading subghz file from favourites a bit faster 2022-10-02 08:50:41 +03:00
MX
e2faf31b45 debug in subghz only when compiled with DEBUG=1 2022-10-02 07:34:39 +03:00
MX
85eb740559 do not save detect raw on/off settings 2022-10-02 06:38:34 +03:00
MX
cea14ae9c5 fix dir creation bug, save files only for RAW
TODO: files are broken when they have more than 512 elements in one line
Split file to 512 element chunks as it done in regular Read RAW
2022-10-02 06:23:09 +03:00
MX
e9a11cfce0 Merge branch 'dev' into fix-read-in-readraw-crash 2022-10-02 04:06:01 +03:00
MX
87a14b96e1 Merge branch 'fz-dev' into dev 2022-10-02 04:05:07 +03:00
derskythe
bbd3f9cf71 Fixed all bugs with saving directly to file, also fixed misspeled if/ifdef in all app 2022-10-02 03:18:30 +04:00
derskythe
230f09dddd enable delete temp files 2022-10-01 08:47:44 +04:00
derskythe
24e744f1d1 Added saving DetectRAW settings, trying to write files on SD instead of memory 2022-10-01 08:39:51 +04:00
あく
0f9ea925d3 UnitTests: fix thread join test (#1808) 2022-09-30 22:03:57 +09:00
Nikolay Minaylov
836de3df16 [FL-2825] iButton GUI fixes (#1805)
* Ibutton GUI fixes
* Fix memory leak in lfRFID write

Co-authored-by: あく <alleteam@gmail.com>
2022-09-30 21:56:12 +09:00
Sergey Gavrilov
c92217a109 Thread: Clear TLS after thread stop (#1807) 2022-09-30 19:59:11 +09:00
MX
41c93431c8 update changelog, readme, assets 2022-09-30 03:46:06 +03:00
MX
f0ea8f3a84 fix clock am/pm logic 2022-09-29 23:50:49 +03:00
MX
4d8f294e7a Merge pull request #79 from derskythe/subghz-freq-analyzer-long-press
Long press OK button in SubGHz Frequency analyzer switch to Read menu
2022-09-29 23:26:02 +03:00
derskythe
f543753873 Long press OK button in SubGHz Frequency analyzer switch to Read menu with selected frequency 2022-09-29 23:46:54 +04:00
MX
1fb1a68842 iButton GUI fixes
OFW PR 1805 by nminaylov
2022-09-29 20:56:04 +03:00
MX
54fedb9bc8 Merge pull request #78 from alexberkowitz/dev
Increase Sub-GHz remote label line length to 16
2022-09-29 18:34:22 +03:00
MX
8af9c00ddb Merge branch 'fz-dev' into dev 2022-09-29 18:20:05 +03:00
Sergey Gavrilov
5a22803bbc Revert "Revert "Furi Thread: don't use thread pointer after FuriThreadStateStopped callback (#1799)""
This reverts commit 7df70d7c62.
2022-09-29 18:15:02 +03:00
Alex Berkowitz
824f5ea027 Merge branch 'Eng1n33r:dev' into dev 2022-09-29 10:04:21 -05:00
hedger
76d38e832e fbt: reproducible manifest builds & improvements (#1801)
* fbt: reproducible manifest builds, less rebuild on small updates; scripts: assets: using timestamp from commandline af available
* fbt: added app import validation for launch_app & single app build targets
* fbt: COMSTR for app imports validation
* docs: minor fixes
* docs: markdown fix
* vscode: comments for RTOS startup

Co-authored-by: あく <alleteam@gmail.com>
2022-09-29 20:00:22 +09:00
Sergey Gavrilov
aba20b6af8 Furi Thread: fixed furi_thread_join, check if thread has not been started (#1803)
* furi thread: fixed furi_thread_join, check if thread has not been started
* Furi: correct returns in furi_thread_join

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2022-09-29 19:42:15 +09:00
MX
226f8517f3 update readme and changelog 2022-09-29 11:01:15 +03:00
Sergey Gavrilov
7df70d7c62 Revert "Furi Thread: don't use thread pointer after FuriThreadStateStopped callback (#1799)"
This reverts commit 5883e134d4.
2022-09-29 09:27:03 +03:00
MX
9176387b9f update assets and changelog 2022-09-29 09:14:47 +03:00
MX
972c0dcb4a hide layouts folder in badusb app 2022-09-29 08:20:30 +03:00
MX
62e56e2618 rename apps to make it look a bit better in Apps tab in archive app
now old assets are removed so we can avoid duplicates
2022-09-29 08:20:00 +03:00
MX
f202d27206 Merge branch 'fz-dev' into dev 2022-09-29 05:57:02 +03:00
Mewa
bcfb12bf28 Keyboard: show Uppercase keys when replacing content (#1548)
Co-authored-by: あく <alleteam@gmail.com>
2022-09-29 02:44:24 +09:00
Sergey Gavrilov
5883e134d4 Furi Thread: don't use thread pointer after FuriThreadStateStopped callback (#1799)
* Furi Thread: correct furi_thread_join, do not use thread pointer after FuriThreadStateStopped callback
* Furi: a little bit easier way to do harakiri
* Furi: crash on thread self join attempt

Co-authored-by: あく <alleteam@gmail.com>
2022-09-29 02:37:07 +09:00
hedger
f8b532f063 [FL-2831] Resources cleanup in updater (#1796)
* updater: remove files from existing resources Manifest file before deploying new resources
* toolbox: tar: single file extraction API

Co-authored-by: あく <alleteam@gmail.com>
2022-09-29 02:13:12 +09:00
Vyacheslav Tumanov
e25b424188 Typos fix in some strings/comments #1794
Co-authored-by: あく <alleteam@gmail.com>
2022-09-29 01:52:46 +09:00
Nikolay Minaylov
4241ad24a3 [FL-2797] Signal Generator app (#1793)
* Signal Generator app
* MCO pin initialization in app
* furi_hal_pwm documentation

Co-authored-by: あく <alleteam@gmail.com>
2022-09-29 01:37:24 +09:00
MX
6bcc6f363b add 868.8 mhz for sommer systems 2022-09-28 16:35:40 +03:00
MX
3dcd8a73f1 update changelog 2022-09-28 08:06:47 +03:00
MX
9ad7f7825d update projector asset
by @Amec0e
2022-09-28 07:50:43 +03:00
MX
aa00606d22 remove unnecessary checks from brute plugin, subghz improvements
fix subghz gui in add manually, add BETT protocol in add manually
2022-09-28 07:50:09 +03:00
MX
9c62e1f6ac Merge pull request #77 from derskythe/subghz-save-settings-v2
SubGHz save settings version 2
2022-09-28 07:00:15 +03:00
MX
b934c41ed0 close file 2022-09-28 06:51:13 +03:00
MX
0ebb3f060e add a bit of changes 2022-09-28 06:46:45 +03:00
derskythe
8f2bd3be57 Update list of frequencies and change name of file of settings to not able to run in browser 2022-09-28 07:14:38 +04:00
derskythe
cc02d57857 Merge remote-tracking branch 'origin/subghz-save-settings-v2' into subghz-save-settings-v2
# Conflicts:
#	applications/main/subghz/subghz_last_settings.c
2022-09-28 07:09:58 +04:00
MX
0c5f11f713 return fix 2022-09-28 06:02:23 +03:00
derskythe
006d27ed93 Add removed fixed 2022-09-28 06:53:52 +04:00
MX
746b732034 remove unused code 2022-09-28 05:49:21 +03:00
Der Skythe
2ec9aeeefa Merge branch 'Eng1n33r:dev' into subghz-save-settings-v2 2022-09-28 06:32:54 +04:00
derskythe
8be08093e2 Change name of file to not able to "Run in App" in Browser 2022-09-28 06:28:23 +04:00
derskythe
406247c5d8 Ok button in frequency analyzer will set this frequency to receiver 2022-09-28 06:22:02 +04:00
derskythe
22a87d5707 struct doesn't correct written 2022-09-28 05:49:06 +04:00
MX
4271246d8a Merge branch 'fz-dev' into dev 2022-09-28 04:04:12 +03:00
derskythe
a3db6718c2 fix bug with invalid settings values in config 2022-09-28 04:31:29 +04:00
derskythe
0f0473bee6 fix bug with invalid settings values in config 2022-09-28 03:27:47 +04:00
derskythe
497be7ccb0 Last SubGHz settings is ready 2022-09-28 02:01:09 +04:00
Georgii Surkov
12a6290e91 [FL-2853] Reorganise Universal A/C library (#1792)
* Reorganise A/C universal remote library file
* Refactor infrared brute force code
* Update UniversalRemotes.md

Co-authored-by: あく <alleteam@gmail.com>
2022-09-28 02:11:28 +09:00
Tom Samstag
e6e1e7fe15 Add formatting to DESfire data dump (#1784)
Co-authored-by: gornekich <n.gorbadey@gmail.com>
2022-09-28 02:02:18 +09:00
MX
cb14d23108 format, add chamberlain 9bit 300mhz 2022-09-27 04:31:52 +03:00
MX
c4783664c0 subghz bruteforcer plugin: move title a bit 2022-09-27 00:51:36 +03:00
MX
91f3774246 update changelog 2022-09-26 23:55:39 +03:00
MX
1f8a034a71 Merge pull request #76 from derskythe/subbrute-deep-refactor
Fix speed problems with linear and some bugs
2022-09-26 23:09:13 +03:00
MX
8cc3e2f35a remove extra environment alloc 2022-09-26 23:07:53 +03:00
MX
069dd29f08 Revert "some fixes, trying to speed up bruteforce(unsuccessful)"
This reverts commit 61fee8e269.
2022-09-26 22:52:22 +03:00
derskythe
91c06a2168 fix disable env allocation many times 2022-09-26 21:41:49 +04:00
derskythe
545c4349d6 add vibro on finish and main menu set left 2022-09-26 21:26:51 +04:00
derskythe
a40e1a2be2 set big step to 50 2022-09-26 21:15:46 +04:00
derskythe
286300b35b fix disable env allocation many times 2022-09-26 21:15:02 +04:00
derskythe
633145495c fix twice button press in manual mode 2022-09-26 21:10:41 +04:00
derskythe
a0bcbf731d fix error on back when selecting existing dump 2022-09-26 21:01:14 +04:00
MX
60242cd7c4 fix nfc device typo, doesn’t affect resulting keys 2022-09-26 19:46:12 +03:00
Alex Berkowitz
3e9409a1a8 Merge branch 'dev' of https://github.com/alexberkowitz/flipperzero-firmware into dev 2022-09-26 11:43:31 -05:00
MX
a9210b2849 Merge branch 'fz-dev' into dev 2022-09-26 19:37:37 +03:00
derskythe
a58807c57a Add SubGhzTxRxWorker for later use 2022-09-26 20:14:33 +04:00
Sergey Gavrilov
5bb7cabea6 Applications loader: do not use view dispatcher queue #1788 2022-09-27 00:59:28 +09:00
phreakocious
f201062819 Add Hisense A/C IR signals.. (#1773)
* add Hisense A/C IR signals.. note that using any will toggle the power and apply the settings
* re-order the entries to be grouped by function

Co-authored-by: あく <alleteam@gmail.com>
2022-09-27 00:42:29 +09:00
Shane Synan
9f501034c3 Power: Also ask charger if charge done (#1378)
* power: Also ask charger if charge done
* F7: bump API Symbols version
* Lib: remove double include in bq25896.c

Co-authored-by: あく <alleteam@gmail.com>
2022-09-27 00:34:59 +09:00
derskythe
7bd0c8ff2c application.fam revert 2022-09-26 18:30:04 +04:00
derskythe
cdcf80ed05 speed-up linear to 07:10 2022-09-26 18:27:58 +04:00
Georgii Surkov
3e3a167764 [FL-2852] Update Universal Remote documentation (#1786)
* Update Universal Remote documentation
* Change formatting
2022-09-26 22:49:18 +09:00
MX
fa9602bd68 Merge branch 'fz-dev' into dev 2022-09-26 15:27:24 +03:00
hedger
efb09380bd [FL-2836] Fast flash programming mode (#1782)
* updater: lowered logging level for resources unpacking; hal: implemented fast flash write mode
* hal: reworked fast flash programming; clearing most error flags on flash init; changed some flash functions return type from bool to void; scripts: fixed malformed CRC values in update bundles in certain cases;
* hal: flash: larger critical section
* hal: flash: enabling fast write inside critical section
* api_symbols: bump minor version
2022-09-26 20:03:21 +09:00
MX
61fee8e269 some fixes, trying to speed up bruteforce(unsuccessful) 2022-09-26 06:24:47 +03:00
MX
5e30b14d90 update changelog 2022-09-26 02:12:11 +03:00
MX
c07e3a34dd Merge pull request #75 from derskythe/subbrute-deep-refactor
SubBrute deep refactor
2022-09-26 02:08:45 +03:00
MX
be7e11e60f Merge branch 'dev' into subbrute-deep-refactor 2022-09-26 02:06:50 +03:00
MX
e96e414561 Merge branch 'fz-dev' into dev 2022-09-26 02:06:09 +03:00
derskythe
0c99cb52ec free transmitter during subbrute_worker_init_manual_transmit 2022-09-26 02:45:09 +04:00
derskythe
ad9e1ce4df set furi_hal_subghz_set_path to FuriHalSubGhzPathIsolate on each manual iteration 2022-09-26 02:42:39 +04:00
derskythe
22dc5190d1 remove furi_hal_power_suppress_charge_enter/exit from other places 2022-09-26 02:39:17 +04:00
derskythe
f2fd97d9c5 fix memory leaks 2022-09-26 02:36:38 +04:00
derskythe
08084d5763 fix first send signal equals last transferred or 0x00 2022-09-26 02:03:36 +04:00
derskythe
add1ad6949 fix manual select key on max and min values 2022-09-26 01:48:51 +04:00
DerSkythe
87654e60b8 Merge remote-tracking branch 'origin/subbrute-deep-refactor' into subbrute-deep-refactor 2022-09-26 01:10:21 +04:00
DerSkythe
6f92cd645e fixed frame width to scroll 2022-09-26 01:09:00 +04:00
DerSkythe
23f6ea2e05 refactor worker moved it to SubBruteState 2022-09-26 01:07:16 +04:00
David Coles
a6b98ccbbe Preliminary Rust support (#1781)
* Add support for R_ARM_THM_MOVW_ABS_NC/THM_MOVT_ABS

These are sometimes emitted by the Rust LLVM compiler.

Ref: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#56relocation

* Discard LLVM bitcode from extension applications

LLVM-based compilers may include uncompressed bitcode in object files
to help with link-time optimization. However this can bloat binary sizes
from KB to MB.

* Expose alligned_malloc/free functions to applications

This is required to implement a global allocator in Rust.
2022-09-26 07:06:46 +10:00
DerSkythe
ba5f590dab switched to manual transmit 2022-09-26 00:07:14 +04:00
Der Skythe
f1048733d2 Merge branch 'Eng1n33r:dev' into subbrute-deep-refactor 2022-09-25 23:16:27 +04:00
DerSkythe
ea7f68fcab fixed load existing dump 2022-09-25 23:12:31 +04:00
MX
8013aacd94 oops 2022-09-25 21:03:32 +03:00
MX
be8f409098 update changelog 2022-09-25 21:01:12 +03:00
MX
97e6fe8f4e update universal remote assets
by @amec0e
2022-09-25 20:39:22 +03:00
DerSkythe
54757428e6 fix bug with return to main menu when choice file 2022-09-25 21:31:33 +04:00
MX
bd39d81324 Merge branch 'fz-dev' into dev 2022-09-25 19:55:35 +03:00
Chris van Marle
2a2078d9b5 Text input overwrite max size template (#1687) 2022-09-26 01:17:09 +09:00
MX
01ca588488 Merge branch 'fz-dev' into dev 2022-09-25 18:27:58 +03:00
Kowalski Dragon
f86eada292 Remove unused headers (#1751) 2022-09-25 23:39:06 +09:00
Skorpionm
bc777b2eff SubGhz: fix config menu (#1748)
* SubGhz: fix config menu
* SubGhz: fix gui Magellen protocol
* SubGhz: fix gui Transmit SubGhz
* SubGhz: keeloq, new gen manufacture code
* SubGhz: Update keeloq_mfcodes

Co-authored-by: あく <alleteam@gmail.com>
2022-09-25 23:34:52 +09:00
DerSkythe
6f91fa42f0 Added additional graphic decorations 2022-09-25 18:26:10 +04:00
Sergey Gavrilov
e6d22ed147 ELF-Loader: C++ plugin support, loader overhaul. (#1744)
* fap-loader: load all code and data sections
* fap-loader: relocate all code and data sections
* fap-loader: remove old elf loader
* fap-loader: new jmp call relocation
* openocd: resume on detach
* fap-loader: trampoline for big jumps
* fap-loader: rename cache
* fap-loader: init_array support
* fap-loader: untangled flipper_application into separate entities
* fap-loader: fix debug
* fap-loader: optimize section container
* fap-loader: optimize key for section container
* fap-loader: disable debug log
* documentation
* F7: bump api symbols version
* Lib: cleanup elf_file.c

Co-authored-by: あく <alleteam@gmail.com>
2022-09-25 23:11:29 +09:00
MX
436f70b69b Merge branch 'fz-dev' into dev 2022-09-25 16:46:23 +03:00
DerSkythe
ec9ce0cad7 Working prototype, but not yet tested on a real device 2022-09-25 17:05:52 +04:00
Jauder Ho
7e2008095e Bump protobuf from 3.20.1 to 3.20.2 in /scripts (#1774) 2022-09-25 20:56:53 +09:00
Sergey Gavrilov
92e440c77d Core: simplify record container (#1776)
Co-authored-by: あく <alleteam@gmail.com>
2022-09-25 20:48:57 +09:00
DerSkythe
666821e9ce SubBruteMainView is ready 2022-09-25 00:46:43 +04:00
MX
1bca477a43 update install instructions
thanks to @Svaarich !
2022-09-24 22:20:13 +03:00
MX
41571ce9ad SubGHz RAW - datetime in default names (+ format changed)
OFW PR 1772 by Skorpionm / printf text format changed by me
2022-09-24 22:15:06 +03:00
MX
038d098c85 Merge branch 'fz-dev' into dev 2022-09-24 21:56:17 +03:00
DerSkythe
b03cc8ddc3 trying to fix load failure 2022-09-24 22:30:08 +04:00
DerSkythe
c8e3d9b040 fix repeat call of view_dispatcher_alloc 2022-09-24 22:15:09 +04:00
DerSkythe
aeb02500de Deep refactor of SubBrute was made, but it doesn't start. Debug device needed 2022-09-24 21:47:21 +04:00
ghettorce
eadd7801af fbt: exclude user site-packages directory from sys.path (#1778)
* fbt: exclude user site-packages directory from sys.path
* fbt: python path fixes for *nix
* fbt: fixed cli target on Windows

Co-authored-by: hedger <hedger@users.noreply.github.com>
2022-09-24 15:30:19 +04:00
Yoanndp
6d2b0a3b6c Update ReadMe.md (#1766) 2022-09-24 19:36:11 +09:00
Alex Berkowitz
8093721c24 Change Sub-Ghz Remote line length max to 16 2022-09-23 20:37:02 -05:00
MX
32a7642761 remove duplicate function, update changelog 2022-09-22 21:51:47 +03:00
MX
e8bb45496d Merge branch 'fz-dev' into dev 2022-09-22 21:45:26 +03:00
Andrea Sacchi
3846852f2b NFC Fix Mifare Classic (#1769)
* Fix Mifare Classic key str to int conversion: Wrong cast lead to unexpected behavior converting key from str to int.
* Nfc: fix type cast in mf_classic_dict and add basic unit tests

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2022-09-23 02:35:28 +09:00
Georgii Surkov
17d01f5c29 [FL-2848] Universal Remote fix (#1770)
* Reset BruteForce on exit from Universal Remote
* Reset current button in ButtonPanel
2022-09-23 01:13:00 +09:00
MX
e6bcba6959 update changelog, minor fixes 2022-09-22 18:23:32 +03:00
MX
e13edc2f70 keeeloq update 2022-09-22 18:01:54 +03:00
MX
de6ff1d9c9 update changelog 2022-09-21 23:07:39 +03:00
MX
bea15134ba fix mousejacker gui 2022-09-21 22:29:42 +03:00
MX
28a55bf576 Merge branch 'fz-dev' into dev 2022-09-21 22:02:02 +03:00
gornekich
e70121e20f [FL-2843] NFC fixes (#1764)
* nfc: fix empty desfire card message
* nfc: limit total user keys to list
* nfc: increase popup timeout

Co-authored-by: あく <alleteam@gmail.com>
2022-09-22 00:53:25 +09:00
hedger
432ff41d6a [FL-2844] desktop: removing slideshow file when leaving slideshow view (#1762)
* [FL-2844] desktop: removing slideshow file when leaving slideshow view; vscode: fix for BM port fetcher; fap api: more symbols for LL
* desktop: actually removing slideshow file
* desktop: moved slideshow removal to scene code; fbt: better blackmagic device handling
* fbt: disabled pagination for gdb
* vscode: restored blackmagic command line
* fbt: fixed debug_other target; added debug_other_blackmagic
* furi: added furi_thread_suspend API group; fixed null-pointer deref for thread name; cleaned up RTOS config
* furi: changed thread state check to eTaskGetState
2022-09-21 23:42:59 +09:00
MX
87393a086c fix rfid fuzzer crashes, some new random names 2022-09-21 08:43:07 +03:00
MX
6000d47a0f allow saving only for protocols without encoder 2022-09-21 07:12:09 +03:00
MX
d986ef4104 fix nice flor s crash, fix debug pack for debug builds 2022-09-21 06:52:34 +03:00
MX
f85dc1675d update changelog, rm unused var from clock 2022-09-21 01:00:56 +03:00
MX
7c7ac07e6a Merge pull request #74 from mvanzanten/adding-support-for-hidprox
adding support for HIDProx, updating the UI to switch between protocols
2022-09-20 23:25:45 +03:00
MX
ca02826cfd set time between cards to 6, run fbt format 2022-09-20 23:24:34 +03:00
MX
96ad7f3cef fix nfc list crash, fix magellen gui, fix transmitter gui 2022-09-20 23:13:15 +03:00
Matt Van Zanten
c213ff596a adding support for HIDProx, updating the UI to switch between protocols 2022-09-20 11:45:16 -07:00
MX
b2589698ff Merge branch 'fz-dev' into dev 2022-09-20 21:39:22 +03:00
Max Lapan
3360f818a1 Subghz: Adding checks for get_upload functions (#1704)
* Adding checks for get_upload functions
  Almost in every protocol, function which generates upload might fail and return false.
  But we don't check this result, which might end up sending random memory contents to the air.
* Format sources and fix crash on ivalid bit count in chamberlain

Co-authored-by: あく <alleteam@gmail.com>
2022-09-20 14:29:10 +09:00
Georgii Surkov
066da4080b [FL-2792] AC Universal Remote (#1725)
* Add Universal AC Remote scene
* Implement AC gui
* Basic working implemetation
* Another Universal AC Remote implementation
* Update icons
* Adjust button positions
* Revert old ButtonPanel class
* Update resource manifest
* [FL-2627] Flipper applications: SDK, build and debug system (#1387)
* Update api definitions
* Add UniversalRemotes documentation
* Use more Flipper-friendly signal names

Co-authored-by: SG <who.just.the.doctor@gmail.com>
2022-09-20 14:09:37 +09:00
MX
b2c118f267 fix null pointer dereference in archive -> Info
and fix long path display
2022-09-20 05:52:13 +03:00
MX
a8db46124e update docs & changelog 2022-09-20 04:09:14 +03:00
MX
672e27f258 fix icon name 2022-09-20 03:23:22 +03:00
MX
e762a68265 Merge pull request #72 from RogueMaster/ApplicationsFromArchive
Applications from archive
2022-09-20 03:20:25 +03:00
MX
8659becc9d fix tab name and add new icon
icon by @Svaarich
2022-09-20 03:19:31 +03:00
RogueMaster
82e1e8af6a Enable fap support on Archive app 2022-09-19 18:47:22 -04:00
RogueMaster
a71d05a114 Update archive_browser.h 2022-09-19 18:39:38 -04:00
MX
8d68bf62a5 update changelog 2022-09-19 23:34:31 +03:00
MX
2c85adb270 remove unused icon, update api symbols and unirf 2022-09-19 21:21:31 +03:00
MX
e2123c55bb Merge branch 'fz-dev' into dev 2022-09-19 21:15:04 +03:00
David
f5ff6438d1 NFC user dict list, delete, and de-duplication. (#1533)
* Add MFC user keys list
* Leakey submenu fix
* Set next target for Save/Delete success scenes
* Delete individual user keys
* Update count of total keys
* Fix memory leak
* Check for duplicate keys
* Remove a submodule that I never added?
* Swap and position icons
* Revamp according to design doc
* Rename icons to include size and replace keychain icon with smaller variant
* Fix typos
* Final fixes
* Fufill requested changes
* Cleanup comments
* Merge dev after SD app loading
* Fixing icon names
* Revert merge mistakes and API version
* Scene switching adjustments
* F7: add/change/remove some nfc icons in api_symbols.csv

Co-authored-by: あく <alleteam@gmail.com>
2022-09-20 01:43:53 +09:00
Astra
9f3b80e606 Add new card parsers (#1503)
* Add the "Two cities" parser
* Add plantain and plantain4k parsers
* Add new parsers to the supported list
* United card PoC
* Fix nfc device not sleeping
* Completely read the 4K troika variants
* Correct naming
* Update to reflect upstream changes
* Add support for MfUl info
* Fix parsers
* Card type detection fixes
* Remove debug info
* Fixes for the verification of cards
* nfc: fix verification for supported cards
* nfc: remove unused vars
* Improve card reading reliability and fix plantain
* plantain: change log level

Co-authored-by: gornekich <n.gorbadey@gmail.com>
2022-09-20 01:05:04 +09:00
MX
111656d2c1 Merge branch 'fz-dev' into dev 2022-09-19 18:50:20 +03:00
MX
2045a29d3f lower frame rate in custom anim to save a bit of battery charge 2022-09-19 18:40:50 +03:00
MX
26e46f9267 Merge pull request #71 from TasyDevilsky/patch-1
Update setting_user
2022-09-19 17:47:12 +03:00
Max Lapan
d003db0404 SubGhz: Oregon v2.1 decoder (#1678)
* Oregon v2.1 decoder
* Refactor FSM to switch
* Refactor headers
* Format strings
* Unit tests of oregon2
* Cleanups
* Add oregon2 raw data to random_test_raw.sub
* Adjust count of packets detected on random test
* Format sources

Co-authored-by: あく <alleteam@gmail.com>
2022-09-19 23:24:24 +09:00
MX
5a31e35dc2 Merge branch 'fz-dev' into dev 2022-09-19 17:21:31 +03:00
Patrick Cunningham
c7cd5721ed Picopass: detect and show SE / SIO (#1701)
* detect and show SE / SIO
* fix fault
* remove bad read check

Co-authored-by: あく <alleteam@gmail.com>
2022-09-19 22:37:12 +09:00
Nikolay Minaylov
fb476c29e6 RFID: fix read info screen (#1723)
* RFID: fix read info screen
* Fix line break for long data string
* Protocol data redecoding before write

Co-authored-by: SG <who.just.the.doctor@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
2022-09-19 22:21:40 +09:00
Nikolay Minaylov
d80329b323 [FL-2815, FL-2821] Dummy mode (#1739)
* Dummy mode implementation
* dumb -> dummy
* F7: Add new api_symbols: game icon
* Starting snake game from dummy mode

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2022-09-19 22:03:42 +09:00
Astra
3d3c422751 [FL-2674] Show error popup when NFC chip is not init/disconnected (#1722)
* Show error popup when NFC chip is not init/disconnected
* Move to dialogs for the error message
* Fix a memory leak and wrap the hal check
* F7: update api_symbols.csv, add furi_hal_nfc_is_init

Co-authored-by: SG <who.just.the.doctor@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
2022-09-19 21:46:56 +09:00
hedger
ed385594a3 faploader: more subsystem headers in API table (#1742)
* faploader: more subsystem headers in API table; not counting header entries for SDK version change
* subghz: removed dead function
* Adjusted API version
* hal: removed furi_hal_power_get_system_voltage
* lib: mbedtls: additional flags for .fap linkage
* fbt: rebuilding assets when git commit id changes
* fbt: removed assets rebuild on git commit id change; added explicit dependency for SDK source on compiled assets parts; removed unneeded sdk regeneration runs
* fbt: changed stock plugins to EXTERNAL apps; restored building app as a PLUGIN as a part of main fw as well as a .fap; readme fixes
* fbt: restored certain apps to PLUGIN type
* fbt: app manifests: renamed version->fap_version, added extra fields
* fbt: fixed version processing after rename

Co-authored-by: あく <alleteam@gmail.com>
2022-09-19 21:39:00 +09:00
Astra
787df44c79 [FL-2800] Fix Mifare Classic 4K reading of the last 8 sectors (#1712)
* Fix FURI_BIT_SET

Co-authored-by: gornekich <n.gorbadey@gmail.com>
Co-authored-by: SG <who.just.the.doctor@gmail.com>
2022-09-19 21:30:18 +09:00
TasmanDevil
f0eedc3243 Update setting_user
Adding the 868.95 frequency for the Sommer device, the `Sommer(fsk476)` protocol was recently added but Flipper could not read it until now.
2022-09-19 08:59:13 +02:00
641 changed files with 17702 additions and 7766 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @xMasterX

View File

@@ -9,6 +9,10 @@
"type": "command",
"command": "shellCommand.execute",
"args": {
"useSingleResult": true,
"env": {
"PATH": "${workspaceFolder};${env:PATH}"
},
"command": "./fbt get_blackmagic",
"description": "Get Blackmagic device",
}
@@ -24,13 +28,14 @@
"servertype": "openocd",
"device": "stlink",
"svdFile": "./debug/STM32WB55_CM4.svd",
// If you're debugging early in the boot process, before OS scheduler is running,
// you have to comment out the following line.
"rtos": "FreeRTOS",
"configFiles": [
"interface/stlink.cfg",
"./debug/stm32wbx.cfg",
],
"postAttachCommands": [
// "attach 1",
// "compare-sections",
"source debug/flipperapps.py",
// "source debug/FreeRTOS/FreeRTOS.py",

View File

@@ -22,4 +22,4 @@
"SConstruct": "python",
"*.fam": "python",
}
}
}

View File

@@ -1,17 +1,32 @@
### New changes
* Spectrum Analyzer moved into Applications -> Tools
* Fixed bug with subghz remote (unirf) that was causing issues with power state
* Added 868.4 MHz into subghz user config
* Updated universal IR assets (by @Amec0e)
* Fixed debug builds - add this parameter to fbt command `FIRMWARE_APP_SET=debug_pack` if you building full fw in debug mode
* Add 312.2 MHz to subghz user config
* PR: Add CAME 12bit 303MHz to SubGHz Bruteforcer (by @derskythe | PR #87)
* PR: Added norwegian keyboard layout for badusb (by @jd-raymaker | PR #88)
* Adapted all plugins and other code to new FuriString, fixed archive menu issues with new string type
* SubGHz: Fix double click after delete scene, fix rename bug
* Plugins: SubGHz Bruteforcer - Fix wrong max value in BF existing dump
* API 3.0 -> 3.1 (all previous compiled apps still compatible)
* SubGHz: proper free of rainbow tables
* OFW: Show in-app icons & names in archive browser
* OFW: M*LIB: non-inlined strings, FuriString primitive
* OFW PR: Remove string_push_uint64 (OFW PR 1832 by Astrrra)
* OFW PR: updated icon names (OFW PR 1829 by nminaylov)
#### **DFU files no longer included in releases to avoid issues with wrong manual installation of assets - use web updater or microSD update package**
#### [🎲 Download extra apps pack](https://download-directory.github.io/?url=https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed)
[- How to install](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md)
[-> How to install firmware](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md)
**Note: To avoid issues prefer installing using web updater or by self update package, all needed assets will be installed**
[-> Download qFlipper 1.2.0 (allows .tgz installation) (official link)](https://update.flipperzero.one/builds/qFlipper/1.2.0/)
Self-update package (update from microSD) - `flipper-z-f7-update-(version).zip` or `.tgz` for iOS mobile app
## Please support development of the project
* ETH/BSC/ERC20-Tokens: `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`
* BTC: `bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`
* DOGE: `D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`
* LTC: `ltc1q3ex4ejkl0xpx3znwrmth4lyuadr5qgv8tmq8z9`
DFU for update using qFlipper is no longer included in releases to avoid issues with assets - Use Web Updater or self-update package!
**Note: To avoid issues with .dfu, prefer installing using .tgz with qFlipper, web updater or by self update package, all needed assets will be installed**
Self-update package (update from microSD) - `flipper-z-f7-update-(version).zip` or download `.tgz` for iOS mobile app / qFlipper
Update using qFlipper (1.2.0) is now possible with `.tgz` update package! Also you can use Web Updater or self-update package.

View File

@@ -36,9 +36,12 @@ Our Discord Community:
* Universal remote for Projectors, Fans, A/Cs and Audio(soundbars, etc.)
* BadUSB keyboard layouts
* Customizable Flipper name
* SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes
* SubGHz -> Long press OK button in SubGHz Frequency analyzer to switch to Read menu
* Other small fixes and changes throughout
* See other changes in changelog and in readme below
See changelog in releases for latest updates!
Also check changelog in releases for latest updates!
### Current modified and new SubGHz protocols list:
- HCS101
@@ -49,7 +52,7 @@ See changelog in releases for latest updates!
- Keeloq [Not ALL systems supported yet!]
- Nice Flor S
- Security+ v1 & v2
- Star Line
- Star Line (saving only)
## Support us so we can buy equipment and develop new features
* ETH/BSC/ERC20-Tokens: `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`
@@ -59,8 +62,8 @@ See changelog in releases for latest updates!
### Community apps included:
- RFID Fuzzer plugin [(by Ganapati)](https://github.com/Eng1n33r/flipperzero-firmware/pull/54) with some changes by xMasterX
- Sub-GHz bruteforce plugin [(by Ganapati & xMasterX)](https://github.com/Eng1n33r/flipperzero-firmware/pull/57)
- RFID Fuzzer plugin [(by Ganapati)](https://github.com/Eng1n33r/flipperzero-firmware/pull/54) with changes by @xMasterX & New protocols by @mvanzanten
- Sub-GHz bruteforce plugin [(by Ganapati & xMasterX)](https://github.com/Eng1n33r/flipperzero-firmware/pull/57) & Refactored by @derskythe
- Sub-GHz playlist plugin [(by darmiel)](https://github.com/Eng1n33r/flipperzero-firmware/pull/62)
- ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module)
- WiFi Scanner plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module)
@@ -85,9 +88,11 @@ Games:
### Other changes
- BadUSB -> Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout)
- SubGHz -> New frequency analyzer - [(by ClusterM)](https://github.com/ClusterM)
- SubGHz -> New frequency analyzer - [(by ClusterM)](https://github.com/Eng1n33r/flipperzero-firmware/pull/43)
- SubGHz -> Detect RAW feature - [(by perspecdev)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/152)
- SubGHz -> Save last used config settings - [(by derskythe)](https://github.com/Eng1n33r/flipperzero-firmware/pull/67)
- SubGHz -> Save last used frequency and moduluation [(by derskythe)](https://github.com/Eng1n33r/flipperzero-firmware/pull/77)
- SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/Eng1n33r/flipperzero-firmware/pull/77)
* SubGHz -> Long press OK button in SubGHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/Eng1n33r/flipperzero-firmware/pull/79)
# Instructions
## [- How to install firmware](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md)
@@ -100,7 +105,7 @@ Games:
### **Plugins**
## [- 💎 Extra plugins precompiled for Unleashed](https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed)
## [- 🎲 Download Extra plugins for Unleashed](https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed)
## [- Configure Sub-GHz Remote App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/SubGHzRemotePlugin.md)
@@ -140,9 +145,10 @@ Games:
<br>
# Where I can find IR, SubGhz, ... files, DBs, and other stuff?
## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero)
## [UberGuidoZ Playground - Large collection of files - Github](https://github.com/UberGuidoZ/Flipper)
## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero)
## [CAME-12bit, NICE-12bit, Linear-10bit, PT-2240 - SubGHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce)
## [SMC5326, UNILARM - SubGHz fixed code bruteforce](https://github.com/Hong5489/flipperzero-gate-bruteforce)
<br>
<br>
@@ -167,4 +173,4 @@ Games:
- `site_scons` - Build helpers
- `scripts` - Supplementary scripts and python libraries home
Also pay attention to `ReadMe.md` files inside of those directories.
Also pay attention to `ReadMe.md` files inside those directories.

View File

@@ -44,6 +44,8 @@ distenv = coreenv.Clone(
"target extended-remote ${GDBREMOTE}",
"-ex",
"set confirm off",
"-ex",
"set pagination off",
],
GDBOPTS_BLACKMAGIC=[
"-ex",
@@ -234,10 +236,19 @@ distenv.PhonyTarget(
distenv.PhonyTarget(
"debug_other",
"${GDBPYCOM}",
GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
GDBOPTS="${GDBOPTS_BASE}",
GDBREMOTE="${OPENOCD_GDB_PIPE}",
GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
)
distenv.PhonyTarget(
"debug_other_blackmagic",
"${GDBPYCOM}",
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="$${BLACKMAGIC_ADDR}",
)
# Just start OpenOCD
distenv.PhonyTarget(
"openocd",

View File

@@ -7,8 +7,8 @@ App(
"vibro_test",
"keypad_test",
"usb_test",
"usb_mouse",
"uart_echo",
"USB_Mouse",
"UART_Echo",
"display_test",
"text_box_test",
"file_browser_test",

View File

@@ -3,14 +3,13 @@
#include <gui/canvas.h>
#include <gui/elements.h>
#include <m-array.h>
#include <m-string.h>
#include <furi.h>
#include <stdint.h>
struct BtTestParam {
const char* label;
uint8_t current_value_index;
string_t current_value_text;
FuriString* current_value_text;
uint8_t values_count;
BtTestParamChangeCallback change_callback;
void* context;
@@ -85,7 +84,8 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_str(canvas, 50, param_text_y, "<");
}
canvas_draw_str(canvas, 61, param_text_y, string_get_cstr(param->current_value_text));
canvas_draw_str(
canvas, 61, param_text_y, furi_string_get_cstr(param->current_value_text));
if(param->current_value_index < (param->values_count - 1)) {
canvas_draw_str(canvas, 113, param_text_y, ">");
@@ -322,7 +322,7 @@ void bt_test_free(BtTest* bt_test) {
BtTestParamArray_it_t it;
for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it);
BtTestParamArray_next(it)) {
string_clear(BtTestParamArray_ref(it)->current_value_text);
furi_string_free(BtTestParamArray_ref(it)->current_value_text);
}
BtTestParamArray_clear(model->params);
return false;
@@ -354,7 +354,7 @@ BtTestParam* bt_test_param_add(
param->change_callback = change_callback;
param->context = context;
param->current_value_index = 0;
string_init(param->current_value_text);
param->current_value_text = furi_string_alloc();
return true;
});
@@ -410,7 +410,7 @@ void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_i
}
void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text) {
string_set_str(param->current_value_text, current_value_text);
furi_string_set(param->current_value_text, current_value_text);
}
uint8_t bt_test_get_current_value_index(BtTestParam* param) {

View File

@@ -113,11 +113,11 @@ static void display_config_set_regulation_ratio(VariableItem* item) {
static void display_config_set_contrast(VariableItem* item) {
DisplayTest* instance = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
string_t temp;
string_init(temp);
string_cat_printf(temp, "%d", index);
variable_item_set_current_value_text(item, string_get_cstr(temp));
string_clear(temp);
FuriString* temp;
temp = furi_string_alloc();
furi_string_cat_printf(temp, "%d", index);
variable_item_set_current_value_text(item, furi_string_get_cstr(temp));
furi_string_free(temp);
instance->config_contrast = index;
display_test_reload_config(instance);
}

View File

@@ -1,7 +1,6 @@
#include "assets_icons.h"
#include "file_browser_app_i.h"
#include "gui/modules/file_browser.h"
#include "m-string.h"
#include <furi.h>
#include <furi_hal.h>
#include <storage/storage.h>
@@ -47,7 +46,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) {
app->widget = widget_alloc();
string_init(app->file_path);
app->file_path = furi_string_alloc();
app->file_browser = file_browser_alloc(app->file_path);
file_browser_configure(app->file_browser, "*", true, &I_badusb_10px, true);
@@ -84,7 +83,7 @@ void file_browser_app_free(FileBrowserApp* app) {
furi_record_close(RECORD_NOTIFICATION);
furi_record_close(RECORD_DIALOGS);
string_clear(app->file_path);
furi_string_free(app->file_path);
free(app);
}

View File

@@ -22,7 +22,7 @@ struct FileBrowserApp {
Widget* widget;
FileBrowser* file_browser;
string_t file_path;
FuriString* file_path;
};
typedef enum {

View File

@@ -1,8 +1,5 @@
#include "../file_browser_app_i.h"
#include <core/check.h>
#include <core/log.h>
#include "furi_hal.h"
#include "m-string.h"
#include <furi.h>
#define DEFAULT_PATH "/"
#define EXTENSION "*"

View File

@@ -1,6 +1,5 @@
#include "../file_browser_app_i.h"
#include "furi_hal.h"
#include "m-string.h"
#include <furi.h>
void file_browser_scene_result_ok_callback(InputType type, void* context) {
furi_assert(context);
@@ -24,7 +23,13 @@ void file_browser_scene_result_on_enter(void* context) {
FileBrowserApp* app = context;
widget_add_string_multiline_element(
app->widget, 64, 10, AlignCenter, AlignTop, FontSecondary, string_get_cstr(app->file_path));
app->widget,
64,
10,
AlignCenter,
AlignTop,
FontSecondary,
furi_string_get_cstr(app->file_path));
view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewResult);
}

View File

@@ -19,7 +19,7 @@ bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) {
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
string_set_str(app->file_path, ANY_PATH("badusb/demo_windows.txt"));
furi_string_set(app->file_path, ANY_PATH("badusb/demo_windows.txt"));
scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser);
consumed = true;
} else if(event.type == SceneManagerEventTypeTick) {

View File

@@ -1,5 +1,5 @@
App(
appid="uart_echo",
appid="UART_Echo",
name="UART Echo",
apptype=FlipperAppType.PLUGIN,
entry_point="uart_echo_app",

View File

@@ -1,5 +1,4 @@
#include <furi.h>
#include <m-string.h>
#include <gui/gui.h>
#include <notification/notification.h>
#include <notification/notification_messages.h>
@@ -25,7 +24,7 @@ typedef struct {
} UartEchoApp;
typedef struct {
string_t text;
FuriString* text;
} ListElement;
struct UartDumpModel {
@@ -64,10 +63,11 @@ static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) {
canvas,
0,
(i + 1) * (canvas_current_font_height(canvas) - 1),
string_get_cstr(model->list[i]->text));
furi_string_get_cstr(model->list[i]->text));
if(i == model->line) {
uint8_t width = canvas_string_width(canvas, string_get_cstr(model->list[i]->text));
uint8_t width =
canvas_string_width(canvas, furi_string_get_cstr(model->list[i]->text));
canvas_draw_box(
canvas,
@@ -113,7 +113,7 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) {
model->escape = true;
} else if((data >= ' ' && data <= '~') || (data == '\n' || data == '\r')) {
bool new_string_needed = false;
if(string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) {
if(furi_string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) {
new_string_needed = true;
} else if((data == '\n' || data == '\r')) {
// pack line breaks
@@ -132,13 +132,13 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) {
model->list[i - 1] = model->list[i];
}
string_reset(first->text);
furi_string_reset(first->text);
model->list[model->line] = first;
}
}
if(data != '\n' && data != '\r') {
string_push_back(model->list[model->line]->text, data);
furi_string_push_back(model->list[model->line]->text, data);
}
}
model->last_char = data;
@@ -208,7 +208,7 @@ static UartEchoApp* uart_echo_app_alloc() {
model->line = 0;
model->escape = false;
model->list[i] = malloc(sizeof(ListElement));
string_init(model->list[i]->text);
model->list[i]->text = furi_string_alloc();
}
return true;
});
@@ -247,7 +247,7 @@ static void uart_echo_app_free(UartEchoApp* app) {
with_view_model(
app->view, (UartDumpModel * model) {
for(size_t i = 0; i < LINES_ON_SCREEN; i++) {
string_clear(model->list[i]->text);
furi_string_free(model->list[i]->text);
free(model->list[i]);
}
return true;

View File

@@ -58,7 +58,7 @@ static const char* test_data_win = "Filetype: Flipper Format test\r\n"
#define ARRAY_W_BSIZE(x) (x), (sizeof(x))
MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
string_t tmpstr;
FuriString* tmpstr;
uint32_t version;
uint32_t uint32_data[COUNT_OF(test_uint_data)];
int32_t int32_data[COUNT_OF(test_int_data)];
@@ -101,14 +101,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
// read test
string_init(tmpstr);
tmpstr = furi_string_alloc();
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
mu_assert_int_eq(test_version, version);
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
mu_assert_string_eq(test_string_data, string_get_cstr(tmpstr));
mu_assert_string_eq(test_string_data, furi_string_get_cstr(tmpstr));
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
mu_assert_int_eq(COUNT_OF(test_int_data), count);
@@ -133,7 +133,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
string_clear(tmpstr);
furi_string_free(tmpstr);
// update data
mu_check(flipper_format_rewind(flipper_format));
@@ -155,14 +155,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
uint8_t hex_updated_data[COUNT_OF(test_hex_updated_data)];
mu_check(flipper_format_rewind(flipper_format));
string_init(tmpstr);
tmpstr = furi_string_alloc();
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
mu_assert_int_eq(test_version, version);
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
mu_assert_string_eq(test_string_updated_data, string_get_cstr(tmpstr));
mu_assert_string_eq(test_string_updated_data, furi_string_get_cstr(tmpstr));
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
mu_assert_int_eq(COUNT_OF(test_int_updated_data), count);
@@ -190,7 +190,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
string_clear(tmpstr);
furi_string_free(tmpstr);
// update data
mu_check(flipper_format_rewind(flipper_format));
@@ -214,14 +214,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
uint8_t hex_new_data[COUNT_OF(test_hex_new_data)];
mu_check(flipper_format_rewind(flipper_format));
string_init(tmpstr);
tmpstr = furi_string_alloc();
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
mu_assert_int_eq(test_version, version);
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
mu_assert_string_eq(test_string_updated_2_data, string_get_cstr(tmpstr));
mu_assert_string_eq(test_string_updated_2_data, furi_string_get_cstr(tmpstr));
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
mu_assert_int_eq(COUNT_OF(test_int_updated_2_data), count);
@@ -255,7 +255,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
string_clear(tmpstr);
furi_string_free(tmpstr);
// delete key test
mu_check(flipper_format_rewind(flipper_format));

View File

@@ -57,6 +57,23 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n"
"Hex data: DE AD BE";
#define READ_TEST_FLP "ff_flp.test"
#define READ_TEST_ODD "ff_oddities.test"
static const char* test_data_odd = "Filetype: Flipper File test\n"
// Tabs before newline
"Version: 666\t\t\n"
"# This is comment\n"
// Windows newline in a UNIX file
"String data: String\r\n"
// Trailing whitespace
"Int32 data: 1234 -6345 7813 0 \n"
// Extra whitespace
"Uint32 data: 1234 0 5678 9098 7654321 \n"
// Mixed whitespace
"Float data: 1.5\t \t1000.0\n"
// Leading tabs after key
"Bool data:\t\ttrue false\n"
// Mixed trailing whitespace
"Hex data: DE AD BE\t ";
// data created by user on linux machine
static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
@@ -64,6 +81,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
static const char* test_file_windows = TEST_DIR READ_TEST_WIN;
// data created by flipper itself
static const char* test_file_flipper = TEST_DIR READ_TEST_FLP;
// data containing odd user input
static const char* test_file_oddities = TEST_DIR READ_TEST_ODD;
static bool storage_write_string(const char* path, const char* data) {
Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -102,8 +121,8 @@ static bool test_read(const char* file_name) {
bool result = false;
FlipperFormat* file = flipper_format_file_alloc(storage);
string_t string_value;
string_init(string_value);
FuriString* string_value;
string_value = furi_string_alloc();
uint32_t uint32_value;
void* scratchpad = malloc(512);
@@ -111,11 +130,11 @@ static bool test_read(const char* file_name) {
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
if(string_cmp_str(string_value, test_filetype) != 0) break;
if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
if(uint32_value != test_version) break;
if(!flipper_format_read_string(file, test_string_key, string_value)) break;
if(string_cmp_str(string_value, test_string_data) != 0) break;
if(furi_string_cmp_str(string_value, test_string_data) != 0) break;
if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_int_data)) break;
@@ -150,7 +169,7 @@ static bool test_read(const char* file_name) {
} while(false);
free(scratchpad);
string_clear(string_value);
furi_string_free(string_value);
flipper_format_free(file);
@@ -164,8 +183,8 @@ static bool test_read_updated(const char* file_name) {
bool result = false;
FlipperFormat* file = flipper_format_file_alloc(storage);
string_t string_value;
string_init(string_value);
FuriString* string_value;
string_value = furi_string_alloc();
uint32_t uint32_value;
void* scratchpad = malloc(512);
@@ -173,11 +192,11 @@ static bool test_read_updated(const char* file_name) {
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
if(string_cmp_str(string_value, test_filetype) != 0) break;
if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
if(uint32_value != test_version) break;
if(!flipper_format_read_string(file, test_string_key, string_value)) break;
if(string_cmp_str(string_value, test_string_updated_data) != 0) break;
if(furi_string_cmp_str(string_value, test_string_updated_data) != 0) break;
if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_int_updated_data)) break;
@@ -228,7 +247,7 @@ static bool test_read_updated(const char* file_name) {
} while(false);
free(scratchpad);
string_clear(string_value);
furi_string_free(string_value);
flipper_format_free(file);
@@ -401,14 +420,14 @@ static bool test_read_multikey(const char* file_name) {
bool result = false;
FlipperFormat* file = flipper_format_file_alloc(storage);
string_t string_value;
string_init(string_value);
FuriString* string_value;
string_value = furi_string_alloc();
uint32_t uint32_value;
do {
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
if(string_cmp_str(string_value, test_filetype) != 0) break;
if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
if(uint32_value != test_version) break;
bool error = false;
@@ -429,7 +448,7 @@ static bool test_read_multikey(const char* file_name) {
result = true;
} while(false);
string_clear(string_value);
furi_string_free(string_value);
flipper_format_free(file);
furi_record_close(RECORD_STORAGE);
@@ -503,6 +522,12 @@ MU_TEST(flipper_format_multikey_test) {
mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error");
}
MU_TEST(flipper_format_oddities_test) {
mu_assert(
storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]");
mu_assert(test_read(test_file_linux), "Read test error [Oddities]");
}
MU_TEST_SUITE(flipper_format) {
tests_setup();
MU_RUN_TEST(flipper_format_write_test);
@@ -516,6 +541,7 @@ MU_TEST_SUITE(flipper_format) {
MU_RUN_TEST(flipper_format_update_2_test);
MU_RUN_TEST(flipper_format_update_2_result_test);
MU_RUN_TEST(flipper_format_multikey_test);
MU_RUN_TEST(flipper_format_oddities_test);
tests_teardown();
}

View File

@@ -0,0 +1,469 @@
#include <furi.h>
#include "../minunit.h"
static void test_setup(void) {
}
static void test_teardown(void) {
}
static FuriString* furi_string_alloc_vprintf_test(const char format[], ...) {
va_list args;
va_start(args, format);
FuriString* string = furi_string_alloc_vprintf(format, args);
va_end(args);
return string;
}
MU_TEST(mu_test_furi_string_alloc_free) {
FuriString* tmp;
FuriString* string;
// test alloc and free
string = furi_string_alloc();
mu_check(string != NULL);
mu_check(furi_string_empty(string));
furi_string_free(string);
// test furi_string_alloc_set_str and free
string = furi_string_alloc_set_str("test");
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
mu_check(furi_string_cmp(string, "test") == 0);
furi_string_free(string);
// test furi_string_alloc_set and free
tmp = furi_string_alloc_set("more");
string = furi_string_alloc_set(tmp);
furi_string_free(tmp);
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
mu_check(furi_string_cmp(string, "more") == 0);
furi_string_free(string);
// test alloc_printf and free
string = furi_string_alloc_printf("test %d %s %c 0x%02x", 1, "two", '3', 0x04);
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
mu_check(furi_string_cmp(string, "test 1 two 3 0x04") == 0);
furi_string_free(string);
// test alloc_vprintf and free
string = furi_string_alloc_vprintf_test("test %d %s %c 0x%02x", 4, "five", '6', 0x07);
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
mu_check(furi_string_cmp(string, "test 4 five 6 0x07") == 0);
furi_string_free(string);
// test alloc_move and free
tmp = furi_string_alloc_set("move");
string = furi_string_alloc_move(tmp);
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
mu_check(furi_string_cmp(string, "move") == 0);
furi_string_free(string);
}
MU_TEST(mu_test_furi_string_mem) {
FuriString* string = furi_string_alloc_set("test");
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
// TODO: how to test furi_string_reserve?
// test furi_string_reset
furi_string_reset(string);
mu_check(furi_string_empty(string));
// test furi_string_swap
furi_string_set(string, "test");
FuriString* swap_string = furi_string_alloc_set("swap");
furi_string_swap(string, swap_string);
mu_check(furi_string_cmp(string, "swap") == 0);
mu_check(furi_string_cmp(swap_string, "test") == 0);
furi_string_free(swap_string);
// test furi_string_move
FuriString* move_string = furi_string_alloc_set("move");
furi_string_move(string, move_string);
mu_check(furi_string_cmp(string, "move") == 0);
// move_string is now empty
// and tested by leaked memory check at the end of the tests
furi_string_set(string, "abracadabra");
// test furi_string_hash
mu_assert_int_eq(0xc3bc16d7, furi_string_hash(string));
// test furi_string_size
mu_assert_int_eq(11, furi_string_size(string));
// test furi_string_empty
mu_check(!furi_string_empty(string));
furi_string_reset(string);
mu_check(furi_string_empty(string));
furi_string_free(string);
}
MU_TEST(mu_test_furi_string_getters) {
FuriString* string = furi_string_alloc_set("test");
// test furi_string_get_char
mu_check(furi_string_get_char(string, 0) == 't');
mu_check(furi_string_get_char(string, 1) == 'e');
mu_check(furi_string_get_char(string, 2) == 's');
mu_check(furi_string_get_char(string, 3) == 't');
// test furi_string_get_cstr
mu_assert_string_eq("test", furi_string_get_cstr(string));
furi_string_free(string);
}
static FuriString* furi_string_vprintf_test(FuriString* string, const char format[], ...) {
va_list args;
va_start(args, format);
furi_string_vprintf(string, format, args);
va_end(args);
return string;
}
MU_TEST(mu_test_furi_string_setters) {
FuriString* tmp;
FuriString* string = furi_string_alloc();
// test furi_string_set_str
furi_string_set_str(string, "test");
mu_assert_string_eq("test", furi_string_get_cstr(string));
// test furi_string_set
tmp = furi_string_alloc_set("more");
furi_string_set(string, tmp);
furi_string_free(tmp);
mu_assert_string_eq("more", furi_string_get_cstr(string));
// test furi_string_set_strn
furi_string_set_strn(string, "test", 2);
mu_assert_string_eq("te", furi_string_get_cstr(string));
// test furi_string_set_char
furi_string_set_char(string, 0, 'a');
furi_string_set_char(string, 1, 'b');
mu_assert_string_eq("ab", furi_string_get_cstr(string));
// test furi_string_set_n
tmp = furi_string_alloc_set("dodecahedron");
furi_string_set_n(string, tmp, 4, 5);
furi_string_free(tmp);
mu_assert_string_eq("cahed", furi_string_get_cstr(string));
// test furi_string_printf
furi_string_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
mu_assert_string_eq("test 1 two 3 0x04", furi_string_get_cstr(string));
// test furi_string_vprintf
furi_string_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
mu_assert_string_eq("test 4 five 6 0x07", furi_string_get_cstr(string));
furi_string_free(string);
}
static FuriString* furi_string_cat_vprintf_test(FuriString* string, const char format[], ...) {
va_list args;
va_start(args, format);
furi_string_cat_vprintf(string, format, args);
va_end(args);
return string;
}
MU_TEST(mu_test_furi_string_appends) {
FuriString* tmp;
FuriString* string = furi_string_alloc();
// test furi_string_push_back
furi_string_push_back(string, 't');
furi_string_push_back(string, 'e');
furi_string_push_back(string, 's');
furi_string_push_back(string, 't');
mu_assert_string_eq("test", furi_string_get_cstr(string));
furi_string_push_back(string, '!');
mu_assert_string_eq("test!", furi_string_get_cstr(string));
// test furi_string_cat_str
furi_string_cat_str(string, "test");
mu_assert_string_eq("test!test", furi_string_get_cstr(string));
// test furi_string_cat
tmp = furi_string_alloc_set("more");
furi_string_cat(string, tmp);
furi_string_free(tmp);
mu_assert_string_eq("test!testmore", furi_string_get_cstr(string));
// test furi_string_cat_printf
furi_string_cat_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
mu_assert_string_eq("test!testmoretest 1 two 3 0x04", furi_string_get_cstr(string));
// test furi_string_cat_vprintf
furi_string_cat_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
mu_assert_string_eq(
"test!testmoretest 1 two 3 0x04test 4 five 6 0x07", furi_string_get_cstr(string));
furi_string_free(string);
}
MU_TEST(mu_test_furi_string_compare) {
FuriString* string_1 = furi_string_alloc_set("string_1");
FuriString* string_2 = furi_string_alloc_set("string_2");
// test furi_string_cmp
mu_assert_int_eq(0, furi_string_cmp(string_1, string_1));
mu_assert_int_eq(0, furi_string_cmp(string_2, string_2));
mu_assert_int_eq(-1, furi_string_cmp(string_1, string_2));
mu_assert_int_eq(1, furi_string_cmp(string_2, string_1));
// test furi_string_cmp_str
mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string_1"));
mu_assert_int_eq(0, furi_string_cmp_str(string_2, "string_2"));
mu_assert_int_eq(-1, furi_string_cmp_str(string_1, "string_2"));
mu_assert_int_eq(1, furi_string_cmp_str(string_2, "string_1"));
// test furi_string_cmpi
furi_string_set(string_1, "string");
furi_string_set(string_2, "StrIng");
mu_assert_int_eq(0, furi_string_cmpi(string_1, string_1));
mu_assert_int_eq(0, furi_string_cmpi(string_2, string_2));
mu_assert_int_eq(0, furi_string_cmpi(string_1, string_2));
mu_assert_int_eq(0, furi_string_cmpi(string_2, string_1));
furi_string_set(string_1, "string_1");
furi_string_set(string_2, "StrIng_2");
mu_assert_int_eq(32, furi_string_cmp(string_1, string_2));
mu_assert_int_eq(-32, furi_string_cmp(string_2, string_1));
mu_assert_int_eq(-1, furi_string_cmpi(string_1, string_2));
mu_assert_int_eq(1, furi_string_cmpi(string_2, string_1));
// test furi_string_cmpi_str
furi_string_set(string_1, "string");
mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string"));
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "String"));
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STring"));
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRing"));
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRIng"));
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRINg"));
mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRING"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "string"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "String"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STring"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRing"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRIng"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRINg"));
mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRING"));
furi_string_free(string_1);
furi_string_free(string_2);
}
MU_TEST(mu_test_furi_string_search) {
// 012345678901234567
FuriString* haystack = furi_string_alloc_set("test321test123test");
FuriString* needle = furi_string_alloc_set("test");
// test furi_string_search
mu_assert_int_eq(0, furi_string_search(haystack, needle));
mu_assert_int_eq(7, furi_string_search(haystack, needle, 1));
mu_assert_int_eq(14, furi_string_search(haystack, needle, 8));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, needle, 15));
FuriString* tmp = furi_string_alloc_set("testnone");
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, tmp));
furi_string_free(tmp);
// test furi_string_search_str
mu_assert_int_eq(0, furi_string_search_str(haystack, "test"));
mu_assert_int_eq(7, furi_string_search_str(haystack, "test", 1));
mu_assert_int_eq(14, furi_string_search_str(haystack, "test", 8));
mu_assert_int_eq(4, furi_string_search_str(haystack, "321"));
mu_assert_int_eq(11, furi_string_search_str(haystack, "123"));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "testnone"));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "test", 15));
// test furi_string_search_char
mu_assert_int_eq(0, furi_string_search_char(haystack, 't'));
mu_assert_int_eq(1, furi_string_search_char(haystack, 'e'));
mu_assert_int_eq(2, furi_string_search_char(haystack, 's'));
mu_assert_int_eq(3, furi_string_search_char(haystack, 't', 1));
mu_assert_int_eq(7, furi_string_search_char(haystack, 't', 4));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_char(haystack, 'x'));
// test furi_string_search_rchar
mu_assert_int_eq(17, furi_string_search_rchar(haystack, 't'));
mu_assert_int_eq(15, furi_string_search_rchar(haystack, 'e'));
mu_assert_int_eq(16, furi_string_search_rchar(haystack, 's'));
mu_assert_int_eq(13, furi_string_search_rchar(haystack, '3'));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, '3', 14));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, 'x'));
furi_string_free(haystack);
furi_string_free(needle);
}
MU_TEST(mu_test_furi_string_equality) {
FuriString* string = furi_string_alloc_set("test");
FuriString* string_eq = furi_string_alloc_set("test");
FuriString* string_neq = furi_string_alloc_set("test2");
// test furi_string_equal
mu_check(furi_string_equal(string, string_eq));
mu_check(!furi_string_equal(string, string_neq));
// test furi_string_equal_str
mu_check(furi_string_equal_str(string, "test"));
mu_check(!furi_string_equal_str(string, "test2"));
mu_check(furi_string_equal_str(string_neq, "test2"));
mu_check(!furi_string_equal_str(string_neq, "test"));
furi_string_free(string);
furi_string_free(string_eq);
furi_string_free(string_neq);
}
MU_TEST(mu_test_furi_string_replace) {
FuriString* needle = furi_string_alloc_set("test");
FuriString* replace = furi_string_alloc_set("replace");
FuriString* string = furi_string_alloc_set("test123test");
// test furi_string_replace_at
furi_string_replace_at(string, 4, 3, "!biglongword!");
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
// test furi_string_replace
mu_assert_int_eq(17, furi_string_replace(string, needle, replace, 1));
mu_assert_string_eq("test!biglongword!replace", furi_string_get_cstr(string));
mu_assert_int_eq(0, furi_string_replace(string, needle, replace));
mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace(string, needle, replace));
mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
// test furi_string_replace_str
mu_assert_int_eq(20, furi_string_replace_str(string, "replace", "test", 1));
mu_assert_string_eq("replace!biglongword!test", furi_string_get_cstr(string));
mu_assert_int_eq(0, furi_string_replace_str(string, "replace", "test"));
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace_str(string, "replace", "test"));
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
// test furi_string_replace_all
furi_string_replace_all(string, needle, replace);
mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
// test furi_string_replace_all_str
furi_string_replace_all_str(string, "replace", "test");
mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
furi_string_free(string);
furi_string_free(needle);
furi_string_free(replace);
}
MU_TEST(mu_test_furi_string_start_end) {
FuriString* string = furi_string_alloc_set("start_end");
FuriString* start = furi_string_alloc_set("start");
FuriString* end = furi_string_alloc_set("end");
// test furi_string_start_with
mu_check(furi_string_start_with(string, start));
mu_check(!furi_string_start_with(string, end));
// test furi_string_start_with_str
mu_check(furi_string_start_with_str(string, "start"));
mu_check(!furi_string_start_with_str(string, "end"));
// test furi_string_end_with
mu_check(furi_string_end_with(string, end));
mu_check(!furi_string_end_with(string, start));
// test furi_string_end_with_str
mu_check(furi_string_end_with_str(string, "end"));
mu_check(!furi_string_end_with_str(string, "start"));
furi_string_free(string);
furi_string_free(start);
furi_string_free(end);
}
MU_TEST(mu_test_furi_string_trim) {
FuriString* string = furi_string_alloc_set("biglongstring");
// test furi_string_left
furi_string_left(string, 7);
mu_assert_string_eq("biglong", furi_string_get_cstr(string));
// test furi_string_right
furi_string_right(string, 3);
mu_assert_string_eq("long", furi_string_get_cstr(string));
// test furi_string_mid
furi_string_mid(string, 1, 2);
mu_assert_string_eq("on", furi_string_get_cstr(string));
// test furi_string_trim
furi_string_set(string, " \n\r\tbiglongstring \n\r\t ");
furi_string_trim(string);
mu_assert_string_eq("biglongstring", furi_string_get_cstr(string));
furi_string_set(string, "aaaabaaaabbaaabaaaabbtestaaaaaabbaaabaababaa");
furi_string_trim(string, "ab");
mu_assert_string_eq("test", furi_string_get_cstr(string));
furi_string_free(string);
}
MU_TEST(mu_test_furi_string_utf8) {
FuriString* utf8_string = furi_string_alloc_set("イルカ");
// test furi_string_utf8_length
mu_assert_int_eq(9, furi_string_size(utf8_string));
mu_assert_int_eq(3, furi_string_utf8_length(utf8_string));
// test furi_string_utf8_decode
const uint8_t dolphin_emoji_array[4] = {0xF0, 0x9F, 0x90, 0xAC};
FuriStringUTF8State state = FuriStringUTF8StateStarting;
FuriStringUnicodeValue value = 0;
furi_string_utf8_decode(dolphin_emoji_array[0], &state, &value);
mu_assert_int_eq(FuriStringUTF8StateDecoding3, state);
furi_string_utf8_decode(dolphin_emoji_array[1], &state, &value);
mu_assert_int_eq(FuriStringUTF8StateDecoding2, state);
furi_string_utf8_decode(dolphin_emoji_array[2], &state, &value);
mu_assert_int_eq(FuriStringUTF8StateDecoding1, state);
furi_string_utf8_decode(dolphin_emoji_array[3], &state, &value);
mu_assert_int_eq(FuriStringUTF8StateStarting, state);
mu_assert_int_eq(0x1F42C, value);
// test furi_string_utf8_push
furi_string_set(utf8_string, "");
furi_string_utf8_push(utf8_string, value);
mu_assert_string_eq("🐬", furi_string_get_cstr(utf8_string));
furi_string_free(utf8_string);
}
MU_TEST_SUITE(test_suite) {
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
MU_RUN_TEST(mu_test_furi_string_alloc_free);
MU_RUN_TEST(mu_test_furi_string_mem);
MU_RUN_TEST(mu_test_furi_string_getters);
MU_RUN_TEST(mu_test_furi_string_setters);
MU_RUN_TEST(mu_test_furi_string_appends);
MU_RUN_TEST(mu_test_furi_string_compare);
MU_RUN_TEST(mu_test_furi_string_search);
MU_RUN_TEST(mu_test_furi_string_equality);
MU_RUN_TEST(mu_test_furi_string_replace);
MU_RUN_TEST(mu_test_furi_string_start_end);
MU_RUN_TEST(mu_test_furi_string_trim);
MU_RUN_TEST(mu_test_furi_string_utf8);
}
int run_minunit_test_furi_string() {
MU_RUN_SUITE(test_suite);
return MU_EXIT_CODE;
}

View File

@@ -11,7 +11,7 @@
typedef struct {
InfraredDecoderHandler* decoder_handler;
InfraredEncoderHandler* encoder_handler;
string_t file_path;
FuriString* file_path;
FlipperFormat* ff;
} InfraredTest;
@@ -23,7 +23,7 @@ static void infrared_test_alloc() {
test->decoder_handler = infrared_alloc_decoder();
test->encoder_handler = infrared_alloc_encoder();
test->ff = flipper_format_buffered_file_alloc(storage);
string_init(test->file_path);
test->file_path = furi_string_alloc();
}
static void infrared_test_free() {
@@ -31,18 +31,18 @@ static void infrared_test_free() {
infrared_free_decoder(test->decoder_handler);
infrared_free_encoder(test->encoder_handler);
flipper_format_free(test->ff);
string_clear(test->file_path);
furi_string_free(test->file_path);
furi_record_close(RECORD_STORAGE);
free(test);
test = NULL;
}
static bool infrared_test_prepare_file(const char* protocol_name) {
string_t file_type;
string_init(file_type);
FuriString* file_type;
file_type = furi_string_alloc();
bool success = false;
string_printf(
furi_string_printf(
test->file_path,
"%s%s%s%s",
IR_TEST_FILES_DIR,
@@ -52,14 +52,15 @@ static bool infrared_test_prepare_file(const char* protocol_name) {
do {
uint32_t format_version;
if(!flipper_format_buffered_file_open_existing(test->ff, string_get_cstr(test->file_path)))
if(!flipper_format_buffered_file_open_existing(
test->ff, furi_string_get_cstr(test->file_path)))
break;
if(!flipper_format_read_header(test->ff, file_type, &format_version)) break;
if(string_cmp_str(file_type, "IR tests file") || format_version != 1) break;
if(furi_string_cmp_str(file_type, "IR tests file") || format_version != 1) break;
success = true;
} while(false);
string_clear(file_type);
furi_string_free(file_type);
return success;
}
@@ -68,18 +69,18 @@ static bool infrared_test_load_raw_signal(
const char* signal_name,
uint32_t** timings,
uint32_t* timings_count) {
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
bool success = false;
do {
bool is_name_found = false;
for(; !is_name_found && flipper_format_read_string(ff, "name", buf);
is_name_found = !string_cmp_str(buf, signal_name))
is_name_found = !furi_string_cmp(buf, signal_name))
;
if(!is_name_found) break;
if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "raw")) break;
if(!flipper_format_read_string(ff, "type", buf) || furi_string_cmp_str(buf, "raw")) break;
if(!flipper_format_get_value_count(ff, "data", timings_count)) break;
if(!*timings_count) break;
@@ -91,18 +92,18 @@ static bool infrared_test_load_raw_signal(
success = true;
} while(false);
string_clear(buf);
furi_string_free(buf);
return success;
}
static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* message) {
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
bool success = false;
do {
if(!flipper_format_read_string(ff, "protocol", buf)) break;
message->protocol = infrared_get_protocol_by_name(string_get_cstr(buf));
message->protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf));
if(!infrared_is_protocol_valid(message->protocol)) break;
if(!flipper_format_read_hex(ff, "address", (uint8_t*)&message->address, sizeof(uint32_t)))
break;
@@ -112,7 +113,7 @@ static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* messa
success = true;
} while(false);
string_clear(buf);
furi_string_free(buf);
return success;
}
@@ -121,18 +122,19 @@ static bool infrared_test_load_messages(
const char* signal_name,
InfraredMessage** messages,
uint32_t* messages_count) {
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
bool success = false;
do {
bool is_name_found = false;
for(; !is_name_found && flipper_format_read_string(ff, "name", buf);
is_name_found = !string_cmp_str(buf, signal_name))
is_name_found = !furi_string_cmp(buf, signal_name))
;
if(!is_name_found) break;
if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "parsed_array"))
if(!flipper_format_read_string(ff, "type", buf) ||
furi_string_cmp_str(buf, "parsed_array"))
break;
if(!flipper_format_read_uint32(ff, "count", messages_count, 1)) break;
if(!*messages_count) break;
@@ -151,7 +153,7 @@ static bool infrared_test_load_messages(
success = true;
} while(false);
string_clear(buf);
furi_string_free(buf);
return success;
}
@@ -213,26 +215,26 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i
InfraredMessage* input_messages;
uint32_t input_messages_count;
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
const char* protocol_name = infrared_get_protocol_name(protocol);
mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file");
string_printf(buf, "encoder_input%d", test_index);
furi_string_printf(buf, "encoder_input%d", test_index);
mu_assert(
infrared_test_load_messages(
test->ff, string_get_cstr(buf), &input_messages, &input_messages_count),
test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count),
"Failed to load messages from file");
string_printf(buf, "encoder_expected%d", test_index);
furi_string_printf(buf, "encoder_expected%d", test_index);
mu_assert(
infrared_test_load_raw_signal(
test->ff, string_get_cstr(buf), &expected_timings, &expected_timings_count),
test->ff, furi_string_get_cstr(buf), &expected_timings, &expected_timings_count),
"Failed to load raw signal from file");
flipper_format_buffered_file_close(test->ff);
string_clear(buf);
furi_string_free(buf);
uint32_t j = 0;
timings = malloc(sizeof(uint32_t) * timings_count);
@@ -267,22 +269,22 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_
uint32_t input_messages_count;
bool level = false;
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
timings = malloc(sizeof(uint32_t) * timings_count);
const char* protocol_name = infrared_get_protocol_name(protocol);
mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file");
string_printf(buf, "encoder_decoder_input%d", test_index);
furi_string_printf(buf, "encoder_decoder_input%d", test_index);
mu_assert(
infrared_test_load_messages(
test->ff, string_get_cstr(buf), &input_messages, &input_messages_count),
test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count),
"Failed to load messages from file");
flipper_format_buffered_file_close(test->ff);
string_clear(buf);
furi_string_free(buf);
for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) {
const InfraredMessage* message_encoded = &input_messages[message_counter];
@@ -327,25 +329,27 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i
InfraredMessage* messages;
uint32_t messages_count;
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
mu_assert(
infrared_test_prepare_file(infrared_get_protocol_name(protocol)),
"Failed to prepare test file");
string_printf(buf, "decoder_input%d", test_index);
furi_string_printf(buf, "decoder_input%d", test_index);
mu_assert(
infrared_test_load_raw_signal(test->ff, string_get_cstr(buf), &timings, &timings_count),
infrared_test_load_raw_signal(
test->ff, furi_string_get_cstr(buf), &timings, &timings_count),
"Failed to load raw signal from file");
string_printf(buf, "decoder_expected%d", test_index);
furi_string_printf(buf, "decoder_expected%d", test_index);
mu_assert(
infrared_test_load_messages(test->ff, string_get_cstr(buf), &messages, &messages_count),
infrared_test_load_messages(
test->ff, furi_string_get_cstr(buf), &messages, &messages_count),
"Failed to load messages from file");
flipper_format_buffered_file_close(test->ff);
string_clear(buf);
furi_string_free(buf);
InfraredMessage message_decoded_check_local;
bool level = 0;

View File

@@ -3,6 +3,7 @@
#include <storage/storage.h>
#include <lib/flipper_format/flipper_format.h>
#include <lib/nfc/protocols/nfca.h>
#include <lib/nfc/helpers/mf_classic_dict.h>
#include <lib/digital_signal/digital_signal.h>
#include <lib/flipper_format/flipper_format_i.h>
@@ -52,14 +53,15 @@ static bool nfc_test_read_signal_from_file(const char* file_name) {
bool success = false;
FlipperFormat* file = flipper_format_file_alloc(nfc_test->storage);
string_t file_type;
string_init(file_type);
FuriString* file_type;
file_type = furi_string_alloc();
uint32_t file_version = 0;
do {
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_read_header(file, file_type, &file_version)) break;
if(string_cmp_str(file_type, nfc_test_file_type) || file_version != nfc_test_file_version)
if(furi_string_cmp_str(file_type, nfc_test_file_type) ||
file_version != nfc_test_file_version)
break;
if(!flipper_format_read_uint32(file, "Data length", &nfc_test->test_data_len, 1)) break;
if(nfc_test->test_data_len > NFC_TEST_DATA_MAX_LEN) break;
@@ -75,7 +77,7 @@ static bool nfc_test_read_signal_from_file(const char* file_name) {
success = true;
} while(false);
string_clear(file_type);
furi_string_free(file_type);
flipper_format_free(file);
return success;
@@ -170,10 +172,59 @@ MU_TEST(nfc_digital_signal_test) {
"NFC long digital signal test failed\r\n");
}
MU_TEST(mf_classic_dict_test) {
MfClassicDict* instance = NULL;
uint64_t key = 0;
FuriString* temp_str;
temp_str = furi_string_alloc();
instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest);
mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n");
mu_assert(
mf_classic_dict_get_total_keys(instance) == 0,
"mf_classic_dict_get_total_keys == 0 assert failed\r\n");
furi_string_set(temp_str, "2196FAD8115B");
mu_assert(
mf_classic_dict_add_key_str(instance, temp_str),
"mf_classic_dict_add_key == true assert failed\r\n");
mu_assert(
mf_classic_dict_get_total_keys(instance) == 1,
"mf_classic_dict_get_total_keys == 1 assert failed\r\n");
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
mu_assert(
mf_classic_dict_get_key_at_index_str(instance, temp_str, 0),
"mf_classic_dict_get_key_at_index_str == true assert failed\r\n");
mu_assert(
furi_string_cmp(temp_str, "2196FAD8115B") == 0,
"string_cmp(temp_str, \"2196FAD8115B\") == 0 assert failed\r\n");
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
mu_assert(
mf_classic_dict_get_key_at_index(instance, &key, 0),
"mf_classic_dict_get_key_at_index == true assert failed\r\n");
mu_assert(key == 0x2196FAD8115B, "key == 0x2196FAD8115B assert failed\r\n");
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
mu_assert(
mf_classic_dict_delete_index(instance, 0),
"mf_classic_dict_delete_index == true assert failed\r\n");
mf_classic_dict_free(instance);
furi_string_free(temp_str);
}
MU_TEST_SUITE(nfc) {
nfc_test_alloc();
MU_RUN_TEST(nfc_digital_signal_test);
MU_RUN_TEST(mf_classic_dict_test);
nfc_test_free();
}

View File

@@ -75,7 +75,7 @@ typedef struct {
bool visited;
} StorageTestPath;
DICT_DEF2(StorageTestPathDict, string_t, STRING_OPLIST, StorageTestPath, M_POD_OPLIST)
DICT_DEF2(StorageTestPathDict, FuriString*, FURI_STRING_OPLIST, StorageTestPath, M_POD_OPLIST)
static StorageTestPathDict_t*
storage_test_paths_alloc(const StorageTestPathDesc paths[], size_t paths_count) {
@@ -83,15 +83,15 @@ static StorageTestPathDict_t*
StorageTestPathDict_init(*data);
for(size_t i = 0; i < paths_count; i++) {
string_t key;
string_init_set(key, paths[i].path);
FuriString* key;
key = furi_string_alloc_set(paths[i].path);
StorageTestPath value = {
.is_dir = paths[i].is_dir,
.visited = false,
};
StorageTestPathDict_set_at(*data, key, value);
string_clear(key);
furi_string_free(key);
}
return data;
@@ -102,7 +102,7 @@ static void storage_test_paths_free(StorageTestPathDict_t* data) {
free(data);
}
static bool storage_test_paths_mark(StorageTestPathDict_t* data, string_t path, bool is_dir) {
static bool storage_test_paths_mark(StorageTestPathDict_t* data, FuriString* path, bool is_dir) {
bool found = false;
StorageTestPath* record = StorageTestPathDict_get(*data, path);
@@ -148,27 +148,27 @@ static bool write_file_13DA(Storage* storage, const char* path) {
}
static void storage_dirs_create(Storage* storage, const char* base) {
string_t path;
string_init(path);
FuriString* path;
path = furi_string_alloc();
storage_common_mkdir(storage, base);
for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_paths); i++) {
string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]);
storage_common_mkdir(storage, string_get_cstr(path));
furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]);
storage_common_mkdir(storage, furi_string_get_cstr(path));
}
for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_files); i++) {
string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]);
write_file_13DA(storage, string_get_cstr(path));
furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]);
write_file_13DA(storage, furi_string_get_cstr(path));
}
string_clear(path);
furi_string_free(path);
}
MU_TEST_1(test_dirwalk_full, Storage* storage) {
string_t path;
string_init(path);
FuriString* path;
path = furi_string_alloc();
FileInfo fileinfo;
StorageTestPathDict_t* paths =
@@ -178,12 +178,12 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) {
mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk")));
while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) {
string_right(path, strlen(EXT_PATH("dirwalk/")));
furi_string_right(path, strlen(EXT_PATH("dirwalk/")));
mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY)));
}
dir_walk_free(dir_walk);
string_clear(path);
furi_string_free(path);
mu_check(storage_test_paths_check(paths) == false);
@@ -191,8 +191,8 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) {
}
MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) {
string_t path;
string_init(path);
FuriString* path;
path = furi_string_alloc();
FileInfo fileinfo;
StorageTestPathDict_t* paths = storage_test_paths_alloc(
@@ -203,12 +203,12 @@ MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) {
mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk")));
while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) {
string_right(path, strlen(EXT_PATH("dirwalk/")));
furi_string_right(path, strlen(EXT_PATH("dirwalk/")));
mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY)));
}
dir_walk_free(dir_walk);
string_clear(path);
furi_string_free(path);
mu_check(storage_test_paths_check(paths) == false);
@@ -230,8 +230,8 @@ static bool test_dirwalk_filter_no_folder_ext(const char* name, FileInfo* filein
}
MU_TEST_1(test_dirwalk_filter, Storage* storage) {
string_t path;
string_init(path);
FuriString* path;
path = furi_string_alloc();
FileInfo fileinfo;
StorageTestPathDict_t* paths = storage_test_paths_alloc(
@@ -242,12 +242,12 @@ MU_TEST_1(test_dirwalk_filter, Storage* storage) {
mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk")));
while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) {
string_right(path, strlen(EXT_PATH("dirwalk/")));
furi_string_right(path, strlen(EXT_PATH("dirwalk/")));
mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY)));
}
dir_walk_free(dir_walk);
string_clear(path);
furi_string_free(path);
mu_check(storage_test_paths_check(paths) == false);

View File

@@ -58,7 +58,7 @@ MU_TEST(storage_file_open_lock) {
storage_file_close(file);
// file_locker thread stop
mu_check(furi_thread_join(locker_thread) == FuriStatusOk);
mu_check(furi_thread_join(locker_thread));
furi_thread_free(locker_thread);
// clean data
@@ -148,7 +148,7 @@ MU_TEST(storage_dir_open_lock) {
storage_dir_close(file);
// file_locker thread stop
mu_check(furi_thread_join(locker_thread) == FuriStatusOk);
mu_check(furi_thread_join(locker_thread));
furi_thread_free(locker_thread);
// clean data
@@ -211,22 +211,22 @@ static bool check_file_13DA(Storage* storage, const char* path) {
}
static void storage_dir_create(Storage* storage, const char* base) {
string_t path;
string_init(path);
FuriString* path;
path = furi_string_alloc();
storage_common_mkdir(storage, base);
for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) {
string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
storage_common_mkdir(storage, string_get_cstr(path));
furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
storage_common_mkdir(storage, furi_string_get_cstr(path));
}
for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) {
string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
write_file_13DA(storage, string_get_cstr(path));
furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
write_file_13DA(storage, furi_string_get_cstr(path));
}
string_clear(path);
furi_string_free(path);
}
static void storage_dir_remove(Storage* storage, const char* base) {
@@ -235,15 +235,15 @@ static void storage_dir_remove(Storage* storage, const char* base) {
static bool storage_dir_rename_check(Storage* storage, const char* base) {
bool result = false;
string_t path;
string_init(path);
FuriString* path;
path = furi_string_alloc();
result = (storage_common_stat(storage, base, NULL) == FSE_OK);
if(result) {
for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) {
string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
result = (storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK);
furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]);
result = (storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK);
if(!result) {
break;
}
@@ -252,15 +252,15 @@ static bool storage_dir_rename_check(Storage* storage, const char* base) {
if(result) {
for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) {
string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
result = check_file_13DA(storage, string_get_cstr(path));
furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]);
result = check_file_13DA(storage, furi_string_get_cstr(path));
if(!result) {
break;
}
}
}
string_clear(path);
furi_string_free(path);
return result;
}

View File

@@ -18,8 +18,8 @@ static const char* stream_test_right_data =
MU_TEST_1(stream_composite_subtest, Stream* stream) {
const size_t data_size = 128;
uint8_t data[data_size];
string_t string_lee;
string_init_set(string_lee, "lee");
FuriString* string_lee;
string_lee = furi_string_alloc_set("lee");
// test that stream is empty
// "" -> ""
@@ -267,7 +267,7 @@ MU_TEST_1(stream_composite_subtest, Stream* stream) {
mu_assert_int_eq(9, stream_tell(stream));
mu_check(stream_eof(stream));
string_clear(string_lee);
furi_string_free(string_lee);
}
MU_TEST(stream_composite_test) {
@@ -416,10 +416,10 @@ MU_TEST(stream_buffered_write_after_read_test) {
}
MU_TEST(stream_buffered_large_file_test) {
string_t input_data;
string_t output_data;
string_init(input_data);
string_init(output_data);
FuriString* input_data;
FuriString* output_data;
input_data = furi_string_alloc();
output_data = furi_string_alloc();
Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -429,7 +429,7 @@ MU_TEST(stream_buffered_large_file_test) {
const size_t rep_count = data_size / line_size + 1;
for(size_t i = 0; i < rep_count; ++i) {
string_cat_printf(input_data, "%s\n", stream_test_data);
furi_string_cat_printf(input_data, "%s\n", stream_test_data);
}
// write test data to file
@@ -437,8 +437,8 @@ MU_TEST(stream_buffered_large_file_test) {
mu_check(buffered_file_stream_open(
stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
mu_assert_int_eq(0, stream_size(stream));
mu_assert_int_eq(string_size(input_data), stream_write_string(stream, input_data));
mu_assert_int_eq(string_size(input_data), stream_size(stream));
mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data));
mu_assert_int_eq(furi_string_size(input_data), stream_size(stream));
const size_t substr_start = 8;
const size_t substr_len = 11;
@@ -475,23 +475,23 @@ MU_TEST(stream_buffered_large_file_test) {
// read the whole file
mu_check(stream_rewind(stream));
string_t tmp;
string_init(tmp);
FuriString* tmp;
tmp = furi_string_alloc();
while(stream_read_line(stream, tmp)) {
string_cat(output_data, tmp);
furi_string_cat(output_data, tmp);
}
string_clear(tmp);
furi_string_free(tmp);
// check against generated data
mu_assert_int_eq(string_size(input_data), string_size(output_data));
mu_check(string_equal_p(input_data, output_data));
mu_assert_int_eq(furi_string_size(input_data), furi_string_size(output_data));
mu_check(furi_string_equal(input_data, output_data));
mu_check(stream_eof(stream));
stream_free(stream);
furi_record_close(RECORD_STORAGE);
string_clear(input_data);
string_clear(output_data);
furi_string_free(input_data);
furi_string_free(output_data);
}
MU_TEST_SUITE(stream_suite) {

View File

@@ -13,7 +13,7 @@
#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
#define TEST_RANDOM_COUNT_PARSE 232
#define TEST_RANDOM_COUNT_PARSE 233
#define TEST_TIMEOUT 10000
static SubGhzEnvironment* environment_handler;
@@ -28,12 +28,12 @@ static void subghz_test_rx_callback(
void* context) {
UNUSED(receiver);
UNUSED(context);
string_t text;
string_init(text);
FuriString* text;
text = furi_string_alloc();
subghz_protocol_decoder_base_get_string(decoder_base, text);
subghz_receiver_reset(receiver_handler);
FURI_LOG_T(TAG, "\r\n%s", string_get_cstr(text));
string_clear(text);
FURI_LOG_T(TAG, "\r\n%s", furi_string_get_cstr(text));
furi_string_free(text);
subghz_test_decoder_count++;
}
@@ -141,8 +141,8 @@ static bool subghz_decode_random_test(const char* path) {
static bool subghz_encoder_test(const char* path) {
subghz_test_decoder_count = 0;
uint32_t test_start = furi_get_tick();
string_t temp_str;
string_init(temp_str);
FuriString* temp_str;
temp_str = furi_string_alloc();
bool file_load = false;
Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -167,11 +167,11 @@ static bool subghz_encoder_test(const char* path) {
} while(false);
if(file_load) {
SubGhzTransmitter* transmitter =
subghz_transmitter_alloc_init(environment_handler, string_get_cstr(temp_str));
subghz_transmitter_alloc_init(environment_handler, furi_string_get_cstr(temp_str));
subghz_transmitter_deserialize(transmitter, fff_data_file);
SubGhzProtocolDecoderBase* decoder = subghz_receiver_search_decoder_base_by_name(
receiver_handler, string_get_cstr(temp_str));
receiver_handler, furi_string_get_cstr(temp_str));
if(decoder) {
LevelDuration level_duration;
@@ -192,10 +192,11 @@ static bool subghz_encoder_test(const char* path) {
flipper_format_free(fff_data_file);
FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count);
if(furi_get_tick() - test_start > TEST_TIMEOUT) {
printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str));
printf(
"\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", furi_string_get_cstr(temp_str));
subghz_test_decoder_count = 0;
}
string_clear(temp_str);
furi_string_free(temp_str);
return subghz_test_decoder_count ? true : false;
}
@@ -434,6 +435,13 @@ MU_TEST(subghz_decoder_clemsa_test) {
"Test decoder " SUBGHZ_PROTOCOL_CLEMSA_NAME " error\r\n");
}
MU_TEST(subghz_decoder_oregon2_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/oregon2_raw.sub"), SUBGHZ_PROTOCOL_OREGON2_NAME),
"Test decoder " SUBGHZ_PROTOCOL_OREGON2_NAME " error\r\n");
}
//test encoders
MU_TEST(subghz_encoder_princeton_test) {
mu_assert(
@@ -595,6 +603,7 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_decoder_magellen_test);
MU_RUN_TEST(subghz_decoder_intertechno_v3_test);
MU_RUN_TEST(subghz_decoder_clemsa_test);
MU_RUN_TEST(subghz_decoder_oregon2_test);
MU_RUN_TEST(subghz_encoder_princeton_test);
MU_RUN_TEST(subghz_encoder_came_test);

View File

@@ -1,5 +1,3 @@
#include "m-string.h"
#include <stdio.h>
#include <furi.h>
#include <furi_hal.h>
@@ -11,6 +9,7 @@
#define TAG "UnitTests"
int run_minunit_test_furi();
int run_minunit_test_furi_string();
int run_minunit_test_infrared();
int run_minunit_test_rpc();
int run_minunit_test_flipper_format();
@@ -33,6 +32,7 @@ typedef struct {
const UnitTest unit_tests[] = {
{.name = "furi", .entry = run_minunit_test_furi},
{.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},
@@ -63,7 +63,7 @@ void minunit_print_fail(const char* str) {
printf(FURI_LOG_CLR_E "%s\r\n" FURI_LOG_CLR_RESET, str);
}
void unit_tests_cli(Cli* cli, string_t args, void* context) {
void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(cli);
UNUSED(args);
UNUSED(context);
@@ -91,8 +91,8 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) {
break;
}
if(string_size(args)) {
if(string_cmp_str(args, unit_tests[i].name) == 0) {
if(furi_string_size(args)) {
if(furi_string_cmp_str(args, unit_tests[i].name) == 0) {
failed_tests += unit_tests[i].entry();
} else {
printf("Skipping %s\r\n", unit_tests[i].name);

View File

@@ -1,5 +1,5 @@
App(
appid="usb_mouse",
appid="USB_Mouse",
name="USB Mouse",
apptype=FlipperAppType.PLUGIN,
entry_point="usb_mouse_app",

View File

@@ -0,0 +1,5 @@
App(
appid="sample_apps",
name="Sample apps bundle",
apptype=FlipperAppType.METAPACKAGE,
)

View File

@@ -0,0 +1,10 @@
App(
appid="example_images",
name="Example: Images",
apptype=FlipperAppType.EXTERNAL,
entry_point="example_images_main",
requires=["gui"],
stack_size=1 * 1024,
fap_category="Examples",
fap_icon_assets="images",
)

View File

@@ -0,0 +1,79 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <input/input.h>
#include "example_images_icons.h"
typedef struct {
uint8_t x, y;
} ImagePosition;
static ImagePosition image_position = {.x = 0, .y = 0};
// Screen is 128x64 px
static void app_draw_callback(Canvas* canvas, void* ctx) {
UNUSED(ctx);
canvas_clear(canvas);
canvas_draw_icon(canvas, image_position.x % 128, image_position.y % 64, &I_dolphin_71x25);
}
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_images_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 InputKeyLeft:
image_position.x -= 2;
break;
case InputKeyRight:
image_position.x += 2;
break;
case InputKeyUp:
image_position.y -= 2;
break;
case InputKeyDown:
image_position.y += 2;
break;
default:
running = false;
break;
}
}
}
view_port_update(view_port);
}
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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -24,13 +24,13 @@ App(
apptype=FlipperAppType.METAPACKAGE,
provides=[
"gpio",
"ibutton",
#"ibutton",
"infrared",
"lfrfid",
"nfc",
"subghz",
"bad_usb",
"u2f",
#"bad_usb",
#"u2f",
"fap_loader",
"archive",
],

View File

@@ -21,7 +21,7 @@ static void archive_tick_event_callback(void* context) {
static ArchiveApp* archive_alloc() {
ArchiveApp* archive = malloc(sizeof(ArchiveApp));
string_init(archive->fav_move_str);
archive->fav_move_str = furi_string_alloc();
archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive);
archive->view_dispatcher = view_dispatcher_alloc();
@@ -81,7 +81,7 @@ void archive_free(ArchiveApp* archive) {
scene_manager_free(archive->scene_manager);
browser_free(archive->browser);
string_clear(archive->fav_move_str);
furi_string_free(archive->fav_move_str);
furi_record_close(RECORD_DIALOGS);
archive->dialogs = NULL;

View File

@@ -36,7 +36,7 @@ struct ArchiveApp {
Loading* loading;
FuriPubSubSubscription* loader_stop_subscription;
string_t fav_move_str;
FuriString* fav_move_str;
char text_store[MAX_NAME_LEN];
char file_extension[MAX_EXT_LEN + 1];
};

View File

@@ -5,7 +5,7 @@
#include <core/common_defines.h>
#include <core/log.h>
#include "gui/modules/file_browser_worker.h"
#include "m-string.h"
#include <fap_loader/fap_loader_app.h>
#include <math.h>
static void
@@ -19,7 +19,7 @@ static void
if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser)) {
archive_switch_tab(browser, browser->last_tab_switch_dir);
} else if(!string_start_with_str_p(browser->path, "/app:")) {
} else if(!furi_string_start_with_str(browser->path, "/app:")) {
with_view_model(
browser->view, (ArchiveBrowserViewModel * model) {
files_array_reset(model->files);
@@ -51,12 +51,13 @@ static void archive_list_load_cb(void* context, uint32_t list_load_offset) {
});
}
static void archive_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last) {
static void
archive_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) {
furi_assert(context);
ArchiveBrowserView* browser = (ArchiveBrowserView*)context;
if(!is_last) {
archive_add_file_item(browser, is_folder, string_get_cstr(item_path));
archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path));
} else {
with_view_model(
browser->view, (ArchiveBrowserViewModel * model) {
@@ -79,7 +80,7 @@ static void archive_long_load_cb(void* context) {
static void archive_file_browser_set_path(
ArchiveBrowserView* browser,
string_t path,
FuriString* path,
const char* filter_ext,
bool skip_assets) {
furi_assert(browser);
@@ -133,7 +134,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) {
furi_assert(browser);
furi_assert(target);
archive_get_items(browser, string_get_cstr(browser->path));
archive_get_items(browser, furi_string_get_cstr(browser->path));
if(!archive_file_get_array_size(browser) && archive_is_home(browser)) {
archive_switch_tab(browser, TAB_RIGHT);
@@ -143,7 +144,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) {
uint16_t idx = 0;
while(idx < files_array_size(model->files)) {
ArchiveFile_t* current = files_array_get(model->files, idx);
if(!string_search(current->path, target)) {
if(!furi_string_search(current->path, target)) {
model->item_idx = idx + model->array_offset;
break;
}
@@ -315,12 +316,12 @@ bool archive_is_home(ArchiveBrowserView* browser) {
}
const char* default_path = archive_get_default_path(archive_get_tab(browser));
return (string_cmp_str(browser->path, default_path) == 0);
return (furi_string_cmp_str(browser->path, default_path) == 0);
}
const char* archive_get_name(ArchiveBrowserView* browser) {
ArchiveFile_t* selected = archive_get_current_file(browser);
return string_get_cstr(selected->path);
return furi_string_get_cstr(selected->path);
}
void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) {
@@ -339,7 +340,7 @@ void archive_add_app_item(ArchiveBrowserView* browser, const char* name) {
ArchiveFile_t item;
ArchiveFile_t_init(&item);
string_set_str(item.path, name);
furi_string_set(item.path, name);
archive_set_file_type(&item, name, false, true);
with_view_model(
@@ -351,16 +352,32 @@ void archive_add_app_item(ArchiveBrowserView* browser, const char* name) {
ArchiveFile_t_clear(&item);
}
static bool archive_get_fap_meta(FuriString* file_path, FuriString* fap_name, uint8_t** icon_ptr) {
Storage* storage = furi_record_open(RECORD_STORAGE);
bool success = false;
if(fap_loader_load_name_and_icon(file_path, storage, icon_ptr, fap_name)) {
success = true;
}
furi_record_close(RECORD_STORAGE);
return success;
}
void archive_add_file_item(ArchiveBrowserView* browser, bool is_folder, const char* name) {
furi_assert(browser);
furi_assert(name);
ArchiveFile_t item;
ArchiveFile_t_init(&item);
string_init_set_str(item.path, name);
archive_set_file_type(&item, string_get_cstr(browser->path), is_folder, false);
furi_string_set(item.path, name);
archive_set_file_type(&item, furi_string_get_cstr(browser->path), is_folder, false);
if(item.type == ArchiveFileTypeApplication) {
item.custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE);
if(!archive_get_fap_meta(item.path, item.custom_name, &item.custom_icon_data)) {
free(item.custom_icon_data);
item.custom_icon_data = NULL;
}
}
with_view_model(
browser->view, (ArchiveBrowserViewModel * model) {
files_array_push_back(model->files, item);
@@ -380,7 +397,8 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show) {
menu_array_reset(model->context_menu);
ArchiveFile_t* selected =
files_array_get(model->files, model->item_idx - model->array_offset);
selected->fav = archive_is_favorite("%s", string_get_cstr(selected->path));
selected->fav =
archive_is_favorite("%s", furi_string_get_cstr(selected->path));
}
} else {
model->menu = false;
@@ -401,14 +419,14 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) {
});
}
static bool archive_is_dir_exists(string_t path) {
if(string_equal_str_p(path, STORAGE_ANY_PATH_PREFIX)) {
static bool archive_is_dir_exists(FuriString* path) {
if(furi_string_equal(path, STORAGE_ANY_PATH_PREFIX)) {
return true;
}
bool state = false;
FileInfo file_info;
Storage* storage = furi_record_open(RECORD_STORAGE);
if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) {
if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) {
if(file_info.flags & FSF_DIRECTORY) {
state = true;
}
@@ -432,16 +450,16 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
browser->is_root = true;
archive_set_tab(browser, tab);
string_set_str(browser->path, archive_get_default_path(tab));
furi_string_set(browser->path, archive_get_default_path(tab));
bool tab_empty = true;
if(tab == ArchiveTabFavorites) {
if(archive_favorites_count(browser) > 0) {
tab_empty = false;
}
} else if(string_start_with_str_p(browser->path, "/app:")) {
char* app_name = strchr(string_get_cstr(browser->path), ':');
} else if(furi_string_start_with_str(browser->path, "/app:")) {
char* app_name = strchr(furi_string_get_cstr(browser->path), ':');
if(app_name != NULL) {
if(archive_app_is_available(browser, string_get_cstr(browser->path))) {
if(archive_app_is_available(browser, furi_string_get_cstr(browser->path))) {
tab_empty = false;
}
}
@@ -464,12 +482,12 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
model->array_offset = 0;
return false;
});
archive_get_items(browser, string_get_cstr(browser->path));
archive_get_items(browser, furi_string_get_cstr(browser->path));
archive_update_offset(browser);
}
}
void archive_enter_dir(ArchiveBrowserView* browser, string_t path) {
void archive_enter_dir(ArchiveBrowserView* browser, FuriString* path) {
furi_assert(browser);
furi_assert(path);
@@ -481,7 +499,7 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t path) {
return false;
});
string_set(browser->path, path);
furi_string_set(browser->path, path);
file_browser_worker_folder_enter(browser->worker, path, idx_temp);
}

View File

@@ -16,6 +16,7 @@ static const char* tab_default_paths[] = {
[ArchiveTabInfrared] = ANY_PATH("infrared"),
[ArchiveTabBadUsb] = ANY_PATH("badusb"),
[ArchiveTabU2f] = "/app:u2f",
[ArchiveTabApplications] = ANY_PATH("apps"),
[ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX,
};
@@ -27,6 +28,7 @@ static const char* known_ext[] = {
[ArchiveFileTypeInfrared] = ".ir",
[ArchiveFileTypeBadUsb] = ".txt",
[ArchiveFileTypeU2f] = "?",
[ArchiveFileTypeApplication] = ".fap",
[ArchiveFileTypeUpdateManifest] = ".fuf",
[ArchiveFileTypeFolder] = "?",
[ArchiveFileTypeUnknown] = "*",
@@ -41,6 +43,7 @@ static const ArchiveFileTypeEnum known_type[] = {
[ArchiveTabInfrared] = ArchiveFileTypeInfrared,
[ArchiveTabBadUsb] = ArchiveFileTypeBadUsb,
[ArchiveTabU2f] = ArchiveFileTypeU2f,
[ArchiveTabApplications] = ArchiveFileTypeApplication,
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
};
@@ -84,6 +87,6 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show);
void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active);
void archive_switch_tab(ArchiveBrowserView* browser, InputKey key);
void archive_enter_dir(ArchiveBrowserView* browser, string_t name);
void archive_enter_dir(ArchiveBrowserView* browser, FuriString* name);
void archive_leave_dir(ArchiveBrowserView* browser);
void archive_refresh_dir(ArchiveBrowserView* browser);

View File

@@ -6,8 +6,8 @@
#define ARCHIVE_FAV_FILE_BUF_LEN 32
static bool archive_favorites_read_line(File* file, string_t str_result) {
string_reset(str_result);
static bool archive_favorites_read_line(File* file, FuriString* str_result) {
furi_string_reset(str_result);
uint8_t buffer[ARCHIVE_FAV_FILE_BUF_LEN];
bool result = false;
@@ -34,7 +34,7 @@ static bool archive_favorites_read_line(File* file, string_t str_result) {
result = true;
break;
} else {
string_push_back(str_result, buffer[i]);
furi_string_push_back(str_result, buffer[i]);
}
}
@@ -52,8 +52,8 @@ uint16_t archive_favorites_count(void* context) {
Storage* fs_api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(fs_api);
string_t buffer;
string_init(buffer);
FuriString* buffer;
buffer = furi_string_alloc();
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
uint16_t lines = 0;
@@ -63,7 +63,7 @@ uint16_t archive_favorites_count(void* context) {
if(!archive_favorites_read_line(file, buffer)) {
break;
}
if(!string_size(buffer)) {
if(!furi_string_size(buffer)) {
continue; // Skip empty lines
}
++lines;
@@ -72,7 +72,7 @@ uint16_t archive_favorites_count(void* context) {
storage_file_close(file);
string_clear(buffer);
furi_string_free(buffer);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
@@ -80,8 +80,8 @@ uint16_t archive_favorites_count(void* context) {
}
static bool archive_favourites_rescan() {
string_t buffer;
string_init(buffer);
FuriString* buffer;
buffer = furi_string_alloc();
Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);
@@ -91,23 +91,25 @@ static bool archive_favourites_rescan() {
if(!archive_favorites_read_line(file, buffer)) {
break;
}
if(!string_size(buffer)) {
if(!furi_string_size(buffer)) {
continue;
}
if(string_search(buffer, "/app:") == 0) {
if(archive_app_is_available(NULL, string_get_cstr(buffer))) {
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
if(furi_string_search(buffer, "/app:") == 0) {
if(archive_app_is_available(NULL, furi_string_get_cstr(buffer))) {
archive_file_append(
ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer));
}
} else {
if(storage_file_exists(storage, string_get_cstr(buffer))) {
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
if(storage_file_exists(storage, furi_string_get_cstr(buffer))) {
archive_file_append(
ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer));
}
}
}
}
string_clear(buffer);
furi_string_free(buffer);
storage_file_close(file);
storage_common_remove(storage, ARCHIVE_FAV_PATH);
@@ -127,9 +129,9 @@ bool archive_favorites_read(void* context) {
Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);
string_t buffer;
FuriString* buffer;
FileInfo file_info;
string_init(buffer);
buffer = furi_string_alloc();
bool need_refresh = false;
uint16_t file_count = 0;
@@ -143,33 +145,33 @@ bool archive_favorites_read(void* context) {
if(!archive_favorites_read_line(file, buffer)) {
break;
}
if(!string_size(buffer)) {
if(!furi_string_size(buffer)) {
continue;
}
if(string_search(buffer, "/app:") == 0) {
if(archive_app_is_available(browser, string_get_cstr(buffer))) {
archive_add_app_item(browser, string_get_cstr(buffer));
if(furi_string_search(buffer, "/app:") == 0) {
if(archive_app_is_available(browser, furi_string_get_cstr(buffer))) {
archive_add_app_item(browser, furi_string_get_cstr(buffer));
file_count++;
} else {
need_refresh = true;
}
} else {
if(storage_file_exists(storage, string_get_cstr(buffer))) {
storage_common_stat(storage, string_get_cstr(buffer), &file_info);
if(storage_file_exists(storage, furi_string_get_cstr(buffer))) {
storage_common_stat(storage, furi_string_get_cstr(buffer), &file_info);
archive_add_file_item(
browser, (file_info.flags & FSF_DIRECTORY), string_get_cstr(buffer));
browser, (file_info.flags & FSF_DIRECTORY), furi_string_get_cstr(buffer));
file_count++;
} else {
need_refresh = true;
}
}
string_reset(buffer);
furi_string_reset(buffer);
}
}
storage_file_close(file);
string_clear(buffer);
furi_string_free(buffer);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
@@ -183,14 +185,14 @@ bool archive_favorites_read(void* context) {
}
bool archive_favorites_delete(const char* format, ...) {
string_t buffer;
string_t filename;
FuriString* buffer;
FuriString* filename;
va_list args;
va_start(args, format);
string_init_vprintf(filename, format, args);
filename = furi_string_alloc_vprintf(format, args);
va_end(args);
string_init(buffer);
buffer = furi_string_alloc();
Storage* fs_api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(fs_api);
@@ -201,18 +203,18 @@ bool archive_favorites_delete(const char* format, ...) {
if(!archive_favorites_read_line(file, buffer)) {
break;
}
if(!string_size(buffer)) {
if(!furi_string_size(buffer)) {
continue;
}
if(string_search(buffer, filename)) {
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
if(furi_string_search(buffer, filename)) {
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer));
}
}
}
string_clear(buffer);
string_clear(filename);
furi_string_free(buffer);
furi_string_free(filename);
storage_file_close(file);
storage_common_remove(fs_api, ARCHIVE_FAV_PATH);
@@ -226,14 +228,14 @@ bool archive_favorites_delete(const char* format, ...) {
}
bool archive_is_favorite(const char* format, ...) {
string_t buffer;
string_t filename;
FuriString* buffer;
FuriString* filename;
va_list args;
va_start(args, format);
string_init_vprintf(filename, format, args);
filename = furi_string_alloc_vprintf(format, args);
va_end(args);
string_init(buffer);
buffer = furi_string_alloc();
Storage* fs_api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(fs_api);
@@ -245,10 +247,10 @@ bool archive_is_favorite(const char* format, ...) {
if(!archive_favorites_read_line(file, buffer)) {
break;
}
if(!string_size(buffer)) {
if(!furi_string_size(buffer)) {
continue;
}
if(!string_search(buffer, filename)) {
if(!furi_string_search(buffer, filename)) {
found = true;
break;
}
@@ -256,8 +258,8 @@ bool archive_is_favorite(const char* format, ...) {
}
storage_file_close(file);
string_clear(buffer);
string_clear(filename);
furi_string_free(buffer);
furi_string_free(filename);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
@@ -271,13 +273,13 @@ bool archive_favorites_rename(const char* src, const char* dst) {
Storage* fs_api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(fs_api);
string_t path;
string_t buffer;
FuriString* path;
FuriString* buffer;
string_init(buffer);
string_init(path);
buffer = furi_string_alloc();
path = furi_string_alloc();
string_printf(path, "%s", src);
furi_string_printf(path, "%s", src);
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
if(result) {
@@ -285,19 +287,19 @@ bool archive_favorites_rename(const char* src, const char* dst) {
if(!archive_favorites_read_line(file, buffer)) {
break;
}
if(!string_size(buffer)) {
if(!furi_string_size(buffer)) {
continue;
}
archive_file_append(
ARCHIVE_FAV_TEMP_PATH,
"%s\n",
string_search(buffer, path) ? string_get_cstr(buffer) : dst);
furi_string_search(buffer, path) ? furi_string_get_cstr(buffer) : dst);
}
}
string_clear(buffer);
string_clear(path);
furi_string_free(buffer);
furi_string_free(path);
storage_file_close(file);
storage_common_remove(fs_api, ARCHIVE_FAV_PATH);
@@ -325,7 +327,7 @@ void archive_favorites_save(void* context) {
for(size_t i = 0; i < archive_file_get_array_size(browser); i++) {
ArchiveFile_t* item = archive_get_file_at(browser, i);
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(item->path));
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(item->path));
}
storage_common_remove(fs_api, ARCHIVE_FAV_PATH);

View File

@@ -15,10 +15,10 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder
} else {
for(size_t i = 0; i < COUNT_OF(known_ext); i++) {
if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue;
if(string_search_str(file->path, known_ext[i], 0) != STRING_FAILURE) {
if(furi_string_search(file->path, known_ext[i], 0) != FURI_STRING_FAILURE) {
if(i == ArchiveFileTypeBadUsb) {
if(string_search_str(file->path, archive_get_default_path(ArchiveTabBadUsb)) ==
0) {
if(furi_string_search(
file->path, archive_get_default_path(ArchiveTabBadUsb)) == 0) {
file->type = i;
return; // *.txt file is a BadUSB script only if it is in BadUSB folder
}
@@ -54,10 +54,10 @@ bool archive_get_items(void* context, const char* path) {
void archive_file_append(const char* path, const char* format, ...) {
furi_assert(path);
string_t string;
FuriString* string;
va_list args;
va_start(args, format);
string_init_vprintf(string, format, args);
string = furi_string_alloc_vprintf(format, args);
va_end(args);
Storage* fs_api = furi_record_open(RECORD_STORAGE);
@@ -66,7 +66,7 @@ void archive_file_append(const char* path, const char* format, ...) {
bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND);
if(res) {
storage_file_write(file, string_get_cstr(string), string_size(string));
storage_file_write(file, furi_string_get_cstr(string), furi_string_size(string));
}
storage_file_close(file);
@@ -77,37 +77,37 @@ void archive_file_append(const char* path, const char* format, ...) {
void archive_delete_file(void* context, const char* format, ...) {
furi_assert(context);
string_t filename;
FuriString* filename;
va_list args;
va_start(args, format);
string_init_vprintf(filename, format, args);
filename = furi_string_alloc_vprintf(format, args);
va_end(args);
ArchiveBrowserView* browser = context;
Storage* fs_api = furi_record_open(RECORD_STORAGE);
FileInfo fileinfo;
storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo);
storage_common_stat(fs_api, furi_string_get_cstr(filename), &fileinfo);
bool res = false;
if(fileinfo.flags & FSF_DIRECTORY) {
res = storage_simply_remove_recursive(fs_api, string_get_cstr(filename));
res = storage_simply_remove_recursive(fs_api, furi_string_get_cstr(filename));
} else {
res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK);
res = (storage_common_remove(fs_api, furi_string_get_cstr(filename)) == FSE_OK);
}
furi_record_close(RECORD_STORAGE);
if(archive_is_favorite("%s", string_get_cstr(filename))) {
archive_favorites_delete("%s", string_get_cstr(filename));
if(archive_is_favorite("%s", furi_string_get_cstr(filename))) {
archive_favorites_delete("%s", furi_string_get_cstr(filename));
}
if(res) {
archive_file_array_rm_selected(browser);
}
string_clear(filename);
furi_string_free(filename);
}
FS_Error archive_rename_file_or_dir(void* context, const char* src_path, const char* dst_path) {

View File

@@ -1,10 +1,12 @@
#pragma once
#include <m-array.h>
#include <m-string.h>
#include <furi.h>
#include <storage/storage.h>
#include "toolbox/path.h"
#define FAP_MANIFEST_MAX_ICON_SIZE 32
typedef enum {
ArchiveFileTypeIButton,
ArchiveFileTypeNFC,
@@ -13,6 +15,7 @@ typedef enum {
ArchiveFileTypeInfrared,
ArchiveFileTypeBadUsb,
ArchiveFileTypeU2f,
ArchiveFileTypeApplication,
ArchiveFileTypeUpdateManifest,
ArchiveFileTypeFolder,
ArchiveFileTypeUnknown,
@@ -20,35 +23,58 @@ typedef enum {
} ArchiveFileTypeEnum;
typedef struct {
string_t path;
FuriString* path;
ArchiveFileTypeEnum type;
uint8_t* custom_icon_data;
FuriString* custom_name;
bool fav;
bool is_app;
} ArchiveFile_t;
static void ArchiveFile_t_init(ArchiveFile_t* obj) {
obj->path = furi_string_alloc();
obj->type = ArchiveFileTypeUnknown;
obj->is_app = false;
obj->custom_icon_data = NULL;
obj->custom_name = furi_string_alloc();
obj->fav = false;
string_init(obj->path);
obj->is_app = false;
}
static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) {
obj->path = furi_string_alloc_set(src->path);
obj->type = src->type;
obj->is_app = src->is_app;
if(src->custom_icon_data) {
obj->custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE);
memcpy(obj->custom_icon_data, src->custom_icon_data, FAP_MANIFEST_MAX_ICON_SIZE);
} else {
obj->custom_icon_data = NULL;
}
obj->custom_name = furi_string_alloc_set(src->custom_name);
obj->fav = src->fav;
string_init_set(obj->path, src->path);
obj->is_app = src->is_app;
}
static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) {
furi_string_set(obj->path, src->path);
obj->type = src->type;
obj->is_app = src->is_app;
if(src->custom_icon_data) {
obj->custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE);
memcpy(obj->custom_icon_data, src->custom_icon_data, FAP_MANIFEST_MAX_ICON_SIZE);
} else {
obj->custom_icon_data = NULL;
}
furi_string_set(obj->custom_name, src->custom_name);
obj->fav = src->fav;
string_set(obj->path, src->path);
obj->is_app = src->is_app;
}
static void ArchiveFile_t_clear(ArchiveFile_t* obj) {
string_clear(obj->path);
furi_string_free(obj->path);
if(obj->custom_icon_data) {
free(obj->custom_icon_data);
obj->custom_icon_data = NULL;
}
furi_string_free(obj->custom_name);
}
ARRAY_DEF(

View File

@@ -1,34 +1,34 @@
#pragma once
#include <furi.h>
#include <m-array.h>
#include <m-string.h>
typedef struct {
string_t text;
FuriString* text;
uint32_t event;
} ArchiveContextMenuItem_t;
static void ArchiveContextMenuItem_t_init(ArchiveContextMenuItem_t* obj) {
string_init(obj->text);
obj->text = furi_string_alloc();
obj->event = 0; // ArchiveBrowserEventFileMenuNone
}
static void ArchiveContextMenuItem_t_init_set(
ArchiveContextMenuItem_t* obj,
const ArchiveContextMenuItem_t* src) {
string_init_set(obj->text, src->text);
obj->text = furi_string_alloc_set(src->text);
obj->event = src->event;
}
static void ArchiveContextMenuItem_t_set(
ArchiveContextMenuItem_t* obj,
const ArchiveContextMenuItem_t* src) {
string_init_set(obj->text, src->text);
furi_string_set(obj->text, src->text);
obj->event = src->event;
}
static void ArchiveContextMenuItem_t_clear(ArchiveContextMenuItem_t* obj) {
string_clear(obj->text);
furi_string_free(obj->text);
}
ARRAY_DEF(
@@ -42,11 +42,9 @@ ARRAY_DEF(
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
// Using in applications/archive/views/archive_browser_view.c
static void archive_menu_add_item(
ArchiveContextMenuItem_t* obj,
string_t text,
uint32_t event) {
string_init_move(obj->text, text);
static void
archive_menu_add_item(ArchiveContextMenuItem_t* obj, FuriString* text, uint32_t event) {
obj->text = furi_string_alloc_set(text);
obj->event = event;
}
#pragma GCC diagnostic pop

View File

@@ -19,6 +19,7 @@ static const char* flipper_app_name[] = {
[ArchiveFileTypeInfrared] = "Infrared",
[ArchiveFileTypeBadUsb] = "Bad USB",
[ArchiveFileTypeU2f] = "U2F",
[ArchiveFileTypeApplication] = "Applications",
[ArchiveFileTypeUpdateManifest] = "UpdaterApp",
};
@@ -40,14 +41,14 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec
LoaderStatus status;
if(selected->is_app) {
char* param = strrchr(string_get_cstr(selected->path), '/');
char* param = strrchr(furi_string_get_cstr(selected->path), '/');
if(param != NULL) {
param++;
}
status = loader_start(loader, flipper_app_name[selected->type], param);
} else {
status = loader_start(
loader, flipper_app_name[selected->type], string_get_cstr(selected->path));
loader, flipper_app_name[selected->type], furi_string_get_cstr(selected->path));
}
if(status != LoaderStatusOk) {
@@ -132,7 +133,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
case ArchiveBrowserEventFileMenuRename:
if(favorites) {
browser->callback(ArchiveBrowserEventEnterFavMove, browser->context);
//} else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) {
//} else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) {
} else {
// Added ability to rename files and folders
archive_show_file_menu(browser, false);
@@ -168,13 +169,13 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
consumed = true;
break;
case ArchiveBrowserEventEnterFavMove:
string_set(archive->fav_move_str, selected->path);
furi_string_set(archive->fav_move_str, selected->path);
archive_show_file_menu(browser, false);
archive_favorites_move_mode(archive->browser, true);
consumed = true;
break;
case ArchiveBrowserEventExitFavMove:
archive_update_focus(browser, string_get_cstr(archive->fav_move_str));
archive_update_focus(browser, furi_string_get_cstr(archive->fav_move_str));
archive_favorites_move_mode(archive->browser, false);
consumed = true;
break;

View File

@@ -22,18 +22,18 @@ void archive_scene_delete_on_enter(void* context) {
widget_add_button_element(
app->widget, GuiButtonTypeRight, "Delete", archive_scene_delete_widget_callback, app);
string_t filename;
string_init(filename);
FuriString* filename;
filename = furi_string_alloc();
ArchiveFile_t* current = archive_get_current_file(app->browser);
path_extract_filename(current->path, filename, false);
char delete_str[64];
snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(filename));
snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", furi_string_get_cstr(filename));
widget_add_text_box_element(
app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false);
string_clear(filename);
furi_string_free(filename);
view_dispatcher_switch_to_view(app->view_dispatcher, ArchiveViewWidget);
}

View File

@@ -18,12 +18,12 @@ void archive_scene_info_on_enter(void* context) {
widget_add_button_element(
instance->widget, GuiButtonTypeLeft, "Back", archive_scene_info_widget_callback, instance);
string_t filename;
string_t dirname;
string_t str_size;
string_init(filename);
string_init(dirname);
string_init(str_size);
FuriString* filename;
FuriString* dirname;
FuriString* str_size;
filename = furi_string_alloc();
dirname = furi_string_alloc();
str_size = furi_string_alloc();
ArchiveFile_t* current = archive_get_current_file(instance->browser);
char file_info_message[128];
@@ -31,44 +31,49 @@ void archive_scene_info_on_enter(void* context) {
// Filename
path_extract_filename(current->path, filename, false);
snprintf(file_info_message, sizeof(file_info_message), "\e#%s\e#", string_get_cstr(filename));
snprintf(
file_info_message, sizeof(file_info_message), "\e#%s\e#", furi_string_get_cstr(filename));
widget_add_text_box_element(
instance->widget, 0, 0, 128, 25, AlignLeft, AlignCenter, file_info_message, false);
// Directory path
path_extract_dirname(string_get_cstr(current->path), dirname);
string_replace_str(dirname, STORAGE_ANY_PATH_PREFIX, "");
path_extract_dirname(furi_string_get_cstr(current->path), dirname);
if(strcmp(furi_string_get_cstr(dirname), "/any") == 0) {
furi_string_replace(dirname, STORAGE_ANY_PATH_PREFIX, "/");
} else {
furi_string_replace(dirname, STORAGE_ANY_PATH_PREFIX, "");
}
// File size
FileInfo fileinfo;
storage_common_stat(fs_api, string_get_cstr(current->path), &fileinfo);
storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo);
if(fileinfo.size <= 1024) {
string_printf(str_size, "%d", fileinfo.size);
furi_string_printf(str_size, "%d", fileinfo.size);
snprintf(
file_info_message,
sizeof(file_info_message),
"Size: \e#%s\e# bytes\n%s",
string_get_cstr(str_size),
string_get_cstr(dirname));
furi_string_get_cstr(str_size),
furi_string_get_cstr(dirname));
} else {
string_printf(str_size, "%d", fileinfo.size / 1024);
furi_string_printf(str_size, "%d", fileinfo.size / 1024);
snprintf(
file_info_message,
sizeof(file_info_message),
"Size: \e#%s\e# Kb.\n%s",
string_get_cstr(str_size),
string_get_cstr(dirname));
furi_string_get_cstr(str_size),
furi_string_get_cstr(dirname));
}
widget_add_text_box_element(
instance->widget, 0, 25, 128, 25, AlignLeft, AlignCenter, file_info_message, false);
instance->widget, 0, 25, 128, 25, AlignLeft, AlignCenter, file_info_message, true);
// This one to return and cursor select this file
path_extract_filename_no_ext(string_get_cstr(current->path), filename);
strlcpy(instance->text_store, string_get_cstr(filename), MAX_NAME_LEN);
path_extract_filename_no_ext(furi_string_get_cstr(current->path), filename);
strlcpy(instance->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN);
string_clear(filename);
string_clear(dirname);
string_clear(str_size);
furi_string_free(filename);
furi_string_free(dirname);
furi_string_free(str_size);
view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewWidget);
}

View File

@@ -22,22 +22,22 @@ void archive_scene_rename_on_enter(void* context) {
TextInput* text_input = archive->text_input;
ArchiveFile_t* current = archive_get_current_file(archive->browser);
string_t path_name;
string_init(path_name);
FuriString* path_name;
path_name = furi_string_alloc();
if(current->type == ArchiveFileTypeFolder) {
path_extract_basename(string_get_cstr(current->path), path_name);
strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN);
path_extract_basename(furi_string_get_cstr(current->path), path_name);
strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN);
text_input_set_header_text(text_input, "Rename directory:");
} else /*if(current->type != ArchiveFileTypeUnknown) */ {
path_extract_filename(current->path, path_name, true);
strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN);
strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN);
path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN);
text_input_set_header_text(text_input, "Rename file:");
} /*else {
path_extract_filename(current->path, path_name, false);
strlcpy(archive->text_store, string_get_cstr(path_name), MAX_NAME_LEN);
strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN);
text_input_set_header_text(text_input, "Rename unknown file:");
}*/
@@ -49,7 +49,7 @@ void archive_scene_rename_on_enter(void* context) {
MAX_TEXT_INPUT_LEN,
false);
string_clear(path_name);
furi_string_free(path_name);
view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput);
}
@@ -63,40 +63,43 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
const char* path_src = archive_get_name(archive->browser);
ArchiveFile_t* file = archive_get_current_file(archive->browser);
string_t path_dst;
string_init(path_dst);
FuriString* path_dst;
path_dst = furi_string_alloc();
if(file->type == ArchiveFileTypeFolder) {
// Rename folder/dir
path_extract_dirname(path_src, path_dst);
string_cat_printf(path_dst, "/%s", archive->text_store);
furi_string_cat_printf(path_dst, "/%s", archive->text_store);
} else if(file->type != ArchiveFileTypeUnknown) {
// Rename known type
path_extract_dirname(path_src, path_dst);
string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]);
furi_string_cat_printf(
path_dst, "/%s%s", archive->text_store, known_ext[file->type]);
} else {
// Rename unknown type
path_extract_dirname(path_src, path_dst);
string_cat_printf(path_dst, "/%s%s", archive->text_store, archive->file_extension);
furi_string_cat_printf(
path_dst, "/%s%s", archive->text_store, archive->file_extension);
}
// Long time process if this is directory
view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewStack);
archive_show_loading_popup(archive, true);
FS_Error error =
archive_rename_file_or_dir(archive->browser, path_src, string_get_cstr(path_dst));
FS_Error error = archive_rename_file_or_dir(
archive->browser, path_src, furi_string_get_cstr(path_dst));
archive_show_loading_popup(archive, false);
archive_show_file_menu(archive->browser, false);
string_clear(path_dst);
furi_string_free(path_dst);
if(error == FSE_OK || error == FSE_EXIST) {
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
} else {
string_t dialog_msg;
string_init(dialog_msg);
string_cat_printf(dialog_msg, "Cannot rename\nCode: %d", error);
dialog_message_show_storage_error(archive->dialogs, string_get_cstr(dialog_msg));
string_clear(dialog_msg);
FuriString* dialog_msg;
dialog_msg = furi_string_alloc();
furi_string_cat_printf(dialog_msg, "Cannot rename\nCode: %d", error);
dialog_message_show_storage_error(
archive->dialogs, furi_string_get_cstr(dialog_msg));
furi_string_free(dialog_msg);
}
consumed = true;
}

View File

@@ -16,6 +16,7 @@ static const char* ArchiveTabNames[] = {
[ArchiveTabInfrared] = "Infrared",
[ArchiveTabBadUsb] = "Bad USB",
[ArchiveTabU2f] = "U2F",
[ArchiveTabApplications] = "Apps",
[ArchiveTabBrowser] = "Browser",
};
@@ -27,6 +28,7 @@ static const Icon* ArchiveItemIcons[] = {
[ArchiveFileTypeInfrared] = &I_ir_10px,
[ArchiveFileTypeBadUsb] = &I_badusb_10px,
[ArchiveFileTypeU2f] = &I_u2f_10px,
[ArchiveFileTypeApplication] = &I_Apps_10px,
[ArchiveFileTypeUpdateManifest] = &I_update_10px,
[ArchiveFileTypeFolder] = &I_dir_10px,
[ArchiveFileTypeUnknown] = &I_unknown_10px,
@@ -46,24 +48,18 @@ void archive_browser_set_callback(
static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
if(menu_array_size(model->context_menu) == 0) {
// Context menu is empty, init array
string_t item_run;
string_t item_pin;
string_t item_info;
string_t item_rename;
string_t item_delete;
string_init_set_str(item_run, "Run In App");
string_init_set_str(item_pin, "Pin");
string_init_set_str(item_info, "Info");
string_init_set_str(item_rename, "Rename");
string_init_set_str(item_delete, "Delete");
FuriString* item_run = furi_string_alloc_set("Run In App");
FuriString* item_pin = furi_string_alloc_set("Pin");
FuriString* item_info = furi_string_alloc_set("Info");
FuriString* item_rename = furi_string_alloc_set("Rename");
FuriString* item_delete = furi_string_alloc_set("Delete");
// Need init context menu
ArchiveFile_t* selected =
files_array_get(model->files, model->item_idx - model->array_offset);
if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) {
string_set_str(item_pin, "Unpin");
furi_string_set(item_pin, "Unpin");
}
if(selected->type == ArchiveFileTypeFolder) {
@@ -94,7 +90,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
} else if(model->tab_idx == ArchiveTabFavorites) {
//FURI_LOG_D(TAG, "ArchiveTabFavorites");
string_set_str(item_rename, "Move");
furi_string_set(item_rename, "Move");
archive_menu_add_item(
menu_array_push_raw(model->context_menu),
@@ -150,11 +146,11 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
ArchiveBrowserEventFileMenuDelete);
}
string_clear(item_run);
string_clear(item_pin);
string_clear(item_info);
string_clear(item_rename);
string_clear(item_delete);
furi_string_free(item_run);
furi_string_free(item_pin);
furi_string_free(item_info);
furi_string_free(item_rename);
furi_string_free(item_delete);
} /*else {
FURI_LOG_D(TAG, "menu_array_size already set: %d", menu_array_size(model->context_menu));
}*/
@@ -176,7 +172,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
model->menu_idx);*/
for(size_t i = 0; i < size_menu; i++) {
ArchiveContextMenuItem_t* current = menu_array_get(model->context_menu, i);
canvas_draw_str(canvas, 82, 21 + i * line_height, string_get_cstr(current->text));
canvas_draw_str(canvas, 82, 21 + i * line_height, furi_string_get_cstr(current->text));
}
canvas_draw_icon(canvas, 74, 14 + model->menu_idx * line_height, &I_ButtonRight_4x7);
@@ -219,20 +215,31 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
bool scrollbar = model->item_cnt > 4;
for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) {
string_t str_buf;
string_init(str_buf);
FuriString* str_buf;
str_buf = furi_string_alloc();
int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u);
uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0;
ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading;
uint8_t* custom_icon_data = NULL;
if(archive_is_item_in_array(model, idx)) {
ArchiveFile_t* file = files_array_get(
model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0));
path_extract_filename(file->path, str_buf, archive_is_known_app(file->type));
file_type = file->type;
if(file_type == ArchiveFileTypeApplication) {
if(file->custom_icon_data) {
custom_icon_data = file->custom_icon_data;
furi_string_set(str_buf, file->custom_name);
} else {
file_type = ArchiveFileTypeUnknown;
path_extract_filename(file->path, str_buf, archive_is_known_app(file->type));
}
} else {
path_extract_filename(file->path, str_buf, archive_is_known_app(file->type));
}
} else {
string_set_str(str_buf, "---");
furi_string_set(str_buf, "---");
}
elements_string_fit_width(
@@ -244,10 +251,17 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
canvas_set_color(canvas, ColorBlack);
}
canvas_draw_icon(canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]);
canvas_draw_str(canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, string_get_cstr(str_buf));
if(custom_icon_data) {
canvas_draw_bitmap(
canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, 11, 10, custom_icon_data);
} else {
canvas_draw_icon(
canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]);
}
canvas_draw_str(
canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buf));
string_clear(str_buf);
furi_string_free(str_buf);
}
if(scrollbar) {
@@ -463,7 +477,7 @@ ArchiveBrowserView* browser_alloc() {
view_set_draw_callback(browser->view, archive_view_render);
view_set_input_callback(browser->view, archive_view_input);
string_init_set_str(browser->path, archive_get_default_path(TAB_DEFAULT));
browser->path = furi_string_alloc_set(archive_get_default_path(TAB_DEFAULT));
with_view_model(
browser->view, (ArchiveBrowserViewModel * model) {
@@ -490,7 +504,7 @@ void browser_free(ArchiveBrowserView* browser) {
return false;
});
string_clear(browser->path);
furi_string_free(browser->path);
view_free(browser->view);
free(browser);

View File

@@ -27,6 +27,7 @@ typedef enum {
ArchiveTabIButton,
ArchiveTabBadUsb,
ArchiveTabU2f,
ArchiveTabApplications,
ArchiveTabBrowser,
ArchiveTabTotal,
} ArchiveTabEnum;
@@ -73,7 +74,7 @@ struct ArchiveBrowserView {
bool worker_running;
ArchiveBrowserViewCallback callback;
void* context;
string_t path;
FuriString* path;
InputKey last_tab_switch_dir;
bool is_root;
};

View File

@@ -1,6 +1,5 @@
#include "bad_usb_app_i.h"
#include "bad_usb_settings_filename.h"
#include "m-string.h"
#include <furi.h>
#include <furi_hal.h>
#include <storage/storage.h>
@@ -32,7 +31,7 @@ static void bad_usb_load_settings(BadUsbApp* app) {
char chr;
while((storage_file_read(settings_file, &chr, 1) == 1) &&
!storage_file_eof(settings_file) && !isspace(chr)) {
string_push_back(app->keyboard_layout, chr);
furi_string_push_back(app->keyboard_layout, chr);
}
}
storage_file_close(settings_file);
@@ -44,8 +43,8 @@ static void bad_usb_save_settings(BadUsbApp* app) {
if(storage_file_open(settings_file, BAD_USB_SETTINGS_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS)) {
storage_file_write(
settings_file,
string_get_cstr(app->keyboard_layout),
string_size(app->keyboard_layout));
furi_string_get_cstr(app->keyboard_layout),
furi_string_size(app->keyboard_layout));
storage_file_write(settings_file, "\n", 1);
}
storage_file_close(settings_file);
@@ -57,10 +56,10 @@ BadUsbApp* bad_usb_app_alloc(char* arg) {
app->bad_usb_script = NULL;
string_init(app->file_path);
string_init(app->keyboard_layout);
app->file_path = furi_string_alloc();
app->keyboard_layout = furi_string_alloc();
if(arg && strlen(arg)) {
string_set_str(app->file_path, arg);
furi_string_set(app->file_path, arg);
}
bad_usb_load_settings(app);
@@ -101,12 +100,12 @@ BadUsbApp* bad_usb_app_alloc(char* arg) {
app->error = BadUsbAppErrorCloseRpc;
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
} else {
if(!string_empty_p(app->file_path)) {
if(!furi_string_empty(app->file_path)) {
app->bad_usb_script = bad_usb_script_open(app->file_path);
bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout);
scene_manager_next_scene(app->scene_manager, BadUsbSceneWork);
} else {
string_set_str(app->file_path, BAD_USB_APP_BASE_FOLDER);
furi_string_set(app->file_path, BAD_USB_APP_BASE_FOLDER);
scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect);
}
}
@@ -145,8 +144,8 @@ void bad_usb_app_free(BadUsbApp* app) {
bad_usb_save_settings(app);
string_clear(app->file_path);
string_clear(app->keyboard_layout);
furi_string_free(app->file_path);
furi_string_free(app->keyboard_layout);
free(app);
}

View File

@@ -34,8 +34,8 @@ struct BadUsbApp {
Submenu* submenu;
BadUsbAppError error;
string_t file_path;
string_t keyboard_layout;
FuriString* file_path;
FuriString* keyboard_layout;
BadUsb* bad_usb_view;
BadUsbScript* bad_usb_script;
};

View File

@@ -29,7 +29,7 @@ typedef enum {
struct BadUsbScript {
FuriHalUsbHidConfig hid_cfg;
BadUsbState st;
string_t file_path;
FuriString* file_path;
uint32_t defdelay;
uint16_t layout[128];
FuriThread* thread;
@@ -37,9 +37,9 @@ struct BadUsbScript {
uint8_t buf_start;
uint8_t buf_len;
bool file_end;
string_t line;
FuriString* line;
string_t line_prev;
FuriString* line_prev;
uint32_t repeat_cnt;
};
@@ -236,9 +236,9 @@ static uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool
return 0;
}
static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
uint32_t line_len = string_size(line);
const char* line_tmp = string_get_cstr(line);
static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) {
uint32_t line_len = furi_string_size(line);
const char* line_tmp = furi_string_get_cstr(line);
bool state = false;
for(uint32_t i = 0; i < line_len; i++) {
@@ -346,7 +346,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
uint8_t ret = 0;
uint32_t line_len = 0;
string_reset(bad_usb->line);
furi_string_reset(bad_usb->line);
do {
ret = storage_file_read(script_file, bad_usb->file_buf, FILE_BUFFER_LEN);
@@ -356,7 +356,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
line_len = 0;
} else {
if(bad_usb->st.line_nb == 0) { // Save first line
string_push_back(bad_usb->line, bad_usb->file_buf[i]);
furi_string_push_back(bad_usb->line, bad_usb->file_buf[i]);
}
line_len++;
}
@@ -369,7 +369,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
}
} while(ret > 0);
const char* line_tmp = string_get_cstr(bad_usb->line);
const char* line_tmp = furi_string_get_cstr(bad_usb->line);
bool id_set = false; // Looking for ID command at first line
if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) {
id_set = ducky_set_usb_id(bad_usb, &line_tmp[strlen(ducky_cmd_id) + 1]);
@@ -382,7 +382,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
}
storage_file_seek(script_file, 0, true);
string_reset(bad_usb->line);
furi_string_reset(bad_usb->line);
return true;
}
@@ -404,8 +404,8 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
}
}
string_set(bad_usb->line_prev, bad_usb->line);
string_reset(bad_usb->line);
furi_string_set(bad_usb->line_prev, bad_usb->line);
furi_string_reset(bad_usb->line);
while(1) {
if(bad_usb->buf_len == 0) {
@@ -422,7 +422,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
if(bad_usb->buf_len == 0) return SCRIPT_STATE_END;
}
for(uint8_t i = bad_usb->buf_start; i < (bad_usb->buf_start + bad_usb->buf_len); i++) {
if(bad_usb->file_buf[i] == '\n' && string_size(bad_usb->line) > 0) {
if(bad_usb->file_buf[i] == '\n' && furi_string_size(bad_usb->line) > 0) {
bad_usb->st.line_cur++;
bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1);
bad_usb->buf_start = i + 1;
@@ -435,7 +435,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
return (delay_val + bad_usb->defdelay);
}
} else {
string_push_back(bad_usb->line, bad_usb->file_buf[i]);
furi_string_push_back(bad_usb->line, bad_usb->file_buf[i]);
}
}
bad_usb->buf_len = 0;
@@ -465,8 +465,8 @@ static int32_t bad_usb_worker(void* context) {
FURI_LOG_I(WORKER_TAG, "Init");
File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
string_init(bad_usb->line);
string_init(bad_usb->line_prev);
bad_usb->line = furi_string_alloc();
bad_usb->line_prev = furi_string_alloc();
furi_hal_hid_set_state_callback(bad_usb_hid_state_callback, bad_usb);
@@ -474,7 +474,7 @@ static int32_t bad_usb_worker(void* context) {
if(worker_state == BadUsbStateInit) { // State: initialization
if(storage_file_open(
script_file,
string_get_cstr(bad_usb->file_path),
furi_string_get_cstr(bad_usb->file_path),
FSAM_READ,
FSOM_OPEN_EXISTING)) {
if((ducky_script_preload(bad_usb, script_file)) && (bad_usb->st.line_nb > 0)) {
@@ -586,8 +586,8 @@ static int32_t bad_usb_worker(void* context) {
storage_file_close(script_file);
storage_file_free(script_file);
string_clear(bad_usb->line);
string_clear(bad_usb->line_prev);
furi_string_free(bad_usb->line);
furi_string_free(bad_usb->line_prev);
FURI_LOG_I(WORKER_TAG, "End");
@@ -600,12 +600,12 @@ static void bad_usb_script_set_default_keyboard_layout(BadUsbScript* bad_usb) {
memcpy(bad_usb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(bad_usb->layout)));
}
BadUsbScript* bad_usb_script_open(string_t file_path) {
BadUsbScript* bad_usb_script_open(FuriString* file_path) {
furi_assert(file_path);
BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript));
string_init(bad_usb->file_path);
string_set(bad_usb->file_path, file_path);
bad_usb->file_path = furi_string_alloc();
furi_string_set(bad_usb->file_path, file_path);
bad_usb_script_set_default_keyboard_layout(bad_usb);
bad_usb->st.state = BadUsbStateInit;
@@ -625,11 +625,11 @@ void bad_usb_script_close(BadUsbScript* bad_usb) {
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtEnd);
furi_thread_join(bad_usb->thread);
furi_thread_free(bad_usb->thread);
string_clear(bad_usb->file_path);
furi_string_free(bad_usb->file_path);
free(bad_usb);
}
void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, string_t layout_path) {
void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, FuriString* layout_path) {
furi_assert(bad_usb);
if((bad_usb->st.state == BadUsbStateRunning) || (bad_usb->st.state == BadUsbStateDelay)) {
@@ -638,9 +638,9 @@ void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, string_t layout_p
}
File* layout_file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
if(!string_empty_p(layout_path)) {
if(!furi_string_empty(layout_path)) {
if(storage_file_open(
layout_file, string_get_cstr(layout_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
layout_file, furi_string_get_cstr(layout_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
uint16_t layout[128];
if(storage_file_read(layout_file, layout, sizeof(layout)) == sizeof(layout)) {
memcpy(bad_usb->layout, layout, sizeof(layout));

View File

@@ -5,7 +5,6 @@ extern "C" {
#endif
#include <furi.h>
#include <m-string.h>
typedef struct BadUsbScript BadUsbScript;
@@ -28,11 +27,11 @@ typedef struct {
uint16_t error_line;
} BadUsbState;
BadUsbScript* bad_usb_script_open(string_t file_path);
BadUsbScript* bad_usb_script_open(FuriString* file_path);
void bad_usb_script_close(BadUsbScript* bad_usb);
void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, string_t layout_path);
void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, FuriString* layout_path);
void bad_usb_script_start(BadUsbScript* bad_usb);

View File

@@ -6,12 +6,12 @@
static bool bad_usb_layout_select(BadUsbApp* bad_usb) {
furi_assert(bad_usb);
string_t predefined_path;
string_init(predefined_path);
if(!string_empty_p(bad_usb->keyboard_layout)) {
string_set(predefined_path, bad_usb->keyboard_layout);
FuriString* predefined_path;
predefined_path = furi_string_alloc();
if(!furi_string_empty(bad_usb->keyboard_layout)) {
furi_string_set(predefined_path, bad_usb->keyboard_layout);
} else {
string_set_str(predefined_path, BAD_USB_APP_PATH_LAYOUT_FOLDER);
furi_string_set(predefined_path, BAD_USB_APP_PATH_LAYOUT_FOLDER);
}
DialogsFileBrowserOptions browser_options;
@@ -22,7 +22,7 @@ static bool bad_usb_layout_select(BadUsbApp* bad_usb) {
bool res = dialog_file_browser_show(
bad_usb->dialogs, bad_usb->keyboard_layout, predefined_path, &browser_options);
string_clear(predefined_path);
furi_string_free(predefined_path);
return res;
}

View File

@@ -8,6 +8,7 @@ static bool bad_usb_file_select(BadUsbApp* bad_usb) {
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
&browser_options, BAD_USB_APP_SCRIPT_EXTENSION, &I_badusb_10px);
browser_options.skip_assets = true;
// Input events and views are managed by file_browser
bool res = dialog_file_browser_show(

View File

@@ -2,7 +2,6 @@
#include "../bad_usb_app_i.h"
#include "../views/bad_usb_view.h"
#include "furi_hal.h"
#include "m-string.h"
#include "toolbox/path.h"
void bad_usb_scene_work_button_callback(InputKey key, void* context) {
@@ -32,17 +31,17 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) {
void bad_usb_scene_work_on_enter(void* context) {
BadUsbApp* app = context;
string_t file_name;
string_init(file_name);
FuriString* file_name;
file_name = furi_string_alloc();
path_extract_filename(app->file_path, file_name, true);
bad_usb_set_file_name(app->bad_usb_view, string_get_cstr(file_name));
string_clear(file_name);
bad_usb_set_file_name(app->bad_usb_view, furi_string_get_cstr(file_name));
furi_string_free(file_name);
string_t layout;
string_init(layout);
FuriString* layout;
layout = furi_string_alloc();
path_extract_filename(app->keyboard_layout, layout, true);
bad_usb_set_layout(app->bad_usb_view, string_get_cstr(layout));
string_clear(layout);
bad_usb_set_layout(app->bad_usb_view, furi_string_get_cstr(layout));
furi_string_free(layout);
bad_usb_set_state(app->bad_usb_view, bad_usb_script_get_state(app->bad_usb_script));

View File

@@ -21,25 +21,26 @@ typedef struct {
static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
BadUsbModel* model = _model;
string_t disp_str;
string_init_set_str(disp_str, model->file_name);
FuriString* disp_str;
disp_str = furi_string_alloc_set(model->file_name);
elements_string_fit_width(canvas, disp_str, 128 - 2);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, 2, 8, string_get_cstr(disp_str));
canvas_draw_str(canvas, 2, 8, furi_string_get_cstr(disp_str));
if(strlen(model->layout) == 0) {
string_set(disp_str, "(default)");
furi_string_set(disp_str, "(default)");
} else {
string_reset(disp_str);
string_push_back(disp_str, '(');
furi_string_reset(disp_str);
furi_string_push_back(disp_str, '(');
for(size_t i = 0; i < strlen(model->layout); i++)
string_push_back(disp_str, model->layout[i]);
string_push_back(disp_str, ')');
furi_string_push_back(disp_str, model->layout[i]);
furi_string_push_back(disp_str, ')');
}
elements_string_fit_width(canvas, disp_str, 128 - 2);
canvas_draw_str(canvas, 2, 8 + canvas_current_font_height(canvas), string_get_cstr(disp_str));
canvas_draw_str(
canvas, 2, 8 + canvas_current_font_height(canvas), furi_string_get_cstr(disp_str));
string_reset(disp_str);
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 22, 24, &I_UsbTree_48x22);
@@ -69,10 +70,10 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 127, 33, AlignRight, AlignBottom, "ERROR:");
canvas_set_font(canvas, FontSecondary);
string_printf(disp_str, "line %u", model->state.error_line);
furi_string_printf(disp_str, "line %u", model->state.error_line);
canvas_draw_str_aligned(
canvas, 127, 46, AlignRight, AlignBottom, string_get_cstr(disp_str));
string_reset(disp_str);
canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
} else if(model->state.state == BadUsbStateIdle) {
canvas_draw_icon(canvas, 4, 26, &I_Smile_18x18);
canvas_set_font(canvas, FontBigNumbers);
@@ -85,16 +86,17 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_icon(canvas, 4, 23, &I_EviSmile2_18x21);
}
canvas_set_font(canvas, FontBigNumbers);
string_printf(disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
furi_string_printf(
disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
canvas_draw_str_aligned(
canvas, 114, 40, AlignRight, AlignBottom, string_get_cstr(disp_str));
string_reset(disp_str);
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
} else if(model->state.state == BadUsbStateDone) {
canvas_draw_icon(canvas, 4, 23, &I_EviSmile1_18x21);
canvas_set_font(canvas, FontBigNumbers);
canvas_draw_str_aligned(canvas, 114, 40, AlignRight, AlignBottom, "100");
string_reset(disp_str);
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
} else if(model->state.state == BadUsbStateDelay) {
if(model->anim_frame == 0) {
@@ -103,21 +105,22 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_icon(canvas, 4, 23, &I_EviWaiting2_18x21);
}
canvas_set_font(canvas, FontBigNumbers);
string_printf(disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
furi_string_printf(
disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
canvas_draw_str_aligned(
canvas, 114, 40, AlignRight, AlignBottom, string_get_cstr(disp_str));
string_reset(disp_str);
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
canvas_set_font(canvas, FontSecondary);
string_printf(disp_str, "delay %us", model->state.delay_remain);
furi_string_printf(disp_str, "delay %us", model->state.delay_remain);
canvas_draw_str_aligned(
canvas, 127, 50, AlignRight, AlignBottom, string_get_cstr(disp_str));
string_reset(disp_str);
canvas, 127, 50, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
} else {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
}
string_clear(disp_str);
furi_string_free(disp_str);
}
static bool bad_usb_input_callback(InputEvent* event, void* context) {

View File

@@ -38,6 +38,7 @@ static void clock_render_callback(Canvas* const canvas, void* ctx) {
time_string, TIME_LEN, CLOCK_TIME_FORMAT, curr_dt.hour, curr_dt.minute, curr_dt.second);
} else {
bool pm = curr_dt.hour > 12;
bool pm12 = curr_dt.hour >= 12;
snprintf(
time_string,
TIME_LEN,
@@ -50,7 +51,7 @@ static void clock_render_callback(Canvas* const canvas, void* ctx) {
meridian_string,
MERIDIAN_LEN,
MERIDIAN_FORMAT,
pm ? MERIDIAN_STRING_PM : MERIDIAN_STRING_AM);
pm12 ? MERIDIAN_STRING_PM : MERIDIAN_STRING_AM);
}
if(state->settings.date_format == Iso) {

View File

@@ -33,5 +33,4 @@ typedef enum {
typedef struct {
TimeFormat time_format;
DateFormat date_format;
uint8_t increment_precision;
} ClockSettings;

View File

@@ -1,31 +1,34 @@
#include <furi.h>
#include <gui/gui.h>
#include <gui/view_dispatcher.h>
#include <gui/modules/loading.h>
#include <storage/storage.h>
#include <gui/modules/loading.h>
#include <dialogs/dialogs.h>
#include "elf_cpp/elf_hashtable.h"
#include <flipper_application/flipper_application.h>
#include "elf_cpp/elf_hashtable.h"
#include "fap_loader_app.h"
#define TAG "fap_loader_app"
typedef struct {
struct FapLoader {
FlipperApplication* app;
Storage* storage;
DialogsApp* dialogs;
Gui* gui;
string_t fap_path;
} FapLoader;
FuriString* fap_path;
ViewDispatcher* view_dispatcher;
Loading* loading;
};
static bool
fap_loader_item_callback(string_t path, void* context, uint8_t** icon_ptr, string_t item_name) {
FapLoader* loader = context;
furi_assert(loader);
FlipperApplication* app = flipper_application_alloc(loader->storage, &hashtable_api_interface);
bool fap_loader_load_name_and_icon(
FuriString* path,
Storage* storage,
uint8_t** icon_ptr,
FuriString* item_name) {
FlipperApplication* app = flipper_application_alloc(storage, &hashtable_api_interface);
FlipperApplicationPreloadStatus preload_res =
flipper_application_preload(app, string_get_cstr(path));
flipper_application_preload_manifest(app, furi_string_get_cstr(path));
bool load_success = false;
@@ -34,10 +37,10 @@ static bool
if(manifest->has_icon) {
memcpy(*icon_ptr, manifest->icon, FAP_MANIFEST_MAX_ICON_SIZE);
}
string_set_str(item_name, manifest->name);
furi_string_set(item_name, manifest->name);
load_success = true;
} else {
FURI_LOG_E(TAG, "FAP Loader failed to preload %s", string_get_cstr(path));
FURI_LOG_E(TAG, "FAP Loader failed to preload %s", furi_string_get_cstr(path));
load_success = false;
}
@@ -45,12 +48,22 @@ static bool
return load_success;
}
static bool fap_loader_item_callback(
FuriString* path,
void* context,
uint8_t** icon_ptr,
FuriString* item_name) {
FapLoader* fap_loader = context;
furi_assert(fap_loader);
return fap_loader_load_name_and_icon(path, fap_loader->storage, icon_ptr, item_name);
}
static bool fap_loader_run_selected_app(FapLoader* loader) {
furi_assert(loader);
string_t error_message;
FuriString* error_message;
string_init_set(error_message, "unknown error");
error_message = furi_string_alloc_set("unknown error");
bool file_selected = false;
bool show_error = true;
@@ -58,17 +71,17 @@ static bool fap_loader_run_selected_app(FapLoader* loader) {
file_selected = true;
loader->app = flipper_application_alloc(loader->storage, &hashtable_api_interface);
FURI_LOG_I(TAG, "FAP Loader is loading %s", string_get_cstr(loader->fap_path));
FURI_LOG_I(TAG, "FAP Loader is loading %s", furi_string_get_cstr(loader->fap_path));
FlipperApplicationPreloadStatus preload_res =
flipper_application_preload(loader->app, string_get_cstr(loader->fap_path));
flipper_application_preload(loader->app, furi_string_get_cstr(loader->fap_path));
if(preload_res != FlipperApplicationPreloadStatusSuccess) {
const char* err_msg = flipper_application_preload_status_to_string(preload_res);
string_printf(error_message, "Preload failed: %s", err_msg);
furi_string_printf(error_message, "Preload failed: %s", err_msg);
FURI_LOG_E(
TAG,
"FAP Loader failed to preload %s: %s",
string_get_cstr(loader->fap_path),
furi_string_get_cstr(loader->fap_path),
err_msg);
break;
}
@@ -77,11 +90,11 @@ static bool fap_loader_run_selected_app(FapLoader* loader) {
FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(loader->app);
if(load_status != FlipperApplicationLoadStatusSuccess) {
const char* err_msg = flipper_application_load_status_to_string(load_status);
string_printf(error_message, "Load failed: %s", err_msg);
furi_string_printf(error_message, "Load failed: %s", err_msg);
FURI_LOG_E(
TAG,
"FAP Loader failed to map to memory %s: %s",
string_get_cstr(loader->fap_path),
furi_string_get_cstr(loader->fap_path),
err_msg);
break;
}
@@ -103,19 +116,19 @@ static bool fap_loader_run_selected_app(FapLoader* loader) {
dialog_message_set_header(message, "Error", 64, 0, AlignCenter, AlignTop);
dialog_message_set_buttons(message, NULL, NULL, NULL);
string_t buffer;
string_init(buffer);
string_printf(buffer, "%s", string_get_cstr(error_message));
string_replace_str(buffer, ":", "\n");
FuriString* buffer;
buffer = furi_string_alloc();
furi_string_printf(buffer, "%s", furi_string_get_cstr(error_message));
furi_string_replace(buffer, ":", "\n");
dialog_message_set_text(
message, string_get_cstr(buffer), 64, 32, AlignCenter, AlignCenter);
message, furi_string_get_cstr(buffer), 64, 32, AlignCenter, AlignCenter);
dialog_message_show(loader->dialogs, message);
dialog_message_free(message);
string_clear(buffer);
furi_string_free(buffer);
}
string_clear(error_message);
furi_string_free(error_message);
if(file_selected) {
flipper_application_free(loader->app);
@@ -128,7 +141,7 @@ static bool fap_loader_select_app(FapLoader* loader) {
const DialogsFileBrowserOptions browser_options = {
.extension = ".fap",
.skip_assets = true,
.icon = &I_badusb_10px,
.icon = &I_unknown_10px,
.hide_ext = true,
.item_loader_callback = fap_loader_item_callback,
.item_loader_context = loader,
@@ -138,39 +151,44 @@ static bool fap_loader_select_app(FapLoader* loader) {
loader->dialogs, loader->fap_path, loader->fap_path, &browser_options);
}
int32_t fap_loader_app(void* p) {
static FapLoader* fap_loader_alloc(const char* path) {
FapLoader* loader = malloc(sizeof(FapLoader));
loader->fap_path = furi_string_alloc_set(path);
loader->storage = furi_record_open(RECORD_STORAGE);
loader->dialogs = furi_record_open(RECORD_DIALOGS);
loader->gui = furi_record_open(RECORD_GUI);
loader->view_dispatcher = view_dispatcher_alloc();
loader->loading = loading_alloc();
view_dispatcher_attach_to_gui(
loader->view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_add_view(loader->view_dispatcher, 0, loading_get_view(loader->loading));
return loader;
}
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
Loading* loading = loading_alloc();
view_dispatcher_enable_queue(view_dispatcher);
view_dispatcher_attach_to_gui(view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_add_view(view_dispatcher, 0, loading_get_view(loading));
if(p) {
string_init_set(loader->fap_path, (const char*)p);
fap_loader_run_selected_app(loader);
} else {
string_init_set(loader->fap_path, EXT_PATH("apps"));
while(fap_loader_select_app(loader)) {
view_dispatcher_switch_to_view(view_dispatcher, 0);
fap_loader_run_selected_app(loader);
};
}
view_dispatcher_remove_view(view_dispatcher, 0);
loading_free(loading);
view_dispatcher_free(view_dispatcher);
string_clear(loader->fap_path);
static void fap_loader_free(FapLoader* loader) {
view_dispatcher_remove_view(loader->view_dispatcher, 0);
loading_free(loader->loading);
view_dispatcher_free(loader->view_dispatcher);
furi_string_free(loader->fap_path);
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_DIALOGS);
furi_record_close(RECORD_STORAGE);
free(loader);
}
int32_t fap_loader_app(void* p) {
FapLoader* loader;
if(p) {
loader = fap_loader_alloc((const char*)p);
fap_loader_run_selected_app(loader);
} else {
loader = fap_loader_alloc(EXT_PATH("apps"));
while(fap_loader_select_app(loader)) {
view_dispatcher_switch_to_view(loader->view_dispatcher, 0);
fap_loader_run_selected_app(loader);
};
}
fap_loader_free(loader);
return 0;
}
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include <storage/storage.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct FapLoader FapLoader;
/**
* @brief Load name and icon from FAP file.
*
* @param path Path to FAP file.
* @param storage Storage instance.
* @param icon_ptr Icon pointer.
* @param item_name Application name.
* @return true if icon and name were loaded successfully.
*/
bool fap_loader_load_name_and_icon(
FuriString* path,
Storage* storage,
uint8_t** icon_ptr,
FuriString* item_name);
#ifdef __cplusplus
}
#endif

View File

@@ -54,7 +54,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_str_aligned(canvas, 116, 24, AlignRight, AlignBottom, temp_str);
} else {
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KB.");
canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KiB.");
canvas_set_font(canvas, FontKeyboard);
snprintf(temp_str, 18, "%lu", model->tx_cnt / 1024);
canvas_draw_str_aligned(canvas, 111, 24, AlignRight, AlignBottom, temp_str);
@@ -68,7 +68,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_str_aligned(canvas, 116, 41, AlignRight, AlignBottom, temp_str);
} else {
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KB.");
canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KiB.");
canvas_set_font(canvas, FontKeyboard);
snprintf(temp_str, 18, "%lu", model->rx_cnt / 1024);
canvas_draw_str_aligned(canvas, 111, 41, AlignRight, AlignBottom, temp_str);

View File

@@ -2,7 +2,6 @@
#include "assets_icons.h"
#include "ibutton_i.h"
#include "ibutton/scenes/ibutton_scene.h"
#include "m-string.h"
#include <toolbox/path.h>
#include <flipper_format/flipper_format.h>
#include <rpc/rpc_app.h>
@@ -39,25 +38,25 @@ static void ibutton_make_app_folder(iButton* ibutton) {
}
}
bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) {
bool ibutton_load_key_data(iButton* ibutton, FuriString* key_path, bool show_dialog) {
FlipperFormat* file = flipper_format_file_alloc(ibutton->storage);
bool result = false;
string_t data;
string_init(data);
FuriString* data;
data = furi_string_alloc();
do {
if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break;
if(!flipper_format_file_open_existing(file, furi_string_get_cstr(key_path))) break;
// header
uint32_t version;
if(!flipper_format_read_header(file, data, &version)) break;
if(string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break;
if(furi_string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break;
if(version != 1) break;
// key type
iButtonKeyType type;
if(!flipper_format_read_string(file, "Key type", data)) break;
if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break;
if(!ibutton_key_get_type_by_string(furi_string_get_cstr(data), &type)) break;
// key data
uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0};
@@ -71,7 +70,7 @@ bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog
} while(false);
flipper_format_free(file);
string_clear(data);
furi_string_free(data);
if((!result) && (show_dialog)) {
dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file");
@@ -119,7 +118,7 @@ void ibutton_tick_event_callback(void* context) {
iButton* ibutton_alloc() {
iButton* ibutton = malloc(sizeof(iButton));
string_init(ibutton->file_path);
ibutton->file_path = furi_string_alloc();
ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton);
@@ -210,7 +209,7 @@ void ibutton_free(iButton* ibutton) {
ibutton_worker_free(ibutton->key_worker);
ibutton_key_free(ibutton->key);
string_clear(ibutton->file_path);
furi_string_free(ibutton->file_path);
free(ibutton);
}
@@ -240,19 +239,19 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) {
do {
// Check if we has old key
if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
// First remove old key
ibutton_delete_key(ibutton);
// Remove old key name from path
size_t filename_start = string_search_rchar(ibutton->file_path, '/');
string_left(ibutton->file_path, filename_start);
size_t filename_start = furi_string_search_rchar(ibutton->file_path, '/');
furi_string_left(ibutton->file_path, filename_start);
}
string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION);
furi_string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION);
// Open file for write
if(!flipper_format_file_open_always(file, string_get_cstr(ibutton->file_path))) break;
if(!flipper_format_file_open_always(file, furi_string_get_cstr(ibutton->file_path))) break;
// Write header
if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break;
@@ -286,7 +285,7 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) {
bool ibutton_delete_key(iButton* ibutton) {
bool result = false;
result = storage_simply_remove(ibutton->storage, string_get_cstr(ibutton->file_path));
result = storage_simply_remove(ibutton->storage, furi_string_get_cstr(ibutton->file_path));
return result;
}
@@ -326,7 +325,7 @@ int32_t ibutton_app(void* p) {
rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton);
rpc_system_app_send_started(ibutton->rpc_ctx);
} else {
string_set_str(ibutton->file_path, (const char*)p);
furi_string_set(ibutton->file_path, (const char*)p);
if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) {
key_loaded = true;
// TODO: Display an error if the key from p could not be loaded

View File

@@ -6,8 +6,8 @@
#include <one_wire/ibutton/ibutton_worker.h>
#include <one_wire/one_wire_host.h>
static void ibutton_cli(Cli* cli, string_t args, void* context);
static void onewire_cli(Cli* cli, string_t args, void* context);
static void ibutton_cli(Cli* cli, FuriString* args, void* context);
static void onewire_cli(Cli* cli, FuriString* args, void* context);
// app cli function
void ibutton_on_system_start() {
@@ -34,16 +34,16 @@ void ibutton_cli_print_usage() {
printf("\t<key_data> are hex-formatted\r\n");
};
bool ibutton_cli_get_key_type(string_t data, iButtonKeyType* type) {
bool ibutton_cli_get_key_type(FuriString* data, iButtonKeyType* type) {
bool result = false;
if(string_cmp_str(data, "Dallas") == 0 || string_cmp_str(data, "dallas") == 0) {
if(furi_string_cmp_str(data, "Dallas") == 0 || furi_string_cmp_str(data, "dallas") == 0) {
result = true;
*type = iButtonKeyDS1990;
} else if(string_cmp_str(data, "Cyfral") == 0 || string_cmp_str(data, "cyfral") == 0) {
} else if(furi_string_cmp_str(data, "Cyfral") == 0 || furi_string_cmp_str(data, "cyfral") == 0) {
result = true;
*type = iButtonKeyCyfral;
} else if(string_cmp_str(data, "Metakom") == 0 || string_cmp_str(data, "metakom") == 0) {
} else if(furi_string_cmp_str(data, "Metakom") == 0 || furi_string_cmp_str(data, "metakom") == 0) {
result = true;
*type = iButtonKeyMetakom;
}
@@ -123,17 +123,17 @@ static void ibutton_cli_worker_write_cb(void* context, iButtonWorkerWriteResult
furi_event_flag_set(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE);
}
void ibutton_cli_write(Cli* cli, string_t args) {
void ibutton_cli_write(Cli* cli, FuriString* args) {
iButtonKey* key = ibutton_key_alloc();
iButtonWorker* worker = ibutton_worker_alloc();
iButtonKeyType type;
iButtonWriteContext write_context;
uint8_t key_data[IBUTTON_KEY_DATA_SIZE];
string_t data;
FuriString* data;
write_context.event = furi_event_flag_alloc();
string_init(data);
data = furi_string_alloc();
ibutton_worker_start_thread(worker);
ibutton_worker_write_set_callback(worker, ibutton_cli_worker_write_cb, &write_context);
@@ -186,7 +186,7 @@ void ibutton_cli_write(Cli* cli, string_t args) {
ibutton_worker_stop(worker);
} while(false);
string_clear(data);
furi_string_free(data);
ibutton_worker_stop_thread(worker);
ibutton_worker_free(worker);
ibutton_key_free(key);
@@ -194,14 +194,14 @@ void ibutton_cli_write(Cli* cli, string_t args) {
furi_event_flag_free(write_context.event);
};
void ibutton_cli_emulate(Cli* cli, string_t args) {
void ibutton_cli_emulate(Cli* cli, FuriString* args) {
iButtonKey* key = ibutton_key_alloc();
iButtonWorker* worker = ibutton_worker_alloc();
iButtonKeyType type;
uint8_t key_data[IBUTTON_KEY_DATA_SIZE];
string_t data;
FuriString* data;
string_init(data);
data = furi_string_alloc();
ibutton_worker_start_thread(worker);
do {
@@ -234,34 +234,34 @@ void ibutton_cli_emulate(Cli* cli, string_t args) {
ibutton_worker_stop(worker);
} while(false);
string_clear(data);
furi_string_free(data);
ibutton_worker_stop_thread(worker);
ibutton_worker_free(worker);
ibutton_key_free(key);
};
static void ibutton_cli(Cli* cli, string_t args, void* context) {
static void ibutton_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
string_t cmd;
string_init(cmd);
FuriString* cmd;
cmd = furi_string_alloc();
if(!args_read_string_and_trim(args, cmd)) {
string_clear(cmd);
furi_string_free(cmd);
ibutton_cli_print_usage();
return;
}
if(string_cmp_str(cmd, "read") == 0) {
if(furi_string_cmp_str(cmd, "read") == 0) {
ibutton_cli_read(cli);
} else if(string_cmp_str(cmd, "write") == 0) {
} else if(furi_string_cmp_str(cmd, "write") == 0) {
ibutton_cli_write(cli, args);
} else if(string_cmp_str(cmd, "emulate") == 0) {
} else if(furi_string_cmp_str(cmd, "emulate") == 0) {
ibutton_cli_emulate(cli, args);
} else {
ibutton_cli_print_usage();
}
string_clear(cmd);
furi_string_free(cmd);
}
void onewire_cli_print_usage() {
@@ -299,20 +299,20 @@ static void onewire_cli_search(Cli* cli) {
onewire_host_free(onewire);
}
void onewire_cli(Cli* cli, string_t args, void* context) {
void onewire_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
string_t cmd;
string_init(cmd);
FuriString* cmd;
cmd = furi_string_alloc();
if(!args_read_string_and_trim(args, cmd)) {
string_clear(cmd);
furi_string_free(cmd);
onewire_cli_print_usage();
return;
}
if(string_cmp_str(cmd, "search") == 0) {
if(furi_string_cmp_str(cmd, "search") == 0) {
onewire_cli_search(cli);
}
string_clear(cmd);
furi_string_free(cmd);
}

View File

@@ -41,7 +41,7 @@ struct iButton {
iButtonWorker* key_worker;
iButtonKey* key;
string_t file_path;
FuriString* file_path;
char text_store[IBUTTON_TEXT_STORE_SIZE + 1];
Submenu* submenu;
@@ -78,7 +78,7 @@ typedef enum {
} iButtonNotificationMessage;
bool ibutton_file_select(iButton* ibutton);
bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog);
bool ibutton_load_key_data(iButton* ibutton, FuriString* key_path, bool show_dialog);
bool ibutton_save_key(iButton* ibutton, const char* key_name);
bool ibutton_delete_key(iButton* ibutton);
void ibutton_text_store_set(iButton* ibutton, const char* text, ...);

View File

@@ -1,5 +1,4 @@
#include "../ibutton_i.h"
#include "m-string.h"
enum SubmenuIndex {
SubmenuIndexCyfral,
@@ -47,7 +46,7 @@ bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) {
furi_crash("Unknown key type");
}
string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER);
furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER);
ibutton_key_clear_data(key);
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue);
}

View File

@@ -17,13 +17,13 @@ void ibutton_scene_delete_confirm_on_enter(void* context) {
iButtonKey* key = ibutton->key;
const uint8_t* key_data = ibutton_key_get_data_p(key);
string_t key_name;
string_init(key_name);
FuriString* key_name;
key_name = furi_string_alloc();
path_extract_filename(ibutton->file_path, key_name, true);
ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", string_get_cstr(key_name));
ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", furi_string_get_cstr(key_name));
widget_add_text_box_element(
widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, false);
widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, true);
widget_add_button_element(
widget, GuiButtonTypeLeft, "Cancel", ibutton_scene_delete_confirm_widget_callback, ibutton);
widget_add_button_element(
@@ -47,28 +47,28 @@ void ibutton_scene_delete_confirm_on_enter(void* context) {
key_data[6],
key_data[7]);
widget_add_string_element(
widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas");
widget, 64, 34, AlignCenter, AlignBottom, FontSecondary, "Dallas");
break;
case iButtonKeyCyfral:
ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]);
widget_add_string_element(
widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral");
widget, 64, 34, AlignCenter, AlignBottom, FontSecondary, "Cyfral");
break;
case iButtonKeyMetakom:
ibutton_text_store_set(
ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]);
widget_add_string_element(
widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom");
widget, 64, 34, AlignCenter, AlignBottom, FontSecondary, "Metakom");
break;
}
widget_add_string_element(
widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store);
widget, 64, 46, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget);
string_clear(key_name);
furi_string_free(key_name);
}
bool ibutton_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) {

View File

@@ -15,31 +15,29 @@ static void ibutton_scene_emulate_callback(void* context, bool emulated) {
void ibutton_scene_emulate_on_enter(void* context) {
iButton* ibutton = context;
Popup* popup = ibutton->popup;
Widget* widget = ibutton->widget;
iButtonKey* key = ibutton->key;
const uint8_t* key_data = ibutton_key_get_data_p(key);
string_t key_name;
string_init(key_name);
if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
FuriString* key_name;
key_name = furi_string_alloc();
if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
path_extract_filename(ibutton->file_path, key_name, true);
}
uint8_t line_count = 2;
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
// check that stored key has name
if(!string_empty_p(key_name)) {
ibutton_text_store_set(ibutton, "emulating\n%s", string_get_cstr(key_name));
line_count = 2;
if(!furi_string_empty(key_name)) {
ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));
} else {
// if not, show key data
switch(ibutton_key_get_type(key)) {
case iButtonKeyDS1990:
ibutton_text_store_set(
ibutton,
"emulating\n%02X %02X %02X %02X\n%02X %02X %02X %02X",
"%02X %02X %02X %02X\n%02X %02X %02X %02X",
key_data[0],
key_data[1],
key_data[2],
@@ -48,46 +46,30 @@ void ibutton_scene_emulate_on_enter(void* context) {
key_data[5],
key_data[6],
key_data[7]);
line_count = 3;
break;
case iButtonKeyCyfral:
ibutton_text_store_set(ibutton, "emulating\n%02X %02X", key_data[0], key_data[1]);
line_count = 2;
ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]);
break;
case iButtonKeyMetakom:
ibutton_text_store_set(
ibutton,
"emulating\n%02X %02X %02X %02X",
key_data[0],
key_data[1],
key_data[2],
key_data[3]);
line_count = 2;
ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]);
break;
}
}
switch(line_count) {
case 3:
popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom);
popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop);
break;
widget_add_string_multiline_element(
widget, 90, 10, AlignCenter, AlignTop, FontPrimary, "iButton\nemulating");
widget_add_icon_element(widget, 3, 10, &I_iButtonKey_49x44);
widget_add_text_box_element(
widget, 54, 39, 75, 22, AlignCenter, AlignCenter, ibutton->text_store, true);
default:
popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom);
popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop);
break;
}
popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget);
ibutton_worker_emulate_set_callback(
ibutton->key_worker, ibutton_scene_emulate_callback, ibutton);
ibutton_worker_emulate_start(ibutton->key_worker, key);
string_clear(key_name);
furi_string_free(key_name);
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
}
@@ -122,10 +104,7 @@ bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) {
void ibutton_scene_emulate_on_exit(void* context) {
iButton* ibutton = context;
Popup* popup = ibutton->popup;
ibutton_worker_stop(ibutton->key_worker);
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
popup_set_icon(popup, 0, 0, NULL);
widget_reset(ibutton->widget);
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
}

View File

@@ -8,13 +8,13 @@ void ibutton_scene_info_on_enter(void* context) {
const uint8_t* key_data = ibutton_key_get_data_p(key);
string_t key_name;
string_init(key_name);
FuriString* key_name;
key_name = furi_string_alloc();
path_extract_filename(ibutton->file_path, key_name, true);
ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name));
ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));
widget_add_text_box_element(
widget, 0, 0, 128, 28, AlignCenter, AlignCenter, ibutton->text_store, false);
widget, 0, 0, 128, 23, AlignCenter, AlignCenter, ibutton->text_store, true);
switch(ibutton_key_get_type(key)) {
case iButtonKeyDS1990:
@@ -29,30 +29,28 @@ void ibutton_scene_info_on_enter(void* context) {
key_data[5],
key_data[6],
key_data[7]);
widget_add_string_element(
widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas");
widget_add_string_element(widget, 64, 36, AlignCenter, AlignBottom, FontPrimary, "Dallas");
break;
case iButtonKeyMetakom:
ibutton_text_store_set(
ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]);
widget_add_string_element(
widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom");
widget, 64, 36, AlignCenter, AlignBottom, FontPrimary, "Metakom");
break;
case iButtonKeyCyfral:
ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]);
widget_add_string_element(
widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral");
widget_add_string_element(widget, 64, 36, AlignCenter, AlignBottom, FontPrimary, "Cyfral");
break;
}
widget_add_string_element(
widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, ibutton->text_store);
widget, 64, 50, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget);
string_clear(key_name);
furi_string_free(key_name);
}
bool ibutton_scene_info_on_event(void* context, SceneManagerEvent event) {

View File

@@ -18,7 +18,7 @@ void ibutton_scene_read_on_enter(void* context) {
popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER);
furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER);
ibutton_worker_read_set_callback(worker, ibutton_scene_read_callback, ibutton);
ibutton_worker_read_start(worker, key);

View File

@@ -29,19 +29,19 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
if(event.event == iButtonCustomEventRpcLoad) {
const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx);
bool result = false;
if(arg && (string_empty_p(ibutton->file_path))) {
string_set_str(ibutton->file_path, arg);
if(arg && (furi_string_empty(ibutton->file_path))) {
furi_string_set(ibutton->file_path, arg);
if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) {
ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key);
string_t key_name;
string_init(key_name);
if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
FuriString* key_name;
key_name = furi_string_alloc();
if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
path_extract_filename(ibutton->file_path, key_name, true);
}
if(!string_empty_p(key_name)) {
if(!furi_string_empty(key_name)) {
ibutton_text_store_set(
ibutton, "emulating\n%s", string_get_cstr(key_name));
ibutton, "emulating\n%s", furi_string_get_cstr(key_name));
} else {
ibutton_text_store_set(ibutton, "emulating");
}
@@ -49,10 +49,10 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
string_clear(key_name);
furi_string_free(key_name);
result = true;
} else {
string_reset(ibutton->file_path);
furi_string_reset(ibutton->file_path);
}
}
rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result);

View File

@@ -1,5 +1,4 @@
#include "../ibutton_i.h"
#include "m-string.h"
#include <lib/toolbox/random_name.h>
#include <toolbox/path.h>
@@ -12,17 +11,17 @@ void ibutton_scene_save_name_on_enter(void* context) {
iButton* ibutton = context;
TextInput* text_input = ibutton->text_input;
string_t key_name;
string_init(key_name);
if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
FuriString* key_name;
key_name = furi_string_alloc();
if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
path_extract_filename(ibutton->file_path, key_name, true);
}
const bool key_name_is_empty = string_empty_p(key_name);
const bool key_name_is_empty = furi_string_empty(key_name);
if(key_name_is_empty) {
set_random_name(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE);
} else {
ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name));
ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));
}
text_input_set_header_text(text_input, "Name the key");
@@ -34,19 +33,19 @@ void ibutton_scene_save_name_on_enter(void* context) {
IBUTTON_KEY_NAME_SIZE,
key_name_is_empty);
string_t folder_path;
string_init(folder_path);
FuriString* folder_path;
folder_path = furi_string_alloc();
path_extract_dirname(string_get_cstr(ibutton->file_path), folder_path);
path_extract_dirname(furi_string_get_cstr(ibutton->file_path), folder_path);
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, string_get_cstr(key_name));
furi_string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, furi_string_get_cstr(key_name));
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput);
string_clear(key_name);
string_clear(folder_path);
furi_string_free(key_name);
furi_string_free(folder_path);
}
bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) {

View File

@@ -29,10 +29,8 @@ bool ibutton_scene_save_success_on_event(void* context, SceneManagerEvent event)
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == iButtonCustomEventBack) {
const uint32_t possible_scenes[] = {
iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType};
scene_manager_search_and_switch_to_previous_scene_one_of(
ibutton->scene_manager, possible_scenes, COUNT_OF(possible_scenes));
scene_manager_search_and_switch_to_another_scene(
ibutton->scene_manager, iButtonSceneSelectKey);
}
}

View File

@@ -39,7 +39,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) {
if(event.event == SubmenuIndexRead) {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead);
} else if(event.event == SubmenuIndexSaved) {
string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER);
furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER);
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey);
} else if(event.event == SubmenuIndexAdd) {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddType);

View File

@@ -1,5 +1,4 @@
#include "../ibutton_i.h"
#include "m-string.h"
#include "toolbox/path.h"
typedef enum {
@@ -14,31 +13,28 @@ static void ibutton_scene_write_callback(void* context, iButtonWorkerWriteResult
void ibutton_scene_write_on_enter(void* context) {
iButton* ibutton = context;
Popup* popup = ibutton->popup;
iButtonKey* key = ibutton->key;
Widget* widget = ibutton->widget;
iButtonWorker* worker = ibutton->key_worker;
const uint8_t* key_data = ibutton_key_get_data_p(key);
string_t key_name;
string_init(key_name);
if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
FuriString* key_name;
key_name = furi_string_alloc();
if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
path_extract_filename(ibutton->file_path, key_name, true);
}
uint8_t line_count = 2;
// check that stored key has name
if(!string_empty_p(key_name)) {
ibutton_text_store_set(ibutton, "writing\n%s", string_get_cstr(key_name));
line_count = 2;
if(!furi_string_empty(key_name)) {
ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));
} else {
// if not, show key data
switch(ibutton_key_get_type(key)) {
case iButtonKeyDS1990:
ibutton_text_store_set(
ibutton,
"writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X",
"%02X %02X %02X %02X\n%02X %02X %02X %02X",
key_data[0],
key_data[1],
key_data[2],
@@ -47,45 +43,29 @@ void ibutton_scene_write_on_enter(void* context) {
key_data[5],
key_data[6],
key_data[7]);
line_count = 3;
break;
case iButtonKeyCyfral:
ibutton_text_store_set(ibutton, "writing\n%02X %02X", key_data[0], key_data[1]);
line_count = 2;
ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]);
break;
case iButtonKeyMetakom:
ibutton_text_store_set(
ibutton,
"writing\n%02X %02X %02X %02X",
key_data[0],
key_data[1],
key_data[2],
key_data[3]);
line_count = 2;
ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]);
break;
}
}
switch(line_count) {
case 3:
popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom);
popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop);
break;
widget_add_string_multiline_element(
widget, 90, 10, AlignCenter, AlignTop, FontPrimary, "iButton\nwriting");
widget_add_icon_element(widget, 3, 10, &I_iButtonKey_49x44);
widget_add_text_box_element(
widget, 54, 39, 75, 22, AlignCenter, AlignCenter, ibutton->text_store, true);
default:
popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom);
popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop);
break;
}
popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget);
ibutton_worker_write_set_callback(worker, ibutton_scene_write_callback, ibutton);
ibutton_worker_write_start(worker, key);
string_clear(key_name);
furi_string_free(key_name);
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
}
@@ -114,11 +94,8 @@ bool ibutton_scene_write_on_event(void* context, SceneManagerEvent event) {
void ibutton_scene_write_on_exit(void* context) {
iButton* ibutton = context;
Popup* popup = ibutton->popup;
ibutton_worker_stop(ibutton->key_worker);
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
popup_set_icon(popup, 0, 0, NULL);
widget_reset(ibutton->widget);
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
}

View File

@@ -65,51 +65,52 @@ static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context
}
}
static void infrared_find_vacant_remote_name(string_t name, const char* path) {
static void infrared_find_vacant_remote_name(FuriString* name, const char* path) {
Storage* storage = furi_record_open(RECORD_STORAGE);
string_t base_path;
string_init_set_str(base_path, path);
FuriString* base_path;
base_path = furi_string_alloc_set(path);
if(string_end_with_str_p(base_path, INFRARED_APP_EXTENSION)) {
size_t filename_start = string_search_rchar(base_path, '/');
string_left(base_path, filename_start);
if(furi_string_end_with(base_path, INFRARED_APP_EXTENSION)) {
size_t filename_start = furi_string_search_rchar(base_path, '/');
furi_string_left(base_path, filename_start);
}
string_printf(base_path, "%s/%s%s", path, string_get_cstr(name), INFRARED_APP_EXTENSION);
furi_string_printf(
base_path, "%s/%s%s", path, furi_string_get_cstr(name), INFRARED_APP_EXTENSION);
FS_Error status = storage_common_stat(storage, string_get_cstr(base_path), NULL);
FS_Error status = storage_common_stat(storage, furi_string_get_cstr(base_path), NULL);
if(status == FSE_OK) {
/* If the suggested name is occupied, try another one (name2, name3, etc) */
size_t dot = string_search_rchar(base_path, '.');
string_left(base_path, dot);
size_t dot = furi_string_search_rchar(base_path, '.');
furi_string_left(base_path, dot);
string_t path_temp;
string_init(path_temp);
FuriString* path_temp;
path_temp = furi_string_alloc();
uint32_t i = 1;
do {
string_printf(
path_temp, "%s%u%s", string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION);
status = storage_common_stat(storage, string_get_cstr(path_temp), NULL);
furi_string_printf(
path_temp, "%s%u%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION);
status = storage_common_stat(storage, furi_string_get_cstr(path_temp), NULL);
} while(status == FSE_OK);
string_clear(path_temp);
furi_string_free(path_temp);
if(status == FSE_NOT_EXIST) {
string_cat_printf(name, "%u", i);
furi_string_cat_printf(name, "%u", i);
}
}
string_clear(base_path);
furi_string_free(base_path);
furi_record_close(RECORD_STORAGE);
}
static Infrared* infrared_alloc() {
Infrared* infrared = malloc(sizeof(Infrared));
string_init(infrared->file_path);
infrared->file_path = furi_string_alloc();
InfraredAppState* app_state = &infrared->app_state;
app_state->is_learning_new_remote = false;
@@ -232,7 +233,7 @@ static void infrared_free(Infrared* infrared) {
furi_record_close(RECORD_GUI);
infrared->gui = NULL;
string_clear(infrared->file_path);
furi_string_free(infrared->file_path);
free(infrared);
}
@@ -243,19 +244,20 @@ bool infrared_add_remote_with_button(
InfraredSignal* signal) {
InfraredRemote* remote = infrared->remote;
string_t new_name, new_path;
string_init_set_str(new_name, INFRARED_DEFAULT_REMOTE_NAME);
string_init_set_str(new_path, INFRARED_APP_FOLDER);
FuriString *new_name, *new_path;
new_name = furi_string_alloc_set(INFRARED_DEFAULT_REMOTE_NAME);
new_path = furi_string_alloc_set(INFRARED_APP_FOLDER);
infrared_find_vacant_remote_name(new_name, string_get_cstr(new_path));
string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION);
infrared_find_vacant_remote_name(new_name, furi_string_get_cstr(new_path));
furi_string_cat_printf(
new_path, "/%s%s", furi_string_get_cstr(new_name), INFRARED_APP_EXTENSION);
infrared_remote_reset(remote);
infrared_remote_set_name(remote, string_get_cstr(new_name));
infrared_remote_set_path(remote, string_get_cstr(new_path));
infrared_remote_set_name(remote, furi_string_get_cstr(new_name));
infrared_remote_set_path(remote, furi_string_get_cstr(new_path));
string_clear(new_name);
string_clear(new_path);
furi_string_free(new_name);
furi_string_free(new_path);
return infrared_remote_add_button(remote, button_name, signal);
}
@@ -267,28 +269,29 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) {
return true;
}
string_t new_name;
string_init_set_str(new_name, name);
FuriString* new_name;
new_name = furi_string_alloc_set(name);
infrared_find_vacant_remote_name(new_name, remote_path);
string_t new_path;
string_init_set(new_path, infrared_remote_get_path(remote));
if(string_end_with_str_p(new_path, INFRARED_APP_EXTENSION)) {
size_t filename_start = string_search_rchar(new_path, '/');
string_left(new_path, filename_start);
FuriString* new_path;
new_path = furi_string_alloc_set(infrared_remote_get_path(remote));
if(furi_string_end_with(new_path, INFRARED_APP_EXTENSION)) {
size_t filename_start = furi_string_search_rchar(new_path, '/');
furi_string_left(new_path, filename_start);
}
string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION);
furi_string_cat_printf(
new_path, "/%s%s", furi_string_get_cstr(new_name), INFRARED_APP_EXTENSION);
Storage* storage = furi_record_open(RECORD_STORAGE);
FS_Error status = storage_common_rename(
storage, infrared_remote_get_path(remote), string_get_cstr(new_path));
infrared_remote_set_name(remote, string_get_cstr(new_name));
infrared_remote_set_path(remote, string_get_cstr(new_path));
storage, infrared_remote_get_path(remote), furi_string_get_cstr(new_path));
infrared_remote_set_name(remote, furi_string_get_cstr(new_name));
infrared_remote_set_path(remote, furi_string_get_cstr(new_path));
string_clear(new_name);
string_clear(new_path);
furi_string_free(new_name);
furi_string_free(new_path);
furi_record_close(RECORD_STORAGE);
return (status == FSE_OK || status == FSE_EXIST);
@@ -435,7 +438,7 @@ int32_t infrared_app(void* p) {
rpc_system_app_send_started(infrared->rpc_ctx);
is_rpc_mode = true;
} else {
string_set_str(infrared->file_path, (const char*)p);
furi_string_set(infrared->file_path, (const char*)p);
is_remote_loaded = infrared_remote_load(infrared->remote, infrared->file_path);
if(!is_remote_loaded) {
dialog_message_show_storage_error(

View File

@@ -2,7 +2,6 @@
#include <stdlib.h>
#include <m-dict.h>
#include <m-string.h>
#include <flipper_format/flipper_format.h>
#include "infrared_signal.h"
@@ -14,43 +13,50 @@ typedef struct {
DICT_DEF2(
InfraredBruteForceRecordDict,
string_t,
STRING_OPLIST,
FuriString*,
FURI_STRING_OPLIST,
InfraredBruteForceRecord,
M_POD_OPLIST);
struct InfraredBruteForce {
FlipperFormat* ff;
const char* db_filename;
string_t current_record_name;
FuriString* current_record_name;
InfraredSignal* current_signal;
InfraredBruteForceRecordDict_t records;
bool is_started;
};
InfraredBruteForce* infrared_brute_force_alloc() {
InfraredBruteForce* brute_force = malloc(sizeof(InfraredBruteForce));
brute_force->ff = NULL;
brute_force->db_filename = NULL;
string_init(brute_force->current_record_name);
brute_force->current_signal = NULL;
brute_force->is_started = false;
brute_force->current_record_name = furi_string_alloc();
InfraredBruteForceRecordDict_init(brute_force->records);
return brute_force;
}
void infrared_brute_force_clear_records(InfraredBruteForce* brute_force) {
furi_assert(!brute_force->is_started);
InfraredBruteForceRecordDict_reset(brute_force->records);
}
void infrared_brute_force_free(InfraredBruteForce* brute_force) {
furi_assert(!brute_force->ff);
furi_assert(!brute_force->is_started);
InfraredBruteForceRecordDict_clear(brute_force->records);
string_clear(brute_force->current_record_name);
furi_string_free(brute_force->current_record_name);
free(brute_force);
}
void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const char* db_filename) {
furi_assert(!brute_force->is_started);
brute_force->db_filename = db_filename;
}
bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) {
furi_assert(!brute_force->is_started);
furi_assert(brute_force->db_filename);
bool success = false;
@@ -59,8 +65,8 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) {
success = flipper_format_buffered_file_open_existing(ff, brute_force->db_filename);
if(success) {
string_t signal_name;
string_init(signal_name);
FuriString* signal_name;
signal_name = furi_string_alloc();
while(flipper_format_read_string(ff, "name", signal_name)) {
InfraredBruteForceRecord* record =
InfraredBruteForceRecordDict_get(brute_force->records, signal_name);
@@ -68,7 +74,7 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) {
++(record->count);
}
}
string_clear(signal_name);
furi_string_free(signal_name);
}
flipper_format_free(ff);
@@ -80,6 +86,7 @@ bool infrared_brute_force_start(
InfraredBruteForce* brute_force,
uint32_t index,
uint32_t* record_count) {
furi_assert(!brute_force->is_started);
bool success = false;
*record_count = 0;
@@ -91,7 +98,7 @@ bool infrared_brute_force_start(
if(record->value.index == index) {
*record_count = record->value.count;
if(*record_count) {
string_set(brute_force->current_record_name, record->key);
furi_string_set(brute_force->current_record_name, record->key);
}
break;
}
@@ -100,50 +107,37 @@ bool infrared_brute_force_start(
if(*record_count) {
Storage* storage = furi_record_open(RECORD_STORAGE);
brute_force->ff = flipper_format_buffered_file_alloc(storage);
brute_force->current_signal = infrared_signal_alloc();
brute_force->is_started = true;
success =
flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename);
if(!success) {
flipper_format_free(brute_force->ff);
brute_force->ff = NULL;
furi_record_close(RECORD_STORAGE);
}
if(!success) infrared_brute_force_stop(brute_force);
}
return success;
}
bool infrared_brute_force_is_started(InfraredBruteForce* brute_force) {
return brute_force->ff;
return brute_force->is_started;
}
void infrared_brute_force_stop(InfraredBruteForce* brute_force) {
furi_assert(string_size(brute_force->current_record_name));
furi_assert(brute_force->ff);
string_reset(brute_force->current_record_name);
furi_assert(brute_force->is_started);
furi_string_reset(brute_force->current_record_name);
infrared_signal_free(brute_force->current_signal);
flipper_format_free(brute_force->ff);
furi_record_close(RECORD_STORAGE);
brute_force->current_signal = NULL;
brute_force->ff = NULL;
brute_force->is_started = false;
furi_record_close(RECORD_STORAGE);
}
bool infrared_brute_force_send_next(InfraredBruteForce* brute_force) {
furi_assert(string_size(brute_force->current_record_name));
furi_assert(brute_force->ff);
bool success = false;
string_t signal_name;
string_init(signal_name);
InfraredSignal* signal = infrared_signal_alloc();
do {
success = infrared_signal_read(signal, brute_force->ff, signal_name);
} while(success && !string_equal_p(brute_force->current_record_name, signal_name));
furi_assert(brute_force->is_started);
const bool success = infrared_signal_search_and_read(
brute_force->current_signal, brute_force->ff, brute_force->current_record_name);
if(success) {
infrared_signal_transmit(signal);
infrared_signal_transmit(brute_force->current_signal);
}
infrared_signal_free(signal);
string_clear(signal_name);
return success;
}
@@ -152,8 +146,8 @@ void infrared_brute_force_add_record(
uint32_t index,
const char* name) {
InfraredBruteForceRecord value = {.index = index, .count = 0};
string_t key;
string_init_set_str(key, name);
FuriString* key;
key = furi_string_alloc_set(name);
InfraredBruteForceRecordDict_set_at(brute_force->records, key, value);
string_clear(key);
furi_string_free(key);
}

View File

@@ -1,4 +1,3 @@
#include <m-string.h>
#include <cli/cli.h>
#include <infrared.h>
#include <infrared_worker.h>
@@ -10,13 +9,13 @@
#define INFRARED_CLI_BUF_SIZE 10
static void infrared_cli_start_ir_rx(Cli* cli, string_t args);
static void infrared_cli_start_ir_tx(Cli* cli, string_t args);
static void infrared_cli_process_decode(Cli* cli, string_t args);
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args);
static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args);
static void infrared_cli_process_decode(Cli* cli, FuriString* args);
static const struct {
const char* cmd;
void (*process_function)(Cli* cli, string_t args);
void (*process_function)(Cli* cli, FuriString* args);
} infrared_cli_commands[] = {
{.cmd = "rx", .process_function = infrared_cli_start_ir_rx},
{.cmd = "tx", .process_function = infrared_cli_start_ir_tx},
@@ -58,7 +57,7 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv
}
}
static void infrared_cli_start_ir_rx(Cli* cli, string_t args) {
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args) {
UNUSED(cli);
UNUSED(args);
InfraredWorker* worker = infrared_worker_alloc();
@@ -151,9 +150,9 @@ static bool infrared_cli_parse_raw(const char* str, InfraredSignal* signal) {
return infrared_signal_is_valid(signal);
}
static void infrared_cli_start_ir_tx(Cli* cli, string_t args) {
static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args) {
UNUSED(cli);
const char* str = string_get_cstr(args);
const char* str = furi_string_get_cstr(args);
InfraredSignal* signal = infrared_signal_alloc();
bool success = infrared_cli_parse_message(str, signal) || infrared_cli_parse_raw(str, signal);
@@ -231,8 +230,8 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o
InfraredSignal* signal = infrared_signal_alloc();
InfraredDecoderHandler* decoder = infrared_alloc_decoder();
string_t tmp;
string_init(tmp);
FuriString* tmp;
tmp = furi_string_alloc();
while(infrared_signal_read(signal, input_file, tmp)) {
ret = false;
@@ -242,7 +241,7 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o
}
if(!infrared_signal_is_raw(signal)) {
if(output_file &&
!infrared_cli_save_signal(signal, output_file, string_get_cstr(tmp))) {
!infrared_cli_save_signal(signal, output_file, furi_string_get_cstr(tmp))) {
break;
} else {
printf("Skipping decoded signal\r\n");
@@ -250,31 +249,33 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o
}
}
InfraredRawSignal* raw_signal = infrared_signal_get_raw_signal(signal);
printf("Raw signal: %s, %u samples\r\n", string_get_cstr(tmp), raw_signal->timings_size);
if(!infrared_cli_decode_raw_signal(raw_signal, decoder, output_file, string_get_cstr(tmp)))
printf(
"Raw signal: %s, %u samples\r\n", furi_string_get_cstr(tmp), raw_signal->timings_size);
if(!infrared_cli_decode_raw_signal(
raw_signal, decoder, output_file, furi_string_get_cstr(tmp)))
break;
ret = true;
}
infrared_free_decoder(decoder);
infrared_signal_free(signal);
string_clear(tmp);
furi_string_free(tmp);
return ret;
}
static void infrared_cli_process_decode(Cli* cli, string_t args) {
static void infrared_cli_process_decode(Cli* cli, FuriString* args) {
UNUSED(cli);
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* input_file = flipper_format_buffered_file_alloc(storage);
FlipperFormat* output_file = NULL;
uint32_t version;
string_t tmp, header, input_path, output_path;
string_init(tmp);
string_init(header);
string_init(input_path);
string_init(output_path);
FuriString *tmp, *header, *input_path, *output_path;
tmp = furi_string_alloc();
header = furi_string_alloc();
input_path = furi_string_alloc();
output_path = furi_string_alloc();
do {
if(!args_read_probably_quoted_string_and_trim(args, input_path)) {
@@ -283,26 +284,32 @@ static void infrared_cli_process_decode(Cli* cli, string_t args) {
break;
}
args_read_probably_quoted_string_and_trim(args, output_path);
if(!flipper_format_buffered_file_open_existing(input_file, string_get_cstr(input_path))) {
printf("Failed to open file for reading: \"%s\"\r\n", string_get_cstr(input_path));
if(!flipper_format_buffered_file_open_existing(
input_file, furi_string_get_cstr(input_path))) {
printf(
"Failed to open file for reading: \"%s\"\r\n", furi_string_get_cstr(input_path));
break;
}
if(!flipper_format_read_header(input_file, header, &version) ||
(!string_start_with_str_p(header, "IR")) || version != 1) {
printf("Invalid or corrupted input file: \"%s\"\r\n", string_get_cstr(input_path));
(!furi_string_start_with_str(header, "IR")) || version != 1) {
printf(
"Invalid or corrupted input file: \"%s\"\r\n", furi_string_get_cstr(input_path));
break;
}
if(!string_empty_p(output_path)) {
printf("Writing output to file: \"%s\"\r\n", string_get_cstr(output_path));
if(!furi_string_empty(output_path)) {
printf("Writing output to file: \"%s\"\r\n", furi_string_get_cstr(output_path));
output_file = flipper_format_file_alloc(storage);
}
if(output_file &&
!flipper_format_file_open_always(output_file, string_get_cstr(output_path))) {
printf("Failed to open file for writing: \"%s\"\r\n", string_get_cstr(output_path));
!flipper_format_file_open_always(output_file, furi_string_get_cstr(output_path))) {
printf(
"Failed to open file for writing: \"%s\"\r\n", furi_string_get_cstr(output_path));
break;
}
if(output_file && !flipper_format_write_header(output_file, header, version)) {
printf("Failed to write to the output file: \"%s\"\r\n", string_get_cstr(output_path));
printf(
"Failed to write to the output file: \"%s\"\r\n",
furi_string_get_cstr(output_path));
break;
}
if(!infrared_cli_decode_file(input_file, output_file)) {
@@ -311,31 +318,31 @@ static void infrared_cli_process_decode(Cli* cli, string_t args) {
printf("File successfully decoded.\r\n");
} while(false);
string_clear(tmp);
string_clear(header);
string_clear(input_path);
string_clear(output_path);
furi_string_free(tmp);
furi_string_free(header);
furi_string_free(input_path);
furi_string_free(output_path);
flipper_format_free(input_file);
if(output_file) flipper_format_free(output_file);
furi_record_close(RECORD_STORAGE);
}
static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) {
static void infrared_cli_start_ir(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
if(furi_hal_infrared_is_busy()) {
printf("INFRARED is busy. Exiting.");
return;
}
string_t command;
string_init(command);
FuriString* command;
command = furi_string_alloc();
args_read_string_and_trim(args, command);
size_t i = 0;
for(; i < COUNT_OF(infrared_cli_commands); ++i) {
size_t cmd_len = strlen(infrared_cli_commands[i].cmd);
if(!strncmp(string_get_cstr(command), infrared_cli_commands[i].cmd, cmd_len)) {
if(!strncmp(furi_string_get_cstr(command), infrared_cli_commands[i].cmd, cmd_len)) {
break;
}
}
@@ -346,7 +353,7 @@ static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) {
infrared_cli_print_usage();
}
string_clear(command);
furi_string_free(command);
}
void infrared_on_system_start() {
#ifdef SRV_CLI

View File

@@ -96,7 +96,7 @@ struct Infrared {
Loading* loading;
InfraredProgressView* progress;
string_t file_path;
FuriString* file_path;
char text_store[INFRARED_TEXT_STORE_NUM][INFRARED_TEXT_STORE_SIZE + 1];
InfraredAppState app_state;

View File

@@ -3,7 +3,6 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <m-string.h>
#include <m-array.h>
#include <toolbox/path.h>
#include <storage/storage.h>
@@ -15,8 +14,8 @@ ARRAY_DEF(InfraredButtonArray, InfraredRemoteButton*, M_PTR_OPLIST);
struct InfraredRemote {
InfraredButtonArray_t buttons;
string_t name;
string_t path;
FuriString* name;
FuriString* path;
};
static void infrared_remote_clear_buttons(InfraredRemote* remote) {
@@ -31,39 +30,39 @@ static void infrared_remote_clear_buttons(InfraredRemote* remote) {
InfraredRemote* infrared_remote_alloc() {
InfraredRemote* remote = malloc(sizeof(InfraredRemote));
InfraredButtonArray_init(remote->buttons);
string_init(remote->name);
string_init(remote->path);
remote->name = furi_string_alloc();
remote->path = furi_string_alloc();
return remote;
}
void infrared_remote_free(InfraredRemote* remote) {
infrared_remote_clear_buttons(remote);
InfraredButtonArray_clear(remote->buttons);
string_clear(remote->path);
string_clear(remote->name);
furi_string_free(remote->path);
furi_string_free(remote->name);
free(remote);
}
void infrared_remote_reset(InfraredRemote* remote) {
infrared_remote_clear_buttons(remote);
string_reset(remote->name);
string_reset(remote->path);
furi_string_reset(remote->name);
furi_string_reset(remote->path);
}
void infrared_remote_set_name(InfraredRemote* remote, const char* name) {
string_set_str(remote->name, name);
furi_string_set(remote->name, name);
}
const char* infrared_remote_get_name(InfraredRemote* remote) {
return string_get_cstr(remote->name);
return furi_string_get_cstr(remote->name);
}
void infrared_remote_set_path(InfraredRemote* remote, const char* path) {
string_set_str(remote->path, path);
furi_string_set(remote->path, path);
}
const char* infrared_remote_get_path(InfraredRemote* remote) {
return string_get_cstr(remote->path);
return furi_string_get_cstr(remote->path);
}
size_t infrared_remote_get_button_count(InfraredRemote* remote) {
@@ -112,7 +111,7 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) {
bool infrared_remote_store(InfraredRemote* remote) {
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* ff = flipper_format_file_alloc(storage);
const char* path = string_get_cstr(remote->path);
const char* path = furi_string_get_cstr(remote->path);
FURI_LOG_I(TAG, "store file: \'%s\'", path);
@@ -138,33 +137,33 @@ bool infrared_remote_store(InfraredRemote* remote) {
return success;
}
bool infrared_remote_load(InfraredRemote* remote, string_t path) {
bool infrared_remote_load(InfraredRemote* remote, FuriString* path) {
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* ff = flipper_format_buffered_file_alloc(storage);
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
FURI_LOG_I(TAG, "load file: \'%s\'", string_get_cstr(path));
bool success = flipper_format_buffered_file_open_existing(ff, string_get_cstr(path));
FURI_LOG_I(TAG, "load file: \'%s\'", furi_string_get_cstr(path));
bool success = flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path));
if(success) {
uint32_t version;
success = flipper_format_read_header(ff, buf, &version) &&
!string_cmp_str(buf, "IR signals file") && (version == 1);
!furi_string_cmp(buf, "IR signals file") && (version == 1);
}
if(success) {
path_extract_filename(path, buf, true);
infrared_remote_clear_buttons(remote);
infrared_remote_set_name(remote, string_get_cstr(buf));
infrared_remote_set_path(remote, string_get_cstr(path));
infrared_remote_set_name(remote, furi_string_get_cstr(buf));
infrared_remote_set_path(remote, furi_string_get_cstr(path));
for(bool can_read = true; can_read;) {
InfraredRemoteButton* button = infrared_remote_button_alloc();
can_read = infrared_signal_read(infrared_remote_button_get_signal(button), ff, buf);
if(can_read) {
infrared_remote_button_set_name(button, string_get_cstr(buf));
infrared_remote_button_set_name(button, furi_string_get_cstr(buf));
InfraredButtonArray_push_back(remote->buttons, button);
} else {
infrared_remote_button_free(button);
@@ -172,7 +171,7 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) {
}
}
string_clear(buf);
furi_string_free(buf);
flipper_format_free(ff);
furi_record_close(RECORD_STORAGE);
return success;
@@ -181,7 +180,7 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) {
bool infrared_remote_remove(InfraredRemote* remote) {
Storage* storage = furi_record_open(RECORD_STORAGE);
FS_Error status = storage_common_remove(storage, string_get_cstr(remote->path));
FS_Error status = storage_common_remove(storage, furi_string_get_cstr(remote->path));
infrared_remote_reset(remote);
furi_record_close(RECORD_STORAGE);

View File

@@ -25,5 +25,5 @@ bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name,
bool infrared_remote_delete_button(InfraredRemote* remote, size_t index);
bool infrared_remote_store(InfraredRemote* remote);
bool infrared_remote_load(InfraredRemote* remote, string_t path);
bool infrared_remote_load(InfraredRemote* remote, FuriString* path);
bool infrared_remote_remove(InfraredRemote* remote);

View File

@@ -1,32 +1,31 @@
#include "infrared_remote_button.h"
#include <stdlib.h>
#include <m-string.h>
struct InfraredRemoteButton {
string_t name;
FuriString* name;
InfraredSignal* signal;
};
InfraredRemoteButton* infrared_remote_button_alloc() {
InfraredRemoteButton* button = malloc(sizeof(InfraredRemoteButton));
string_init(button->name);
button->name = furi_string_alloc();
button->signal = infrared_signal_alloc();
return button;
}
void infrared_remote_button_free(InfraredRemoteButton* button) {
string_clear(button->name);
furi_string_free(button->name);
infrared_signal_free(button->signal);
free(button);
}
void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name) {
string_set_str(button->name, name);
furi_string_set(button->name, name);
}
const char* infrared_remote_button_get_name(InfraredRemoteButton* button) {
return string_get_cstr(button->name);
return furi_string_get_cstr(button->name);
}
void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal) {

View File

@@ -100,15 +100,15 @@ static inline bool infrared_signal_save_raw(InfraredRawSignal* raw, FlipperForma
}
static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperFormat* ff) {
string_t buf;
string_init(buf);
FuriString* buf;
buf = furi_string_alloc();
bool success = false;
do {
if(!flipper_format_read_string(ff, "protocol", buf)) break;
InfraredMessage message;
message.protocol = infrared_get_protocol_by_name(string_get_cstr(buf));
message.protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf));
success = flipper_format_read_hex(ff, "address", (uint8_t*)&message.address, 4) &&
flipper_format_read_hex(ff, "command", (uint8_t*)&message.command, 4) &&
@@ -119,7 +119,7 @@ static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperF
infrared_signal_set_message(signal, &message);
} while(0);
string_clear(buf);
furi_string_free(buf);
return success;
}
@@ -146,6 +146,26 @@ static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperForma
return success;
}
static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) {
FuriString* tmp = furi_string_alloc();
bool success = false;
do {
if(!flipper_format_read_string(ff, "type", tmp)) break;
if(furi_string_equal(tmp, "raw")) {
success = infrared_signal_read_raw(signal, ff);
} else if(furi_string_equal(tmp, "parsed")) {
success = infrared_signal_read_message(signal, ff);
} else {
FURI_LOG_E(TAG, "Unknown signal type");
}
} while(false);
furi_string_free(tmp);
return success;
}
InfraredSignal* infrared_signal_alloc() {
InfraredSignal* signal = malloc(sizeof(InfraredSignal));
@@ -226,25 +246,41 @@ bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char*
}
}
bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name) {
string_t buf;
string_init(buf);
bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name) {
FuriString* tmp = furi_string_alloc();
bool success = false;
do {
if(!flipper_format_read_string(ff, "name", buf)) break;
string_set(name, buf);
if(!flipper_format_read_string(ff, "type", buf)) break;
if(!string_cmp_str(buf, "raw")) {
success = infrared_signal_read_raw(signal, ff);
} else if(!string_cmp_str(buf, "parsed")) {
success = infrared_signal_read_message(signal, ff);
} else {
FURI_LOG_E(TAG, "Unknown type of signal (allowed - raw/parsed) ");
}
if(!flipper_format_read_string(ff, "name", tmp)) break;
furi_string_set(name, tmp);
if(!infrared_signal_read_body(signal, ff)) break;
success = true;
} while(0);
string_clear(buf);
furi_string_free(tmp);
return success;
}
bool infrared_signal_search_and_read(
InfraredSignal* signal,
FlipperFormat* ff,
const FuriString* name) {
bool success = false;
FuriString* tmp = furi_string_alloc();
do {
bool is_name_found = false;
while(flipper_format_read_string(ff, "name", tmp)) {
is_name_found = furi_string_equal(name, tmp);
if(is_name_found) break;
}
if(!is_name_found) break;
if(!infrared_signal_read_body(signal, ff)) break;
success = true;
} while(false);
furi_string_free(tmp);
return success;
}

View File

@@ -36,6 +36,10 @@ void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage*
InfraredMessage* infrared_signal_get_message(InfraredSignal* signal);
bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name);
bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name);
bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name);
bool infrared_signal_search_and_read(
InfraredSignal* signal,
FlipperFormat* ff,
const FuriString* name);
void infrared_signal_transmit(InfraredSignal* signal);

View File

@@ -33,8 +33,6 @@ static void infrared_scene_universal_common_hide_popup(Infrared* infrared) {
void infrared_scene_universal_common_on_enter(void* context) {
Infrared* infrared = context;
infrared_brute_force_clear_records(infrared->brute_force);
button_panel_reset_selection(infrared->button_panel);
view_stack_add_view(infrared->view_stack, button_panel_get_view(infrared->button_panel));
}
@@ -89,5 +87,6 @@ void infrared_scene_universal_common_on_exit(void* context) {
Infrared* infrared = context;
ButtonPanel* button_panel = infrared->button_panel;
view_stack_remove_view(infrared->view_stack, button_panel_get_view(button_panel));
infrared_brute_force_clear_records(infrared->brute_force);
button_panel_reset(button_panel);
}

View File

@@ -29,20 +29,20 @@ void infrared_scene_edit_rename_on_enter(void* context) {
enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH;
strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length);
string_t folder_path;
string_init(folder_path);
FuriString* folder_path;
folder_path = furi_string_alloc();
if(string_end_with_str_p(infrared->file_path, INFRARED_APP_EXTENSION)) {
path_extract_dirname(string_get_cstr(infrared->file_path), folder_path);
if(furi_string_end_with(infrared->file_path, INFRARED_APP_EXTENSION)) {
path_extract_dirname(furi_string_get_cstr(infrared->file_path), folder_path);
}
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
string_get_cstr(folder_path),
furi_string_get_cstr(folder_path),
INFRARED_APP_EXTENSION,
infrared_remote_get_name(remote));
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
string_clear(folder_path);
furi_string_free(folder_path);
} else {
furi_assert(0);
}

View File

@@ -50,8 +50,10 @@ bool infrared_scene_learn_enter_name_on_event(void* context, SceneManagerEvent e
if(success) {
scene_manager_next_scene(scene_manager, InfraredSceneLearnDone);
} else {
scene_manager_search_and_switch_to_previous_scene(
scene_manager, InfraredSceneRemoteList);
dialog_message_show_storage_error(infrared->dialogs, "Failed to save file");
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
scene_manager_search_and_switch_to_previous_scene_one_of(
scene_manager, possible_scenes, COUNT_OF(possible_scenes));
}
consumed = true;
}

View File

@@ -42,7 +42,7 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
bool result = false;
const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
if(arg && (state == InfraredRpcStateIdle)) {
string_set_str(infrared->file_path, arg);
furi_string_set(infrared->file_path, arg);
result = infrared_remote_load(infrared->remote, infrared->file_path);
if(result) {
scene_manager_set_scene_state(

View File

@@ -66,7 +66,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(scene_manager, InfraredSceneLearn);
consumed = true;
} else if(submenu_index == SubmenuIndexSavedRemotes) {
string_set_str(infrared->file_path, INFRARED_APP_FOLDER);
furi_string_set(infrared->file_path, INFRARED_APP_FOLDER);
scene_manager_next_scene(scene_manager, InfraredSceneRemoteList);
consumed = true;
} else if(submenu_index == SubmenuIndexDebug) {

View File

@@ -4,7 +4,6 @@
#include "gui/canvas.h"
#include "gui/view.h"
#include "input/input.h"
#include "m-string.h"
#include <gui/elements.h>
#include <furi.h>
#include "infrared_progress_view.h"

View File

@@ -36,9 +36,9 @@ static LfRfid* lfrfid_alloc() {
lfrfid->storage = furi_record_open(RECORD_STORAGE);
lfrfid->dialogs = furi_record_open(RECORD_DIALOGS);
string_init(lfrfid->file_name);
string_init(lfrfid->raw_file_name);
string_init_set_str(lfrfid->file_path, LFRFID_APP_FOLDER);
lfrfid->file_name = furi_string_alloc();
lfrfid->raw_file_name = furi_string_alloc();
lfrfid->file_path = furi_string_alloc_set(LFRFID_APP_FOLDER);
lfrfid->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
@@ -104,9 +104,9 @@ static LfRfid* lfrfid_alloc() {
static void lfrfid_free(LfRfid* lfrfid) {
furi_assert(lfrfid);
string_clear(lfrfid->raw_file_name);
string_clear(lfrfid->file_name);
string_clear(lfrfid->file_path);
furi_string_free(lfrfid->raw_file_name);
furi_string_free(lfrfid->file_name);
furi_string_free(lfrfid->file_path);
protocol_dict_free(lfrfid->dict);
lfrfid_worker_free(lfrfid->lfworker);
@@ -183,7 +183,7 @@ int32_t lfrfid_app(void* p) {
app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop);
scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc);
} else {
string_set_str(app->file_path, args);
furi_string_set(app->file_path, args);
lfrfid_load_key_data(app, app->file_path, true);
view_dispatcher_attach_to_gui(
app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
@@ -210,13 +210,13 @@ bool lfrfid_save_key(LfRfid* app) {
lfrfid_make_app_folder(app);
if(string_end_with_str_p(app->file_path, LFRFID_APP_EXTENSION)) {
size_t filename_start = string_search_rchar(app->file_path, '/');
string_left(app->file_path, filename_start);
if(furi_string_end_with(app->file_path, LFRFID_APP_EXTENSION)) {
size_t filename_start = furi_string_search_rchar(app->file_path, '/');
furi_string_left(app->file_path, filename_start);
}
string_cat_printf(
app->file_path, "/%s%s", string_get_cstr(app->file_name), LFRFID_APP_EXTENSION);
furi_string_cat_printf(
app->file_path, "/%s%s", furi_string_get_cstr(app->file_name), LFRFID_APP_EXTENSION);
result = lfrfid_save_key_data(app, app->file_path);
return result;
@@ -242,14 +242,14 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) {
bool lfrfid_delete_key(LfRfid* app) {
furi_assert(app);
return storage_simply_remove(app->storage, string_get_cstr(app->file_path));
return storage_simply_remove(app->storage, furi_string_get_cstr(app->file_path));
}
bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) {
bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog) {
bool result = false;
do {
app->protocol_id = lfrfid_dict_file_load(app->dict, string_get_cstr(path));
app->protocol_id = lfrfid_dict_file_load(app->dict, furi_string_get_cstr(path));
if(app->protocol_id == PROTOCOL_NO) break;
path_extract_filename(path, app->file_name, true);
@@ -263,8 +263,8 @@ bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) {
return result;
}
bool lfrfid_save_key_data(LfRfid* app, string_t path) {
bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, string_get_cstr(path));
bool lfrfid_save_key_data(LfRfid* app, FuriString* path) {
bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, furi_string_get_cstr(path));
if(!result) {
dialog_message_show_storage_error(app->dialogs, "Cannot save\nkey file");

View File

@@ -14,7 +14,7 @@
#include <lfrfid/lfrfid_raw_file.h>
#include <toolbox/pulse_protocols/pulse_glue.h>
static void lfrfid_cli(Cli* cli, string_t args, void* context);
static void lfrfid_cli(Cli* cli, FuriString* args, void* context);
// app cli function
void lfrfid_on_system_start() {
@@ -46,27 +46,28 @@ static void lfrfid_cli_read_callback(LFRFIDWorkerReadResult result, ProtocolId p
furi_event_flag_set(context->event, 1 << result);
}
static void lfrfid_cli_read(Cli* cli, string_t args) {
string_t type_string;
string_init(type_string);
static void lfrfid_cli_read(Cli* cli, FuriString* args) {
FuriString* type_string;
type_string = furi_string_alloc();
LFRFIDWorkerReadType type = LFRFIDWorkerReadTypeAuto;
if(args_read_string_and_trim(args, type_string)) {
if(string_cmp_str(type_string, "normal") == 0 || string_cmp_str(type_string, "ask") == 0) {
if(furi_string_cmp_str(type_string, "normal") == 0 ||
furi_string_cmp_str(type_string, "ask") == 0) {
// ask
type = LFRFIDWorkerReadTypeASKOnly;
} else if(
string_cmp_str(type_string, "indala") == 0 ||
string_cmp_str(type_string, "psk") == 0) {
furi_string_cmp_str(type_string, "indala") == 0 ||
furi_string_cmp_str(type_string, "psk") == 0) {
// psk
type = LFRFIDWorkerReadTypePSKOnly;
} else {
lfrfid_cli_print_usage();
string_clear(type_string);
furi_string_free(type_string);
return;
}
}
string_clear(type_string);
furi_string_free(type_string);
ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
LFRFIDWorker* worker = lfrfid_worker_alloc(dict);
@@ -111,13 +112,13 @@ static void lfrfid_cli_read(Cli* cli, string_t args) {
printf("\r\n");
free(data);
string_t info;
string_init(info);
FuriString* info;
info = furi_string_alloc();
protocol_dict_render_data(dict, info, context.protocol);
if(!string_empty_p(info)) {
printf("%s\r\n", string_get_cstr(info));
if(!furi_string_empty(info)) {
printf("%s\r\n", furi_string_get_cstr(info));
}
string_clear(info);
furi_string_free(info);
}
printf("Reading stopped\r\n");
@@ -126,11 +127,11 @@ static void lfrfid_cli_read(Cli* cli, string_t args) {
furi_event_flag_free(context.event);
}
static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* protocol) {
static bool lfrfid_cli_parse_args(FuriString* args, ProtocolDict* dict, ProtocolId* protocol) {
bool result = false;
string_t protocol_name, data_text;
string_init(protocol_name);
string_init(data_text);
FuriString *protocol_name, *data_text;
protocol_name = furi_string_alloc();
data_text = furi_string_alloc();
size_t data_size = protocol_dict_get_max_data_size(dict);
uint8_t* data = malloc(data_size);
@@ -143,12 +144,12 @@ static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId*
}
// check protocol arg
*protocol = protocol_dict_get_protocol_by_name(dict, string_get_cstr(protocol_name));
*protocol = protocol_dict_get_protocol_by_name(dict, furi_string_get_cstr(protocol_name));
if(*protocol == PROTOCOL_NO) {
printf(
"Unknown protocol: %s\r\n"
"Available protocols:\r\n",
string_get_cstr(protocol_name));
furi_string_get_cstr(protocol_name));
for(ProtocolId i = 0; i < LFRFIDProtocolMax; i++) {
printf(
@@ -177,8 +178,8 @@ static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId*
} while(false);
free(data);
string_clear(protocol_name);
string_clear(data_text);
furi_string_free(protocol_name);
furi_string_free(data_text);
return result;
}
@@ -188,7 +189,7 @@ static void lfrfid_cli_write_callback(LFRFIDWorkerWriteResult result, void* ctx)
furi_event_flag_set(events, 1 << result);
}
static void lfrfid_cli_write(Cli* cli, string_t args) {
static void lfrfid_cli_write(Cli* cli, FuriString* args) {
ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
ProtocolId protocol;
@@ -235,7 +236,7 @@ static void lfrfid_cli_write(Cli* cli, string_t args) {
furi_event_flag_free(event);
}
static void lfrfid_cli_emulate(Cli* cli, string_t args) {
static void lfrfid_cli_emulate(Cli* cli, FuriString* args) {
ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
ProtocolId protocol;
@@ -261,11 +262,11 @@ static void lfrfid_cli_emulate(Cli* cli, string_t args) {
protocol_dict_free(dict);
}
static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) {
static void lfrfid_cli_raw_analyze(Cli* cli, FuriString* args) {
UNUSED(cli);
string_t filepath, info_string;
string_init(filepath);
string_init(info_string);
FuriString *filepath, *info_string;
filepath = furi_string_alloc();
info_string = furi_string_alloc();
Storage* storage = furi_record_open(RECORD_STORAGE);
LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage);
@@ -278,7 +279,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) {
break;
}
if(!lfrfid_raw_file_open_read(file, string_get_cstr(filepath))) {
if(!lfrfid_raw_file_open_read(file, furi_string_get_cstr(filepath))) {
printf("Failed to open file\r\n");
break;
}
@@ -308,10 +309,10 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) {
warn = true;
}
string_printf(info_string, "[%ld %ld]", pulse, duration);
printf("%-16s", string_get_cstr(info_string));
string_printf(info_string, "[%ld %ld]", pulse, duration - pulse);
printf("%-16s", string_get_cstr(info_string));
furi_string_printf(info_string, "[%ld %ld]", pulse, duration);
printf("%-16s", furi_string_get_cstr(info_string));
furi_string_printf(info_string, "[%ld %ld]", pulse, duration - pulse);
printf("%-16s", furi_string_get_cstr(info_string));
if(warn) {
printf(" <<----");
@@ -366,7 +367,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) {
printf("]\r\n");
protocol_dict_render_data(dict, info_string, total_protocol);
printf("%s\r\n", string_get_cstr(info_string));
printf("%s\r\n", furi_string_get_cstr(info_string));
free(data);
} else {
@@ -376,8 +377,8 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) {
protocol_dict_free(dict);
} while(false);
string_clear(filepath);
string_clear(info_string);
furi_string_free(filepath);
furi_string_free(info_string);
lfrfid_raw_file_free(file);
furi_record_close(RECORD_STORAGE);
}
@@ -388,23 +389,23 @@ static void lfrfid_cli_raw_read_callback(LFRFIDWorkerReadRawResult result, void*
furi_event_flag_set(event, 1 << result);
}
static void lfrfid_cli_raw_read(Cli* cli, string_t args) {
static void lfrfid_cli_raw_read(Cli* cli, FuriString* args) {
UNUSED(cli);
string_t filepath, type_string;
string_init(filepath);
string_init(type_string);
FuriString *filepath, *type_string;
filepath = furi_string_alloc();
type_string = furi_string_alloc();
LFRFIDWorkerReadType type = LFRFIDWorkerReadTypeAuto;
do {
if(args_read_string_and_trim(args, type_string)) {
if(string_cmp_str(type_string, "normal") == 0 ||
string_cmp_str(type_string, "ask") == 0) {
if(furi_string_cmp_str(type_string, "normal") == 0 ||
furi_string_cmp_str(type_string, "ask") == 0) {
// ask
type = LFRFIDWorkerReadTypeASKOnly;
} else if(
string_cmp_str(type_string, "indala") == 0 ||
string_cmp_str(type_string, "psk") == 0) {
furi_string_cmp_str(type_string, "indala") == 0 ||
furi_string_cmp_str(type_string, "psk") == 0) {
// psk
type = LFRFIDWorkerReadTypePSKOnly;
} else {
@@ -430,7 +431,7 @@ static void lfrfid_cli_raw_read(Cli* cli, string_t args) {
(1 << LFRFIDWorkerReadRawOverrun);
lfrfid_worker_read_raw_start(
worker, string_get_cstr(filepath), type, lfrfid_cli_raw_read_callback, event);
worker, furi_string_get_cstr(filepath), type, lfrfid_cli_raw_read_callback, event);
while(true) {
uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100);
@@ -465,8 +466,8 @@ static void lfrfid_cli_raw_read(Cli* cli, string_t args) {
} while(false);
string_clear(filepath);
string_clear(type_string);
furi_string_free(filepath);
furi_string_free(type_string);
}
static void lfrfid_cli_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, void* context) {
@@ -475,11 +476,11 @@ static void lfrfid_cli_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result,
furi_event_flag_set(event, 1 << result);
}
static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) {
static void lfrfid_cli_raw_emulate(Cli* cli, FuriString* args) {
UNUSED(cli);
string_t filepath;
string_init(filepath);
FuriString* filepath;
filepath = furi_string_alloc();
Storage* storage = furi_record_open(RECORD_STORAGE);
do {
@@ -488,8 +489,8 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) {
break;
}
if(!storage_file_exists(storage, string_get_cstr(filepath))) {
printf("File not found: \"%s\"\r\n", string_get_cstr(filepath));
if(!storage_file_exists(storage, furi_string_get_cstr(filepath))) {
printf("File not found: \"%s\"\r\n", furi_string_get_cstr(filepath));
break;
}
@@ -505,7 +506,7 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) {
(1 << LFRFIDWorkerEmulateRawOverrun);
lfrfid_worker_emulate_raw_start(
worker, string_get_cstr(filepath), lfrfid_cli_raw_emulate_callback, event);
worker, furi_string_get_cstr(filepath), lfrfid_cli_raw_emulate_callback, event);
while(true) {
uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100);
@@ -541,35 +542,35 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) {
} while(false);
furi_record_close(RECORD_STORAGE);
string_clear(filepath);
furi_string_free(filepath);
}
static void lfrfid_cli(Cli* cli, string_t args, void* context) {
static void lfrfid_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
string_t cmd;
string_init(cmd);
FuriString* cmd;
cmd = furi_string_alloc();
if(!args_read_string_and_trim(args, cmd)) {
string_clear(cmd);
furi_string_free(cmd);
lfrfid_cli_print_usage();
return;
}
if(string_cmp_str(cmd, "read") == 0) {
if(furi_string_cmp_str(cmd, "read") == 0) {
lfrfid_cli_read(cli, args);
} else if(string_cmp_str(cmd, "write") == 0) {
} else if(furi_string_cmp_str(cmd, "write") == 0) {
lfrfid_cli_write(cli, args);
} else if(string_cmp_str(cmd, "emulate") == 0) {
} else if(furi_string_cmp_str(cmd, "emulate") == 0) {
lfrfid_cli_emulate(cli, args);
} else if(string_cmp_str(cmd, "raw_read") == 0) {
} else if(furi_string_cmp_str(cmd, "raw_read") == 0) {
lfrfid_cli_raw_read(cli, args);
} else if(string_cmp_str(cmd, "raw_emulate") == 0) {
} else if(furi_string_cmp_str(cmd, "raw_emulate") == 0) {
lfrfid_cli_raw_emulate(cli, args);
} else if(string_cmp_str(cmd, "raw_analyze") == 0) {
} else if(furi_string_cmp_str(cmd, "raw_analyze") == 0) {
lfrfid_cli_raw_analyze(cli, args);
} else {
lfrfid_cli_print_usage();
}
string_clear(cmd);
furi_string_free(cmd);
}

View File

@@ -1,7 +1,5 @@
#pragma once
#include "m-string.h"
#include <furi.h>
#include <furi_hal.h>
@@ -86,9 +84,9 @@ struct LfRfid {
Widget* widget;
char text_store[LFRFID_TEXT_STORE_SIZE + 1];
string_t file_path;
string_t file_name;
string_t raw_file_name;
FuriString* file_path;
FuriString* file_name;
FuriString* raw_file_name;
ProtocolDict* dict;
ProtocolId protocol_id;
@@ -128,9 +126,9 @@ bool lfrfid_load_key_from_file_select(LfRfid* app);
bool lfrfid_delete_key(LfRfid* app);
bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog);
bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog);
bool lfrfid_save_key_data(LfRfid* app, string_t path);
bool lfrfid_save_key_data(LfRfid* app, FuriString* path);
void lfrfid_make_app_folder(LfRfid* app);

View File

@@ -4,31 +4,31 @@ void lfrfid_scene_delete_confirm_on_enter(void* context) {
LfRfid* app = context;
Widget* widget = app->widget;
string_t tmp_string;
string_init(tmp_string);
FuriString* tmp_string;
tmp_string = furi_string_alloc();
widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app);
widget_add_button_element(widget, GuiButtonTypeRight, "Delete", lfrfid_widget_callback, app);
string_printf(tmp_string, "Delete %s?", string_get_cstr(app->file_name));
furi_string_printf(tmp_string, "Delete %s?", furi_string_get_cstr(app->file_name));
widget_add_string_element(
widget, 64, 0, AlignCenter, AlignTop, FontPrimary, string_get_cstr(tmp_string));
widget, 64, 0, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string));
string_reset(tmp_string);
furi_string_reset(tmp_string);
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
uint8_t* data = (uint8_t*)malloc(size);
protocol_dict_get_data(app->dict, app->protocol_id, data, size);
for(uint8_t i = 0; i < MIN(size, (size_t)8); i++) {
if(i != 0) {
string_cat_printf(tmp_string, " ");
furi_string_cat_printf(tmp_string, " ");
}
string_cat_printf(tmp_string, "%02X", data[i]);
furi_string_cat_printf(tmp_string, "%02X", data[i]);
}
free(data);
widget_add_string_element(
widget, 64, 19, AlignCenter, AlignTop, FontSecondary, string_get_cstr(tmp_string));
widget, 64, 19, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string));
widget_add_string_element(
widget,
64,
@@ -39,7 +39,7 @@ void lfrfid_scene_delete_confirm_on_enter(void* context) {
protocol_dict_get_name(app->dict, app->protocol_id));
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
string_clear(tmp_string);
furi_string_free(tmp_string);
}
bool lfrfid_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) {

View File

@@ -8,8 +8,8 @@ void lfrfid_scene_emulate_on_enter(void* context) {
DOLPHIN_DEED(DolphinDeedRfidEmulate);
popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop);
if(!string_empty_p(app->file_name)) {
popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);
if(!furi_string_empty(app->file_name)) {
popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);
} else {
popup_set_text(
popup,

View File

@@ -42,7 +42,7 @@ void lfrfid_scene_extra_actions_on_enter(void* context) {
submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneExtraActions));
// clear key
string_reset(app->file_name);
furi_string_reset(app->file_name);
app->protocol_id = PROTOCOL_NO;
app->read_type = LFRFIDWorkerReadTypeAuto;

View File

@@ -4,8 +4,8 @@ void lfrfid_scene_raw_info_on_enter(void* context) {
LfRfid* app = context;
Widget* widget = app->widget;
// string_t tmp_string;
// string_init(tmp_string);
// FuriString* tmp_string;
// tmp_string = furi_string_alloc();
bool sd_exist = storage_sd_status(app->storage) == FSE_OK;
if(!sd_exist) {
@@ -34,7 +34,7 @@ void lfrfid_scene_raw_info_on_enter(void* context) {
}
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
//string_clear(tmp_string);
//furi_string_free(tmp_string);
}
bool lfrfid_scene_raw_info_on_event(void* context, SceneManagerEvent event) {

View File

@@ -4,9 +4,9 @@ void lfrfid_scene_raw_name_on_enter(void* context) {
LfRfid* app = context;
TextInput* text_input = app->text_input;
const char* key_name = string_get_cstr(app->raw_file_name);
const char* key_name = furi_string_get_cstr(app->raw_file_name);
bool key_name_is_empty = string_empty_p(app->file_name);
bool key_name_is_empty = furi_string_empty(app->file_name);
if(key_name_is_empty) {
lfrfid_text_store_set(app, "RfidRecord");
} else {
@@ -38,7 +38,7 @@ bool lfrfid_scene_raw_name_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == LfRfidEventNext) {
consumed = true;
string_set_str(app->raw_file_name, app->text_store);
furi_string_set(app->raw_file_name, app->text_store);
scene_manager_next_scene(scene_manager, LfRfidSceneRawInfo);
}
}

View File

@@ -3,7 +3,7 @@
#define RAW_READ_TIME 5000
typedef struct {
string_t string_file_name;
FuriString* string_file_name;
FuriTimer* timer;
bool is_psk;
bool error;
@@ -31,7 +31,7 @@ void lfrfid_scene_raw_read_on_enter(void* context) {
LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState));
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state);
string_init(state->string_file_name);
state->string_file_name = furi_string_alloc();
popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
@@ -40,16 +40,16 @@ void lfrfid_scene_raw_read_on_enter(void* context) {
state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app);
furi_timer_start(state->timer, RAW_READ_TIME);
string_printf(
furi_string_printf(
state->string_file_name,
"%s/%s%s",
LFRFID_SD_FOLDER,
string_get_cstr(app->raw_file_name),
furi_string_get_cstr(app->raw_file_name),
LFRFID_APP_RAW_ASK_EXTENSION);
popup_set_header(popup, "Reading\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop);
lfrfid_worker_read_raw_start(
app->lfworker,
string_get_cstr(state->string_file_name),
furi_string_get_cstr(state->string_file_name),
LFRFIDWorkerReadTypeASKOnly,
lfrfid_read_callback,
app);
@@ -88,15 +88,15 @@ bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) {
popup, "Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop);
notification_message(app->notifications, &sequence_blink_start_yellow);
lfrfid_worker_stop(app->lfworker);
string_printf(
furi_string_printf(
state->string_file_name,
"%s/%s%s",
LFRFID_SD_FOLDER,
string_get_cstr(app->raw_file_name),
furi_string_get_cstr(app->raw_file_name),
LFRFID_APP_RAW_PSK_EXTENSION);
lfrfid_worker_read_raw_start(
app->lfworker,
string_get_cstr(state->string_file_name),
furi_string_get_cstr(state->string_file_name),
LFRFIDWorkerReadTypePSKOnly,
lfrfid_read_callback,
app);
@@ -121,6 +121,6 @@ void lfrfid_scene_raw_read_on_exit(void* context) {
lfrfid_worker_stop_thread(app->lfworker);
furi_timer_free(state->timer);
string_clear(state->string_file_name);
furi_string_free(state->string_file_name);
free(state);
}

View File

@@ -81,7 +81,7 @@ bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) {
app->protocol_id = app->protocol_id_next;
DOLPHIN_DEED(DolphinDeedRfidReadSuccess);
notification_message(app->notifications, &sequence_success);
string_reset(app->file_name);
furi_string_reset(app->file_name);
scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess);
consumed = true;
} else if(event.event == LfRfidEventReadStartPSK) {

View File

@@ -38,7 +38,7 @@ bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event)
scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite);
consumed = true;
} else if(event.event == SubmenuIndexSave) {
string_reset(app->file_name);
furi_string_reset(app->file_name);
scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveName);
consumed = true;
} else if(event.event == SubmenuIndexEmulate) {

View File

@@ -4,53 +4,53 @@ void lfrfid_scene_read_success_on_enter(void* context) {
LfRfid* app = context;
Widget* widget = app->widget;
string_t tmp_string;
string_init(tmp_string);
FuriString* tmp_string;
tmp_string = furi_string_alloc();
widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app);
widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app);
string_printf(
furi_string_printf(
tmp_string,
"%s[%s]",
protocol_dict_get_name(app->dict, app->protocol_id),
protocol_dict_get_manufacturer(app->dict, app->protocol_id));
widget_add_string_element(
widget, 16, 3, AlignLeft, AlignTop, FontPrimary, string_get_cstr(tmp_string));
widget, 16, 3, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string));
string_reset(tmp_string);
furi_string_reset(tmp_string);
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
uint8_t* data = (uint8_t*)malloc(size);
protocol_dict_get_data(app->dict, app->protocol_id, data, size);
for(uint8_t i = 0; i < size; i++) {
if(i >= 9) {
string_cat_printf(tmp_string, "..");
furi_string_cat_printf(tmp_string, "..");
break;
} else {
if(i != 0) {
string_cat_printf(tmp_string, ":");
furi_string_cat_printf(tmp_string, ":");
}
string_cat_printf(tmp_string, "%02X", data[i]);
furi_string_cat_printf(tmp_string, "%02X", data[i]);
}
}
free(data);
string_t render_data;
string_init(render_data);
FuriString* render_data;
render_data = furi_string_alloc();
protocol_dict_render_brief_data(app->dict, render_data, app->protocol_id);
string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data));
string_clear(render_data);
furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data));
furi_string_free(render_data);
widget_add_string_multiline_element(
widget, 0, 16, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string));
widget, 0, 16, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string));
widget_add_icon_element(app->widget, 0, 0, &I_RFIDSmallChip_14x14);
notification_message_block(app->notifications, &sequence_set_green_255);
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
string_clear(tmp_string);
furi_string_free(tmp_string);
}
bool lfrfid_scene_read_success_on_event(void* context, SceneManagerEvent event) {

View File

@@ -34,13 +34,14 @@ bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) {
const char* arg = rpc_system_app_get_data(app->rpc_ctx);
bool result = false;
if(arg && (app->rpc_state == LfRfidRpcStateIdle)) {
string_set_str(app->file_path, arg);
furi_string_set(app->file_path, arg);
if(lfrfid_load_key_data(app, app->file_path, false)) {
lfrfid_worker_start_thread(app->lfworker);
lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id);
app->rpc_state = LfRfidRpcStateEmulating;
lfrfid_text_store_set(app, "emulating\n%s", string_get_cstr(app->file_name));
lfrfid_text_store_set(
app, "emulating\n%s", furi_string_get_cstr(app->file_name));
popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop);
notification_message(app->notifications, &sequence_blink_start_magenta);

Some files were not shown because too many files have changed in this diff Show More