From bdf4a395307cb31f915057624316fcf4a480b47e Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sun, 5 Nov 2023 01:12:28 +0000 Subject: [PATCH] 13 more apps done, 31 to go --- .../external/blackjack/application.fam | 14 - .../external/blackjack/assets/blackjack.png | Bin 1324 -> 0 bytes .../blackjack/assets/card_graphics.png | Bin 409 -> 0 bytes .../external/blackjack/assets/endscreen.png | Bin 1241 -> 0 bytes applications/external/blackjack/blackjack.c | 634 ---- .../external/blackjack/blackjack_10px.png | Bin 119 -> 0 bytes applications/external/blackjack/common/card.c | 353 --- applications/external/blackjack/common/card.h | 192 -- applications/external/blackjack/common/dml.c | 53 - applications/external/blackjack/common/dml.h | 116 - applications/external/blackjack/common/menu.c | 103 - applications/external/blackjack/common/menu.h | 77 - .../external/blackjack/common/queue.c | 69 - .../external/blackjack/common/queue.h | 70 - applications/external/blackjack/common/ui.c | 257 -- applications/external/blackjack/common/ui.h | 105 - applications/external/blackjack/defines.h | 77 - applications/external/blackjack/ui.c | 186 -- applications/external/blackjack/ui.h | 18 - applications/external/blackjack/util.c | 124 - applications/external/blackjack/util.h | 7 - applications/external/nrf24batch/LICENSE | 674 ---- .../external/nrf24batch/application.fam | 19 - .../external/nrf24batch/lib/nrf24/nrf24.c | 384 --- .../external/nrf24batch/lib/nrf24/nrf24.h | 392 --- applications/external/nrf24batch/nrf24batch.c | 1973 ------------ applications/external/nrf24batch/nrf24batch.h | 32 - .../external/nrf24batch/nrf24batch_10px.png | Bin 1771 -> 0 bytes .../nrf24channelscanner/application.fam | 23 - .../external/nrf24channelscanner/fapicon.png | Bin 145 -> 0 bytes .../nrf24channelscanner/lib/nrf24/nrf24.c | 117 - .../nrf24channelscanner/lib/nrf24/nrf24.h | 129 - .../nrf24channelscanner/nrf24channelscanner.c | 269 -- applications/external/nrf24scan/LICENSE | 674 ---- .../external/nrf24scan/application.fam | 19 - .../external/nrf24scan/lib/nrf24/nrf24.c | 556 ---- .../external/nrf24scan/lib/nrf24/nrf24.h | 387 --- .../nrf24scan/nrf24_packet_decoder.py | 131 - applications/external/nrf24scan/nrf24scan.c | 1662 ---------- applications/external/nrf24scan/nrf24scan.h | 39 - .../external/nrf24scan/nrf24scan_10px.png | Bin 1771 -> 0 bytes applications/external/rootoflife/LICENSE | 21 - .../external/rootoflife/application.fam | 17 - .../rootoflife/images/place_error.png | Bin 159 -> 0 bytes .../external/rootoflife/images/place_ok.png | Bin 163 -> 0 bytes .../rootoflife/images/root_reroll.png | Bin 174 -> 0 bytes .../external/rootoflife/images/score.png | Bin 192 -> 0 bytes .../external/rootoflife/images/tree.png | Bin 165 -> 0 bytes .../rootoflife/roots_of_life_10px.png | Bin 1679 -> 0 bytes .../external/rootoflife/roots_of_life_game.c | 751 ----- applications/external/scorched_tanks/LICENSE | 674 ---- .../external/scorched_tanks/application.fam | 15 - .../scorched_tanks/scorchedTanks_10px.png | Bin 536 -> 0 bytes .../scorched_tanks/scorched_tanks_game_app.c | 546 ---- .../external/signal_generator/application.fam | 13 - .../scenes/signal_gen_scene.c | 30 - .../scenes/signal_gen_scene.h | 29 - .../scenes/signal_gen_scene_config.h | 3 - .../scenes/signal_gen_scene_mco.c | 145 - .../scenes/signal_gen_scene_pwm.c | 79 - .../scenes/signal_gen_scene_start.c | 55 - .../signal_generator/signal_gen_10px.png | Bin 6082 -> 0 bytes .../signal_generator/signal_gen_app.c | 93 - .../signal_generator/signal_gen_app_i.h | 46 - .../signal_generator/views/signal_gen_pwm.c | 311 -- .../signal_generator/views/signal_gen_pwm.h | 21 - applications/external/simonsays/LICENSE | 674 ---- .../external/simonsays/application.fam | 15 - .../simonsays/images/DolphinLeft_56x48.png | Bin 1416 -> 0 bytes .../images/DolphinNiceLeft_96x59.png | Bin 2459 -> 0 bytes .../images/DolphinNiceRight_96x59.png | Bin 1066 -> 0 bytes .../simonsays/images/DolphinRight_56x48.png | Bin 601 -> 0 bytes .../simonsays/images/DolphinTalking_59x63.png | Bin 1177 -> 0 bytes .../external/simonsays/images/board.png | Bin 826 -> 0 bytes .../external/simonsays/images/down.png | Bin 954 -> 0 bytes .../external/simonsays/images/left.png | Bin 921 -> 0 bytes .../external/simonsays/images/right.png | Bin 948 -> 0 bytes applications/external/simonsays/images/up.png | Bin 867 -> 0 bytes applications/external/simonsays/simon_says.c | 661 ---- .../external/simonsays/simon_says.png | Bin 133 -> 0 bytes applications/external/slots/application.fam | 16 - .../external/slots/assets/little_coin.png | Bin 158 -> 0 bytes applications/external/slots/assets/x2.png | Bin 256 -> 0 bytes applications/external/slots/assets/x2_2.png | Bin 212 -> 0 bytes applications/external/slots/assets/x3.png | Bin 251 -> 0 bytes applications/external/slots/assets/x4.png | Bin 224 -> 0 bytes applications/external/slots/assets/x5.png | Bin 247 -> 0 bytes applications/external/slots/ddgame_icon.png | Bin 177 -> 0 bytes applications/external/slots/slotmachine.c | 273 -- applications/external/solitaire/LICENSE | 21 - .../external/solitaire/application.fam | 14 - .../solitaire/assets/card_graphics.png | Bin 409 -> 0 bytes .../solitaire/assets/solitaire_main.png | Bin 1158 -> 0 bytes applications/external/solitaire/common/card.c | 353 --- applications/external/solitaire/common/card.h | 192 -- applications/external/solitaire/common/dml.c | 53 - applications/external/solitaire/common/dml.h | 116 - applications/external/solitaire/common/menu.c | 103 - applications/external/solitaire/common/menu.h | 77 - .../external/solitaire/common/queue.c | 69 - .../external/solitaire/common/queue.h | 70 - applications/external/solitaire/common/ui.c | 257 -- applications/external/solitaire/common/ui.h | 105 - applications/external/solitaire/defines.h | 58 - applications/external/solitaire/solitaire.c | 580 ---- .../external/solitaire/solitaire_10px.png | Bin 121 -> 0 bytes applications/external/t_rex_runner/LICENSE | 674 ---- .../external/t_rex_runner/application.fam | 16 - .../external/t_rex_runner/assets/Cactus.png | Bin 110 -> 0 bytes .../external/t_rex_runner/assets/Dino.png | Bin 4339 -> 0 bytes .../external/t_rex_runner/assets/DinoRun0.png | Bin 149 -> 0 bytes .../external/t_rex_runner/assets/DinoRun1.png | Bin 152 -> 0 bytes .../t_rex_runner/assets/HorizonLine0.png | Bin 5289 -> 0 bytes .../external/t_rex_runner/trexrunner.c | 289 -- .../external/t_rex_runner/trexrunner_icon.png | Bin 110 -> 0 bytes .../uncut_assets/HorizonLine0.png | Bin 203 -> 0 bytes .../uncut_assets/HorizonLine1.png | Bin 272 -> 0 bytes applications/external/tuning_fork/LICENSE | 674 ---- .../external/tuning_fork/application.fam | 17 - applications/external/tuning_fork/notes.h | 158 - .../external/tuning_fork/tuning_fork.c | 405 --- .../external/tuning_fork/tuning_fork_icon.png | Bin 1187 -> 0 bytes applications/external/tuning_fork/tunings.h | 151 - .../external/wifi_marauder_companion/LICENSE | 674 ---- .../wifi_marauder_companion/application.fam | 12 - .../assets/Text_10x10.png | Bin 158 -> 0 bytes .../file/sequential_file.c | 46 - .../file/sequential_file.h | 15 - .../scenes/wifi_marauder_scene.c | 30 - .../scenes/wifi_marauder_scene.h | 29 - .../scenes/wifi_marauder_scene_config.h | 15 - .../wifi_marauder_scene_console_output.c | 219 -- .../scenes/wifi_marauder_scene_log_viewer.c | 187 -- ...ifi_marauder_scene_script_confirm_delete.c | 83 - .../scenes/wifi_marauder_scene_script_edit.c | 125 - .../wifi_marauder_scene_script_edit_list.c | 188 -- .../wifi_marauder_scene_script_options.c | 111 - .../wifi_marauder_scene_script_select.c | 92 - .../wifi_marauder_scene_script_settings.c | 87 - .../wifi_marauder_scene_script_stage_add.c | 297 -- .../wifi_marauder_scene_script_stage_edit.c | 203 -- .../wifi_marauder_scene_settings_init.c | 130 - .../wifi_marauder_scene_sniffpmkid_options.c | 117 - .../scenes/wifi_marauder_scene_start.c | 287 -- .../scenes/wifi_marauder_scene_text_input.c | 156 - .../scenes/wifi_marauder_scene_user_input.c | 156 - .../wifi_marauder_companion/script/cJSON.c | 2743 ----------------- .../wifi_marauder_companion/script/cJSON.h | 321 -- .../menu/wifi_marauder_script_stage_menu.c | 32 - .../menu/wifi_marauder_script_stage_menu.h | 42 - ...wifi_marauder_script_stage_menu_beaconap.c | 27 - ...fi_marauder_script_stage_menu_beaconlist.c | 59 - .../wifi_marauder_script_stage_menu_config.h | 14 - .../wifi_marauder_script_stage_menu_deauth.c | 27 - .../wifi_marauder_script_stage_menu_delay.c | 27 - .../wifi_marauder_script_stage_menu_exec.c | 30 - .../wifi_marauder_script_stage_menu_probe.c | 27 - .../wifi_marauder_script_stage_menu_scan.c | 93 - .../wifi_marauder_script_stage_menu_select.c | 95 - ...i_marauder_script_stage_menu_sniffbeacon.c | 27 - ...i_marauder_script_stage_menu_sniffdeauth.c | 27 - ...wifi_marauder_script_stage_menu_sniffesp.c | 27 - ...fi_marauder_script_stage_menu_sniffpmkid.c | 118 - ...wifi_marauder_script_stage_menu_sniffpwn.c | 27 - ...wifi_marauder_script_stage_menu_sniffraw.c | 27 - .../script/wifi_marauder_script.c | 962 ------ .../script/wifi_marauder_script.h | 258 -- .../script/wifi_marauder_script_executor.c | 443 --- .../script/wifi_marauder_script_executor.h | 6 - .../script/wifi_marauder_script_worker.c | 74 - .../script/wifi_marauder_script_worker.h | 44 - .../wifi_marauder_companion/wifi_10px.png | Bin 1781 -> 0 bytes .../wifi_marauder_app.c | 206 -- .../wifi_marauder_app.h | 13 - .../wifi_marauder_app_i.h | 154 - .../wifi_marauder_custom_event.h | 13 - .../wifi_marauder_uart.c | 116 - .../wifi_marauder_uart.h | 20 - .../wifi_marauder_validators.c | 57 - .../wifi_marauder_validators.h | 21 - 180 files changed, 28311 deletions(-) delete mode 100644 applications/external/blackjack/application.fam delete mode 100644 applications/external/blackjack/assets/blackjack.png delete mode 100644 applications/external/blackjack/assets/card_graphics.png delete mode 100644 applications/external/blackjack/assets/endscreen.png delete mode 100644 applications/external/blackjack/blackjack.c delete mode 100644 applications/external/blackjack/blackjack_10px.png delete mode 100644 applications/external/blackjack/common/card.c delete mode 100644 applications/external/blackjack/common/card.h delete mode 100644 applications/external/blackjack/common/dml.c delete mode 100644 applications/external/blackjack/common/dml.h delete mode 100644 applications/external/blackjack/common/menu.c delete mode 100644 applications/external/blackjack/common/menu.h delete mode 100644 applications/external/blackjack/common/queue.c delete mode 100644 applications/external/blackjack/common/queue.h delete mode 100644 applications/external/blackjack/common/ui.c delete mode 100644 applications/external/blackjack/common/ui.h delete mode 100644 applications/external/blackjack/defines.h delete mode 100644 applications/external/blackjack/ui.c delete mode 100644 applications/external/blackjack/ui.h delete mode 100644 applications/external/blackjack/util.c delete mode 100644 applications/external/blackjack/util.h delete mode 100644 applications/external/nrf24batch/LICENSE delete mode 100644 applications/external/nrf24batch/application.fam delete mode 100644 applications/external/nrf24batch/lib/nrf24/nrf24.c delete mode 100644 applications/external/nrf24batch/lib/nrf24/nrf24.h delete mode 100644 applications/external/nrf24batch/nrf24batch.c delete mode 100644 applications/external/nrf24batch/nrf24batch.h delete mode 100644 applications/external/nrf24batch/nrf24batch_10px.png delete mode 100644 applications/external/nrf24channelscanner/application.fam delete mode 100644 applications/external/nrf24channelscanner/fapicon.png delete mode 100644 applications/external/nrf24channelscanner/lib/nrf24/nrf24.c delete mode 100644 applications/external/nrf24channelscanner/lib/nrf24/nrf24.h delete mode 100644 applications/external/nrf24channelscanner/nrf24channelscanner.c delete mode 100644 applications/external/nrf24scan/LICENSE delete mode 100644 applications/external/nrf24scan/application.fam delete mode 100644 applications/external/nrf24scan/lib/nrf24/nrf24.c delete mode 100644 applications/external/nrf24scan/lib/nrf24/nrf24.h delete mode 100644 applications/external/nrf24scan/nrf24_packet_decoder.py delete mode 100644 applications/external/nrf24scan/nrf24scan.c delete mode 100644 applications/external/nrf24scan/nrf24scan.h delete mode 100644 applications/external/nrf24scan/nrf24scan_10px.png delete mode 100644 applications/external/rootoflife/LICENSE delete mode 100644 applications/external/rootoflife/application.fam delete mode 100644 applications/external/rootoflife/images/place_error.png delete mode 100644 applications/external/rootoflife/images/place_ok.png delete mode 100644 applications/external/rootoflife/images/root_reroll.png delete mode 100644 applications/external/rootoflife/images/score.png delete mode 100644 applications/external/rootoflife/images/tree.png delete mode 100644 applications/external/rootoflife/roots_of_life_10px.png delete mode 100644 applications/external/rootoflife/roots_of_life_game.c delete mode 100644 applications/external/scorched_tanks/LICENSE delete mode 100644 applications/external/scorched_tanks/application.fam delete mode 100644 applications/external/scorched_tanks/scorchedTanks_10px.png delete mode 100644 applications/external/scorched_tanks/scorched_tanks_game_app.c delete mode 100644 applications/external/signal_generator/application.fam delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene.c delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene.h delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_config.h delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_mco.c delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_pwm.c delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_start.c delete mode 100644 applications/external/signal_generator/signal_gen_10px.png delete mode 100644 applications/external/signal_generator/signal_gen_app.c delete mode 100644 applications/external/signal_generator/signal_gen_app_i.h delete mode 100644 applications/external/signal_generator/views/signal_gen_pwm.c delete mode 100644 applications/external/signal_generator/views/signal_gen_pwm.h delete mode 100644 applications/external/simonsays/LICENSE delete mode 100644 applications/external/simonsays/application.fam delete mode 100644 applications/external/simonsays/images/DolphinLeft_56x48.png delete mode 100644 applications/external/simonsays/images/DolphinNiceLeft_96x59.png delete mode 100644 applications/external/simonsays/images/DolphinNiceRight_96x59.png delete mode 100644 applications/external/simonsays/images/DolphinRight_56x48.png delete mode 100644 applications/external/simonsays/images/DolphinTalking_59x63.png delete mode 100644 applications/external/simonsays/images/board.png delete mode 100644 applications/external/simonsays/images/down.png delete mode 100644 applications/external/simonsays/images/left.png delete mode 100644 applications/external/simonsays/images/right.png delete mode 100644 applications/external/simonsays/images/up.png delete mode 100644 applications/external/simonsays/simon_says.c delete mode 100644 applications/external/simonsays/simon_says.png delete mode 100644 applications/external/slots/application.fam delete mode 100644 applications/external/slots/assets/little_coin.png delete mode 100644 applications/external/slots/assets/x2.png delete mode 100644 applications/external/slots/assets/x2_2.png delete mode 100644 applications/external/slots/assets/x3.png delete mode 100644 applications/external/slots/assets/x4.png delete mode 100644 applications/external/slots/assets/x5.png delete mode 100644 applications/external/slots/ddgame_icon.png delete mode 100644 applications/external/slots/slotmachine.c delete mode 100644 applications/external/solitaire/LICENSE delete mode 100644 applications/external/solitaire/application.fam delete mode 100644 applications/external/solitaire/assets/card_graphics.png delete mode 100644 applications/external/solitaire/assets/solitaire_main.png delete mode 100644 applications/external/solitaire/common/card.c delete mode 100644 applications/external/solitaire/common/card.h delete mode 100644 applications/external/solitaire/common/dml.c delete mode 100644 applications/external/solitaire/common/dml.h delete mode 100644 applications/external/solitaire/common/menu.c delete mode 100644 applications/external/solitaire/common/menu.h delete mode 100644 applications/external/solitaire/common/queue.c delete mode 100644 applications/external/solitaire/common/queue.h delete mode 100644 applications/external/solitaire/common/ui.c delete mode 100644 applications/external/solitaire/common/ui.h delete mode 100644 applications/external/solitaire/defines.h delete mode 100644 applications/external/solitaire/solitaire.c delete mode 100644 applications/external/solitaire/solitaire_10px.png delete mode 100644 applications/external/t_rex_runner/LICENSE delete mode 100644 applications/external/t_rex_runner/application.fam delete mode 100644 applications/external/t_rex_runner/assets/Cactus.png delete mode 100644 applications/external/t_rex_runner/assets/Dino.png delete mode 100644 applications/external/t_rex_runner/assets/DinoRun0.png delete mode 100644 applications/external/t_rex_runner/assets/DinoRun1.png delete mode 100644 applications/external/t_rex_runner/assets/HorizonLine0.png delete mode 100644 applications/external/t_rex_runner/trexrunner.c delete mode 100644 applications/external/t_rex_runner/trexrunner_icon.png delete mode 100644 applications/external/t_rex_runner/uncut_assets/HorizonLine0.png delete mode 100644 applications/external/t_rex_runner/uncut_assets/HorizonLine1.png delete mode 100644 applications/external/tuning_fork/LICENSE delete mode 100644 applications/external/tuning_fork/application.fam delete mode 100644 applications/external/tuning_fork/notes.h delete mode 100644 applications/external/tuning_fork/tuning_fork.c delete mode 100644 applications/external/tuning_fork/tuning_fork_icon.png delete mode 100644 applications/external/tuning_fork/tunings.h delete mode 100644 applications/external/wifi_marauder_companion/LICENSE delete mode 100644 applications/external/wifi_marauder_companion/application.fam delete mode 100644 applications/external/wifi_marauder_companion/assets/Text_10x10.png delete mode 100644 applications/external/wifi_marauder_companion/file/sequential_file.c delete mode 100644 applications/external/wifi_marauder_companion/file/sequential_file.h delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.h delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_config.h delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_log_viewer.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_confirm_delete.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit_list.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_options.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_select.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_settings.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_add.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_edit.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_settings_init.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_sniffpmkid_options.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c delete mode 100644 applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_user_input.c delete mode 100644 applications/external/wifi_marauder_companion/script/cJSON.c delete mode 100644 applications/external/wifi_marauder_companion/script/cJSON.h delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.h delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconap.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconlist.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_config.h delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_deauth.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_delay.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_exec.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_probe.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_scan.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_select.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffesp.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpwn.c delete mode 100644 applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffraw.c delete mode 100644 applications/external/wifi_marauder_companion/script/wifi_marauder_script.c delete mode 100644 applications/external/wifi_marauder_companion/script/wifi_marauder_script.h delete mode 100644 applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.c delete mode 100644 applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.h delete mode 100644 applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.c delete mode 100644 applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.h delete mode 100644 applications/external/wifi_marauder_companion/wifi_10px.png delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_app.c delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_app.h delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_app_i.h delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_custom_event.h delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_uart.c delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_uart.h delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_validators.c delete mode 100644 applications/external/wifi_marauder_companion/wifi_marauder_validators.h diff --git a/applications/external/blackjack/application.fam b/applications/external/blackjack/application.fam deleted file mode 100644 index 504989116..000000000 --- a/applications/external/blackjack/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="blackjack", - name="BlackJack", - apptype=FlipperAppType.EXTERNAL, - entry_point="blackjack_app", - requires=["gui", "storage", "canvas"], - stack_size=2 * 1024, - fap_icon="blackjack_10px.png", - fap_category="Games", - fap_icon_assets="assets", - fap_author="@teeebor", - fap_version="1.0", - fap_description="Blackjack Game", -) diff --git a/applications/external/blackjack/assets/blackjack.png b/applications/external/blackjack/assets/blackjack.png deleted file mode 100644 index bb367f28e971c12e2cb31c99a4aeec27b403c4d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1324 zcmV+{1=IS8P)Px(=1D|BRCt{2TFH{*APmLM{QoDLIgnB*+7M!KNc$bS(tw4~j_f1noF3eV^KJ&d z2w;mVjq-Rr;9fi)a5EkSeBd~a#XCLG4=b(s&J=}n zI8Vs1#zSgF6@;?|FztN(1liK#^3EwyULI)l%Xp0D6a^d%;sTq9=gvv!3{RNnd16~J zYA37%-cz!+XyqvYTij%doYr34%0}x-{(1oaCX$7eKsK`Xov46};D1EZhp|PRMV+iT zUU<8%D@kI-DZwB@@UMqaC%Dh%oX_(lBMJF9JS84OJgT8Neq|M@X|vcVJ+%#7Bg9#P zi5>t6fXmUS8LG+FX2%Ss#!-9xTbzHhhDcSfP0Y ziuHGY2(r_uF|MI{Fux*gYIrbq_x5L|d%B@Gd^>s7LP}yKpfmbci+7%u_$>dowccHk z1GFjpgR*s=WC|xqqt3&W$(lkF4+6Eo4NK%9aNAhq0i3N;%q1mBR`0ZSQb|f2*Qk+_ z3>a$)KC!#rqHgFUG^IN~P2RWQwG$YS_>>>RJYcvEJcVW}omM6_cO>K0(%C>nZ<#e@ z?(zTwvFasB9$=rY(+eXW&{XZ+g_!g){1@7u<45iR+_=OfHWru$95Xu zH%1Q;+EK%yh7eE8yB*{ zz-vCP5|ABPNfwvCC2x_(L4{4N!yas-0Dv>-Lp;I1as4iuu=b$?QR=|Nxt{_6)j&~g zLcoQVw?nE;x>49q0lZ$sQ`pSQTY+S%N((re9}F)VcPc|WzrwVMSJi`6JCKc?6rha{ z=_m5&PfF5Bg4#v_RrDC9{p{3c*M2zwz+1$vkHDb)>{J{59S<0Yu~FW}HXhJvDAmWS zSFJD20o9Uuwkc`+4{1jap;MthL$NdD-pZ%PEQa&hM9`%GQkIER_&(_oQ>>^6D8OKz zGsAz_%ou`(wss(arWKe&EU%_ypba{!CXZOu72+P+#&Ac) zZh>tO8jyC=cph+n0vLe5yjO~k038mpk}M+)l7gxZf}bYhFp5XG7sq_OADqLK((CoY zj1}KCxFS7po|eUvayE?f#=i~4-0)@=xAFBC4$dKAtkn@gnmC{VedB0vQU8QEBkP1`D7tN0K1CkMLO_x&XR0000Px$Q%OWYR7i=%R?89tAqWG<|NmusprtekbbIM?*iqyWAUf;k9CtUfbB>wCI=3Nd zkf&e|zMV0MyGy;9?L3P`+JU}vH`1-1@>YgochGRI-4)H10h(B| zu?)rikl@mNhYz!-W=#V~0KAmRK+~04F`1bkqP(mdn%5c6D6h*(rq>F9=Af6x^3-1f zL5A%URz$fnekt74ZgADU;s&o+tZ=(d4uHb%6NF*|d6@v*Hbn?_24XTYSs2`#s+{HB zt&Xj%;ir{>eoZXlre_D_j|PV6WL%OHRp!4I>_|q!^r> z=1*6(z84Z7Kc`qgR-c`O1<-b2v9y7hT^W!Oe-q>z!=01&K$^jK=yvNbnTDWEt0U-ExF~o%D-WCQ~}Km-Ad{Hoy_b3ZonT2xiD0D00000NkvXXu0mjf DEMm7A diff --git a/applications/external/blackjack/assets/endscreen.png b/applications/external/blackjack/assets/endscreen.png deleted file mode 100644 index 7a3abc927a5294323ffd3affee953e3a24efd14d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241 zcmV;~1Sb25P)Px(lSxEDRCt{2TidpyFbFlS`TtMWd9cG!Hn+q}(zN@jM^ixVU{Bfiefgmu*4_eq zJAMY}jGqCPWm!7r;g$3L+Imn*>BjnNl|BgGQqa#B&qGE)$6$O6L;2YsymX;_`@UNi zJ-9q?@6kL=F#tixT5A|b`$+t2@u~r+TvSl4%8v6L<9(=9W8q~0ps=j7v^ z45Ksnh#>o)f-qwUWznDOs`pOh^5O%Y;fz$1sFJMfDqMjFSt+HIBAf$7vJ}w^|5a)E zOJT5-g-Q_wtov`W2yfhu}C!ts;a@F)s;^rt6N@tXtx{oP}td4xiYzP0&Pj zV-_6;UKeycjM^`r_bE&=n4Llhb&u@n7CZwSITx>s%$wvSl+`u>9z@jA($~jT`7`q9 z20(wr0wA;*YS4)xwF#~bg^=bQKv&4$Jz&-VY$SMgwm4-Fs)l%}51@*nb^&*T!p^UA zzIQ5qJ!Y{=B8c=LddPB_iTc(>Z@siiU5fT$cteKbo5pq_b@scG9JkbzQ?H zg2QP32*6=YEy4m+lhu}w!h#~ep935l%vOXELi@anRkhYOS~iE;v<48`!7S`3nmf49 zg@UPh5}rQ=aRli&@#?}Vr%oyMtMs%HPzBs(TYHy=#1#yNUlIXgyJc+#9WSN>wHm8i zMNE$ZuaBI)6F+9%rCZy!S^HxL)21NH?`YXT12EuqFd_i(IB zGo}sWV2B8~)=6(F25S4ni+TR*T*BuJpzdUz;cit+F&r#xwSdP^gJLTeilKT&hX@$$ zttXd9l}&W6;=6d#;UZ>^rF#wFKB&GaGsxPs@!N%0}v(W`t_sVI*9y)=>{bRNX$ z!NSCieu_h^byB_CkOtK`i;r?B4-R?)LrlVaDCL^PGwPq#V#nd7!Ve1)%<^<@2CL*E zIvAk2Md4XE3>Tl2n$5#d2saI67;(~}e7gbA{%sXlBo>EV#!k&n;8PZHnIU+)0jeI= z%0E6qt9sY6&P$j-AEN&xoKX|cyjC-AT|Xm6*ms`CSS|UI$i@0N^Y6C~SdcGQ*|iwU z097Mp*!g^fF>W!yn2&lAH$BuXHNfxHJ`~n4d=h~H3WE>@g_|DMgovYfo~CC2i>_c< z-v3jsS(L%S_ek6${m2M&fH?=K6s;mDgurQKf?R|%3iiafccQx%*~S{cx0rml#eYIf zo0Dm3a#dSJkMI8$xP1~T<{{PyG!`ZeXmDc%1nv`@m}`p{{R=LiUa#`hf0 z=;9X#79M&ZFq8JLb=ijuFjLOC)|s9#z?AvtDwp~T<$Jc0(92j>00000NkvXXu0mjf Dj4@Yv diff --git a/applications/external/blackjack/blackjack.c b/applications/external/blackjack/blackjack.c deleted file mode 100644 index 8cf698d85..000000000 --- a/applications/external/blackjack/blackjack.c +++ /dev/null @@ -1,634 +0,0 @@ - -#include -#include -#include -#include -#include - -#include -#include "util.h" -#include "defines.h" -#include "common/card.h" -#include "common/dml.h" -#include "common/queue.h" -#include "util.h" -#include "ui.h" - -#include "blackjack_icons.h" -#include - -#define DEALER_MAX 17 - -void start_round(GameState* game_state); - -void init(GameState* game_state); - -static void draw_ui(Canvas* const canvas, const GameState* game_state) { - draw_money(canvas, game_state->player_score); - - draw_score(canvas, true, hand_count(game_state->player_cards, game_state->player_card_count)); - - if(!game_state->queue_state.running && game_state->state == GameStatePlay) { - render_menu(game_state->menu, canvas, 2, 47); - } -} - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const GameState* game_state = ctx; - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, 0, 0, 128, 64); - - if(game_state->state == GameStateStart) { - canvas_draw_icon(canvas, 0, 0, &I_blackjack); - } - if(game_state->state == GameStateGameOver) { - canvas_draw_icon(canvas, 0, 0, &I_endscreen); - } - - if(game_state->state == GameStatePlay || game_state->state == GameStateDealer) { - if(game_state->state == GameStatePlay) - draw_player_scene(canvas, game_state); - else - draw_dealer_scene(canvas, game_state); - render_queue(&(game_state->queue_state), game_state, canvas); - draw_ui(canvas, game_state); - } else if(game_state->state == GameStateSettings) { - settings_page(canvas, game_state); - } - - furi_mutex_release(game_state->mutex); -} - -//region card draw -Card draw_card(GameState* game_state) { - Card c = game_state->deck.cards[game_state->deck.index]; - game_state->deck.index++; - return c; -} - -void drawPlayerCard(void* ctx) { - GameState* game_state = ctx; - Card c = draw_card(game_state); - game_state->player_cards[game_state->player_card_count] = c; - game_state->player_card_count++; - if(game_state->player_score < game_state->settings.round_price || game_state->doubled) { - set_menu_state(game_state->menu, 0, false); - } -} - -void drawDealerCard(void* ctx) { - GameState* game_state = ctx; - Card c = draw_card(game_state); - game_state->dealer_cards[game_state->dealer_card_count] = c; - game_state->dealer_card_count++; -} -//endregion - -//region queue callbacks -void to_lose_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; - popup_frame(canvas); - elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You lost"); -} - -void to_bust_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; - popup_frame(canvas); - elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Busted!"); -} - -void to_draw_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; - popup_frame(canvas); - elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Draw"); -} - -void to_dealer_turn(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; - popup_frame(canvas); - elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Dealers turn"); -} - -void to_win_state(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; - popup_frame(canvas); - elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "You win"); -} - -void to_start(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - if(game_state->settings.message_duration == 0) return; - popup_frame(canvas); - elements_multiline_text_aligned(canvas, 64, 22, AlignCenter, AlignCenter, "Round started"); -} - -void before_start(void* ctx) { - GameState* game_state = ctx; - game_state->dealer_card_count = 0; - game_state->player_card_count = 0; -} - -void start(void* ctx) { - GameState* game_state = ctx; - start_round(game_state); -} - -void draw(void* ctx) { - GameState* game_state = ctx; - game_state->player_score += game_state->bet; - game_state->bet = 0; - enqueue( - &(game_state->queue_state), - game_state, - start, - before_start, - to_start, - game_state->settings.message_duration); -} - -void game_over(void* ctx) { - GameState* game_state = ctx; - game_state->state = GameStateGameOver; -} - -void lose(void* ctx) { - GameState* game_state = ctx; - game_state->state = GameStatePlay; - game_state->bet = 0; - if(game_state->player_score >= game_state->settings.round_price) { - enqueue( - &(game_state->queue_state), - game_state, - start, - before_start, - to_start, - game_state->settings.message_duration); - } else { - enqueue(&(game_state->queue_state), game_state, game_over, NULL, NULL, 0); - } -} - -void win(void* ctx) { - GameState* game_state = ctx; - game_state->state = GameStatePlay; - game_state->player_score += game_state->bet * 2; - game_state->bet = 0; - enqueue( - &(game_state->queue_state), - game_state, - start, - before_start, - to_start, - game_state->settings.message_duration); -} - -void dealerTurn(void* ctx) { - GameState* game_state = ctx; - game_state->state = GameStateDealer; -} - -float animationTime(const GameState* game_state) { - return (float)(furi_get_tick() - game_state->queue_state.start) / - (float)(game_state->settings.animation_duration); -} - -void dealer_card_animation(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - float t = animationTime(game_state); - - Card animatingCard = game_state->deck.cards[game_state->deck.index]; - if(game_state->dealer_card_count > 1) { - Vector end = card_pos_at_index(game_state->dealer_card_count); - draw_card_animation(animatingCard, (Vector){0, 64}, (Vector){0, 32}, end, t, true, canvas); - } else { - draw_card_animation( - animatingCard, - (Vector){32, -CARD_HEIGHT}, - (Vector){64, 32}, - (Vector){2, 2}, - t, - false, - canvas); - } -} - -void dealer_back_card_animation(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - float t = animationTime(game_state); - - Vector currentPos = - quadratic_2d((Vector){32, -CARD_HEIGHT}, (Vector){64, 32}, (Vector){13, 5}, t); - draw_card_back_at(currentPos.x, currentPos.y, canvas); -} - -void player_card_animation(const void* ctx, Canvas* const canvas) { - const GameState* game_state = ctx; - float t = animationTime(game_state); - - Card animatingCard = game_state->deck.cards[game_state->deck.index]; - Vector end = card_pos_at_index(game_state->player_card_count); - - draw_card_animation( - animatingCard, (Vector){32, -CARD_HEIGHT}, (Vector){0, 32}, end, t, true, canvas); -} -//endregion - -void player_tick(GameState* game_state) { - uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count); - if((game_state->doubled && score <= 21) || score == 21) { - enqueue( - &(game_state->queue_state), - game_state, - dealerTurn, - NULL, - to_dealer_turn, - game_state->settings.message_duration); - } else if(score > 21) { - enqueue( - &(game_state->queue_state), - game_state, - lose, - NULL, - to_bust_state, - game_state->settings.message_duration); - } else { - if(game_state->selectDirection == DirectionUp || - game_state->selectDirection == DirectionDown) { - move_menu(game_state->menu, game_state->selectDirection == DirectionUp ? -1 : 1); - } - - if(game_state->selectDirection == Select) { - activate_menu(game_state->menu, game_state); - } - } -} - -void dealer_tick(GameState* game_state) { - uint8_t dealer_score = hand_count(game_state->dealer_cards, game_state->dealer_card_count); - uint8_t player_score = hand_count(game_state->player_cards, game_state->player_card_count); - - if(dealer_score >= DEALER_MAX) { - if(dealer_score > 21 || dealer_score < player_score) { - dolphin_deed(DolphinDeedPluginGameWin); - enqueue( - &(game_state->queue_state), - game_state, - win, - NULL, - to_win_state, - game_state->settings.message_duration); - } else if(dealer_score > player_score) { - enqueue( - &(game_state->queue_state), - game_state, - lose, - NULL, - to_lose_state, - game_state->settings.message_duration); - } else if(dealer_score == player_score) { - enqueue( - &(game_state->queue_state), - game_state, - draw, - NULL, - to_draw_state, - game_state->settings.message_duration); - } - } else { - enqueue( - &(game_state->queue_state), - game_state, - drawDealerCard, - NULL, - dealer_card_animation, - game_state->settings.animation_duration); - } -} - -void settings_tick(GameState* game_state) { - if(game_state->selectDirection == DirectionDown && game_state->selectedMenu < 4) { - game_state->selectedMenu++; - } - if(game_state->selectDirection == DirectionUp && game_state->selectedMenu > 0) { - game_state->selectedMenu--; - } - - if(game_state->selectDirection == DirectionLeft || - game_state->selectDirection == DirectionRight) { - int nextScore = 0; - switch(game_state->selectedMenu) { - case 0: - nextScore = game_state->settings.starting_money; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 10; - else - nextScore += 10; - if(nextScore >= (int)game_state->settings.round_price && nextScore < 400) - game_state->settings.starting_money = nextScore; - break; - case 1: - nextScore = game_state->settings.round_price; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 10; - else - nextScore += 10; - if(nextScore >= 5 && nextScore <= (int)game_state->settings.starting_money) - game_state->settings.round_price = nextScore; - break; - case 2: - nextScore = game_state->settings.animation_duration; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 100; - else - nextScore += 100; - if(nextScore >= 0 && nextScore < 2000) - game_state->settings.animation_duration = nextScore; - break; - case 3: - nextScore = game_state->settings.message_duration; - if(game_state->selectDirection == DirectionLeft) - nextScore -= 100; - else - nextScore += 100; - if(nextScore >= 0 && nextScore < 2000) - game_state->settings.message_duration = nextScore; - break; - case 4: - game_state->settings.sound_effects = !game_state->settings.sound_effects; - default: - break; - } - } -} - -void tick(GameState* game_state) { - game_state->last_tick = furi_get_tick(); - bool queue_ran = run_queue(&(game_state->queue_state), game_state); - - switch(game_state->state) { - case GameStateGameOver: - case GameStateStart: - if(game_state->selectDirection == Select) - init(game_state); - else if(game_state->selectDirection == DirectionRight) { - game_state->selectedMenu = 0; - game_state->state = GameStateSettings; - } - break; - case GameStatePlay: - if(!game_state->started) { - game_state->selectedMenu = 0; - game_state->started = true; - enqueue( - &(game_state->queue_state), - game_state, - drawDealerCard, - NULL, - dealer_back_card_animation, - game_state->settings.animation_duration); - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); - enqueue( - &(game_state->queue_state), - game_state, - drawDealerCard, - NULL, - dealer_card_animation, - game_state->settings.animation_duration); - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); - } - if(!queue_ran) player_tick(game_state); - break; - case GameStateDealer: - if(!queue_ran) dealer_tick(game_state); - break; - case GameStateSettings: - settings_tick(game_state); - break; - default: - break; - } - - game_state->selectDirection = None; -} - -void start_round(GameState* game_state) { - game_state->menu->current_menu = 1; - game_state->player_card_count = 0; - game_state->dealer_card_count = 0; - set_menu_state(game_state->menu, 0, true); - game_state->menu->enabled = true; - game_state->started = false; - game_state->doubled = false; - game_state->queue_state.running = true; - shuffle_deck(&(game_state->deck)); - game_state->doubled = false; - game_state->bet = game_state->settings.round_price; - if(game_state->player_score < game_state->settings.round_price) { - game_state->state = GameStateGameOver; - } else { - game_state->player_score -= game_state->settings.round_price; - } - game_state->state = GameStatePlay; -} - -void init(GameState* game_state) { - set_menu_state(game_state->menu, 0, true); - game_state->menu->enabled = true; - game_state->menu->current_menu = 1; - game_state->settings = load_settings(); - game_state->last_tick = 0; - game_state->processing = true; - game_state->selectedMenu = 0; - game_state->player_score = game_state->settings.starting_money; - generate_deck(&(game_state->deck), 6); - start_round(game_state); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - AppEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); - AppEvent event = {.type = EventTypeTick}; - furi_message_queue_put(event_queue, &event, 0); -} - -void doubleAction(void* state) { - GameState* game_state = state; - if(!game_state->doubled && game_state->player_score >= game_state->settings.round_price) { - game_state->player_score -= game_state->settings.round_price; - game_state->bet += game_state->settings.round_price; - game_state->doubled = true; - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); - game_state->player_cards[game_state->player_card_count] = - game_state->deck.cards[game_state->deck.index]; - uint8_t score = hand_count(game_state->player_cards, game_state->player_card_count + 1); - if(score > 21) { - enqueue( - &(game_state->queue_state), - game_state, - lose, - NULL, - to_bust_state, - game_state->settings.message_duration); - } else { - enqueue( - &(game_state->queue_state), - game_state, - dealerTurn, - NULL, - to_dealer_turn, - game_state->settings.message_duration); - } - set_menu_state(game_state->menu, 0, false); - } -} - -void hitAction(void* state) { - GameState* game_state = state; - enqueue( - &(game_state->queue_state), - game_state, - drawPlayerCard, - NULL, - player_card_animation, - game_state->settings.animation_duration); -} -void stayAction(void* state) { - GameState* game_state = state; - enqueue( - &(game_state->queue_state), - game_state, - dealerTurn, - NULL, - to_dealer_turn, - game_state->settings.message_duration); -} - -int32_t blackjack_app(void* p) { - UNUSED(p); - - int32_t return_code = 0; - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); - - GameState* game_state = malloc(sizeof(GameState)); - game_state->menu = malloc(sizeof(Menu)); - game_state->menu->menu_width = 40; - init(game_state); - add_menu(game_state->menu, "Double", doubleAction); - add_menu(game_state->menu, "Hit", hitAction); - add_menu(game_state->menu, "Stay", stayAction); - set_card_graphics(&I_card_graphics); - - game_state->state = GameStateStart; - - game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!game_state->mutex) { - FURI_LOG_E(APP_NAME, "cannot create mutex\r\n"); - return_code = 255; - goto free_and_exit; - } - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, game_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - FuriTimer* timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25); - - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - AppEvent event; - - // Call dolphin deed on game start - dolphin_deed(DolphinDeedPluginGameStart); - - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - if(event.input.type == InputTypePress) { - switch(event.input.key) { - case InputKeyUp: - game_state->selectDirection = DirectionUp; - break; - case InputKeyDown: - game_state->selectDirection = DirectionDown; - break; - case InputKeyRight: - game_state->selectDirection = DirectionRight; - break; - case InputKeyLeft: - game_state->selectDirection = DirectionLeft; - break; - case InputKeyBack: - if(game_state->state == GameStateSettings) { - game_state->state = GameStateStart; - save_settings(game_state->settings); - } else - processing = false; - break; - case InputKeyOk: - game_state->selectDirection = Select; - break; - default: - break; - } - } - } else if(event.type == EventTypeTick) { - tick(game_state); - processing = game_state->processing; - } - } - view_port_update(view_port); - furi_mutex_release(game_state->mutex); - } - - furi_timer_free(timer); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_mutex_free(game_state->mutex); - -free_and_exit: - free(game_state->deck.cards); - free_menu(game_state->menu); - queue_clear(&(game_state->queue_state)); - free(game_state); - furi_message_queue_free(event_queue); - - return return_code; -} \ No newline at end of file diff --git a/applications/external/blackjack/blackjack_10px.png b/applications/external/blackjack/blackjack_10px.png deleted file mode 100644 index 7382d6358bde65d970575fb40995145d5d3e26d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&F%}28J29*~C-V}>VGHmHasB`Q zKad%E=yDy9lJ|6R4B?oWoZ!IP)59UwbM^#Bva!*jn+{A(9T(Wx892Nd)DK8X1_G5b Nc)I$ztaD0e0sxqvA7ual diff --git a/applications/external/blackjack/common/card.c b/applications/external/blackjack/common/card.c deleted file mode 100644 index 88228fda4..000000000 --- a/applications/external/blackjack/common/card.c +++ /dev/null @@ -1,353 +0,0 @@ -#include "card.h" -#include "dml.h" -#include "ui.h" - -#define CARD_DRAW_X_START 108 -#define CARD_DRAW_Y_START 38 -#define CARD_DRAW_X_SPACE 10 -#define CARD_DRAW_Y_SPACE 8 -#define CARD_DRAW_X_OFFSET 4 -#define CARD_DRAW_FIRST_ROW_LENGTH 7 - -uint8_t pips[4][3] = { - {21, 10, 7}, //spades - {7, 10, 7}, //hearts - {0, 10, 7}, //diamonds - {14, 10, 7}, //clubs -}; -uint8_t letters[13][3] = { - {0, 0, 5}, - {5, 0, 5}, - {10, 0, 5}, - {15, 0, 5}, - {20, 0, 5}, - {25, 0, 5}, - {30, 0, 5}, - {0, 5, 5}, - {5, 5, 5}, - {10, 5, 5}, - {15, 5, 5}, - {20, 5, 5}, - {25, 5, 5}, -}; - -//region Player card positions -uint8_t playerCardPositions[22][4] = { - //first row - {108, 38}, - {98, 38}, - {88, 38}, - {78, 38}, - {68, 38}, - {58, 38}, - {48, 38}, - {38, 38}, - //second row - {104, 26}, - {94, 26}, - {84, 26}, - {74, 26}, - {64, 26}, - {54, 26}, - {44, 26}, - //third row - {99, 14}, - {89, 14}, - {79, 14}, - {69, 14}, - {59, 14}, - {49, 14}, -}; -//endregion -Icon* card_graphics = NULL; - -void set_card_graphics(const Icon* graphics) { - card_graphics = (Icon*)graphics; -} - -void draw_card_at_colored( - int8_t pos_x, - int8_t pos_y, - uint8_t pip, - uint8_t character, - bool inverted, - Canvas* const canvas) { - DrawMode primary = inverted ? Black : White; - DrawMode secondary = inverted ? White : Black; - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, primary); - draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - - uint8_t* drawInfo = pips[pip]; - uint8_t px = drawInfo[0], py = drawInfo[1], s = drawInfo[2]; - - uint8_t left = pos_x + 2; - uint8_t right = (pos_x + CARD_WIDTH - s - 2); - uint8_t top = pos_y + 2; - uint8_t bottom = (pos_y + CARD_HEIGHT - s - 2); - - draw_icon_clip(canvas, card_graphics, right, top, px, py, s, s, secondary); - draw_icon_clip_flipped(canvas, card_graphics, left, bottom, px, py, s, s, secondary); - - drawInfo = letters[character]; - px = drawInfo[0], py = drawInfo[1], s = drawInfo[2]; - left = pos_x + 2; - right = (pos_x + CARD_WIDTH - s - 2); - top = pos_y + 2; - bottom = (pos_y + CARD_HEIGHT - s - 2); - - draw_icon_clip(canvas, card_graphics, left, top + 1, px, py, s, s, secondary); - draw_icon_clip_flipped(canvas, card_graphics, right, bottom - 1, px, py, s, s, secondary); -} - -void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas* const canvas) { - draw_card_at_colored(pos_x, pos_y, pip, character, false, canvas); -} - -void draw_deck(const Card* cards, uint8_t count, Canvas* const canvas) { - for(int i = count - 1; i >= 0; i--) { - draw_card_at( - playerCardPositions[i][0], - playerCardPositions[i][1], - cards[i].pip, - cards[i].character, - canvas); - } -} - -Vector card_pos_at_index(uint8_t index) { - return (Vector){playerCardPositions[index][0], playerCardPositions[index][1]}; -} - -void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas) { - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, White); - draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - - draw_icon_clip(canvas, card_graphics, pos_x + 1, pos_y + 1, 35, 0, 15, 21, Black); -} - -void generate_deck(Deck* deck_ptr, uint8_t deck_count) { - uint16_t counter = 0; - if(deck_ptr->cards != NULL) { - free(deck_ptr->cards); - } - - deck_ptr->deck_count = deck_count; - deck_ptr->card_count = deck_count * 52; - deck_ptr->cards = malloc(sizeof(Card) * deck_ptr->card_count); - - for(uint8_t deck = 0; deck < deck_count; deck++) { - for(uint8_t pip = 0; pip < 4; pip++) { - for(uint8_t label = 0; label < 13; label++) { - deck_ptr->cards[counter] = (Card){pip, label, false, false}; - counter++; - } - } - } -} - -void shuffle_deck(Deck* deck_ptr) { - srand(DWT->CYCCNT); - deck_ptr->index = 0; - int max = deck_ptr->deck_count * 52; - for(int i = 0; i < max; i++) { - int r = i + (rand() % (max - i)); - Card tmp = deck_ptr->cards[i]; - deck_ptr->cards[i] = deck_ptr->cards[r]; - deck_ptr->cards[r] = tmp; - } -} - -uint8_t hand_count(const Card* cards, uint8_t count) { - uint8_t aceCount = 0; - uint8_t score = 0; - - for(uint8_t i = 0; i < count; i++) { - if(cards[i].character == 12) - aceCount++; - else { - if(cards[i].character > 8) - score += 10; - else - score += cards[i].character + 2; - } - } - - for(uint8_t i = 0; i < aceCount; i++) { - if((score + 11 + (aceCount - 1)) <= 21) - score += 11; - else - score++; - } - - return score; -} - -void draw_card_animation( - Card animatingCard, - Vector from, - Vector control, - Vector to, - float t, - bool extra_margin, - Canvas* const canvas) { - float time = t; - if(extra_margin) { - time += 0.2; - } - - Vector currentPos = quadratic_2d(from, control, to, time); - if(t > 1) { - draw_card_at( - currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas); - } else { - if(t < 0.5) - draw_card_back_at(currentPos.x, currentPos.y, canvas); - else - draw_card_at( - currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas); - } -} - -void init_hand(Hand* hand_ptr, uint8_t count) { - hand_ptr->cards = malloc(sizeof(Card) * count); - hand_ptr->index = 0; - hand_ptr->max = count; -} - -void free_hand(Hand* hand_ptr) { - FURI_LOG_D("CARD", "Freeing hand"); - free(hand_ptr->cards); -} - -void add_to_hand(Hand* hand_ptr, Card card) { - FURI_LOG_D("CARD", "Adding to hand"); - if(hand_ptr->index < hand_ptr->max) { - hand_ptr->cards[hand_ptr->index] = card; - hand_ptr->index++; - } -} - -void draw_card_space(int16_t pos_x, int16_t pos_y, bool highlighted, Canvas* const canvas) { - if(highlighted) { - draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - draw_rounded_box_frame( - canvas, pos_x + 2, pos_y + 2, CARD_WIDTH - 4, CARD_HEIGHT - 4, White); - } else { - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - draw_rounded_box_frame( - canvas, pos_x + 2, pos_y + 2, CARD_WIDTH - 4, CARD_HEIGHT - 4, White); - } -} - -int first_non_flipped_card(Hand hand) { - for(int i = 0; i < hand.index; i++) { - if(!hand.cards[i].flipped) { - return i; - } - } - return hand.index; -} - -void draw_hand_column( - Hand hand, - int16_t pos_x, - int16_t pos_y, - int8_t highlight, - Canvas* const canvas) { - if(hand.index == 0) { - draw_card_space(pos_x, pos_y, highlight > 0, canvas); - if(highlight == 0) - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Inverse); - return; - } - - int loopEnd = hand.index; - int hStart = max(loopEnd - 4, 0); - int pos = 0; - int first = first_non_flipped_card(hand); - bool wastop = false; - if(first >= 0 && first <= hStart && highlight != first) { - if(first > 0) { - draw_card_back_at(pos_x, pos_y + pos, canvas); - pos += 4; - hStart++; - wastop = true; - } - draw_card_at_colored( - pos_x, pos_y + pos, hand.cards[first].pip, hand.cards[first].character, false, canvas); - pos += 8; - hStart++; - } - if(hStart > highlight && highlight >= 0) { - if(!wastop && first > 0) { - draw_card_back_at(pos_x, pos_y + pos, canvas); - pos += 4; - hStart++; - } - draw_card_at_colored( - pos_x, - pos_y + pos, - hand.cards[highlight].pip, - hand.cards[highlight].character, - true, - canvas); - pos += 8; - hStart++; - } - for(int i = hStart; i < loopEnd; i++, pos += 4) { - if(hand.cards[i].flipped) { - draw_card_back_at(pos_x, pos_y + pos, canvas); - if(i == highlight) - draw_rounded_box( - canvas, pos_x + 1, pos_y + pos + 1, CARD_WIDTH - 2, CARD_HEIGHT - 2, Inverse); - } else { - draw_card_at_colored( - pos_x, - pos_y + pos, - hand.cards[i].pip, - hand.cards[i].character, - (i == highlight), - canvas); - if(i == highlight || i == first) pos += 4; - } - } -} - -Card remove_from_deck(uint16_t index, Deck* deck) { - FURI_LOG_D("CARD", "Removing from deck"); - Card result = {0, 0, true, false}; - if(deck->card_count > 0) { - deck->card_count--; - for(int i = 0, curr_index = 0; i <= deck->card_count; i++) { - if(i != index) { - deck->cards[curr_index] = deck->cards[i]; - curr_index++; - } else { - result = deck->cards[i]; - } - } - if(deck->index >= 0) { - deck->index--; - } - } - return result; -} - -void extract_hand_region(Hand* hand, Hand* to, uint8_t start_index) { - FURI_LOG_D("CARD", "Extracting hand region"); - if(start_index >= hand->index) return; - - for(uint8_t i = start_index; i < hand->index; i++) { - add_to_hand(to, hand->cards[i]); - } - hand->index = start_index; -} - -void add_hand_region(Hand* to, Hand* from) { - FURI_LOG_D("CARD", "Adding hand region"); - if((to->index + from->index) <= to->max) { - for(int i = 0; i < from->index; i++) { - add_to_hand(to, from->cards[i]); - } - } -} diff --git a/applications/external/blackjack/common/card.h b/applications/external/blackjack/common/card.h deleted file mode 100644 index 8e5e23bbf..000000000 --- a/applications/external/blackjack/common/card.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include -#include -#include -#include "dml.h" - -#define CARD_HEIGHT 23 -#define CARD_HALF_HEIGHT 11 -#define CARD_WIDTH 17 -#define CARD_HALF_WIDTH 8 - -//region types -typedef struct { - uint8_t pip; //Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - uint8_t character; //Card letter [0-12], 0 means 2, 12 is Ace - bool disabled; - bool flipped; -} Card; - -typedef struct { - uint8_t deck_count; //Number of decks used - Card* cards; //Cards in the deck - int card_count; - int index; //Card index (to know where we at in the deck) -} Deck; - -typedef struct { - Card* cards; //Cards in the deck - uint8_t index; //Current index - uint8_t max; //How many cards we want to store -} Hand; -//endregion - -void set_card_graphics(const Icon* graphics); - -/** - * Gets card coordinates at the index (range: 0-20). - * - * @param index Index to check 0-20 - * @return Position of the card - */ -Vector card_pos_at_index(uint8_t index); - -/** - * Draws card at a given coordinate (top-left corner) - * - * @param pos_x X position - * @param pos_y Y position - * @param pip Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - * @param character Letter [0-12] 0 is 2, 12 is A - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas* const canvas); - -/** - * Draws card at a given coordinate (top-left corner) - * - * @param pos_x X position - * @param pos_y Y position - * @param pip Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - * @param character Letter [0-12] 0 is 2, 12 is A - * @param inverted Invert colors - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_at_colored( - int8_t pos_x, - int8_t pos_y, - uint8_t pip, - uint8_t character, - bool inverted, - Canvas* const canvas); - -/** - * Draws 'count' cards at the bottom right corner - * - * @param cards List of cards - * @param count Count of cards - * @param canvas Pointer to Flipper's canvas object - */ -void draw_deck(const Card* cards, uint8_t count, Canvas* const canvas); - -/** - * Draws card back at a given coordinate (top-left corner) - * - * @param pos_x X coordinate - * @param pos_y Y coordinate - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas); - -/** - * Generates the deck - * - * @param deck_ptr Pointer to the deck - * @param deck_count Number of decks - */ -void generate_deck(Deck* deck_ptr, uint8_t deck_count); - -/** - * Shuffles the deck - * - * @param deck_ptr Pointer to the deck - */ -void shuffle_deck(Deck* deck_ptr); - -/** - * Calculates the hand count for blackjack - * - * @param cards List of cards - * @param count Count of cards - * @return Hand value - */ -uint8_t hand_count(const Card* cards, uint8_t count); - -/** - * Draws card animation - * - * @param animatingCard Card to animate - * @param from Starting position - * @param control Quadratic lerp control point - * @param to End point - * @param t Current time (0-1) - * @param extra_margin Use extra margin at the end (arrives 0.2 unit before the end so it can stay there a bit) - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_animation( - Card animatingCard, - Vector from, - Vector control, - Vector to, - float t, - bool extra_margin, - Canvas* const canvas); - -/** - * Init hand pointer - * @param hand_ptr Pointer to hand - * @param count Number of cards we want to store - */ -void init_hand(Hand* hand_ptr, uint8_t count); - -/** - * Free hand resources - * @param hand_ptr Pointer to hand - */ -void free_hand(Hand* hand_ptr); - -/** - * Add card to hand - * @param hand_ptr Pointer to hand - * @param card Card to add - */ -void add_to_hand(Hand* hand_ptr, Card card); - -/** - * Draw card placement position at coordinate - * @param pos_x X coordinate - * @param pos_y Y coordinate - * @param highlighted Apply highlight effect - * @param canvas Canvas object - */ -void draw_card_space(int16_t pos_x, int16_t pos_y, bool highlighted, Canvas* const canvas); - -/** - * Draws a column of card, displaying the last [max_cards] cards on the list - * @param hand Hand object - * @param pos_x X coordinate to draw - * @param pos_y Y coordinate to draw - * @param highlight Index to highlight, negative means no highlight - * @param canvas Canvas object - */ -void draw_hand_column( - Hand hand, - int16_t pos_x, - int16_t pos_y, - int8_t highlight, - Canvas* const canvas); - -/** - * Removes a card from the deck (Be aware, if you remove the first item, the deck index will be at -1 so you have to handle that) - * @param index Index to remove - * @param deck Deck reference - * @return The removed card - */ -Card remove_from_deck(uint16_t index, Deck* deck); - -int first_non_flipped_card(Hand hand); - -void extract_hand_region(Hand* hand, Hand* to, uint8_t start_index); - -void add_hand_region(Hand* to, Hand* from); \ No newline at end of file diff --git a/applications/external/blackjack/common/dml.c b/applications/external/blackjack/common/dml.c deleted file mode 100644 index b9a0e395f..000000000 --- a/applications/external/blackjack/common/dml.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "dml.h" -#include - -float lerp(float v0, float v1, float t) { - if(t > 1) return v1; - return (1 - t) * v0 + t * v1; -} - -Vector lerp_2d(Vector start, Vector end, float t) { - return (Vector){ - lerp(start.x, end.x, t), - lerp(start.y, end.y, t), - }; -} - -Vector quadratic_2d(Vector start, Vector control, Vector end, float t) { - return lerp_2d(lerp_2d(start, control, t), lerp_2d(control, end, t), t); -} - -Vector vector_add(Vector a, Vector b) { - return (Vector){a.x + b.x, a.y + b.y}; -} - -Vector vector_sub(Vector a, Vector b) { - return (Vector){a.x - b.x, a.y - b.y}; -} - -Vector vector_mul_components(Vector a, Vector b) { - return (Vector){a.x * b.x, a.y * b.y}; -} - -Vector vector_div_components(Vector a, Vector b) { - return (Vector){a.x / b.x, a.y / b.y}; -} - -Vector vector_normalized(Vector a) { - float length = vector_magnitude(a); - return (Vector){a.x / length, a.y / length}; -} - -float vector_magnitude(Vector a) { - return sqrt(a.x * a.x + a.y * a.y); -} - -float vector_distance(Vector a, Vector b) { - return vector_magnitude(vector_sub(a, b)); -} - -float vector_dot(Vector a, Vector b) { - Vector _a = vector_normalized(a); - Vector _b = vector_normalized(b); - return _a.x * _b.x + _a.y * _b.y; -} \ No newline at end of file diff --git a/applications/external/blackjack/common/dml.h b/applications/external/blackjack/common/dml.h deleted file mode 100644 index 0e1a23e23..000000000 --- a/applications/external/blackjack/common/dml.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// Doofy's Math library -// - -#pragma once - -typedef struct { - float x; - float y; -} Vector; - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) -#define abs(x) ((x) > 0 ? (x) : -(x)) - -/** - * Lerp function - * - * @param v0 Start value - * @param v1 End value - * @param t Time (0-1 range) - * @return Point between v0-v1 at a given time - */ -float lerp(float v0, float v1, float t); - -/** - * 2D lerp function - * - * @param start Start vector - * @param end End vector - * @param t Time (0-1 range) - * @return 2d Vector between start and end at time - */ -Vector lerp_2d(Vector start, Vector end, float t); - -/** - * Quadratic lerp function - * - * @param start Start vector - * @param control Control point - * @param end End vector - * @param t Time (0-1 range) - * @return 2d Vector at time - */ -Vector quadratic_2d(Vector start, Vector control, Vector end, float t); - -/** - * Add vector components together - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_add(Vector a, Vector b); - -/** - * Subtract vector components together - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_sub(Vector a, Vector b); - -/** - * Multiplying vector components together - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_mul_components(Vector a, Vector b); - -/** - * Dividing vector components - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_div_components(Vector a, Vector b); - -/** - * Calculating Vector length - * - * @param a Direction vector - * @return Length of the vector - */ -float vector_magnitude(Vector a); - -/** - * Get a normalized vector (length of 1) - * - * @param a Direction vector - * @return Normalized vector - */ -Vector vector_normalized(Vector a); - -/** - * Calculate two vector's distance - * - * @param a First vector - * @param b Second vector - * @return Distance between vectors - */ -float vector_distance(Vector a, Vector b); - -/** - * Calculate the dot product of the vectors. - * No need to normalize, it will do it - * - * @param a First vector - * @param b Second vector - * @return value from -1 to 1 - */ -float vector_dot(Vector a, Vector b); diff --git a/applications/external/blackjack/common/menu.c b/applications/external/blackjack/common/menu.c deleted file mode 100644 index ffc3921b7..000000000 --- a/applications/external/blackjack/common/menu.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "menu.h" - -void add_menu(Menu* menu, const char* name, void (*callback)(void*)) { - MenuItem* items = menu->items; - - menu->items = malloc(sizeof(MenuItem) * (menu->menu_count + 1)); - for(uint8_t i = 0; i < menu->menu_count; i++) { - menu->items[i] = items[i]; - } - free(items); - - menu->items[menu->menu_count] = (MenuItem){name, true, callback}; - menu->menu_count++; -} - -void free_menu(Menu* menu) { - free(menu->items); - free(menu); -} - -void set_menu_state(Menu* menu, uint8_t index, bool state) { - if(menu->menu_count > index) { - menu->items[index].enabled = state; - } - if(!state && menu->current_menu == index) move_menu(menu, 1); -} - -void move_menu(Menu* menu, int8_t direction) { - if(!menu->enabled) return; - int max = menu->menu_count; - for(int8_t i = 0; i < max; i++) { - FURI_LOG_D( - "MENU", - "Iteration %i, current %i, direction %i, state %i", - i, - menu->current_menu, - direction, - menu->items[menu->current_menu].enabled ? 1 : 0); - if(direction < 0 && menu->current_menu == 0) { - menu->current_menu = menu->menu_count - 1; - } else { - menu->current_menu = (menu->current_menu + direction) % menu->menu_count; - } - FURI_LOG_D( - "MENU", - "After process current %i, direction %i, state %i", - menu->current_menu, - direction, - menu->items[menu->current_menu].enabled ? 1 : 0); - if(menu->items[menu->current_menu].enabled) { - FURI_LOG_D("MENU", "Next menu %i", menu->current_menu); - return; - } - } - FURI_LOG_D("MENU", "Not found, setting false"); - menu->enabled = false; -} - -void activate_menu(Menu* menu, void* state) { - if(!menu->enabled) return; - menu->items[menu->current_menu].callback(state); -} - -void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y) { - if(!menu->enabled) return; - canvas_set_color(canvas, ColorWhite); - canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); - - uint8_t w = pos_x + menu->menu_width; - uint8_t h = pos_y + 10; - uint8_t p1x = pos_x + 2; - uint8_t p2x = pos_x + menu->menu_width - 2; - uint8_t p1y = pos_y + 2; - uint8_t p2y = pos_y + 8; - - canvas_set_color(canvas, ColorBlack); - canvas_draw_line(canvas, p1x, pos_y, p2x, pos_y); - canvas_draw_line(canvas, p1x, h, p2x, h); - canvas_draw_line(canvas, pos_x, p1y, pos_x, p2y); - canvas_draw_line(canvas, w, p1y, w, p2y); - canvas_draw_dot(canvas, pos_x + 1, pos_y + 1); - canvas_draw_dot(canvas, w - 1, pos_y + 1); - canvas_draw_dot(canvas, w - 1, h - 1); - canvas_draw_dot(canvas, pos_x + 1, h - 1); - - // canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - pos_x + menu->menu_width / 2, - pos_y + 6, - AlignCenter, - AlignCenter, - menu->items[menu->current_menu].name); - //9*5 - int center = pos_x + menu->menu_width / 2; - for(uint8_t i = 0; i < 4; i++) { - for(int8_t j = -i; j <= i; j++) { - canvas_draw_dot(canvas, center + j, pos_y - 4 + i); - canvas_draw_dot(canvas, center + j, pos_y + 14 - i); - } - } -} \ No newline at end of file diff --git a/applications/external/blackjack/common/menu.h b/applications/external/blackjack/common/menu.h deleted file mode 100644 index 9f2852522..000000000 --- a/applications/external/blackjack/common/menu.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include -#include - -typedef struct { - const char* name; //Name of the menu - bool enabled; //Is the menu item enabled (it will not render, you cannot select it) - - void (*callback)( - void* state); //Callback for when the activate_menu is called while this menu is selected -} MenuItem; - -typedef struct { - MenuItem* items; //list of menu items - uint8_t menu_count; //count of menu items (do not change) - uint8_t current_menu; //currently selected menu item - uint8_t menu_width; //width of the menu - bool enabled; //is the menu enabled (it will not render and accept events when disabled) -} Menu; - -/** - * Cleans up the pointers used by the menu - * - * @param menu Pointer of the menu to clean up - */ -void free_menu(Menu* menu); - -/** - * Add a new menu item - * - * @param menu Pointer of the menu - * @param name Name of the menu item - * @param callback Callback called on activation - */ -void add_menu(Menu* menu, const char* name, void (*callback)(void*)); - -/** - * Setting menu item to be enabled/disabled - * - * @param menu Pointer of the menu - * @param index Menu index to set - * @param state Enabled (true), Disabled(false) - */ -void set_menu_state(Menu* menu, uint8_t index, bool state); - -/** - * Moves selection up or down - * - * @param menu Pointer of the menu - * @param direction Direction to move -1 down, 1 up - */ -void move_menu(Menu* menu, int8_t direction); - -/** - * Triggers the current menu callback - * - * @param menu Pointer of the menu - * @param state Usually your application state - */ -void activate_menu(Menu* menu, void* state); - -/** - * Renders the menu at a coordinate (call it in your render function). - * - * Keep in mind that Flipper has a 128x64 pixel screen resolution and the coordinate - * you give is the menu's rectangle top-left corner (arrows not included). - * The rectangle height is 10 px, the arrows have a 4 pixel height. Space needed is 18px. - * The width of the menu can be configured in the menu object. - * - * - * @param menu Pointer of the menu - * @param canvas Flippers Canvas pointer - * @param pos_x X position to draw - * @param pos_y Y position to draw - */ -void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y); \ No newline at end of file diff --git a/applications/external/blackjack/common/queue.c b/applications/external/blackjack/common/queue.c deleted file mode 100644 index a80373460..000000000 --- a/applications/external/blackjack/common/queue.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "queue.h" - -void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas) { - if(queue_state->current != NULL && queue_state->current->render != NULL) - ((QueueItem*)queue_state->current)->render(app_state, canvas); -} - -bool run_queue(QueueState* queue_state, void* app_state) { - if(queue_state->current != NULL) { - queue_state->running = true; - if((furi_get_tick() - queue_state->start) >= queue_state->current->duration) - dequeue(queue_state, app_state); - - return true; - } - return false; -} - -void dequeue(QueueState* queue_state, void* app_state) { - ((QueueItem*)queue_state->current)->callback(app_state); - QueueItem* f = queue_state->current; - queue_state->current = f->next; - free(f); - if(queue_state->current != NULL) { - if(queue_state->current->start != NULL) queue_state->current->start(app_state); - queue_state->start = furi_get_tick(); - } else { - queue_state->running = false; - } -} - -void queue_clear(QueueState* queue_state) { - queue_state->running = false; - QueueItem* curr = queue_state->current; - while(curr != NULL) { - QueueItem* f = curr; - curr = curr->next; - free(f); - } -} - -void enqueue( - QueueState* queue_state, - void* app_state, - void (*done)(void* state), - void (*start)(void* state), - void (*render)(const void* state, Canvas* const canvas), - uint32_t duration) { - QueueItem* next; - if(queue_state->current == NULL) { - queue_state->start = furi_get_tick(); - queue_state->current = malloc(sizeof(QueueItem)); - next = queue_state->current; - if(next->start != NULL) next->start(app_state); - - } else { - next = queue_state->current; - while(next->next != NULL) { - next = (QueueItem*)(next->next); - } - next->next = malloc(sizeof(QueueItem)); - next = next->next; - } - next->callback = done; - next->render = render; - next->start = start; - next->duration = duration; - next->next = NULL; -} \ No newline at end of file diff --git a/applications/external/blackjack/common/queue.h b/applications/external/blackjack/common/queue.h deleted file mode 100644 index dcfe0c091..000000000 --- a/applications/external/blackjack/common/queue.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include - -typedef struct { - void (*callback)(void* state); //Callback for when the item is dequeued - void (*render)( - const void* state, - Canvas* const canvas); //Callback for the rendering loop while this item is running - void (*start)(void* state); //Callback when this item is started running - void* next; //Pointer to the next item - uint32_t duration; //duration of the item -} QueueItem; - -typedef struct { - unsigned int start; //current queue item start time - QueueItem* current; //current queue item - bool running; //is the queue running -} QueueState; - -/** - * Enqueue a new item. - * - * @param queue_state The queue state pointer - * @param app_state Your app state - * @param done Callback for dequeue event - * @param start Callback for when the item is activated - * @param render Callback to render loop if needed - * @param duration Length of the item - */ -void enqueue( - QueueState* queue_state, - void* app_state, - void (*done)(void* state), - void (*start)(void* state), - void (*render)(const void* state, Canvas* const canvas), - uint32_t duration); -/** - * Clears all queue items - * - * @param queue_state The queue state pointer - */ -void queue_clear(QueueState* queue_state); - -/** - * Dequeues the active queue item. Usually you don't need to call it directly. - * - * @param queue_state The queue state pointer - * @param app_state Your application state - */ -void dequeue(QueueState* queue_state, void* app_state); - -/** - * Runs the queue logic (place it in your tick function) - * - * @param queue_state The queue state pointer - * @param app_state Your application state - * @return FALSE when there is nothing to run, TRUE otherwise - */ -bool run_queue(QueueState* queue_state, void* app_state); - -/** - * Calls the currently active queue items render callback (if there is any) - * - * @param queue_state The queue state pointer - * @param app_state Your application state - * @param canvas Pointer to Flipper's canvas object - */ -void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas); \ No newline at end of file diff --git a/applications/external/blackjack/common/ui.c b/applications/external/blackjack/common/ui.c deleted file mode 100644 index 032877a9e..000000000 --- a/applications/external/blackjack/common/ui.c +++ /dev/null @@ -1,257 +0,0 @@ -#include "ui.h" -#include -#include -#include -#include -#include -#include - -TileMap* tileMap; -uint8_t tileMapCount = 0; - -void ui_cleanup() { - if(tileMap != NULL) { - for(uint8_t i = 0; i < tileMapCount; i++) { - if(tileMap[i].data != NULL) free(tileMap[i].data); - } - free(tileMap); - } -} - -void add_new_tilemap(uint8_t* data, unsigned long iconId) { - TileMap* old = tileMap; - tileMapCount++; - tileMap = malloc(sizeof(TileMap) * tileMapCount); - if(tileMapCount > 1) { - for(uint8_t i = 0; i < tileMapCount; i++) tileMap[i] = old[i]; - } - tileMap[tileMapCount - 1] = (TileMap){data, iconId}; -} - -uint8_t* get_tilemap(unsigned long icon_id) { - for(uint8_t i = 0; i < tileMapCount; i++) { - if(tileMap[i].iconId == icon_id) return tileMap[i].data; - } - - return NULL; -} - -uint32_t pixel_index(uint8_t x, uint8_t y) { - return y * SCREEN_WIDTH + x; -} - -bool in_screen(int16_t x, int16_t y) { - return x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT; -} - -unsigned flipBit(uint8_t x, uint8_t bit) { - return x ^ (1 << bit); -} - -unsigned setBit(uint8_t x, uint8_t bit) { - return x | (1 << bit); -} - -unsigned unsetBit(uint8_t x, uint8_t bit) { - return x & ~(1 << bit); -} - -bool test_pixel(uint8_t* data, uint8_t x, uint8_t y, uint8_t w) { - uint8_t current_bit = (y % 8); - uint8_t current_row = ((y - current_bit) / 8); - uint8_t current_value = data[current_row * w + x]; - return current_value & (1 << current_bit); -} - -uint8_t* get_buffer(Canvas* const canvas) { - return canvas->fb.tile_buf_ptr; - // return canvas_get_buffer(canvas); -} -uint8_t* make_buffer() { - return malloc(sizeof(uint8_t) * 8 * 128); -} -void clone_buffer(uint8_t* canvas, uint8_t* data) { - for(int i = 0; i < 1024; i++) { - data[i] = canvas[i]; - } -} - -bool read_pixel(Canvas* const canvas, int16_t x, int16_t y) { - if(in_screen(x, y)) { - return test_pixel(get_buffer(canvas), x, y, SCREEN_WIDTH); - } - return false; -} - -void set_pixel(Canvas* const canvas, int16_t x, int16_t y, DrawMode draw_mode) { - if(in_screen(x, y)) { - uint8_t current_bit = (y % 8); - uint8_t current_row = ((y - current_bit) / 8); - uint32_t i = pixel_index(x, current_row); - uint8_t* buffer = get_buffer(canvas); - - uint8_t current_value = buffer[i]; - if(draw_mode == Inverse) { - buffer[i] = flipBit(current_value, current_bit); - } else { - if(draw_mode == White) { - buffer[i] = unsetBit(current_value, current_bit); - } else { - buffer[i] = setBit(current_value, current_bit); - } - } - } -} - -void draw_line( - Canvas* const canvas, - int16_t x1, - int16_t y1, - int16_t x2, - int16_t y2, - DrawMode draw_mode) { - for(int16_t x = x2; x >= x1; x--) { - for(int16_t y = y2; y >= y1; y--) { - set_pixel(canvas, x, y, draw_mode); - } - } -} - -void draw_rounded_box_frame( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode draw_mode) { - int16_t xMinCorner = x + 1; - int16_t xMax = x + w - 1; - int16_t xMaxCorner = x + w - 2; - int16_t yMinCorner = y + 1; - int16_t yMax = y + h - 1; - int16_t yMaxCorner = y + h - 2; - draw_line(canvas, xMinCorner, y, xMaxCorner, y, draw_mode); - draw_line(canvas, xMinCorner, yMax, xMaxCorner, yMax, draw_mode); - draw_line(canvas, x, yMinCorner, x, yMaxCorner, draw_mode); - draw_line(canvas, xMax, yMinCorner, xMax, yMaxCorner, draw_mode); -} - -void draw_rounded_box( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode draw_mode) { - for(int16_t o = w - 2; o >= 1; o--) { - for(int16_t p = h - 2; p >= 1; p--) { - set_pixel(canvas, x + o, y + p, draw_mode); - } - } - draw_rounded_box_frame(canvas, x, y, w, h, draw_mode); -} - -void invert_shape(Canvas* const canvas, uint8_t* data, int16_t x, int16_t y, uint8_t w, uint8_t h) { - draw_pixels(canvas, data, x, y, w, h, Inverse); -} - -void draw_pixels( - Canvas* const canvas, - uint8_t* data, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - for(int8_t o = 0; o < w; o++) { - for(int8_t p = 0; p < h; p++) { - if(in_screen(o + x, p + y) && data[p * w + o] == 1) - set_pixel(canvas, o + x, p + y, drawMode); - } - } -} - -void draw_rectangle( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - for(int8_t o = 0; o < w; o++) { - for(int8_t p = 0; p < h; p++) { - if(in_screen(o + x, p + y)) { - set_pixel(canvas, o + x, p + y, drawMode); - } - } - } -} - -void invert_rectangle(Canvas* const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h) { - draw_rectangle(canvas, x, y, w, h, Inverse); -} - -uint8_t* image_data(Canvas* const canvas, const Icon* icon) { - uint8_t* data = malloc(sizeof(uint8_t) * 8 * 128); - uint8_t* screen = canvas->fb.tile_buf_ptr; - canvas->fb.tile_buf_ptr = data; - canvas_draw_icon(canvas, 0, 0, icon); - canvas->fb.tile_buf_ptr = screen; - return data; -} - -uint8_t* getOrAddIconData(Canvas* const canvas, const Icon* icon) { - uint8_t* icon_data = get_tilemap((unsigned long)icon); - if(icon_data == NULL) { - icon_data = image_data(canvas, icon); - add_new_tilemap(icon_data, (unsigned long)icon); - } - return icon_data; -} - -void draw_icon_clip( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - uint8_t* icon_data = getOrAddIconData(canvas, icon); - - for(int i = 0; i < w; i++) { - for(int j = 0; j < h; j++) { - bool on = test_pixel(icon_data, left + i, top + j, SCREEN_WIDTH); - if(drawMode == Filled) { - set_pixel(canvas, x + i, y + j, on ? Black : White); - } else if(on) - set_pixel(canvas, x + i, y + j, drawMode); - } - } -} - -void draw_icon_clip_flipped( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - uint8_t* icon_data = getOrAddIconData(canvas, icon); - - for(int i = 0; i < w; i++) { - for(int j = 0; j < h; j++) { - bool on = test_pixel(icon_data, left + i, top + j, SCREEN_WIDTH); - - if(drawMode == Filled) { - set_pixel(canvas, x + w - i - 1, y + h - j - 1, on ? Black : White); - } else if(on) - set_pixel(canvas, x + w - i - 1, y + h - j - 1, drawMode); - } - } -} \ No newline at end of file diff --git a/applications/external/blackjack/common/ui.h b/applications/external/blackjack/common/ui.h deleted file mode 100644 index 13d8da257..000000000 --- a/applications/external/blackjack/common/ui.h +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include -#include - -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 - -typedef enum { - Black, - White, - Inverse, - Filled //Currently only for Icon clip drawing -} DrawMode; - -// size is the screen size - -typedef struct { - uint8_t* data; - unsigned long iconId; -} TileMap; - -bool test_pixel(uint8_t* data, uint8_t x, uint8_t y, uint8_t w); - -uint8_t* image_data(Canvas* const canvas, const Icon* icon); - -uint32_t pixel_index(uint8_t x, uint8_t y); - -void draw_icon_clip( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_icon_clip_flipped( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_rounded_box( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_rounded_box_frame( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_rectangle( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void invert_rectangle(Canvas* const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h); - -void invert_shape(Canvas* const canvas, uint8_t* data, int16_t x, int16_t y, uint8_t w, uint8_t h); - -void draw_pixels( - Canvas* const canvas, - uint8_t* data, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -bool read_pixel(Canvas* const canvas, int16_t x, int16_t y); - -void set_pixel(Canvas* const canvas, int16_t x, int16_t y, DrawMode draw_mode); - -void draw_line( - Canvas* const canvas, - int16_t x1, - int16_t y1, - int16_t x2, - int16_t y2, - DrawMode draw_mode); - -bool in_screen(int16_t x, int16_t y); - -void ui_cleanup(); -uint8_t* get_buffer(Canvas* const canvas); -uint8_t* make_buffer(); -void clone_buffer(uint8_t* canvas, uint8_t* data); \ No newline at end of file diff --git a/applications/external/blackjack/defines.h b/applications/external/blackjack/defines.h deleted file mode 100644 index 0a3fdf53e..000000000 --- a/applications/external/blackjack/defines.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "common/card.h" -#include "common/queue.h" -#include "common/menu.h" - -#define APP_NAME "Blackjack" - -#define CONF_ANIMATION_DURATION "AnimationDuration" -#define CONF_MESSAGE_DURATION "MessageDuration" -#define CONF_STARTING_MONEY "StartingMoney" -#define CONF_ROUND_PRICE "RoundPrice" -#define CONF_SOUND_EFFECTS "SoundEffects" - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - uint32_t animation_duration; - uint32_t message_duration; - uint32_t starting_money; - uint32_t round_price; - bool sound_effects; -} Settings; - -typedef struct { - EventType type; - InputEvent input; -} AppEvent; - -typedef enum { - GameStateGameOver, - GameStateStart, - GameStatePlay, - GameStateSettings, - GameStateDealer, -} PlayState; - -typedef enum { - DirectionUp, - DirectionDown, - DirectionRight, - DirectionLeft, - Select, - Back, - None -} Direction; - -typedef struct { - FuriMutex* mutex; - Card player_cards[21]; - Card dealer_cards[21]; - uint8_t player_card_count; - uint8_t dealer_card_count; - - Direction selectDirection; - Settings settings; - - uint32_t player_score; - uint32_t bet; - uint8_t selectedMenu; - bool doubled; - bool started; - bool processing; - Deck deck; - PlayState state; - QueueState queue_state; - Menu* menu; - unsigned int last_tick; -} GameState; diff --git a/applications/external/blackjack/ui.c b/applications/external/blackjack/ui.c deleted file mode 100644 index d4ee82191..000000000 --- a/applications/external/blackjack/ui.c +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include - -#include "ui.h" - -#define LINE_HEIGHT 16 -#define ITEM_PADDING 4 - -const char MoneyMul[4] = {'K', 'B', 'T', 'S'}; - -void draw_player_scene(Canvas* const canvas, const GameState* game_state) { - int max_card = game_state->player_card_count; - - if(max_card > 0) draw_deck((game_state->player_cards), max_card, canvas); - - if(game_state->dealer_card_count > 0) draw_card_back_at(13, 5, canvas); - - max_card = game_state->dealer_card_count; - if(max_card > 1) { - draw_card_at( - 2, 2, game_state->dealer_cards[1].pip, game_state->dealer_cards[1].character, canvas); - } -} - -void draw_dealer_scene(Canvas* const canvas, const GameState* game_state) { - uint8_t max_card = game_state->dealer_card_count; - draw_deck((game_state->dealer_cards), max_card, canvas); -} - -void popup_frame(Canvas* const canvas) { - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 32, 15, 66, 13); - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, 32, 15, 66, 13); - canvas_set_font(canvas, FontSecondary); -} - -void draw_play_menu(Canvas* const canvas, const GameState* game_state) { - const char* menus[3] = {"Double", "Hit", "Stay"}; - for(uint8_t m = 0; m < 3; m++) { - if(m == 0 && - (game_state->doubled || game_state->player_score < game_state->settings.round_price)) - continue; - int y = m * 13 + 25; - canvas_set_color(canvas, ColorBlack); - - if(game_state->selectedMenu == m) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 1, y, 31, 12); - } else { - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 1, y, 31, 12); - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, 1, y, 31, 12); - } - - if(game_state->selectedMenu == m) - canvas_set_color(canvas, ColorWhite); - else - canvas_set_color(canvas, ColorBlack); - canvas_draw_str_aligned(canvas, 16, y + 6, AlignCenter, AlignCenter, menus[m]); - } -} - -void draw_screen(Canvas* const canvas, const bool* points) { - for(uint8_t x = 0; x < 128; x++) { - for(uint8_t y = 0; y < 64; y++) { - if(points[y * 128 + x]) canvas_draw_dot(canvas, x, y); - } - } -} - -void draw_score(Canvas* const canvas, bool top, uint8_t amount) { - char drawChar[20]; - snprintf(drawChar, sizeof(drawChar), "Player score: %i", amount); - if(top) - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, drawChar); - else - canvas_draw_str_aligned(canvas, 64, 62, AlignCenter, AlignBottom, drawChar); -} - -void draw_money(Canvas* const canvas, uint32_t score) { - canvas_set_font(canvas, FontSecondary); - char drawChar[11]; - uint32_t currAmount = score; - if(currAmount < 1000) { - snprintf(drawChar, sizeof(drawChar), "$%lu", currAmount); - } else { - char c = 'K'; - for(uint8_t i = 0; i < 4; i++) { - currAmount = currAmount / 1000; - if(currAmount < 1000) { - c = MoneyMul[i]; - break; - } - } - - snprintf(drawChar, sizeof(drawChar), "$%lu %c", currAmount, c); - } - canvas_draw_str_aligned(canvas, 126, 2, AlignRight, AlignTop, drawChar); -} - -void draw_menu( - Canvas* const canvas, - const char* text, - const char* value, - int8_t y, - bool left_caret, - bool right_caret, - bool selected) { - UNUSED(selected); - if(y < 0 || y >= 64) return; - - if(selected) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 0, y, 122, LINE_HEIGHT); - canvas_set_color(canvas, ColorWhite); - } - - canvas_draw_str_aligned(canvas, 4, y + ITEM_PADDING, AlignLeft, AlignTop, text); - if(left_caret) canvas_draw_str_aligned(canvas, 80, y + ITEM_PADDING, AlignLeft, AlignTop, "<"); - canvas_draw_str_aligned(canvas, 100, y + ITEM_PADDING, AlignCenter, AlignTop, value); - if(right_caret) - canvas_draw_str_aligned(canvas, 120, y + ITEM_PADDING, AlignRight, AlignTop, ">"); - - canvas_set_color(canvas, ColorBlack); -} - -void settings_page(Canvas* const canvas, const GameState* gameState) { - char drawChar[10]; - int startY = 0; - if(LINE_HEIGHT * (gameState->selectedMenu + 1) >= 64) { - startY -= (LINE_HEIGHT * (gameState->selectedMenu + 1)) - 64; - } - - int scrollHeight = round(64 / 6.0) + ITEM_PADDING * 2; - int scrollPos = 64 / (6.0 / (gameState->selectedMenu + 1)) - ITEM_PADDING * 2; - - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 123, scrollPos, 4, scrollHeight); - canvas_draw_box(canvas, 125, 0, 1, 64); - - snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.starting_money); - draw_menu( - canvas, - "Start money", - drawChar, - 0 * LINE_HEIGHT + startY, - gameState->settings.starting_money > gameState->settings.round_price, - gameState->settings.starting_money < 400, - gameState->selectedMenu == 0); - snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.round_price); - draw_menu( - canvas, - "Round price", - drawChar, - 1 * LINE_HEIGHT + startY, - gameState->settings.round_price > 10, - gameState->settings.round_price < gameState->settings.starting_money, - gameState->selectedMenu == 1); - - snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.animation_duration); - draw_menu( - canvas, - "Anim. length", - drawChar, - 2 * LINE_HEIGHT + startY, - gameState->settings.animation_duration > 0, - gameState->settings.animation_duration < 2000, - gameState->selectedMenu == 2); - snprintf(drawChar, sizeof(drawChar), "%li", gameState->settings.message_duration); - draw_menu( - canvas, - "Popup time", - drawChar, - 3 * LINE_HEIGHT + startY, - gameState->settings.message_duration > 0, - gameState->settings.message_duration < 2000, - gameState->selectedMenu == 3); - // draw_menu(canvas, "Sound", gameState->settings.sound_effects ? "Yes" : "No", - // 5 * LINE_HEIGHT + startY, - // true, - // true, - // gameState->selectedMenu == 5 - // ); -} \ No newline at end of file diff --git a/applications/external/blackjack/ui.h b/applications/external/blackjack/ui.h deleted file mode 100644 index 51b388010..000000000 --- a/applications/external/blackjack/ui.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "defines.h" -#include - -void draw_player_scene(Canvas* const canvas, const GameState* game_state); - -void draw_dealer_scene(Canvas* const canvas, const GameState* game_state); - -void draw_play_menu(Canvas* const canvas, const GameState* game_state); - -void draw_score(Canvas* const canvas, bool top, uint8_t amount); - -void draw_money(Canvas* const canvas, uint32_t score); -void settings_page(Canvas* const canvas, const GameState* gameState); - -void popup_frame(Canvas* const canvas); -void draw_screen(Canvas* const canvas, const bool* points); diff --git a/applications/external/blackjack/util.c b/applications/external/blackjack/util.c deleted file mode 100644 index c1cb01c13..000000000 --- a/applications/external/blackjack/util.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include "util.h" - -const char* CONFIG_FILE_PATH = APP_DATA_PATH("blackjack.settings"); - -void save_settings(Settings settings) { - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); - FURI_LOG_D(APP_NAME, "Saving config"); - if(flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { - FURI_LOG_D( - APP_NAME, "Saving %s: %ld", CONF_ANIMATION_DURATION, settings.animation_duration); - flipper_format_update_uint32( - file, CONF_ANIMATION_DURATION, &(settings.animation_duration), 1); - - FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_MESSAGE_DURATION, settings.message_duration); - flipper_format_update_uint32(file, CONF_MESSAGE_DURATION, &(settings.message_duration), 1); - - FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_STARTING_MONEY, settings.starting_money); - flipper_format_update_uint32(file, CONF_STARTING_MONEY, &(settings.starting_money), 1); - - FURI_LOG_D(APP_NAME, "Saving %s: %ld", CONF_ROUND_PRICE, settings.round_price); - flipper_format_update_uint32(file, CONF_ROUND_PRICE, &(settings.round_price), 1); - - FURI_LOG_D(APP_NAME, "Saving %s: %i", CONF_SOUND_EFFECTS, settings.sound_effects ? 1 : 0); - flipper_format_update_bool(file, CONF_SOUND_EFFECTS, &(settings.sound_effects), 1); - FURI_LOG_D(APP_NAME, "Config saved"); - } else { - FURI_LOG_E(APP_NAME, "Save error"); - } - flipper_format_file_close(file); - flipper_format_free(file); - furi_record_close(RECORD_STORAGE); -} - -void save_settings_file(FlipperFormat* file, Settings* settings) { - flipper_format_write_header_cstr(file, CONFIG_FILE_HEADER, CONFIG_FILE_VERSION); - flipper_format_write_comment_cstr(file, "Card animation duration in ms"); - flipper_format_write_uint32(file, CONF_ANIMATION_DURATION, &(settings->animation_duration), 1); - flipper_format_write_comment_cstr(file, "Popup message duration in ms"); - flipper_format_write_uint32(file, CONF_MESSAGE_DURATION, &(settings->message_duration), 1); - flipper_format_write_comment_cstr(file, "Player's starting money"); - flipper_format_write_uint32(file, CONF_STARTING_MONEY, &(settings->starting_money), 1); - flipper_format_write_comment_cstr(file, "Round price"); - flipper_format_write_uint32(file, CONF_ROUND_PRICE, &(settings->round_price), 1); - flipper_format_write_comment_cstr(file, "Enable sound effects"); - flipper_format_write_bool(file, CONF_SOUND_EFFECTS, &(settings->sound_effects), 1); -} - -Settings load_settings() { - Settings settings; - - FURI_LOG_D(APP_NAME, "Loading default settings"); - settings.animation_duration = 800; - settings.message_duration = 1500; - settings.starting_money = 200; - settings.round_price = 10; - settings.sound_effects = true; - - FURI_LOG_D(APP_NAME, "Opening storage"); - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(storage, EXT_PATH(".blackjack.settings"), CONFIG_FILE_PATH); - FURI_LOG_D(APP_NAME, "Allocating file"); - FlipperFormat* file = flipper_format_file_alloc(storage); - - FURI_LOG_D(APP_NAME, "Allocating string"); - FuriString* string_value; - string_value = furi_string_alloc(); - - if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) != FSE_OK) { - FURI_LOG_D(APP_NAME, "Config file %s not found, creating new one...", CONFIG_FILE_PATH); - if(!flipper_format_file_open_new(file, CONFIG_FILE_PATH)) { - FURI_LOG_E(APP_NAME, "Error creating new file %s", CONFIG_FILE_PATH); - flipper_format_file_close(file); - } else { - save_settings_file(file, &settings); - } - } else { - if(!flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { - FURI_LOG_E(APP_NAME, "Error opening existing file %s", CONFIG_FILE_PATH); - flipper_format_file_close(file); - } else { - uint32_t value; - bool valueBool; - FURI_LOG_D(APP_NAME, "Checking version"); - if(!flipper_format_read_header(file, string_value, &value)) { - FURI_LOG_E(APP_NAME, "Config file mismatch"); - } else { - FURI_LOG_D(APP_NAME, "Loading %s", CONF_ANIMATION_DURATION); - if(flipper_format_read_uint32(file, CONF_ANIMATION_DURATION, &value, 1)) { - settings.animation_duration = value; - FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_ANIMATION_DURATION, value); - } - FURI_LOG_D(APP_NAME, "Loading %s", CONF_MESSAGE_DURATION); - if(flipper_format_read_uint32(file, CONF_MESSAGE_DURATION, &value, 1)) { - settings.message_duration = value; - FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_MESSAGE_DURATION, value); - } - FURI_LOG_D(APP_NAME, "Loading %s", CONF_STARTING_MONEY); - if(flipper_format_read_uint32(file, CONF_STARTING_MONEY, &value, 1)) { - settings.starting_money = value; - FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_STARTING_MONEY, value); - } - FURI_LOG_D(APP_NAME, "Loading %s", CONF_ROUND_PRICE); - if(flipper_format_read_uint32(file, CONF_ROUND_PRICE, &value, 1)) { - settings.round_price = value; - FURI_LOG_D(APP_NAME, "Loaded %s: %ld", CONF_ROUND_PRICE, value); - } - FURI_LOG_D(APP_NAME, "Loading %s", CONF_SOUND_EFFECTS); - if(flipper_format_read_bool(file, CONF_SOUND_EFFECTS, &valueBool, 1)) { - settings.sound_effects = valueBool; - FURI_LOG_D(APP_NAME, "Loaded %s: %i", CONF_ROUND_PRICE, valueBool ? 1 : 0); - } - } - flipper_format_file_close(file); - } - } - - furi_string_free(string_value); - // flipper_format_file_close(file); - flipper_format_free(file); - furi_record_close(RECORD_STORAGE); - return settings; -} diff --git a/applications/external/blackjack/util.h b/applications/external/blackjack/util.h deleted file mode 100644 index 4bcc4d890..000000000 --- a/applications/external/blackjack/util.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "defines.h" -#define CONFIG_FILE_HEADER "Blackjack config file" -#define CONFIG_FILE_VERSION 1 - -void save_settings(Settings settings); -Settings load_settings(); \ No newline at end of file diff --git a/applications/external/nrf24batch/LICENSE b/applications/external/nrf24batch/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/nrf24batch/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/nrf24batch/application.fam b/applications/external/nrf24batch/application.fam deleted file mode 100644 index aff3ffd30..000000000 --- a/applications/external/nrf24batch/application.fam +++ /dev/null @@ -1,19 +0,0 @@ -App( - appid="nrf24batch", - name="[NRF24] Batch", - apptype=FlipperAppType.EXTERNAL, - entry_point="nrf24batch_app", - cdefines=["APP_NRF24BATCH"], - requires=["gui"], - stack_size=2 * 1024, - fap_icon="nrf24batch_10px.png", - fap_category="GPIO", - fap_private_libs=[ - Lib( - name="nrf24", - sources=[ - "nrf24.c", - ], - ), - ], -) diff --git a/applications/external/nrf24batch/lib/nrf24/nrf24.c b/applications/external/nrf24batch/lib/nrf24/nrf24.c deleted file mode 100644 index dbc1c1966..000000000 --- a/applications/external/nrf24batch/lib/nrf24/nrf24.c +++ /dev/null @@ -1,384 +0,0 @@ -// Modified by vad7, 24.02.2023 -// -#include "nrf24.h" -#include -#include -#include -#include -#include - -void nrf24_init() { - // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pa4, true); - } - - furi_hal_spi_bus_handle_init(nrf24_HANDLE); - furi_hal_spi_acquire(nrf24_HANDLE); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - furi_hal_gpio_write(nrf24_CE_PIN, false); -} - -void nrf24_deinit() { - furi_hal_spi_release(nrf24_HANDLE); - furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); - furi_hal_gpio_write(nrf24_CE_PIN, false); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - // resetting the CS pins to floating - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); - } -} - -void nrf24_spi_trx(FuriHalSpiBusHandle* handle, uint8_t* tx, uint8_t* rx, uint8_t size) { - furi_hal_gpio_write(handle->cs, false); - furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT); - furi_hal_gpio_write(handle->cs, true); -} - -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { - uint8_t buf[] = {W_REGISTER | (REGISTER_MASK & reg), data}; - nrf24_spi_trx(handle, buf, buf, 2); - //FURI_LOG_D("NRF_WR", " #%02X=%02X", reg, data); - return buf[0]; -} - -uint8_t - nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t buf[size + 1]; - buf[0] = W_REGISTER | (REGISTER_MASK & reg); - memcpy(&buf[1], data, size); - nrf24_spi_trx(handle, buf, buf, size + 1); - //FURI_LOG_D("NRF_WR", " #%02X(%02X)=0x%02X%02X%02X%02X%02X", reg, size, data[0], data[1], data[2], data[3], data[4] ); - return buf[0]; -} - -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t buf[size + 1]; - memset(buf, 0, size + 1); - buf[0] = R_REGISTER | (REGISTER_MASK & reg); - nrf24_spi_trx(handle, buf, buf, size + 1); - memcpy(data, &buf[1], size); - return buf[0]; -} - -uint8_t nrf24_read_register(FuriHalSpiBusHandle* handle, uint8_t reg) { - uint8_t buf[] = {R_REGISTER | (REGISTER_MASK & reg), 0}; - nrf24_spi_trx(handle, buf, buf, 2); - return buf[1]; -} - -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_RX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1); - return rx[0]; -} - -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_TX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1); - return rx[0]; -} - -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle) { - uint8_t maclen; - nrf24_read_reg(handle, REG_SETUP_AW, &maclen, 1); - maclen &= 3; - return maclen + 2; -} - -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen) { - assert(maclen > 1 && maclen < 6); - uint8_t status = 0; - status = nrf24_write_reg(handle, REG_SETUP_AW, maclen - 2); - return status; -} - -uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { - uint8_t tx = RF24_NOP; - nrf24_spi_trx(handle, &tx, &tx, 1); - return tx; -} - -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle) { - uint8_t setup = 0; - uint32_t rate = 0; - nrf24_read_reg(handle, REG_RF_SETUP, &setup, 1); - setup &= 0x28; - if(setup == 0x20) - rate = 250000; // 250kbps - else if(setup == 0x08) - rate = 2000000; // 2Mbps - else if(setup == 0x00) - rate = 1000000; // 1Mbps - - return rate; -} - -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate) { - uint8_t r6 = 0; - uint8_t status = 0; - if(!rate) rate = 2000000; - - nrf24_read_reg(handle, REG_RF_SETUP, &r6, 1); // RF_SETUP register - r6 = r6 & (~0x28); // Clear rate fields. - if(rate == 2000000) - r6 = r6 | 0x08; - else if(rate == 1000000) - r6 = r6; - else if(rate == 250000) - r6 = r6 | 0x20; - - status = nrf24_write_reg(handle, REG_RF_SETUP, r6); // Write new rate. - return status; -} - -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle) { - uint8_t channel = 0; - nrf24_read_reg(handle, REG_RF_CH, &channel, 1); - return channel; -} - -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan) { - uint8_t status; - status = nrf24_write_reg(handle, REG_RF_CH, chan); - return status; -} - -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_TX_ADDR, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle, uint8_t pipe) { - uint8_t len = 0; - if(pipe > 5) pipe = 0; - nrf24_read_reg(handle, RX_PW_P0 + pipe, &len, 1); - return len; -} - -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len) { - uint8_t status = 0; - status = nrf24_write_reg(handle, RX_PW_P0, len); - return status; -} - -// packet_size: 0 - dyn payload (read from PL_WID), 1 - read from pipe size, >1 - override -// Return STATUS reg + additional: RX_DR - new data available, 0x80 - NRF24 hardware error -uint8_t nrf24_rxpacket( - FuriHalSpiBusHandle* handle, - uint8_t* packet, - uint8_t* ret_packetsize, - uint8_t packet_size) { - uint8_t status = 0; - uint8_t buf[33]; // 32 max payload size + 1 for command - - status = nrf24_status(handle); - if(!(status & RX_DR)) { - uint8_t st = nrf24_read_register(handle, REG_FIFO_STATUS); - if(st == 0xFF || st == 0) return 0x80; // hardware error - if((st & 1) == 0) { - FURI_LOG_D("NRF", "FIFO PKT"); - status |= RX_DR; // packet in FIFO buffer - } - } - if(status & RX_DR) { - if(status & 0x80) return 0x80; // hardware error - if(packet_size == 1) - packet_size = nrf24_get_packetlen(handle, (status >> 1) & 7); - else if(packet_size == 0) { - buf[0] = R_RX_PL_WID; - buf[1] = 0xFF; - nrf24_spi_trx(handle, buf, buf, 2); - packet_size = buf[1]; - } - if(packet_size > 32 || packet_size == 0) packet_size = 32; - memset(buf, 0, packet_size + 1); - buf[0] = R_RX_PAYLOAD; - nrf24_spi_trx(handle, buf, buf, packet_size + 1); - memcpy(packet, &buf[1], packet_size); - nrf24_write_reg(handle, REG_STATUS, RX_DR); // clear RX_DR - } - if(status & (MAX_RT)) { // MAX_RT - nrf24_write_reg(handle, REG_STATUS, (MAX_RT)); // clear MAX_RT. - } - - *ret_packetsize = packet_size; - return status; -} - -// Return 0 when error -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack) { - uint8_t status = 0; - uint8_t buf[size + 1]; - buf[0] = ack ? W_TX_PAYLOAD : W_TX_PAYLOAD_NOACK; - memcpy(&buf[1], payload, size); - nrf24_set_tx_mode(handle); - nrf24_spi_trx(handle, buf, buf, size + 1); - uint32_t start_time = furi_get_tick(); - do { - furi_delay_us(100); - status = nrf24_status(handle); - } while(!(status & (TX_DS | MAX_RT)) && furi_get_tick() - start_time < 100UL); - if(status & MAX_RT) { - if(furi_log_get_level() == FuriLogLevelDebug) - FURI_LOG_D( - "NRF", "MAX RT: %X (%X)", nrf24_read_register(handle, REG_OBSERVE_TX), status); - nrf24_flush_tx(handle); - } - furi_hal_gpio_write(nrf24_CE_PIN, false); - //nrf24_set_idle(handle); - if(status & (TX_DS | MAX_RT)) nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); - return status & TX_DS; -} - -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg = cfg | 2; - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //furi_delay_ms(1000); - return status; -} - -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfc; // clear bottom two bits to power down the radio - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, false); - return status; -} - -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle) { - uint8_t cfg = 0; - cfg = nrf24_read_register(handle, REG_CONFIG); - cfg |= 0x03; // PWR_UP, and PRIM_RX - cfg = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, true); - return cfg; -} - -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle) { - uint8_t reg; - furi_hal_gpio_write(nrf24_CE_PIN, false); - //nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); - reg = nrf24_read_register(handle, REG_CONFIG); - reg &= ~0x01; // disable PRIM_RX - reg |= 0x02; // PWR_UP - reg = nrf24_write_reg(handle, REG_CONFIG, reg); - furi_hal_gpio_write(nrf24_CE_PIN, true); - return reg; -} - -void hexlify(uint8_t* in, uint8_t size, char* out) { - memset(out, 0, size * 2); - for(int i = 0; i < size; i++) - snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); -} - -uint64_t bytes_to_int64(uint8_t* bytes, uint8_t size, bool bigendian) { - uint64_t ret = 0; - for(int i = 0; i < size; i++) - if(bigendian) - ret |= bytes[i] << ((size - 1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 8; i++) { - if(bigendian) - out[i] = (val >> ((7 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian) { - uint32_t ret = 0; - for(int i = 0; i < 4; i++) - if(bigendian) - ret |= bytes[i] << ((3 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 4; i++) { - if(bigendian) - out[i] = (val >> ((3 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint64_t bytes_to_int16(uint8_t* bytes, bool bigendian) { - uint16_t ret = 0; - for(int i = 0; i < 2; i++) - if(bigendian) - ret |= bytes[i] << ((1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int16_to_bytes(uint16_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 2; i++) { - if(bigendian) - out[i] = (val >> ((1 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t* mac, uint8_t mlen) { - uint8_t addr[5]; - for(int i = 0; i < mlen; i++) addr[i] = mac[mlen - i - 1]; - return nrf24_write_buf_reg(nrf24_HANDLE, mac_addr, addr, mlen); -} diff --git a/applications/external/nrf24batch/lib/nrf24/nrf24.h b/applications/external/nrf24batch/lib/nrf24/nrf24.h deleted file mode 100644 index 2fb249f68..000000000 --- a/applications/external/nrf24batch/lib/nrf24/nrf24.h +++ /dev/null @@ -1,392 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define R_REGISTER 0x00 -#define W_REGISTER 0x20 -#define REGISTER_MASK 0x1F -#define ACTIVATE 0x50 -#define R_RX_PL_WID 0x60 -#define R_RX_PAYLOAD 0x61 -#define W_TX_PAYLOAD 0xA0 -#define W_TX_PAYLOAD_NOACK 0xB0 -#define W_ACK_PAYLOAD 0xA8 -#define FLUSH_TX 0xE1 -#define FLUSH_RX 0xE2 -#define REUSE_TX_PL 0xE3 -#define RF24_NOP 0xFF - -#define REG_CONFIG 0x00 -#define REG_EN_AA 0x01 -#define REG_EN_RXADDR 0x02 -#define REG_SETUP_AW 0x03 -#define REG_SETUP_RETR 0x04 -#define REG_DYNPD 0x1C -#define REG_FEATURE 0x1D -#define REG_RF_SETUP 0x06 -#define REG_STATUS 0x07 -#define REG_RX_ADDR_P0 0x0A -#define REG_RX_ADDR_P1 0x0B -#define REG_RX_ADDR_P2 0x0C -#define REG_RX_ADDR_P3 0x0D -#define REG_RX_ADDR_P4 0x0E -#define REG_RX_ADDR_P5 0x0F -#define REG_RF_CH 0x05 -#define REG_TX_ADDR 0x10 -#define REG_FIFO_STATUS 0x17 -#define REG_OBSERVE_TX 0x08 - -#define RX_PW_P0 0x11 -#define RX_PW_P1 0x12 -#define RX_PW_P2 0x13 -#define RX_PW_P3 0x14 -#define RX_PW_P4 0x15 -#define RX_PW_P5 0x16 -#define RX_DR 0x40 -#define TX_DS 0x20 -#define MAX_RT 0x10 -#define NRF24_EN_DYN_ACK 0x01 - -#define nrf24_TIMEOUT 500 -#define nrf24_CE_PIN &gpio_ext_pb2 -#define nrf24_HANDLE \ - (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ - &furi_hal_spi_bus_handle_external_extra) - -/* Low level API */ - -/** Write device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * - * @return device status - */ -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); - -/** Write buffer to device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * @param size - size of data to write - * - * @return device status - */ -uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Read device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param[out] data - pointer to data - * - * @return device status - */ -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -// Read single register (1 byte) -uint8_t nrf24_read_register(FuriHalSpiBusHandle* handle, uint8_t reg); - -/** Power up the radio for operation - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle); - -/** Power down the radio - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); - -/** Sets the radio to RX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle); - -/** Sets the radio to TX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); - -/*=============================================================================================================*/ - -/* High level API */ - -/** Must call this before using any other nrf24 API - * - */ -void nrf24_init(); - -/** Must call this when we end using nrf24 device - * - */ -void nrf24_deinit(); - -/** Send flush rx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); - -/** Send flush tx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle); - -/** Gets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * pipe - pipe index (0..5) - * @return packet length in data pipe 0 - */ -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle, uint8_t pipe); - -/** Sets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * @param len - length to set - * - * @return device status - */ -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len); - -/** Gets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return MAC address length - */ -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle); - -/** Sets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length to set MAC address to, must be greater than 1 and less than 6 - * - * @return MAC address length - */ -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen); - -/** Gets the current status flags from the STATUS register - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return status flags - */ -uint8_t nrf24_status(FuriHalSpiBusHandle* handle); - -/** Gets the current transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return transfer rate in bps - */ -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle); - -/** Sets the transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * @param rate - the transfer rate in bps - * - * @return device status - */ -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate); - -/** Gets the current channel - * In nrf24, the channel number is multiplied times 1MHz and added to 2400MHz to get the frequency - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return channel - */ -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle); - -/** Sets the channel - * - * @param handle - pointer to FuriHalSpiHandle - * @param frequency - the frequency in hertz - * - * @return device status - */ -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan); - -/** Gets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Gets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Reads RX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] packet - the packet contents - * @param[out] ret_packetsize - size of the received packet - * @param packet_size: >1 - size, 1 - packet length is determined by RX_PW_P0 register, 0 - it is determined by dynamic payload length command - * - * @return device status - */ -uint8_t nrf24_rxpacket( - FuriHalSpiBusHandle* handle, - uint8_t* packet, - uint8_t* ret_packetsize, - uint8_t packet_size_flag); - -/** Sends TX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param packet - the packet contents - * @param size - packet size - * @param ack - boolean to determine whether an ACK is required for the packet or not - * - * @return device status - */ -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack); - -/** Configure the radio - * This is not comprehensive, but covers a lot of the common configuration options that may be changed - * @param handle - pointer to FuriHalSpiHandle - * @param rate - transfer rate in Mbps (1 or 2) - * @param srcmac - source mac address - * @param dstmac - destination mac address - * @param maclen - length of mac address - * @param channel - channel to tune to - * @param noack - if true, disable auto-acknowledge - * @param disable_aa - if true, disable ShockBurst - * - */ -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa); - -// Set mac address (MSB first), Return: Status -uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t* mac, uint8_t mlen); - -/** Configures the radio for "promiscuous mode" and primes it for rx - * This is not an actual mode of the nrf24, but this function exploits a few bugs in the chip that allows it to act as if it were. - * See http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html for details. - * @param handle - pointer to FuriHalSpiHandle - * @param channel - channel to tune to - * @param rate - transfer rate in Mbps (1 or 2) - */ -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate); - -/** Listens for a packet and returns first possible address sniffed - * Call this only after calling nrf24_init_promisc_mode - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length of target mac address - * @param[out] addresses - sniffed address - * - * @return success - */ -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address); - -/** Sends ping packet on each channel for designated tx mac looking for ack - * - * @param handle - pointer to FuriHalSpiHandle - * @param srcmac - source address - * @param dstmac - destination address - * @param maclen - length of address - * @param rate - transfer rate in Mbps (1 or 2) - * @param min_channel - channel to start with - * @param max_channel - channel to end at - * @param autoinit - if true, automatically configure radio for this channel - * - * @return channel that the address is listening on, if this value is above the max_channel param, it failed - */ -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit); - -/** Converts 64 bit value into uint8_t array - * @param val - 64-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian); - -/** Converts 32 bit value into uint8_t array - * @param val - 32-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian); - -/** Converts uint8_t array into 32 bit value - * @param bytes - uint8_t array - * @param bigendian - if true, convert as big endian, otherwise little endian - * - * @return 32-bit value - */ -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/nrf24batch/nrf24batch.c b/applications/external/nrf24batch/nrf24batch.c deleted file mode 100644 index 1eb90c3c2..000000000 --- a/applications/external/nrf24batch/nrf24batch.c +++ /dev/null @@ -1,1973 +0,0 @@ -// -// Written by vad7, 10.01.2023. vad7@yahoo.com -// -#include "nrf24batch.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TAG "nrf24batch" -#define VERSION "1.9" - -#define SCAN_APP_PATH_FOLDER STORAGE_APP_DATA_PATH_PREFIX -#define LOG_FILEEXT ".txt" -#define NRF_READ_TIMEOUT 300UL // ms -#define WORK_PERIOD 2 // ms, Timer period -#define MAX_CHANNEL 125 -#define FONT_5x7_SCREEN_WIDTH 25 -#define NRF_EN_DYN_ACK 0 // does not work on some nrf24l01+ chips, (0/1) - -const char SettingsFld_Info[] = "Info:"; -const char SettingsFld_Ch[] = "Ch:"; -const char SettingsFld_Rate[] = "Rate:"; -const char SettingsFld_DPL[] = "DPL:"; -const char SettingsFld_CRC[] = "CRC:"; -const char SettingsFld_RETR[] = "RETR:"; -const char SettingsFld_Address[] = "Address:"; -const char SettingsFld_Resend[] = "Resend:"; -const char SettingsFld_Delay[] = "Delay_ms:"; -const char SettingsFld_WriteStart[] = "Write start:"; -const char SettingsFld_Payload[] = "Payload struct:"; -const char SettingsFld_ReadDefault[] = "R default:"; -const char SettingsFld_WriteDefault[] = "W default:"; -const char SettingsFld_Read[] = "R:"; // Read cmd -const char SettingsFld_Write[] = "W:"; // Write cmd -const char SettingsFld_Set[] = "S:"; // Set cmd (like Write but without "Write start" packet) -const char SettingsFld_ReadBatch[] = "RBatch:"; -const char SettingsFld_WriteBatch[] = "WBatch:"; -const char SettingsFld_SetBatch[] = "SBatch:"; -const char SettingsFld_Listen[] = "Listen:"; -const char SettingsFld_ReadCmdRepeatPeriod[] = "ReadCmd repeat:"; -const char AskQuestion_Save[] = "SAVE BATCH?"; -#define Settings_i 'i' -#define Settings_n 'n' -#define VAR_EMPTY ((int32_t)0x80000000) - -nRF24Batch* APP; -uint8_t what_doing = 0; // 0 - setup, 1 - cmd list, 2 - read/write/listen cmd -enum { - rwt_set_batch = 0, // fast send packet without question - rwt_read_batch, // Send read cmd and wait for answer in batch - rwt_read_cmd, // Send read cmd and wait for answer - rwt_write_batch, // Send write cmd (with Write start pkt if available) with a question before it - rwt_listen, // Listen mode (wait incoming pkts) - rwt_max -}; -uint8_t rw_type = rwt_read_batch; // What to do: rwt_* -enum { sst_none = 0, sst_sending, sst_receiving, sst_ok, sst_error, sst_timeout }; -uint8_t send_status = sst_none; // sst_* -bool cmd_array = false; -uint8_t cmd_array_idx; -uint8_t cmd_array_cnt = 0; -bool cmd_array_hex; -uint8_t save_settings = 0; -uint16_t view_cmd[rwt_max - 1] = {0}; // SetBatch, ReadBatch, Read, WriteBatch -uint8_t view_x = 0; -char screen_buf[64]; -char Info[35] = ""; -char file_name[FONT_5x7_SCREEN_WIDTH]; -char ERR_STR[FONT_5x7_SCREEN_WIDTH]; -uint8_t ERR = 0; -uint8_t NRF_rate; // 0 - 250Kbps, 1 - 1Mbps, 2 - 2Mbps -uint8_t NRF_channel; // 0..125 -uint8_t NRF_DPL; // 1 - Dynamic Payload Length -uint8_t NRF_CRC; // 1 - No, 1 - CRC 1byte, 2 - CRC 2byte -uint8_t NRF_RETR = ((0b0011 << 4) | 0b1111); // Automatic Retransmission, ARD, ARC -uint8_t NRF_Payload; // Payload len in bytes, 0..32 -bool NRF_ERROR = 0; -uint8_t NRF_INITED = 0; // 0 - not, 1 - rw, rwt_listen - listen -bool NRF_BOARD_POWER_5V = false; -uint8_t NRF_last_packet_send_st = 0; -uint8_t NRF_resend = 1; // number of transaction attempts -int8_t NRF_repeat = 0; // count number of repeated requests (until < NRF_resend) -uint32_t NRF_time; -uint16_t ReadCmdRepeatPeriod = 10; // s -bool ReadRepeat = false; -uint32_t delay_between_pkt = 10; // ms - -uint8_t addr[5]; // nRF24 address, MSB first -uint8_t addr_len = 0; // 2..5 -uint8_t payload[32]; -uint8_t payload_receive[32]; -uint8_t payload_struct[32]; // sizeof(1..4) in bytes of each field, example: 2,1,1 -uint8_t payload_fields = 0; -uint8_t payload_size = 0; // bytes -uint16_t view_Batch = 0; // view pos in Batch or inside WriteBatch (Log[view_Batch]) -uint16_t view_WriteBatch = 0; // view pos of WriteBatch list -uint8_t setup_cursor = 0; // cursor position on Setup scr -uint8_t Edit = 0; -char* Edit_pos; -char* Edit_start; -bool Edit_hex; // 0 - decimal, 1 - hex -bool Edited = false; // list of cmds edited - -Stream* file_stream = NULL; -FuriString* ReadDefault = NULL; -FuriString* WriteDefault = NULL; -FuriString* WriteStart = NULL; -FuriString* Constants = NULL; // text of STR=x -uint8_t listen_addr[5]; -uint8_t listen_addr_len = 0; -char* ListenFields = NULL; // ptr to string: field1,field2,... max 5 field now -bool ListenNew; -FuriHalRtcDateTime ListenLastTime = {0}; -uint32_t ListenPrev = 0; -uint32_t ListenLast = 0; -FuriString** Read_cmd = NULL; // Names of read cmd -uint16_t Read_cmd_Total = 0; -FuriString** Log = NULL; // Strings: var=n -uint16_t Log_Total = 0; -FuriString** ReadBatch_cmd = NULL; // Names of read batch cmd -uint16_t ReadBatch_cmd_Total = 0; -char* ReadBatch_cmd_curr = NULL; // =0xFFFFFFFF - finish -FuriString** WriteBatch_cmd = NULL; // Names of write batch cmd -uint16_t WriteBatch_cmd_Total = 0; -uint16_t WriteBatch_cmd_curr = 0; // == _Total - finish -FuriString** SetBatch_cmd = NULL; // Names of set batch cmd -uint16_t SetBatch_cmd_Total = 0; -uint16_t SetBatch_cmd_curr = 0; // == _Total - finish - -#define POWER_READ_PERIOD 501 // ms -uint16_t pwr_read_timer = 0; -int Current = 0; -int CurrentStart = 0; - -enum { ask_write_batch = 1, ask_save_batch, ask_skip_cmd, ask_return, ask_exit }; -uint8_t ask_question = 0; // 1 - Ask now - ask_* -uint8_t ask_question_answer = 0; // 0 - no, 1 - yes - -static bool ask_fill_screen_buf(void) { - if(ask_question == ask_write_batch) - strcpy(screen_buf, "RUN WRITE BATCH?"); - else if(ask_question == ask_save_batch) - strcpy(screen_buf, "SAVE AS WRITE BATCH?"); - else if(ask_question == ask_skip_cmd) - strcpy(screen_buf, "SKIP CMD?"); - else if(ask_question == ask_return) - strcpy(screen_buf, "RETURN?"); - else if(ask_question == ask_exit) - strcpy(screen_buf, "EXIT?"); - else - return false; - strcat(screen_buf, ask_question_answer ? " YES" : " NO"); - return true; -} - -//#define MIN(a, b) ((a= '0' && c <= '9') return true; - if(hex) { - c &= ~0x20; - if(c >= 'A' && c <= 'F') return true; - } else if(c == '-') - return true; - return false; -} - -// Return num bytes in array -static uint8_t ConvertHexToArray(char* hex, uint8_t* array, uint8_t maxlen) { - uint8_t len = 0; - while(maxlen) { - uint8_t ch = *hex++; - if(ch < ' ') break; - if(ch < '0') continue; - *array++ = (GetHexVal(ch) << 4) + GetHexVal(*hex++); - len++; - maxlen--; - } - return len; -} - -int32_t str_to_int(char* p) { - if(*(p + 1) == 'x') { // hex - return strtol(p + 2, NULL, 16); - } else - return strtol(p, NULL, 10); -} - -void str_rtrim(char* p) { - char* delim_col = strchr(p, '\r'); - if(delim_col) - *delim_col = '\0'; - else { - delim_col = strchr(p, '\n'); - if(delim_col) *delim_col = '\0'; - } -} - -static void add_to_str_hex_bytes(char* out, uint8_t* arr, int bytes) { - if(bytes <= 0) return; - out += strlen(out); - do { - snprintf(out, 3, "%02X", *arr++); - out += 2; - } while(--bytes); -} - -// skip leading zeros -static void add_to_str_hex_variable(char* out, uint8_t* arr, int size) { - if(size <= 0) return; - out += strlen(out); - arr += size - 1; - while(*arr == 0 && size > 1) { - arr--; - size--; - } - do { - snprintf(out, 3, "%02X", *arr--); - out += 2; - } while(--size); -} - -void Edit_insert_digit(char new) { - if(*Edit_pos == '-') return; - if(what_doing <= 1) { - if(strlen(Edit_start) < (what_doing == 0 && setup_cursor == 2 ? 3 : 5 * 2)) { - memmove(Edit_pos + 1, Edit_pos, strlen(Edit_pos) + 1); - *Edit_pos = new; - } - } else { - FuriString* fs = Log[view_Batch]; - FuriString* ns = furi_string_alloc(); - if(ns) { - uint16_t len = Edit_pos - (char*)furi_string_get_cstr(fs); - furi_string_set_n(ns, fs, 0, len); - furi_string_cat_printf(ns, "%c", new); - furi_string_cat_str(ns, Edit_pos); - Log[view_Batch] = ns; - Edit_pos = (char*)furi_string_get_cstr(ns); - Edit_start = Edit_pos + (Edit_start - (char*)furi_string_get_cstr(fs)); - Edit_pos += len; - furi_string_free(fs); - } - } -} - -int32_t get_payload_receive_field(uint8_t* var, uint8_t size) { - if(size <= 1) - return *var; - else if(size == 2) - return *(int16_t*)var; - else if(size == 3) - return (*(uint32_t*)var) & 0xFFFFFF; - else - return *(int32_t*)var; -} - -void free_Log() { - if(Log_Total) { - for(uint16_t i = 0; i < Log_Total; i++) - if(Log[i]) furi_string_free(Log[i]); - Log_Total = 0; - } - if(Log) { - free(Log); - Log = NULL; - } -} - -void free_store(void) { - if(Constants) { - furi_string_free(Constants); - Constants = NULL; - } - if(ReadDefault) { - furi_string_free(ReadDefault); - ReadDefault = NULL; - } - if(WriteDefault) { - furi_string_free(WriteDefault); - WriteDefault = NULL; - } - if(WriteStart) { - furi_string_free(WriteStart); - WriteDefault = NULL; - } - if(ListenFields) { - free(ListenFields); - ListenFields = NULL; - } - if(Read_cmd_Total) { - for(uint16_t i = 0; i < Read_cmd_Total; i++) furi_string_free(Read_cmd[i]); - Read_cmd_Total = 0; - } - if(Read_cmd) { - free(Read_cmd); - Read_cmd = NULL; - } - if(ReadBatch_cmd_Total) { - for(uint16_t i = 0; i < ReadBatch_cmd_Total; i++) furi_string_free(ReadBatch_cmd[i]); - ReadBatch_cmd_Total = 0; - } - if(ReadBatch_cmd) { - free(ReadBatch_cmd); - ReadBatch_cmd = NULL; - } - if(WriteBatch_cmd_Total) { - for(uint16_t i = 0; i < WriteBatch_cmd_Total; i++) furi_string_free(WriteBatch_cmd[i]); - WriteBatch_cmd_Total = 0; - } - if(WriteBatch_cmd) { - free(WriteBatch_cmd); - WriteBatch_cmd = NULL; - } - if(SetBatch_cmd_Total) { - for(uint16_t i = 0; i < SetBatch_cmd_Total; i++) furi_string_free(SetBatch_cmd[i]); - SetBatch_cmd_Total = 0; - } - if(SetBatch_cmd) { - free(SetBatch_cmd); - SetBatch_cmd = NULL; - } - free_Log(); -} - -void update_power(void) { - Current = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge) * 1000; -} - -void check_en_power_5V(void) { - if(!furi_hal_power_is_otg_enabled() && !furi_hal_power_is_charging()) { - FURI_LOG_D("PWR", "NO 5V, TURN ON"); - notification_message(APP->notification, &sequence_blink_yellow_100); - furi_delay_ms(10); - update_power(); - CurrentStart = Current; - furi_hal_power_enable_otg(); - NRF_BOARD_POWER_5V = true; - furi_delay_ms(100); - NRF_INITED = 0; - } -} - -static bool select_settings_file() { - DialogsApp* dialogs = furi_record_open("dialogs"); - bool result = false; - FuriString* path; - path = furi_string_alloc(); - furi_string_set(path, SCAN_APP_PATH_FOLDER); - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, ".txt", NULL); - browser_options.hide_ext = false; - bool ret = dialog_file_browser_show(dialogs, path, path, &browser_options); - furi_record_close("dialogs"); - if(ret) { - if(!file_stream_open( - file_stream, furi_string_get_cstr(path), FSAM_READ_WRITE, FSOM_OPEN_EXISTING)) { - FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path)); - file_stream_close(file_stream); - } else { - FURI_LOG_D(TAG, "Open file \"%s\"", furi_string_get_cstr(path)); - strncpy( - file_name, - furi_string_get_cstr(path) + sizeof(SCAN_APP_PATH_FOLDER), - sizeof(file_name)); - result = true; - } - } - furi_string_free(path); - return result; -} - -static void prepare_nrf24(void) { - check_en_power_5V(); - if(!NRF_INITED || rw_type == rwt_listen || NRF_INITED == rwt_listen) { - FURI_LOG_D("NRF", "Prepare"); - uint8_t adrlen, *adr; - if(rw_type == rwt_listen) { - adrlen = listen_addr_len; - adr = listen_addr; - NRF_INITED = rwt_listen; - } else { - adrlen = addr_len; - adr = addr; - NRF_INITED = 1; - } - furi_hal_gpio_write(nrf24_CE_PIN, false); - nrf24_set_mac(REG_RX_ADDR_P0, adr, adrlen); - uint8_t tmp[5] = {0}; - nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adrlen); - for(uint8_t i = 0; i < adrlen / 2; i++) { - uint8_t tb = tmp[i]; - tmp[i] = tmp[adrlen - i - 1]; - tmp[adrlen - i - 1] = tb; - } - NRF_ERROR = memcmp(adr, tmp, adrlen) != 0; - if(NRF_ERROR) { - NRF_INITED = 0; - return; - } - // EN_DYN_ACK(0x01) option for W_TX_PAYLOAD_NOACK cmd broke AA on some fake nRF24l01+, i.e. set it to 0 - nrf24_write_reg( - nrf24_HANDLE, - REG_FEATURE, - NRF_EN_DYN_ACK + - (NRF_DPL ? 4 : - 0)); // Dynamic Payload, Payload with ACK, W_TX_PAYLOAD_NOACK command - nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel); - nrf24_write_reg( - nrf24_HANDLE, - REG_RF_SETUP, - (NRF_rate == 0 ? 0b00100000 : - NRF_rate == 1 ? 0 : - 0b00001000) | - 0b111); // +TX high power - nrf24_write_reg( - nrf24_HANDLE, - REG_CONFIG, - 0x70 | ((NRF_CRC == 1 ? 0b1000 : - NRF_CRC == 2 ? 0b1100 : - 0))); // Mask all interrupts - nrf24_write_reg( - nrf24_HANDLE, REG_SETUP_RETR, NRF_RETR); // Automatic Retransmission, ARD<<4 + ARC - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x01); // Auto acknowledgement - nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg - nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload_size); - nrf24_set_maclen(nrf24_HANDLE, adrlen); - nrf24_set_mac(REG_TX_ADDR, adr, adrlen); - nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, 1); - //nrf24_set_idle(nrf24_HANDLE); - } - nrf24_flush_tx(nrf24_HANDLE); - nrf24_flush_rx(nrf24_HANDLE); - nrf24_write_reg(nrf24_HANDLE, REG_STATUS, MAX_RT | RX_DR | TX_DS); -} - -// true - ok -uint8_t nrf24_send_packet() { - if(furi_log_get_level() == FuriLogLevelDebug) { - char buf[65]; - buf[0] = 0; - add_to_str_hex_bytes(buf, payload, payload_size); - FURI_LOG_D(TAG, "SEND: %s", buf); - } - //nrf24_flush_tx(nrf24_HANDLE); - //nrf24_write_reg(nrf24_HANDLE, REG_STATUS, RX_DR | TX_DS | MAX_RT); - NRF_last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, payload, payload_size, true); // ACK - if(NRF_last_packet_send_st) { - if((rw_type == rwt_read_cmd || rw_type == rwt_read_batch) && - send_status == sst_sending) { // Read - nrf24_set_rx_mode(nrf24_HANDLE); - send_status = sst_receiving; // receiving - } - } else - notification_message(APP->notification, &sequence_blink_red_100); - NRF_time = furi_get_tick(); - FURI_LOG_D( - TAG, - "Send packet: %d%s", - NRF_last_packet_send_st, - send_status == sst_receiving ? ", Receiving" : ""); - return NRF_last_packet_send_st; -} - -uint8_t nrf24_resend_read_packet() { - if(Log_Total && !cmd_array) { - FuriString* str = Log[Log_Total - 1]; - char* p = strstr(furi_string_get_cstr(str), ": "); - if(p) { - if(strncmp(p + 2, "0x", 2) == 0) p += 2; - furi_string_left(str, p - furi_string_get_cstr(str) + 2); - } - } - return nrf24_send_packet(); -} - -// true - new packet -bool nrf24_read_newpacket() { - bool found = false; - uint8_t packetsize; - uint8_t st = - nrf24_rxpacket(nrf24_HANDLE, payload_receive, &packetsize, NRF_DPL ? 0 : payload_size); - if(st & RX_DR) { - NRF_time = furi_get_tick(); - if(furi_log_get_level() == FuriLogLevelDebug) { - char buf[65]; - buf[0] = 0; - add_to_str_hex_bytes(buf, payload_receive, packetsize); - FURI_LOG_D(TAG, "READ(%X): %s", st, buf); - } - if(Log_Total) { - FuriString* str = Log[Log_Total - 1]; - uint8_t size = 1; - char* p = strchr((char*)furi_string_get_cstr(str), '*'); - if(p) { - p++; - if(*p == '=') - size = 0; // string - else { - size = *p - '0'; - if(size > 4) size = 0; - } - } - int32_t var = get_payload_receive_field(payload_receive, size); - //FURI_LOG_D(TAG, "VAR(%d): %ld", size, var); - if(size == 0) - furi_string_cat_printf(str, "%c", (char)var); - else { - char hex[9]; - hex[0] = '\0'; - add_to_str_hex_variable(hex, (uint8_t*)&var, size); - if((cmd_array && cmd_array_hex) || furi_string_end_with_str(str, "0x")) - furi_string_cat_str(str, hex); - else { - if(var >= 0 && var <= 9) - furi_string_cat_printf(str, "%ld", var); - else - furi_string_cat_printf(str, "%ld (%s)", var, hex); - } - } - if(cmd_array) { - if(--cmd_array_cnt) { - furi_string_cat_str(str, ","); - if(cmd_array_hex) furi_string_cat_str(str, "0x"); - payload[cmd_array_idx] += size; // next array element - NRF_repeat = -1; - send_status = sst_sending; // Will be send after delay_between_pkt - } else - send_status = sst_ok; - } else { - if(size == 0) { // string, until '\0' - if(var == 0) send_status = sst_ok; - } else - send_status = sst_ok; - } - } - //notification_message(APP->notification, &sequence_blink_white_100); - found = true; - } else if(st & 0x80) { // NRF24 hardware error - NRF_ERROR = 1; - NRF_INITED = 0; - } - return found; -} - -// Search in constatnt pull (Const1=n; Const2=n;...) -// VAR_EMPTY - not found -int32_t subs_constant(char* p, uint8_t len) { - char* c = (char*)furi_string_get_cstr(Constants); - while((c = strchr(c, *p))) { - if(strncmp(c, p, len) != 0) { - c++; - continue; - } - if(c == (char*)furi_string_get_cstr(Constants) || *(c - 1) == ';' || *(c - 1) <= ' ') { - c += len; - if(*c == '=') { - c++; - return str_to_int(c); - } - } else - c += len; - } - return VAR_EMPTY; -} - -// fill payload with default = p -// if var_n = VAR_EMPTY - skip filling var_* -bool fill_payload(char* p, uint8_t* idx_i, int32_t var_n) { - if(idx_i) *idx_i = 255; - uint8_t fld = 0; // field # - uint8_t idx = 0; // byte index - do { - int32_t b = 0; - char* end = strchr(p, ','); - if(*p >= '0' && *p <= '9') { // Number found - b = str_to_int(p); - } else if(*p == 'i' && *(p + 1) == ':') { // 'i:' array index - b = str_to_int(p + 2); - if(idx_i) *idx_i = idx; - } else if(*p == 'n' && *(p + 1) < '0') { // var_n - if(var_n != VAR_EMPTY) b = var_n; - } else if(*p >= 'A') { // constant found - uint8_t len; - if(end) - len = end - p; - else { - len = strlen(p); - if(*(p + len - 1) == '#') len--; - } - b = subs_constant(p, len); - if(b == VAR_EMPTY) { - ERR = 1; - memset(ERR_STR, 0, sizeof(ERR_STR)); - strcpy(ERR_STR, "No "); - strncpy(ERR_STR + strlen(ERR_STR), p, sizeof(ERR_STR) - 4); - FURI_LOG_D(TAG, "Constant not found: %s", p); - return false; - } - } else if(end == p) { - idx += payload_struct[fld]; - } else if(*p == '#') { // value in Hexadecimal, end string - break; - } else { - ERR = 2; - strcpy(ERR_STR, "char: "); - uint8_t l = strlen(ERR_STR); - ERR_STR[l] = *p; - ERR_STR[l + 1] = '\0'; - FURI_LOG_D(TAG, "Wrong format char(%c)", *p); - return false; - } - if(end != p) { - payload[idx++] = b; - if(payload_struct[fld] > 1) payload[idx++] = b >> 8; - if(payload_struct[fld] > 2) payload[idx++] = b >> 16; - if(payload_struct[fld] > 3) payload[idx++] = b >> 24; - } - if(++fld == payload_fields || idx >= sizeof(payload) || end == NULL) break; - p = end + 1; - } while(1); - return true; -} - -// Cmd: "name=payload" -bool Run_Read_cmd(FuriString* cmd) { - char* p = (char*)furi_string_get_cstr(cmd); - p = strchr(p, '='); - if(p == NULL) return false; - if(Log == NULL) - Log = malloc(sizeof(Log)); - else - Log = realloc(Log, sizeof(Log) * (Log_Total + 1)); - if(Log == NULL) { - ERR = 3; - strcpy(ERR_STR, "Memory low"); - FURI_LOG_D(TAG, ERR_STR); - return false; - } - FuriString* fs = furi_string_alloc(); - furi_string_set_strn( - fs, (char*)furi_string_get_cstr(cmd), p - (char*)furi_string_get_cstr(cmd)); - furi_string_cat_str(fs, ": "); - bool hexval; - if((hexval = *(p + strlen(p) - 1) == '#')) - furi_string_cat_str(fs, "0x"); // value in Hex format - Log[Log_Total++] = fs; - p++; - memset(payload, 0, sizeof(payload)); - if(ReadDefault && !fill_payload((char*)furi_string_get_cstr(ReadDefault), NULL, VAR_EMPTY)) - return false; - if(!fill_payload(p, &cmd_array_idx, VAR_EMPTY)) return false; - memset(payload_receive, 0, sizeof(payload_receive)); - cmd_array = false; - if(*(p - 2) == ']' && cmd_array_idx != 255) { // array - p = strchr(furi_string_get_cstr(cmd), '['); - if(p) { - cmd_array_cnt = str_to_int(p + 1); - if(cmd_array_cnt > 1) { - cmd_array_hex = hexval; - cmd_array = true; // array - } - } - } - prepare_nrf24(); - if(NRF_ERROR) return false; - what_doing = 2; - NRF_repeat = 0; - send_status = sst_sending; // Read - sending - nrf24_send_packet(); - return true; -} - -// run commands one by one, true - command running -bool Run_ReadBatch_cmd(FuriString* cmd) { - char* p; - if(cmd) { - p = strchr((char*)furi_string_get_cstr(cmd), ':'); - if(p == NULL) { - ERR = 5; - strcpy(ERR_STR, "WRONG FORMAT"); - return false; - } - p += 2; - ReadBatch_cmd_curr = NULL; - free_Log(); - } else { - if(ReadBatch_cmd_curr) - p = ReadBatch_cmd_curr; - else - return false; - } - char* end = strchr(p, ';'); - uint8_t len; - if(end) - len = end - p; - else { - str_rtrim(p); - len = strlen(p); - } - for(uint16_t i = 0; i < Read_cmd_Total; i++) { - FuriString* fs = Read_cmd[i]; - if(strncmp((char*)furi_string_get_cstr(fs), p, len) == 0) { - char c = *((char*)furi_string_get_cstr(fs) + len); - if(c != '=' && c != '*' && c != '[') continue; - if(end) - ReadBatch_cmd_curr = end + 1; - else - ReadBatch_cmd_curr = (char*)0xFFFFFFFF; - if(!Run_Read_cmd(fs)) break; - return true; - } - } - if(NRF_ERROR) return false; - if(ERR == 0) { - ERR = 4; - strcpy(ERR_STR, "NOT FOUND"); - FuriString* fs = furi_string_alloc(); - furi_string_set_strn(fs, p, len); - Log[Log_Total++] = fs; - FURI_LOG_D(TAG, "CMD %s: %s", ERR_STR, p); - } - view_Batch = Log_Total ? Log_Total - 1 : 0; - return false; -} - -void Prepare_Write_cmd(FuriString* cmd) { - free_Log(); - if(cmd == NULL) return; - char *end, *p = strchr((char*)furi_string_get_cstr(cmd), ':'); - if(p == NULL) { - ERR = 8; - strcpy(ERR_STR, "Wrong batch"); - FURI_LOG_D(TAG, ERR_STR); - return; - } - p += 2; - Log = malloc(sizeof(Log)); - do { - end = strchr(p, ';'); - uint8_t len; - if(end) { - len = end - p; - end++; - } else { - str_rtrim(p); - len = strlen(p); - } - FuriString* fs = furi_string_alloc(); - if(Log_Total) Log = realloc(Log, sizeof(Log) * (Log_Total + 1)); - if(Log == NULL) { - ERR = 3; - strcpy(ERR_STR, "Memory low"); - FURI_LOG_D(TAG, ERR_STR); - return; - } - furi_string_set_strn(fs, p, len); - Log[Log_Total++] = fs; - } while((p = end)); -} - -// Write / Set batch -bool Run_WriteBatch_cmd() { - if(Log_Total == 0) return false; - uint16_t cmd_curr = rw_type == rwt_write_batch ? WriteBatch_cmd_curr : SetBatch_cmd_curr; - if(cmd_curr == 0) { // first - prepare_nrf24(); - if(NRF_ERROR) return false; - if(rw_type == rwt_write_batch && WriteStart) { - if(!fill_payload((char*)furi_string_get_cstr(WriteStart), NULL, VAR_EMPTY)) - return false; - send_status = sst_sending; - if(!nrf24_send_packet()) return false; - } - } - char* p = (char*)furi_string_get_cstr(Log[cmd_curr]); - uint16_t len = furi_string_size(Log[cmd_curr]); - char* arr = NULL; - cmd_array = false; - int32_t new = 0; - for(uint16_t i = 0; i < len; i++) { - if(p[i] == '=') { - len = i; - char* p2 = p + i + 1; - if(*p2 == '{') { - arr = ++p2; // array - cmd_array = true; - } - new = str_to_int(p2); - break; - } - } - FURI_LOG_D( - TAG, "%cBatch: =%d, (%d)%s", rw_type == rwt_write_batch ? 'W' : 'S', (int)new, len, p); - char *w, *delim_col, i, size; - FuriString* str = furi_string_alloc(); - stream_rewind(file_stream); - while(stream_read_line(file_stream, str)) { - w = (char*)furi_string_get_cstr(str); - if(strncmp(w, SettingsFld_Write, sizeof(SettingsFld_Write) - 1) == 0) - w += sizeof(SettingsFld_Write); - else if(strncmp(w, SettingsFld_Set, sizeof(SettingsFld_Set) - 1) == 0) - w += sizeof(SettingsFld_Set); - else - continue; - delim_col = strchr(w, '='); - if(delim_col == NULL) continue; - size = 1; - if(*(delim_col - 2) == '*') { - if(len != delim_col - w - 2) continue; - size = *(delim_col - 1) - '0'; - new = new&(size == 1 ? 0xFF : size == 2 ? 0xFFFF : size == 3 ? 0xFFFFFF : 0xFFFFFFFF); - } else if(len != delim_col - w) - continue; - if(strncmp(p, w, len) != 0) continue; - delim_col++; - str_rtrim(delim_col); - cmd_array_cnt = 255; - do { - memset(payload, 0, sizeof(payload)); - if(WriteDefault && - !fill_payload((char*)furi_string_get_cstr(WriteDefault), NULL, new)) { - view_Batch = cmd_curr; - return false; - } - if(!fill_payload(delim_col, &cmd_array_idx, VAR_EMPTY)) { - view_Batch = cmd_curr; - return false; - } - if(cmd_array && cmd_array_idx != 255) { - if(cmd_array_cnt != 255) payload[cmd_array_idx] = cmd_array_cnt; - } else - cmd_array = false; - send_status = sst_sending; - NRF_repeat = 0; - i = 0; - do { - if(nrf24_send_packet()) break; - furi_delay_ms(delay_between_pkt); - } while(i++ < NRF_resend); - if(i < NRF_resend || i == 0) { // ok - if(cmd_array) { // array - for(; arr != NULL;) { - if(*arr == ',') break; - if(*arr == '}' || *arr < ' ') - arr = NULL; - else - arr++; - } - if(arr == NULL) { - send_status = sst_ok; - break; - } - arr++; - new = str_to_int(arr); - cmd_array_cnt = payload[cmd_array_idx] + size; - //furi_delay_ms(delay_between_pkt); // do it fast - continue; // send next array element - } else - send_status = sst_ok; - } - break; - } while(1); - if(send_status != sst_ok) { - send_status = sst_error; - view_Batch = cmd_curr; - return false; - } - return true; - } - ERR = 7; - strcpy(ERR_STR, "NOT FOUND!"); - send_status = sst_error; - view_Batch = cmd_curr; - return false; -} - -// Return 0 - success, otherwise an error -static uint8_t load_settings_file() { - uint8_t err = 0; - FURI_LOG_D(TAG, "Loading settings file"); - FuriString* str = furi_string_alloc(); - free_store(); - Info[0] = '\0'; - NRF_INITED = false; - while(stream_read_line(file_stream, str)) { - char* p = (char*)furi_string_get_cstr(str); - if(*p <= '!' || *p == ';') continue; - //char* delim_eq = strchr(p, '='); - char* delim_col = strchr(p, ':'); - if(delim_col == NULL) { // Constant found - no ':' - if(Constants == NULL) { - Constants = furi_string_alloc_set(str); - } else - furi_string_cat(Constants, str); - } else { - str_rtrim(p); - if(strncmp(p, SettingsFld_Rate, sizeof(SettingsFld_Rate) - 1) == 0) { - NRF_rate = str_to_int(p + sizeof(SettingsFld_Rate)); - } else if(strncmp(p, SettingsFld_Info, sizeof(SettingsFld_Info) - 1) == 0) { - strncpy(Info, p + sizeof(SettingsFld_Info), sizeof(Info) - 1); - } else if(strncmp(p, SettingsFld_Ch, sizeof(SettingsFld_Ch) - 1) == 0) { - NRF_channel = str_to_int(p + sizeof(SettingsFld_Ch)); - } else if(strncmp(p, SettingsFld_Address, sizeof(SettingsFld_Address) - 1) == 0) { - p += sizeof(SettingsFld_Address); - addr_len = ConvertHexToArray(p, addr, 5); - } else if(strncmp(p, SettingsFld_CRC, sizeof(SettingsFld_CRC) - 1) == 0) { - NRF_CRC = str_to_int(p + sizeof(SettingsFld_CRC)); - } else if(strncmp(p, SettingsFld_DPL, sizeof(SettingsFld_DPL) - 1) == 0) { - NRF_DPL = str_to_int(p + sizeof(SettingsFld_DPL)); - } else if(strncmp(p, SettingsFld_RETR, sizeof(SettingsFld_RETR) - 1) == 0) { - NRF_RETR = str_to_int(p + sizeof(SettingsFld_RETR)); - } else if(strncmp(p, SettingsFld_Resend, sizeof(SettingsFld_Resend) - 1) == 0) { - NRF_resend = str_to_int(p + sizeof(SettingsFld_Resend)); - } else if(strncmp(p, SettingsFld_Delay, sizeof(SettingsFld_Delay) - 1) == 0) { - delay_between_pkt = str_to_int(p + sizeof(SettingsFld_Delay)); - } else if( - strncmp( - p, - SettingsFld_ReadCmdRepeatPeriod, - sizeof(SettingsFld_ReadCmdRepeatPeriod) - 1) == 0) { - ReadCmdRepeatPeriod = str_to_int(p + sizeof(SettingsFld_ReadCmdRepeatPeriod)); - } else if(strncmp(p, SettingsFld_Payload, sizeof(SettingsFld_Payload) - 1) == 0) { - p += sizeof(SettingsFld_Payload); - payload_fields = 0; - payload_size = 0; - do { - uint8_t b = str_to_int(p); - if(b < 1 || b > 4) { - FURI_LOG_D(TAG, "Wrong payload format (%d)", b); - err = 3; - break; - } - payload_struct[payload_fields++] = b; - payload_size += b; - if(payload_fields == sizeof(payload_struct) - 1) break; - if((p = strchr(p, ',')) == NULL) break; - p++; - } while(1); - FURI_LOG_D( - TAG, - "Payload fields %d: %d,%d,%d", - payload_fields, - payload_struct[0], - payload_struct[1], - payload_struct[2]); - } else if(strncmp(p, SettingsFld_ReadDefault, sizeof(SettingsFld_ReadDefault) - 1) == 0) { - ReadDefault = furi_string_alloc_set_str(p + sizeof(SettingsFld_ReadDefault)); - } else if(strncmp(p, SettingsFld_WriteStart, sizeof(SettingsFld_WriteStart) - 1) == 0) { - WriteStart = furi_string_alloc_set_str(p + sizeof(SettingsFld_WriteStart)); - } else if(strncmp(p, SettingsFld_WriteDefault, sizeof(SettingsFld_WriteDefault) - 1) == 0) { - WriteDefault = furi_string_alloc_set_str(p + sizeof(SettingsFld_WriteDefault)); - } else if(strncmp(p, SettingsFld_Read, sizeof(SettingsFld_Read) - 1) == 0) { - p += sizeof(SettingsFld_Read); - if(Read_cmd == NULL) - Read_cmd = malloc(sizeof(Read_cmd)); - else { - Read_cmd = realloc(Read_cmd, sizeof(Read_cmd) * (Read_cmd_Total + 1)); - } - if(Read_cmd == NULL) { - FURI_LOG_D(TAG, "Memory low, err 4"); - err = 4; - break; - } - Read_cmd[Read_cmd_Total++] = furi_string_alloc_set_str(p); - } else if(strncmp(p, SettingsFld_ReadBatch, sizeof(SettingsFld_ReadBatch) - 1) == 0) { - p += sizeof(SettingsFld_ReadBatch); - if(ReadBatch_cmd == NULL) - ReadBatch_cmd = malloc(sizeof(ReadBatch_cmd)); - else { - ReadBatch_cmd = - realloc(ReadBatch_cmd, sizeof(ReadBatch_cmd) * (ReadBatch_cmd_Total + 1)); - } - if(ReadBatch_cmd == NULL) { - FURI_LOG_D(TAG, "Memory low, err 5"); - err = 5; - break; - } - ReadBatch_cmd[ReadBatch_cmd_Total++] = furi_string_alloc_set_str(p); - } else if(strncmp(p, SettingsFld_WriteBatch, sizeof(SettingsFld_WriteBatch) - 1) == 0) { - p += sizeof(SettingsFld_WriteBatch); - if(WriteBatch_cmd == NULL) - WriteBatch_cmd = malloc(sizeof(WriteBatch_cmd)); - else { - WriteBatch_cmd = realloc( - WriteBatch_cmd, sizeof(WriteBatch_cmd) * (WriteBatch_cmd_Total + 1)); - } - if(WriteBatch_cmd == NULL) { - FURI_LOG_D(TAG, "Memory low, err 6"); - err = 6; - break; - } - WriteBatch_cmd[WriteBatch_cmd_Total++] = furi_string_alloc_set_str(p); - } else if(strncmp(p, SettingsFld_SetBatch, sizeof(SettingsFld_SetBatch) - 1) == 0) { - p += sizeof(SettingsFld_SetBatch); - if(SetBatch_cmd == NULL) - SetBatch_cmd = malloc(sizeof(SetBatch_cmd)); - else { - SetBatch_cmd = - realloc(SetBatch_cmd, sizeof(SetBatch_cmd) * (SetBatch_cmd_Total + 1)); - } - if(SetBatch_cmd == NULL) { - FURI_LOG_D(TAG, "Memory low, err 7"); - err = 7; - break; - } - SetBatch_cmd[SetBatch_cmd_Total++] = furi_string_alloc_set_str(p); - } else if(strncmp(p, SettingsFld_Listen, sizeof(SettingsFld_Listen) - 1) == 0) { - p += sizeof(SettingsFld_Listen); - char* p2 = strchr(p, '='); - if(p2) { - listen_addr_len = ConvertHexToArray(p, listen_addr, (p2 - p) / 2); - p2++; - uint8_t len = strlen(p2); - ListenFields = malloc(len + 1); - if(ListenFields) memcpy(ListenFields, p2, len); - } - } - } - } - furi_string_free(str); - return err; -} - -static void save_batch(void) { - FURI_LOG_D(TAG, "Save Batch"); - char *p, *p2; - stream_seek(file_stream, 0, StreamOffsetFromEnd); - FuriHalRtcDateTime dt; - furi_hal_rtc_get_datetime(&dt); - stream_write_format(file_stream, "\n%s ", SettingsFld_WriteBatch); - p = (char*)furi_string_get_cstr(ReadBatch_cmd[view_cmd[rwt_read_batch]]); - p2 = strchr(p, ':'); - if(p2 == NULL) p2 = p + strlen(p); - stream_write(file_stream, (uint8_t*)p, p2 - p); - stream_write_format( - file_stream, - " %02d.%02d.%02d %02d.%02d: ", - dt.day, - dt.month, - dt.year % 100, - dt.hour, - dt.minute); - for(uint16_t i = 0; i < Log_Total; i++) { - p = (char*)furi_string_get_cstr(Log[i]); - p2 = strchr(p, ':'); - if(p2 && *(p2 - 1) != '*') { // skip string - if(*(p2 - 1) == ']') { // array - char* p3 = strchr(p, '['); - if(p3) { - stream_write(file_stream, (uint8_t*)p, p3 - p - (*(p3 - 2) == '*' ? 2 : 0)); - stream_write_cstring(file_stream, "={"); - p = (p2 += 2); - do { - while(is_digit(p2, true) || *p2 == 'x') p2++; - stream_write(file_stream, (uint8_t*)p, p2 - p); - char c = *p2; - if(c == '\0') break; - if(c != ',') { - p2 = strchr(p2, ','); - if(p2 == NULL) break; - } - stream_write_char(file_stream, ','); - p = ++p2; - } while(1); - stream_write_char(file_stream, '}'); - } - } else { - stream_write(file_stream, (uint8_t*)p, p2 - p - (*(p2 - 2) == '*' ? 2 : 0)); - stream_write_char(file_stream, '='); - p2 += 2; - p = strchr(p2, ' '); - if(p == NULL) p = p2 + strlen(p2); - stream_write(file_stream, (uint8_t*)p2, p - p2); - } - if(i < Log_Total - 1) stream_write_char(file_stream, ';'); - } - } -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -void display_remove_asterisk(char* fsp, uint8_t vx) { - char* p2 = strchr(fsp, '*'); - if(p2) { // remove '*' or '*n' - int pos = p2 - fsp; - if((pos -= vx) < 0) pos = 0; - char c = *(p2 + 1); - if(*(screen_buf + pos)) - memmove( - screen_buf + pos, - screen_buf + pos + (c == ':' || c == '=' ? 1 : 2), - FONT_5x7_SCREEN_WIDTH + 1 + 2 - pos); - } -} - -void render_display_list( - Canvas* const canvas, - FuriString*** fsa, - char delim, - uint16_t view_pos, - uint16_t max_i) { - uint16_t page = view_pos & ~7; - char *p, *end; - uint16_t y, len; - for(uint8_t i = 0; i < 8 && page + i < max_i; i++) { - y = 14 + i * 7; - p = (char*)furi_string_get_cstr((*fsa)[page + i]); - end = strchr(p, delim); - if(end) { - len = MIN(end - p, view_x); - len = MIN(end - p - len, FONT_5x7_SCREEN_WIDTH); - strncpy(screen_buf, p + view_x, len); - screen_buf[len] = '\0'; - display_remove_asterisk(p, MIN(end - p, view_x)); - canvas_draw_str(canvas, 5, y, screen_buf); - } - if((view_pos & 7) == i) { - canvas_draw_str(canvas, 0, y, ">"); - canvas_draw_str(canvas, -1, y, ">"); - } - } -} - -void display_edit_ttf_font(Canvas* const canvas, uint8_t start_x, uint8_t start_y) { - screen_buf[0] = *Edit_pos; - screen_buf[1] = '\0'; - int n = canvas_string_width(canvas, screen_buf); - int len = Edit_pos - Edit_start; - memcpy(screen_buf, Edit_start, len); - screen_buf[len] = '\0'; - int x = start_x + canvas_string_width(canvas, screen_buf); - int len2 = strlen(Edit_pos); - memcpy(screen_buf + len, Edit_pos, len2); - screen_buf[len + len2] = '\0'; - canvas_draw_str(canvas, start_x, start_y, screen_buf); - start_y += 1; - canvas_draw_line( - canvas, x + (len ? 1 : 0), start_y, x + n + (*Edit_pos == '1' && len ? 1 : 0), start_y); -} - -void display_add_status(void) { - if(NRF_ERROR) - strcat(screen_buf, "nRF24 ERROR!"); - else if(ERR) - snprintf(screen_buf, sizeof(screen_buf), "ERROR %s", ERR_STR); - else if(send_status == sst_error) - strcat(screen_buf, "NO ACK!"); - else if(send_status == sst_timeout) - strcat(screen_buf, "TIMEOUT!"); - else if(send_status == sst_none) - ; - else if(send_status == sst_sending) - strcat(screen_buf, "sending"); - else if(send_status == sst_receiving) - strcat(screen_buf, "receiving"); - else if( - send_status == sst_ok && - (rw_type == rwt_read_cmd || - (rw_type == rwt_read_batch && (uint32_t)ReadBatch_cmd_curr == 0xFFFFFFFF) || - (rw_type == rwt_set_batch && SetBatch_cmd_curr == Log_Total) || - (rw_type == rwt_write_batch && WriteBatch_cmd_curr == Log_Total))) - strcat(screen_buf, "OK"); - else - strcat(screen_buf, "working"); -} - -static void render_callback(Canvas* const canvas, void* ctx) { - if(ctx == NULL) return; - const PluginState* plugin_state = ctx; - if(furi_mutex_acquire(plugin_state->mutex, 5) != FuriStatusOk) return; - - //canvas_draw_frame(canvas, 0, 0, 128, 64); // border around the edge of the screen - if(what_doing == 0) { - canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines - snprintf(screen_buf, sizeof(screen_buf), "%s: %s", addr_len ? "File" : "Open", file_name); - canvas_draw_str(canvas, 8, 10, screen_buf); - if(addr_len) { - if(Edit) { - if(setup_cursor == 1) - display_edit_ttf_font(canvas, 45, 20); - else if(setup_cursor == 2) - display_edit_ttf_font(canvas, 55, 30); - } - if(!Edit || setup_cursor != 1) { - screen_buf[0] = '\0'; - add_to_str_hex_bytes(screen_buf, addr, addr_len); - canvas_draw_str(canvas, 45, 20, screen_buf); - } - if(!Edit || setup_cursor != 2) { - snprintf(screen_buf, sizeof(screen_buf), "%d", NRF_channel); - canvas_draw_str(canvas, 55, 30, screen_buf); - } - canvas_draw_str(canvas, 8, 20, "Address:"); - snprintf(screen_buf, sizeof(screen_buf), "Rate: %d, Ch:", NRF_rate); - canvas_draw_str(canvas, 8, 30, screen_buf); - snprintf( - screen_buf, - sizeof(screen_buf), - "RB: %d, R: %d, WB: %d", - ReadBatch_cmd_Total, - Read_cmd_Total, - WriteBatch_cmd_Total); - canvas_draw_str(canvas, 8, 40, screen_buf); - canvas_draw_str(canvas, 0, 64, Info); - canvas_draw_str(canvas, 0, 10 + setup_cursor * 10, ">"); - } else { - snprintf(screen_buf, sizeof(screen_buf), "Ver. %s, vad7", VERSION); - canvas_draw_str(canvas, 10, 60, screen_buf); - canvas_draw_str(canvas, 0, 10, ">"); - } - } else if(what_doing == 1) { - if(rw_type == rwt_listen) { - canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines - canvas_draw_str(canvas, 0, 10, "Listen mode"); - canvas_draw_str(canvas, 0, 25, "Address:"); - if(Edit) - display_edit_ttf_font(canvas, 40, 25); - else if(listen_addr_len) { - screen_buf[0] = '\0'; - add_to_str_hex_bytes(screen_buf, listen_addr, listen_addr_len); - canvas_draw_str(canvas, 40, 25, screen_buf); - } - snprintf( - screen_buf, - sizeof(screen_buf), - "I: %d +(%d) mA", - Current - CurrentStart, - CurrentStart); - canvas_draw_str(canvas, 0, 60, screen_buf); - } else { - canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines, 25 cols - if(rw_type == rwt_read_batch) { - canvas_draw_str(canvas, 0, 7, "Read Batch:"); - render_display_list( - canvas, &ReadBatch_cmd, ':', view_cmd[rw_type], ReadBatch_cmd_Total); - } else if(rw_type == rwt_read_cmd) { - canvas_draw_str(canvas, 0, 7, "Read Command:"); - render_display_list(canvas, &Read_cmd, '=', view_cmd[rw_type], Read_cmd_Total); - } else if(rw_type == rwt_write_batch) { - if(!ask_fill_screen_buf()) strcpy(screen_buf, "Write Batch:"); - canvas_draw_str(canvas, 0, 7, screen_buf); - render_display_list( - canvas, &WriteBatch_cmd, ':', view_cmd[rw_type], WriteBatch_cmd_Total); - } else if(rw_type == rwt_set_batch) { - strcpy(screen_buf, "Set: "); - display_add_status(); - canvas_draw_str(canvas, 0, 7, screen_buf); - render_display_list( - canvas, &SetBatch_cmd, ':', view_cmd[rw_type], SetBatch_cmd_Total); - } - } - } else { // what_doing == 2 - if(rw_type == rwt_listen) { - canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines - strcpy(screen_buf, "Listen: "); - if(NRF_ERROR) - strcat(screen_buf, "nRF24 ERROR!"); - else if(ListenNew) { - snprintf( - screen_buf + strlen(screen_buf), - 16, - "%02d:%02d:%02d", - ListenLastTime.hour, - ListenLastTime.minute, - ListenLastTime.second); - if(ListenPrev) - snprintf( - screen_buf + strlen(screen_buf), 16, " (%lu)", ListenLast - ListenPrev); - } else - strcat(screen_buf, "receiving"); - snprintf(screen_buf + strlen(screen_buf), 16, " %dmA", Current - CurrentStart); - canvas_draw_str(canvas, 0, 10, screen_buf); - if(ListenFields) { - char *p2, *p = ListenFields; - uint8_t hex, len, *pld = payload_receive; - for(uint8_t i = 0; i < 5 && *p; i++) { - hex = false; - p2 = strchr(p, ','); - if(p2 == NULL) p2 = p + strlen(p); - if(*(p2 - 1) == '#') hex = true; - memcpy(screen_buf, p, len = p2 - p); - strcpy(screen_buf + len, ": "); - if(ListenNew) { - len = payload_struct[i]; - int32_t n = get_payload_receive_field(pld, len); - if(hex) { - strcat(screen_buf, "0x"); - add_to_str_hex_variable(screen_buf, pld, len); - } else { - snprintf(screen_buf + strlen(screen_buf), 20, "%ld", n); - if(n > 9) { - strcat(screen_buf, " ("); - add_to_str_hex_variable(screen_buf, pld, len); - strcat(screen_buf, ")"); - } - } - pld += len; - } - canvas_draw_str(canvas, 0, 20 + i * 10, screen_buf); - if(*p2 == '\0') break; - p = p2 + 1; - } - } - } else if(rw_type == rwt_read_cmd) { // Read command - canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines - if(!ask_fill_screen_buf()) { - strcpy(screen_buf, "Read "); - strcat(screen_buf, ReadRepeat ? "rep: " : "cmd: "); - } - display_add_status(); - canvas_draw_str(canvas, 0, 10, screen_buf); - if(Log_Total) { - char* p = (char*)furi_string_get_cstr(Log[Log_Total - 1]); - uint8_t vx = MIN(view_x, strlen(p)); - strncpy(screen_buf, p + vx, 30); - display_remove_asterisk(p, vx); - canvas_draw_str(canvas, 0, 15 + 10, screen_buf); - } - } else if(rw_type == rwt_set_batch) { - canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines, 25 cols - strcpy(screen_buf, "Set: "); - display_add_status(); - canvas_draw_str(canvas, 0, 7, screen_buf); - render_display_list(canvas, &SetBatch_cmd, ':', view_cmd[rw_type], SetBatch_cmd_Total); - } else { // rwt_read_batch, rwt_write_batch - canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines, 25 cols - if(!ask_fill_screen_buf()) { - strcpy(screen_buf, rw_type == rwt_read_batch ? "Read Batch: " : "Write: "); - if(rw_type == rwt_read_batch || send_status != sst_none) { - display_add_status(); - } else if(rw_type == rwt_write_batch) { - char* p = - (char*)furi_string_get_cstr(WriteBatch_cmd[view_cmd[rwt_write_batch]]); - char* end = strchr(p, ':'); - if(end) { - uint8_t len = end - p; - uint8_t lenb = strlen(screen_buf); - end = screen_buf + lenb; - lenb = FONT_5x7_SCREEN_WIDTH - lenb; - if(len > lenb) { - if(view_x < len) { - strncpy(end, p + view_x, len = MIN(lenb, len - view_x)); - end[len] = '\0'; - } - } else { - strncpy(end, p, len); - end[len] = '\0'; - } - } - } - } - canvas_draw_str(canvas, 0, 7, screen_buf); - if(Log_Total) { - char* p; - uint16_t y, page = view_Batch & ~7; - uint8_t vx; - for(uint8_t i = 0; i < 8 && page + i < Log_Total; i++) { - p = (char*)furi_string_get_cstr(Log[page + i]); - y = 14 + i * 7; - vx = MIN(view_x, strlen(p)); - if((view_Batch & 7) == i) { - canvas_draw_str(canvas, 0, y, ">"); - canvas_draw_str(canvas, -1, y, ">"); - if(Edit) { - int n = Edit_pos - p - vx - (FONT_5x7_SCREEN_WIDTH - 4); - if(n > 0) vx += n; // fix out of screen - int x = 6 + (Edit_pos - p - vx) * 5; - canvas_draw_line(canvas, x - 1, y, x - 1, y - 1); - canvas_draw_line(canvas, x - 1, y, n = x + 1 * 5, y); - canvas_draw_line(canvas, n, y, n, y - 1); - } - } - strncpy(screen_buf, p + vx, FONT_5x7_SCREEN_WIDTH + 2); - screen_buf[FONT_5x7_SCREEN_WIDTH + 2] = '\0'; - display_remove_asterisk(p, vx); - canvas_draw_str(canvas, 6, y, screen_buf); - } - } - } - } - furi_mutex_release(plugin_state->mutex); -} - -void work_timer_callback(void* ctx) { - if(ctx == NULL) return; - if(rw_type == rwt_listen && (pwr_read_timer += WORK_PERIOD) >= POWER_READ_PERIOD) { - pwr_read_timer = 0; - update_power(); - } - if(what_doing == 2) { - const PluginState* plugin_state = ctx; - if(furi_mutex_acquire(plugin_state->mutex, 0) != FuriStatusOk) return; - if(rw_type == rwt_write_batch || rw_type == rwt_set_batch) { - uint16_t* cmd_curr = rw_type == rwt_set_batch ? &SetBatch_cmd_curr : - &WriteBatch_cmd_curr; - if(ERR == 0 && furi_get_tick() - NRF_time >= delay_between_pkt) { - if(send_status == sst_ok) { - if(ERR == 0 && *cmd_curr < Log_Total) { - if(++(*cmd_curr) < Log_Total) - Run_WriteBatch_cmd(); - else { // finished ok - if(rw_type == rwt_set_batch) what_doing = 1; - Edited = false; - } - } - } else if(send_status == sst_sending) { - if(NRF_repeat++ < NRF_resend) - nrf24_send_packet(); - else { - view_Batch = *cmd_curr; - send_status = sst_error; // error NO_ACK - } - } - } - if((ERR || send_status == sst_error) && rw_type == rwt_set_batch) { - what_doing = 1; - } - // ReadBatch or ReadCmd - } else if(send_status == sst_sending) { // sending - if(furi_get_tick() - NRF_time > delay_between_pkt) { - if(NRF_repeat++ < NRF_resend) { - nrf24_resend_read_packet(); - } else - send_status = sst_error; // error NO_ACK - } - } else if(send_status == sst_receiving) { // receiving - for(uint8_t i = 0; i < 3; i++) { - if(nrf24_read_newpacket()) { - if(rw_type == rwt_listen) { - ListenPrev = ListenLast; - furi_hal_rtc_get_datetime(&ListenLastTime); - ListenLast = furi_hal_rtc_datetime_to_timestamp(&ListenLastTime); - ListenNew = true; - } else if(send_status != sst_receiving) - break; - } else { - if(rw_type != rwt_listen && furi_get_tick() - NRF_time > NRF_READ_TIMEOUT) { - if(NRF_repeat++ < NRF_resend) { - send_status = sst_sending; - nrf24_resend_read_packet(); - } else { - FURI_LOG_D(TAG, "TIMEOUT: %lu", furi_get_tick() - NRF_time); - send_status = sst_timeout; - } - } - break; - } - } - } else if(send_status == sst_ok) { - if(rw_type == rwt_read_batch) { - if((uint32_t)ReadBatch_cmd_curr != 0xFFFFFFFF && ERR == 0 && - furi_get_tick() - NRF_time >= delay_between_pkt) { - Run_ReadBatch_cmd(NULL); - } - } - } - furi_mutex_release(plugin_state->mutex); - } -} - -void next_rw_type(int8_t add) { - do { - rw_type += add; - if(rw_type >= rwt_max) { - if(add > 0) - rw_type = 0; - else - rw_type = rwt_max - 1; - } - if(rw_type == rwt_set_batch && SetBatch_cmd_Total) break; - if(rw_type == rwt_read_batch && ReadBatch_cmd_Total) break; - if(rw_type == rwt_read_cmd && Read_cmd_Total) break; - if(rw_type == rwt_write_batch && WriteBatch_cmd_Total) break; - } while(rw_type != rwt_listen); - send_status = sst_none; -} - -void next_view_cmd(int8_t add) { - if(rw_type == rwt_listen) return; - uint16_t max = - (rw_type == rwt_read_batch ? ReadBatch_cmd_Total : - rw_type == rwt_read_cmd ? Read_cmd_Total : - rw_type == rwt_set_batch ? SetBatch_cmd_Total : - WriteBatch_cmd_Total); - if((view_cmd[rw_type] += add) >= max) view_cmd[rw_type] = add > 0 ? 0 : max - 1; -} - -int32_t nrf24batch_app(void* p) { - UNUSED(p); - APP = malloc(sizeof(nRF24Batch)); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - APP->plugin_state = malloc(sizeof(PluginState)); - APP->plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!APP->plugin_state->mutex) { - furi_message_queue_free(event_queue); - FURI_LOG_E(TAG, "cannot create mutex"); - free(APP->plugin_state); - return 255; - } - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, APP->plugin_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - APP->gui = furi_record_open(RECORD_GUI); - gui_add_view_port(APP->gui, view_port, GuiLayerFullscreen); - APP->notification = furi_record_open(RECORD_NOTIFICATION); - APP->storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(APP->storage, EXT_PATH("nrf24batch"), SCAN_APP_PATH_FOLDER); - storage_common_mkdir(APP->storage, SCAN_APP_PATH_FOLDER); - file_stream = file_stream_alloc(APP->storage); - FuriTimer* work_timer = - furi_timer_alloc(work_timer_callback, FuriTimerTypePeriodic, APP->plugin_state); - furi_timer_start(work_timer, WORK_PERIOD); - nrf24_init(); - check_en_power_5V(); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(APP->plugin_state->mutex, FuriWaitForever); - - static FuriLogLevel FuriLogLevel = FuriLogLevelDefault; - if(furi_log_get_level() != FuriLogLevel) { - FuriLogLevel = furi_log_get_level(); - if(FuriLogLevel == FuriLogLevelDebug) - furi_hal_uart_set_br(FuriHalUartIdUSART1, 1843200); - } - if(what_doing == 2 && rw_type == rwt_read_cmd && ReadRepeat && - furi_get_tick() - NRF_time > (uint32_t)(ReadCmdRepeatPeriod * 1000)) { - ERR = 0; - free_Log(); - Run_Read_cmd(Read_cmd[view_cmd[rwt_read_cmd]]); - notification_message(APP->notification, &sequence_blink_blue_100); - } - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - switch(event.input.key) { - case InputKeyUp: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(!ask_question) { - if(Edit) { - char c = *Edit_pos; - if(Edit_hex) { - if(c == '9') - *Edit_pos = 'A'; - else if(c < 'F' || c < '9') - *Edit_pos = c + 1; - } else { - if(c == '-') - *Edit_pos = '0'; - else if(c < '9') - *Edit_pos = c + 1; - else { - c = *(Edit_pos - 1); - if(Edit_pos > Edit_start && c < '9' && c >= '0') { - *Edit_pos = '0'; - (*(Edit_pos - 1)) = c + 1; - } - } - } - } else if(what_doing == 0) { - if(addr_len) { - if(setup_cursor > 0) - setup_cursor--; - else - setup_cursor = 2; - } - } else if(what_doing == 1) - next_view_cmd(-1); - else if(what_doing == 2) - if(view_Batch) view_Batch--; - } - } - break; - case InputKeyDown: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(!ask_question) { - if(Edit) { - if(*Edit_pos != '-') { - if(Edit_hex && *Edit_pos == 'A') - (*Edit_pos) = '9'; - else if(*Edit_pos > '0') - (*Edit_pos)--; - else if(!Edit_hex) { - if(Edit_pos > Edit_start) { - if(*(Edit_pos - 1) > '0' && *(Edit_pos - 1) <= '9') { - *Edit_pos = '9'; - (*(Edit_pos - 1))--; - } - } else - Edit_insert_digit('-'); // negative - } - } - } else if(what_doing == 0) { - if(addr_len) { - if(setup_cursor < 2) - setup_cursor++; - else - setup_cursor = 0; - } - } else if(what_doing == 1) - next_view_cmd(+1); - else if(what_doing == 2) - if(view_Batch < Log_Total - 1) view_Batch++; - } - } - break; - case InputKeyLeft: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(ask_question) { - if(event.input.type == InputTypeShort) ask_question_answer ^= 1; - } else if(Edit) { - if(Edit_pos > Edit_start) { - if(is_digit(Edit_pos - 1, Edit_hex)) - Edit_pos--; - else if(*(Edit_pos - 1) == 'x' && *(Edit_pos - 3) == ',') - Edit_pos -= 4; - else if(*(Edit_pos - 1) == ',') - Edit_pos -= 2; - } - } else if(what_doing == 0) { - if(addr_len) { - rw_type = rwt_listen; - what_doing = 1; - } - } else if(what_doing == 1) { - if(event.input.type == InputTypeShort) - next_rw_type(-1); - else if(view_x) - view_x--; - } else if(what_doing == 2) - if(view_x) view_x--; - } else if(event.input.type == InputTypeLong) { - if(!ask_question && view_x == 0 && what_doing == 2 && - (rw_type == rwt_write_batch || rw_type == rwt_read_batch) && - Log_Total && Log[view_Batch] != NULL) { - ask_question = ask_skip_cmd; - ask_question_answer = 1; - } - } - break; - case InputKeyRight: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(ask_question) { - ask_question_answer ^= 1; - } else if(Edit) { - if(is_digit(Edit_pos + 1, Edit_hex)) - Edit_pos++; - else if(*(Edit_pos + 1) == ',') { - Edit_pos += 2; - if(*(Edit_pos + 1) == 'x') Edit_pos += 2; - } - } else if(what_doing == 0) { - if(addr_len) { - rw_type = rwt_set_batch; - what_doing = 1; - } - } else if(what_doing == 1) { - if(event.input.type == InputTypeShort) - next_rw_type(+1); - else - view_x++; - } else if(what_doing == 2) - view_x++; - } - break; - case InputKeyOk: - if(event.input.type == InputTypeShort) { - if(ask_question) { - if(ask_question_answer) { - if(ask_question == ask_save_batch) { - save_batch(); - } else if(ask_question == ask_write_batch) { - if(WriteBatch_cmd_Total) { - if(what_doing == 1) { - Prepare_Write_cmd( - WriteBatch_cmd[view_cmd[rwt_write_batch]]); - send_status = sst_none; - Edited = false; - view_x = 0; - view_Batch = 0; - } - if(Log_Total) { - ERR = 0; - WriteBatch_cmd_curr = 0; - Run_WriteBatch_cmd(); - what_doing = 2; - } - } - } else if(ask_question == ask_skip_cmd) { - if(rw_type == rwt_write_batch || rw_type == rwt_read_batch) { - furi_string_free(Log[view_Batch]); - if(view_Batch < Log_Total - 1) - memmove( - &Log[view_Batch], - &Log[view_Batch + 1], - sizeof(Log) * (Log_Total - view_Batch - 1)); - else - view_Batch--; - Log_Total--; - } - } else if(ask_question == ask_exit) { - processing = false; - } else if(ask_question == ask_return) { - if(what_doing == 2) { - ERR = 0; - send_status = sst_none; - Edited = false; - what_doing--; - } - } - } - ask_question = 0; - } else if(Edit) { // insert digit - Edit_insert_digit('0'); - } else if(what_doing == 0) { - if(setup_cursor == 0) { // open file - file_stream_close(file_stream); - if(select_settings_file()) { - uint8_t err = load_settings_file(); - if(err) - snprintf( - file_name, sizeof(file_name), "LOAD ERROR #%d", err); - } - } else if(setup_cursor == 1) { // change address - char* ebuf = (char*)payload; - ebuf[0] = '\0'; - add_to_str_hex_bytes(ebuf, addr, addr_len); - Edit_hex = true; - Edit_pos = ebuf + strlen(ebuf) - 1; - Edit_start = ebuf; - Edit = 1; - NRF_INITED = 0; - } else if(setup_cursor == 2) { // change channel - char* ebuf = (char*)payload; - snprintf(ebuf, sizeof(payload), "%d", NRF_channel); - Edit_hex = false; - Edit_pos = ebuf + strlen(ebuf) - 1; - Edit_start = ebuf; - Edit = 1; - NRF_INITED = 0; - } - } else if(what_doing == 1) { - if(rw_type == rwt_set_batch) { - if(SetBatch_cmd_Total) { - ERR = 0; - send_status = sst_none; - Prepare_Write_cmd(SetBatch_cmd[view_cmd[rwt_set_batch]]); - if(!ERR) { - SetBatch_cmd_curr = 0; - Run_WriteBatch_cmd(); - what_doing = 2; - } - Edited = false; - } - } else if(rw_type == rwt_read_batch) { - if(ReadBatch_cmd_Total) { - ERR = 0; - Run_ReadBatch_cmd(ReadBatch_cmd[view_cmd[rwt_read_batch]]); - view_x = 0; - view_Batch = 0; - what_doing = 2; - } - } else if(rw_type == rwt_read_cmd) { - if(Read_cmd_Total) { - ERR = 0; - free_Log(); - Run_Read_cmd(Read_cmd[view_cmd[rwt_read_cmd]]); - view_x = 0; - what_doing = 2; - } - } else if(rw_type == rwt_write_batch) { - if(WriteBatch_cmd_Total) { - ERR = 0; - Prepare_Write_cmd(WriteBatch_cmd[view_cmd[rwt_write_batch]]); - send_status = sst_none; - Edited = false; - view_x = 0; - view_Batch = 0; - what_doing = 2; - } - } else if(rw_type == rwt_listen) { - if(listen_addr_len) { - free_Log(); - prepare_nrf24(); - if(!NRF_ERROR) { - nrf24_set_rx_mode(nrf24_HANDLE); - ListenNew = false; - send_status = sst_receiving; // receiving - } - what_doing = 2; - } - } - } else if(what_doing == 2) { - if(rw_type == rwt_read_cmd) { - ERR = 0; - free_Log(); - Run_Read_cmd(Read_cmd[view_cmd[rwt_read_cmd]]); - } else if(Log_Total) { - if(rw_type == rwt_read_batch) { - ask_question = ask_save_batch; - ask_question_answer = 0; - } else if(rw_type == rwt_write_batch) { - ask_question = ask_write_batch; - ask_question_answer = 0; - } - } - } - } else if(event.input.type == InputTypeLong) { - if(Edit) { // delete - if(what_doing <= 1) { - if(strlen(Edit_start) > 1) { - memmove(Edit_pos, Edit_pos + 1, strlen(Edit_pos)); - if(*Edit_pos == '\0') Edit_pos--; - } - } else { - FuriString* fs = Log[view_Batch]; - if(is_digit(Edit_pos + 1, Edit_hex) || - (Edit_pos > Edit_start && is_digit(Edit_pos - 1, Edit_hex))) { - memmove(Edit_pos, Edit_pos + 1, strlen(Edit_pos)); - if(*Edit_pos == '\0') Edit_pos--; - furi_string_left(fs, furi_string_size(fs) - 1); - } - } - } else if(what_doing == 1) { - if(rw_type == rwt_listen) { - if(listen_addr_len) { - char* ebuf = (char*)payload; - ebuf[0] = '\0'; - add_to_str_hex_bytes(ebuf, listen_addr, listen_addr_len); - Edit_hex = true; - Edit_pos = ebuf + strlen(ebuf) - 1; - Edit_start = ebuf; - Edit = 1; - NRF_INITED = 0; - } - } else if(rw_type == rwt_read_batch) { - if(ReadBatch_cmd_Total) { - ERR = 0; - Run_ReadBatch_cmd(ReadBatch_cmd[view_cmd[rwt_read_batch]]); - view_x = 0; - view_Batch = 0; - what_doing = 2; - } - } else if(rw_type == rwt_write_batch) { - ask_question = ask_write_batch; - ask_question_answer = 0; - } - } else if(what_doing == 2) { - if(rw_type == rwt_read_cmd) { - ReadRepeat = !ReadRepeat; - } else if(Log_Total) { - if(rw_type == rwt_write_batch) { - if(!Edit) { - Edit = 0; - Edit_hex = 0; - char* s = (char*)furi_string_get_cstr(Log[view_Batch]); - char* p = strchr(s, '='); - if(p) { - p++; - if(*p == '{') p++; // array - if(*(p + 1) == 'x') { - p += 2; - Edit_hex = 1; // hex - } - if(is_digit(p, Edit_hex)) { - Edit_start = p; - while(is_digit(p, Edit_hex)) p++; - Edit_pos = p - 1; - Edited = true; - Edit = 1; - } - } - } - } else if(rw_type == rwt_read_batch) { - ask_question = ask_save_batch; - ask_question_answer = 0; - } - } - } - } - break; - case InputKeyBack: - if(event.input.type == InputTypeLong) { - if(what_doing == 2 && Edited) { - if(!ask_question) ask_question_answer = 1; - ask_question = ask_exit; - } else - processing = false; - } else if(event.input.type == InputTypeShort) { - if(ask_question) - ask_question = 0; - else if(Edit) { - if(what_doing == 0) { - if(setup_cursor == 1) { - addr_len = ConvertHexToArray((char*)payload, addr, 5); - } else if(setup_cursor == 2) { - NRF_channel = str_to_int((char*)payload); - if(NRF_channel > MAX_CHANNEL) NRF_channel = MAX_CHANNEL; - } - } else if(what_doing == 1 && rw_type == rwt_listen) { - listen_addr_len = - ConvertHexToArray((char*)payload, listen_addr, 5); - } - Edit = 0; - } else { - if(what_doing == 2 && Edited) { - ask_question = ask_return; - ask_question_answer = 1; - } else if(what_doing != 0) { - if(what_doing) what_doing--; - if(what_doing == 0) rw_type = rwt_read_batch; - if(what_doing <= 1) view_x = 0; - ERR = 0; - send_status = sst_none; - } - } - } - break; - default: - break; - } - } - } - - view_port_update(view_port); - furi_mutex_release(APP->plugin_state->mutex); - } - nrf24_set_idle(nrf24_HANDLE); - nrf24_deinit(); - if(NRF_BOARD_POWER_5V) furi_hal_power_disable_otg(); - - view_port_enabled_set(view_port, false); - gui_remove_view_port(APP->gui, view_port); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_STORAGE); - if(file_stream) { - file_stream_close(file_stream); - stream_free(file_stream); - } - view_port_free(view_port); - furi_message_queue_free(event_queue); - free_store(); - furi_timer_stop(work_timer); - furi_timer_free(work_timer); - furi_mutex_free(APP->plugin_state->mutex); - free(APP->plugin_state); - free(APP); - return 0; -} diff --git a/applications/external/nrf24batch/nrf24batch.h b/applications/external/nrf24batch/nrf24batch.h deleted file mode 100644 index 02db0a402..000000000 --- a/applications/external/nrf24batch/nrf24batch.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - FuriMutex* mutex; -} PluginState; - -typedef struct { - Gui* gui; - Storage* storage; - NotificationApp* notification; - PluginState* plugin_state; -} nRF24Batch; diff --git a/applications/external/nrf24batch/nrf24batch_10px.png b/applications/external/nrf24batch/nrf24batch_10px.png deleted file mode 100644 index 348b35eca7599d1c72a7b1efea9fd7f263e4606f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1771 zcmcIlO>f*p7x-sRO- zS0zchJlO8D=?T@&96%@6B`l63J-Ivmxb=!1apOvRMP zOl`6P(2{h0y(uu+XSE!&ahiw9U%&jS$SDn#+fJlM#U`7i+s7rlb-Xhq$NR*m%K8oY zdJ_Oa#%e4#*)*?$CRFCU0gT0CO_Ar2dOuV)L_v8J?aG_HWU{B4i0Ha5d%kMKu7f@Q z9of`PQ`23|u#n*ewi_6>+%ZF;gS$|f)O8VP+H5vcXO_y#v1a(buj!^{ zng|f6I?8L@puAe^82YRtWm?oJ&t<`gV}4MF3P@e7AuE=&dDZ#^j%f`pG(*+JnmS+< zoej;hCAzA&4xvh`_p!v)@Tg$g9;^64N!ZpQ%j>nSSTW%>uO|En+LnL+MyFy@;}*Nuj;5(R4_$zX z$a<&{(PT!I_Hp_c_s*wtK|7l;AU&h`3s}XIdWK83F$Slf8ZPZg;wyZ3w)FEg{uxSd zZ6y<&j~VQonj#jXi7jT)6z%{0df4wSGaHa*(aoy0;U*q04Y|>U31f>wFfsDno`rl9 z!qiLj7!jJ7)btGECGMi`H0=~Dh_tgS&b2!ap z0w+mt(BBwd`-Gwau&+ngqv~uO^Yk#kNGO$cD{`nQ-o0Att`WFvA{_gdY i=ihk$!R+PXOVW$?Uc1=*arGZ@91XU1`aj;h``Nz$VJy}F diff --git a/applications/external/nrf24channelscanner/application.fam b/applications/external/nrf24channelscanner/application.fam deleted file mode 100644 index 42e47e57c..000000000 --- a/applications/external/nrf24channelscanner/application.fam +++ /dev/null @@ -1,23 +0,0 @@ -App( - appid="nrf24channelscanner", - name="[NRF24] Channel Scan", - apptype=FlipperAppType.EXTERNAL, - entry_point="nrf24channelscanner_main", - fap_author="HTotoo", - fap_weburl="https://github.com/htotoo/NRF24ChannelScanner", - stack_size=2 * 1024, - requires=["gui"], - fap_category="GPIO", - fap_version=(1, 3), - fap_icon_assets="images", - fap_icon="fapicon.png", - fap_description="Scans 2.4Ghz frequency for usage data.", - fap_private_libs=[ - Lib( - name="nrf24", - sources=[ - "nrf24.c", - ], - ), - ], -) diff --git a/applications/external/nrf24channelscanner/fapicon.png b/applications/external/nrf24channelscanner/fapicon.png deleted file mode 100644 index a77435427cb1d976366633ace7eef4f22f5bfe12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f@+>Fjv*Ss$v^nncqAC6TSzkG@onXCVM|C? lVhEX%)NtBl!i)d^8P>kgxw5Cj?le#bgQu&X%Q~loCIIBQCVKz? diff --git a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c deleted file mode 100644 index d9f53658b..000000000 --- a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "nrf24.h" -#include -#include -#include -#include -#include - -void nrf24_init() { - // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pa4, true); - } - - furi_hal_spi_bus_handle_init(nrf24_HANDLE); - furi_hal_spi_acquire(nrf24_HANDLE); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - furi_hal_gpio_write(nrf24_CE_PIN, false); -} - -void nrf24_deinit() { - furi_hal_spi_release(nrf24_HANDLE); - furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); - furi_hal_gpio_write(nrf24_CE_PIN, false); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - // resetting the CS pins to floating - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); - } -} - -void nrf24_spi_trx( - FuriHalSpiBusHandle* handle, - uint8_t* tx, - uint8_t* rx, - uint8_t size, - uint32_t timeout) { - UNUSED(timeout); - furi_hal_gpio_write(handle->cs, false); - furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT); - furi_hal_gpio_write(handle->cs, true); -} - -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { - uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data}; - uint8_t rx[2] = {0}; - nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = R_REGISTER | (REGISTER_MASK & reg); - memset(&tx[1], 0, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - memcpy(data, &rx[1], size); - return rx[0]; -} - -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_RX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_get_rdp(FuriHalSpiBusHandle* handle) { - uint8_t rdp; - nrf24_read_reg(handle, REG_RDP, &rdp, 1); - return rdp; -} - -uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { - uint8_t status; - uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)}; - nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT); - return status; -} - -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfc; // clear bottom two bits to power down the radio - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, false); - return status; -} - -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle, bool nodelay) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg |= 0x03; // PWR_UP, and PRIM_RX - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, true); - if(!nodelay) furi_delay_ms(2000); - return status; -} - -bool nrf24_check_connected(FuriHalSpiBusHandle* handle) { - uint8_t status = nrf24_status(handle); - - if(status != 0x00) { - return true; - } else { - return false; - } -} diff --git a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h deleted file mode 100644 index ca80816af..000000000 --- a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define R_REGISTER 0x00 -#define W_REGISTER 0x20 -#define REGISTER_MASK 0x1F -#define ACTIVATE 0x50 -#define R_RX_PL_WID 0x60 -#define R_RX_PAYLOAD 0x61 -#define W_TX_PAYLOAD 0xA0 -#define W_TX_PAYLOAD_NOACK 0xB0 -#define W_ACK_PAYLOAD 0xA8 -#define FLUSH_TX 0xE1 -#define FLUSH_RX 0xE2 -#define REUSE_TX_PL 0xE3 -#define RF24_NOP 0xFF - -#define REG_CONFIG 0x00 -#define REG_EN_AA 0x01 -#define REG_EN_RXADDR 0x02 -#define REG_SETUP_AW 0x03 -#define REG_SETUP_RETR 0x04 -#define REG_RDP 0x09 -#define REG_DYNPD 0x1C -#define REG_FEATURE 0x1D -#define REG_RF_SETUP 0x06 -#define REG_STATUS 0x07 -#define REG_RX_ADDR_P0 0x0A -#define REG_RF_CH 0x05 -#define REG_TX_ADDR 0x10 - -#define RX_PW_P0 0x11 -#define TX_DS 0x20 -#define MAX_RT 0x10 - -#define nrf24_TIMEOUT 500 -#define nrf24_CE_PIN &gpio_ext_pb2 -#define nrf24_HANDLE \ - (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ - &furi_hal_spi_bus_handle_external_extra) - -/* Low level API */ - -/** Write device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * - * @return device status - */ -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); - -/** Read device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param[out] data - pointer to data - * - * @return device status - */ -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Power down the radio - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); - -/** Sets the radio to RX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle, bool nodelay); - -/*=============================================================================================================*/ - -/* High level API */ - -/** Must call this before using any other nrf24 API - * - */ -void nrf24_init(); - -/** Must call this when we end using nrf24 device - * - */ -void nrf24_deinit(); - -/** Send flush rx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); - -/** Gets RDP from register 0x09 - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return RDP from register 0x09 - */ -uint8_t nrf24_get_rdp(FuriHalSpiBusHandle* handle); - -/** Gets the current status flags from the STATUS register - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return status flags - */ -uint8_t nrf24_status(FuriHalSpiBusHandle* handle); - -bool nrf24_check_connected(FuriHalSpiBusHandle* handle); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/nrf24channelscanner/nrf24channelscanner.c b/applications/external/nrf24channelscanner/nrf24channelscanner.c deleted file mode 100644 index 5f7f7e42f..000000000 --- a/applications/external/nrf24channelscanner/nrf24channelscanner.c +++ /dev/null @@ -1,269 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "nrf24channelscanner_icons.h" -#include - -const uint8_t num_channels = 128; -static uint8_t nrf24values[128] = {0}; //to store channel data - -bool ifNotFoundNrf = false; //to show error message -bool szuz = true; //to show welcome screen -static bool isScanning = false; //to track the progress -static bool stopNrfScan = false; //to exit thread - -static bool isInfiniteScan = false; //to prevent stop scan when OK long pressed - -static bool threadStoppedsoFree = false; //indicate if I can free the thread from ram. -static uint8_t currCh = 0; //for the progress bar or the channel selector - -static int delayPerChan = 150; //can set via up / down. - -bool showFreq = true; - -FuriThread* thread; - -typedef enum { - EventTypeKey, - EventTypeTick, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} Event; - -static void draw_callback(Canvas* canvas, void* ctx) { - UNUSED(ctx); - - canvas_clear(canvas); - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 100, 0, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 112, 8, "Exit"); - canvas_draw_icon(canvas, 1, 0, &I_Ok_btn_9x9); - canvas_set_font(canvas, FontSecondary); - if(isScanning) { - canvas_draw_str(canvas, 12, 8, "Stop"); - } else { - canvas_draw_str(canvas, 12, 8, "Scan"); - } - canvas_draw_line(canvas, 0, 11, 127, 11); - - if(ifNotFoundNrf) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 23, 35, "NRF24 not found!"); - return; - } - - canvas_draw_line(canvas, currCh, 12, currCh, 13); //draw the current channel - - //draw hello mesage - if(szuz) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 1, 22, "OK: scan / stop. Long: infinite."); - canvas_draw_str(canvas, 1, 33, "Up / Down to change channel time."); - canvas_draw_str(canvas, 1, 44, "Left / Right to select channel"); - canvas_draw_str(canvas, 1, 56, " to get it's frequency"); - } - - //draw freq ir the progress - canvas_set_font(canvas, FontSecondary); - if(isScanning) { - if(isInfiniteScan) - canvas_draw_str(canvas, 37, 8, "scanning..."); - else - canvas_draw_str(canvas, 37, 8, "scanning"); - - } else { - if(showFreq) { - int freq = 2400 + currCh; - char strfreq[10] = {0}; - snprintf(strfreq, sizeof(strfreq), "%d MHZ", freq); - canvas_draw_str(canvas, 40, 8, strfreq); - } else { - //show delay - int dly = delayPerChan; - char strdel[10] = {0}; - snprintf(strdel, sizeof(strdel), "%d us", dly); - canvas_draw_str(canvas, 40, 8, strdel); - } - } - - //draw the chart - for(int i = 0; i < num_channels; ++i) { - int h = 64 - nrf24values[i]; - if(h < 11) h = 12; - canvas_draw_line(canvas, i, h, i, 64); - } -} - -static void input_callback(InputEvent* input_event, void* ctx) { - furi_assert(ctx); - FuriMessageQueue* event_queue = ctx; - Event event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static int32_t scanner(void* context) { - UNUSED(context); - isScanning = true; - stopNrfScan = false; - threadStoppedsoFree = false; - uint8_t tmp = 0; - currCh = 0; - nrf24_set_rx_mode(nrf24_HANDLE, false); - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x0); - nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, 0x0f); - while(true) { //scan until stopped somehow - if(stopNrfScan) break; - for(uint8_t i = 0; i < num_channels; i++) { - if(stopNrfScan) break; - currCh = i; - nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, i); - nrf24_set_rx_mode(nrf24_HANDLE, true); - for(uint8_t ii = 0; ii < 3; ++ii) { - nrf24_flush_rx(nrf24_HANDLE); - furi_delay_us(delayPerChan); - tmp = nrf24_get_rdp(nrf24_HANDLE); - if(tmp > 0 && nrf24values[i] < 65) { - nrf24values[i]++; //don't overrun it - } - if(nrf24values[i] > 50 && !isInfiniteScan) { - stopNrfScan = true; //stop, bc maxed, but only when not infinite - } - } - } - furi_delay_ms(1); - //for screen refresh. - } - //cleanup - nrf24_set_idle(nrf24_HANDLE); - isScanning = false; - threadStoppedsoFree = true; - currCh = 0; - return 0; -} - -void ChangeFreq(int delta) { - currCh += delta; - if(currCh > num_channels) currCh = 0; - showFreq = true; -} - -void ChangeDelay(int delta) { - delayPerChan += delta; - if(delayPerChan > 4000) delayPerChan = 4000; - if(delayPerChan < 120) delayPerChan = 120; - if(delayPerChan == 170) delayPerChan = 150; //rounding for the next - showFreq = false; -} - -// Main entry of the application -int32_t nrf24channelscanner_main(void* p) { - UNUSED(p); - - Event event; - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(Event)); - - //turn on 5v for some modules - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - - nrf24_init(); - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, draw_callback, NULL); - view_port_input_callback_set(view_port, input_callback, event_queue); - - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - while(true) { - furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk); - - if(event.type == EventTypeKey) { - szuz = false; //hit any button, so hide welcome screen - if((event.input.type == InputTypeShort || event.input.type == InputTypeLong) && - event.input.key == InputKeyBack) { - if(isScanning) { - stopNrfScan = true; //if running, stop it. - notification_message(notification, &sequence_blink_yellow_100); - furi_thread_join(thread); - furi_thread_free(thread); - } - break; - } - //isInfiniteScan - if((event.input.type == InputTypeShort || event.input.type == InputTypeLong) && - event.input.key == InputKeyOk) { - if(isScanning) { - notification_message(notification, &sequence_blink_yellow_100); - stopNrfScan = true; - furi_thread_join(thread); - furi_thread_free(thread); - threadStoppedsoFree = false; //to prevent double free - continue; - } - memset(nrf24values, 0, sizeof(nrf24values)); - if(nrf24_check_connected(nrf24_HANDLE)) { - threadStoppedsoFree = false; - ifNotFoundNrf = false; - notification_message(notification, &sequence_blink_green_100); - isInfiniteScan = (event.input.type == InputTypeLong); - thread = furi_thread_alloc(); - furi_thread_set_name(thread, "nrfscannerth"); - furi_thread_set_stack_size(thread, 1024); - furi_thread_set_callback(thread, scanner); - furi_thread_start(thread); - } else { - ifNotFoundNrf = true; - notification_message(notification, &sequence_error); - } - } - //change the delay - if(event.input.type == InputTypeShort && event.input.key == InputKeyUp) { - ChangeDelay(50); - } - if(event.input.type == InputTypeShort && event.input.key == InputKeyDown) { - ChangeDelay(-50); - } - - if(!isScanning) { - if(event.input.type == InputTypeLong && event.input.key == InputKeyLeft) - ChangeFreq(-10); - if(event.input.type == InputTypeShort && event.input.key == InputKeyLeft) - ChangeFreq(-1); - if(event.input.type == InputTypeLong && event.input.key == InputKeyRight) - ChangeFreq(10); - if(event.input.type == InputTypeShort && event.input.key == InputKeyRight) - ChangeFreq(1); - } - } - if(threadStoppedsoFree) { - threadStoppedsoFree = false; - furi_thread_join(thread); - furi_thread_free(thread); - } - } - nrf24_deinit(); - furi_message_queue_free(event_queue); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_record_close(RECORD_GUI); - //turn off 5v - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } - return 0; -} \ No newline at end of file diff --git a/applications/external/nrf24scan/LICENSE b/applications/external/nrf24scan/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/nrf24scan/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/nrf24scan/application.fam b/applications/external/nrf24scan/application.fam deleted file mode 100644 index 5ad617ad4..000000000 --- a/applications/external/nrf24scan/application.fam +++ /dev/null @@ -1,19 +0,0 @@ -App( - appid="nrf24scan", - name="[NRF24] Scanner", - apptype=FlipperAppType.EXTERNAL, - entry_point="nrf24scan_app", - cdefines=["APP_NRF24SCAN"], - requires=["gui"], - stack_size=2 * 1024, - fap_icon="nrf24scan_10px.png", - fap_category="GPIO", - fap_private_libs=[ - Lib( - name="nrf24", - sources=[ - "nrf24.c", - ], - ), - ], -) diff --git a/applications/external/nrf24scan/lib/nrf24/nrf24.c b/applications/external/nrf24scan/lib/nrf24/nrf24.c deleted file mode 100644 index 8ee8e7828..000000000 --- a/applications/external/nrf24scan/lib/nrf24/nrf24.c +++ /dev/null @@ -1,556 +0,0 @@ -// Modified by vad7, 25.11.2022 -// -#include "nrf24.h" -#include -#include -#include -#include -#include - -void nrf24_init() { - // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pa4, true); - } - - furi_hal_spi_bus_handle_init(nrf24_HANDLE); - furi_hal_spi_acquire(nrf24_HANDLE); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - furi_hal_gpio_write(nrf24_CE_PIN, false); -} - -void nrf24_deinit() { - furi_hal_spi_release(nrf24_HANDLE); - furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); - furi_hal_gpio_write(nrf24_CE_PIN, false); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - // resetting the CS pins to floating - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); - } -} - -void nrf24_spi_trx( - FuriHalSpiBusHandle* handle, - uint8_t* tx, - uint8_t* rx, - uint8_t size, - uint32_t timeout) { - UNUSED(timeout); - furi_hal_gpio_write(handle->cs, false); - furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT); - furi_hal_gpio_write(handle->cs, true); -} - -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { - uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data}; - uint8_t rx[2] = {0}; - nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT); - //FURI_LOG_D("NRF_WR", " #%02X=%02X", reg, data); - return rx[0]; -} - -uint8_t - nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = W_REGISTER | (REGISTER_MASK & reg); - memcpy(&tx[1], data, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - //FURI_LOG_D("NRF_WR", " #%02X(%02X)=0x%02X%02X%02X%02X%02X", reg, size, data[0], data[1], data[2], data[3], data[4] ); - return rx[0]; -} - -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = R_REGISTER | (REGISTER_MASK & reg); - memset(&tx[1], 0, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - memcpy(data, &rx[1], size); - return rx[0]; -} - -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_RX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_TX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle) { - uint8_t maclen; - nrf24_read_reg(handle, REG_SETUP_AW, &maclen, 1); - maclen &= 3; - return maclen + 2; -} - -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen) { - assert(maclen > 1 && maclen < 6); - uint8_t status = 0; - status = nrf24_write_reg(handle, REG_SETUP_AW, maclen - 2); - return status; -} - -uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { - uint8_t status; - uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)}; - nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT); - return status; -} - -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle) { - uint8_t setup = 0; - uint32_t rate = 0; - nrf24_read_reg(handle, REG_RF_SETUP, &setup, 1); - setup &= 0x28; - if(setup == 0x20) - rate = 250000; // 250kbps - else if(setup == 0x08) - rate = 2000000; // 2Mbps - else if(setup == 0x00) - rate = 1000000; // 1Mbps - - return rate; -} - -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate) { - uint8_t r6 = 0; - uint8_t status = 0; - if(!rate) rate = 2000000; - - nrf24_read_reg(handle, REG_RF_SETUP, &r6, 1); // RF_SETUP register - r6 = r6 & (~0x28); // Clear rate fields. - if(rate == 2000000) - r6 = r6 | 0x08; - else if(rate == 1000000) - r6 = r6; - else if(rate == 250000) - r6 = r6 | 0x20; - - status = nrf24_write_reg(handle, REG_RF_SETUP, r6); // Write new rate. - return status; -} - -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle) { - uint8_t channel = 0; - nrf24_read_reg(handle, REG_RF_CH, &channel, 1); - return channel; -} - -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan) { - uint8_t status; - status = nrf24_write_reg(handle, REG_RF_CH, chan); - return status; -} - -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_TX_ADDR, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle, uint8_t pipe) { - uint8_t len = 0; - if(pipe > 5) pipe = 0; - nrf24_read_reg(handle, RX_PW_P0 + pipe, &len, 1); - return len; -} - -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len) { - uint8_t status = 0; - status = nrf24_write_reg(handle, RX_PW_P0, len); - return status; -} - -uint8_t nrf24_rxpacket( - FuriHalSpiBusHandle* handle, - uint8_t* packet, - uint8_t* ret_packetsize, - uint8_t packet_size) { - uint8_t status = 0; - uint8_t tx_cmd[33] = {0}; // 32 max payload size + 1 for command - uint8_t tmp_packet[33] = {0}; - - status = nrf24_status(handle); - if(!(status & RX_DR)) { - tx_cmd[0] = R_REGISTER | (REGISTER_MASK & REG_FIFO_STATUS); - nrf24_spi_trx(handle, tx_cmd, tmp_packet, 2, nrf24_TIMEOUT); - if((tmp_packet[1] & 1) == 0) status |= RX_DR; // packet in FIFO buffer - } - if(status & RX_DR) { - if(packet_size == 1) - packet_size = nrf24_get_packetlen(handle, (status >> 1) & 7); - else if(packet_size == 0) { - tx_cmd[0] = R_RX_PL_WID; - tx_cmd[1] = 0; - nrf24_spi_trx(handle, tx_cmd, tmp_packet, 2, nrf24_TIMEOUT); - packet_size = tmp_packet[1]; - } - if(packet_size > 32 || packet_size == 0) packet_size = 32; - tx_cmd[0] = R_RX_PAYLOAD; - tx_cmd[1] = 0; - nrf24_spi_trx(handle, tx_cmd, tmp_packet, packet_size + 1, nrf24_TIMEOUT); - memcpy(packet, &tmp_packet[1], packet_size); - nrf24_write_reg(handle, REG_STATUS, RX_DR); // clear RX_DR - } else if(status & (TX_DS | MAX_RT)) { // MAX_RT, TX_DS - nrf24_write_reg(handle, REG_STATUS, (TX_DS | MAX_RT)); // clear RX_DR, MAX_RT. - } - - *ret_packetsize = packet_size; - return status; -} - -// Return 0 when error -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack) { - uint8_t status = 0; - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(tx, 0, size + 1); - memset(rx, 0, size + 1); - - if(!ack) - tx[0] = W_TX_PAYLOAD_NOACK; - else - tx[0] = W_TX_PAYLOAD; - - memcpy(&tx[1], payload, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - nrf24_set_tx_mode(handle); - - uint32_t start_time = furi_get_tick(); - while(!(status & (TX_DS | MAX_RT)) && furi_get_tick() - start_time < 2000UL) - status = nrf24_status(handle); - - if(status & MAX_RT) nrf24_flush_tx(handle); - - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); - return status & TX_DS; -} - -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg = cfg | 2; - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_delay_ms(1000); - return status; -} - -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfc; // clear bottom two bits to power down the radio - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(handle, REG_EN_RXADDR, 0x0); - furi_hal_gpio_write(nrf24_CE_PIN, false); - return status; -} - -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0F); // enable 2-byte CRC, PWR_UP, and PRIM_RX - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg |= 0x03; // PWR_UP, and PRIM_RX - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(REG_EN_RXADDR, 0x03) // Set RX Pipe 0 and 1 - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(2); - return status; -} - -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - furi_hal_gpio_write(nrf24_CE_PIN, false); - nrf24_write_reg(handle, REG_STATUS, 0x30); - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0E); // enable 2-byte CRC, PWR_UP - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfe; // disable PRIM_RX - cfg |= 0x02; // PWR_UP - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(2); - return status; -} - -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa) { - assert(channel <= 125); - assert(rate == 1 || rate == 2); - if(rate == 2) - rate = 8; // 2Mbps - else - rate = 0; // 1Mbps - - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, 0x70); // clear interrupts - if(disable_aa) - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - else - nrf24_write_reg(handle, REG_EN_AA, 0x1F); // Enable Shockburst - - nrf24_write_reg(handle, REG_DYNPD, 0x3F); // enable dynamic payload length on all pipes - if(noack) - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - else { - nrf24_write_reg(handle, REG_CONFIG, 0x0C); // 2 byte CRC - nrf24_write_reg(handle, REG_FEATURE, 0x07); // enable dyn payload and ack - nrf24_write_reg( - handle, REG_SETUP_RETR, 0x1f); // 15 retries for AA, 500us auto retransmit delay - } - - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - - if(maclen) nrf24_set_maclen(handle, maclen); - if(srcmac) nrf24_set_src_mac(handle, srcmac, maclen); - if(dstmac) nrf24_set_dst_mac(handle, dstmac, maclen); - - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - furi_delay_ms(200); -} - -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate) { - //uint8_t preamble[] = {0x55, 0x00}; // little endian - uint8_t preamble[] = {0xAA, 0x00}; // little endian - //uint8_t preamble[] = {0x00, 0x55}; // little endian - //uint8_t preamble[] = {0x00, 0xAA}; // little endian - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_write_reg(handle, REG_STATUS, 0x70); // clear interrupts - nrf24_write_reg(handle, REG_DYNPD, 0x0); // disable shockburst - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - nrf24_set_maclen(handle, 2); // shortest address - nrf24_set_src_mac(handle, preamble, 2); // set src mac to preamble bits to catch everything - nrf24_set_packetlen(handle, 32); // set max packet length - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - - // prime for RX, no checksum - nrf24_write_reg(handle, REG_CONFIG, 0x03); // PWR_UP and PRIM_RX, disable AA and CRC - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(100); -} - -void hexlify(uint8_t* in, uint8_t size, char* out) { - memset(out, 0, size * 2); - for(int i = 0; i < size; i++) - snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); -} - -uint64_t bytes_to_int64(uint8_t* bytes, uint8_t size, bool bigendian) { - uint64_t ret = 0; - for(int i = 0; i < size; i++) - if(bigendian) - ret |= bytes[i] << ((size - 1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 8; i++) { - if(bigendian) - out[i] = (val >> ((7 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian) { - uint32_t ret = 0; - for(int i = 0; i < 4; i++) - if(bigendian) - ret |= bytes[i] << ((3 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 4; i++) { - if(bigendian) - out[i] = (val >> ((3 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint64_t bytes_to_int16(uint8_t* bytes, bool bigendian) { - uint16_t ret = 0; - for(int i = 0; i < 2; i++) - if(bigendian) - ret |= bytes[i] << ((1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int16_to_bytes(uint16_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 2; i++) { - if(bigendian) - out[i] = (val >> ((1 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -// handle iffyness with preamble processing sometimes being a bit (literally) off -void alt_address_old(uint8_t* packet, uint8_t* altaddr) { - uint8_t macmess_hi_b[4]; - uint8_t macmess_lo_b[2]; - uint32_t macmess_hi; - uint16_t macmess_lo; - uint8_t preserved; - - // get first 6 bytes into 32-bit and 16-bit variables - memcpy(macmess_hi_b, packet, 4); - memcpy(macmess_lo_b, packet + 4, 2); - - macmess_hi = bytes_to_int32(macmess_hi_b, true); - - //preserve least 7 bits from hi that will be shifted down to lo - preserved = macmess_hi & 0x7f; - macmess_hi >>= 7; - - macmess_lo = bytes_to_int16(macmess_lo_b, true); - macmess_lo >>= 7; - macmess_lo = (preserved << 9) | macmess_lo; - int32_to_bytes(macmess_hi, macmess_hi_b, true); - int16_to_bytes(macmess_lo, macmess_lo_b, true); - memcpy(altaddr, &macmess_hi_b[1], 3); - memcpy(altaddr + 3, macmess_lo_b, 2); -} - -bool validate_address(uint8_t* addr) { - uint8_t bad[][3] = {{0x55, 0x55}, {0xAA, 0xAA}, {0x00, 0x00}, {0xFF, 0xFF}}; - for(int i = 0; i < 4; i++) - for(int j = 0; j < 2; j++) - if(!memcmp(addr + j * 2, bad[i], 2)) return false; - - return true; -} - -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address) { - bool found = false; - uint8_t packet[32] = {0}; - uint8_t packetsize; - //char printit[65]; - uint8_t status = 0; - status = nrf24_rxpacket(handle, packet, &packetsize, true); - if(status & 0x40) { - if(validate_address(packet)) { - for(int i = 0; i < maclen; i++) address[i] = packet[maclen - 1 - i]; - - /* - alt_address(packet, packet); - - for(i = 0; i < maclen; i++) - address[i + 5] = packet[maclen - 1 - i]; - */ - - //memcpy(address, packet, maclen); - //hexlify(packet, packetsize, printit); - found = true; - } - } - - return found; -} - -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit) { - uint8_t ping_packet[] = {0x0f, 0x0f, 0x0f, 0x0f}; // this can be anything, we just need an ack - uint8_t ch = max_channel + 1; // means fail - nrf24_configure(handle, rate, srcmac, dstmac, maclen, 2, false, false); - for(ch = min_channel; ch <= max_channel + 1; ch++) { - nrf24_write_reg(handle, REG_RF_CH, ch); - if(nrf24_txpacket(handle, ping_packet, 4, true)) break; - } - - if(autoinit) { - FURI_LOG_D("nrf24", "initializing radio for channel %d", ch); - nrf24_configure(handle, rate, srcmac, dstmac, maclen, ch, false, false); - return ch; - } - - return ch; -} - -uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t* mac, uint8_t mlen) { - uint8_t addr[5]; - for(int i = 0; i < mlen; i++) addr[i] = mac[mlen - i - 1]; - return nrf24_write_buf_reg(nrf24_HANDLE, mac_addr, addr, mlen); -} diff --git a/applications/external/nrf24scan/lib/nrf24/nrf24.h b/applications/external/nrf24scan/lib/nrf24/nrf24.h deleted file mode 100644 index 5016a89ad..000000000 --- a/applications/external/nrf24scan/lib/nrf24/nrf24.h +++ /dev/null @@ -1,387 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define R_REGISTER 0x00 -#define W_REGISTER 0x20 -#define REGISTER_MASK 0x1F -#define ACTIVATE 0x50 -#define R_RX_PL_WID 0x60 -#define R_RX_PAYLOAD 0x61 -#define W_TX_PAYLOAD 0xA0 -#define W_TX_PAYLOAD_NOACK 0xB0 -#define W_ACK_PAYLOAD 0xA8 -#define FLUSH_TX 0xE1 -#define FLUSH_RX 0xE2 -#define REUSE_TX_PL 0xE3 -#define RF24_NOP 0xFF - -#define REG_CONFIG 0x00 -#define REG_EN_AA 0x01 -#define REG_EN_RXADDR 0x02 -#define REG_SETUP_AW 0x03 -#define REG_SETUP_RETR 0x04 -#define REG_DYNPD 0x1C -#define REG_FEATURE 0x1D -#define REG_RF_SETUP 0x06 -#define REG_STATUS 0x07 -#define REG_RX_ADDR_P0 0x0A -#define REG_RX_ADDR_P1 0x0B -#define REG_RX_ADDR_P2 0x0C -#define REG_RX_ADDR_P3 0x0D -#define REG_RX_ADDR_P4 0x0E -#define REG_RX_ADDR_P5 0x0F -#define REG_RF_CH 0x05 -#define REG_TX_ADDR 0x10 -#define REG_FIFO_STATUS 0x17 - -#define RX_PW_P0 0x11 -#define RX_PW_P1 0x12 -#define RX_PW_P2 0x13 -#define RX_PW_P3 0x14 -#define RX_PW_P4 0x15 -#define RX_PW_P5 0x16 -#define RX_DR 0x40 -#define TX_DS 0x20 -#define MAX_RT 0x10 - -#define nrf24_TIMEOUT 500 -#define nrf24_CE_PIN &gpio_ext_pb2 -#define nrf24_HANDLE \ - (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ - &furi_hal_spi_bus_handle_external_extra) - -/* Low level API */ - -/** Write device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * - * @return device status - */ -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); - -/** Write buffer to device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * @param size - size of data to write - * - * @return device status - */ -uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Read device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param[out] data - pointer to data - * - * @return device status - */ -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Power up the radio for operation - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle); - -/** Power down the radio - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); - -/** Sets the radio to RX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle); - -/** Sets the radio to TX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); - -/*=============================================================================================================*/ - -/* High level API */ - -/** Must call this before using any other nrf24 API - * - */ -void nrf24_init(); - -/** Must call this when we end using nrf24 device - * - */ -void nrf24_deinit(); - -/** Send flush rx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); - -/** Send flush tx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle); - -/** Gets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * pipe - pipe index (0..5) - * @return packet length in data pipe 0 - */ -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle, uint8_t pipe); - -/** Sets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * @param len - length to set - * - * @return device status - */ -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len); - -/** Gets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return MAC address length - */ -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle); - -/** Sets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length to set MAC address to, must be greater than 1 and less than 6 - * - * @return MAC address length - */ -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen); - -/** Gets the current status flags from the STATUS register - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return status flags - */ -uint8_t nrf24_status(FuriHalSpiBusHandle* handle); - -/** Gets the current transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return transfer rate in bps - */ -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle); - -/** Sets the transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * @param rate - the transfer rate in bps - * - * @return device status - */ -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate); - -/** Gets the current channel - * In nrf24, the channel number is multiplied times 1MHz and added to 2400MHz to get the frequency - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return channel - */ -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle); - -/** Sets the channel - * - * @param handle - pointer to FuriHalSpiHandle - * @param frequency - the frequency in hertz - * - * @return device status - */ -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan); - -/** Gets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Gets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Reads RX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] packet - the packet contents - * @param[out] ret_packetsize - size of the received packet - * @param packet_size: >1 - size, 1 - packet length is determined by RX_PW_P0 register, 0 - it is determined by dynamic payload length command - * - * @return device status - */ -uint8_t nrf24_rxpacket( - FuriHalSpiBusHandle* handle, - uint8_t* packet, - uint8_t* ret_packetsize, - uint8_t packet_size_flag); - -/** Sends TX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param packet - the packet contents - * @param size - packet size - * @param ack - boolean to determine whether an ACK is required for the packet or not - * - * @return device status - */ -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack); - -/** Configure the radio - * This is not comprehensive, but covers a lot of the common configuration options that may be changed - * @param handle - pointer to FuriHalSpiHandle - * @param rate - transfer rate in Mbps (1 or 2) - * @param srcmac - source mac address - * @param dstmac - destination mac address - * @param maclen - length of mac address - * @param channel - channel to tune to - * @param noack - if true, disable auto-acknowledge - * @param disable_aa - if true, disable ShockBurst - * - */ -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa); - -// Set mac address (MSB first), Return: Status -uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t* mac, uint8_t mlen); - -/** Configures the radio for "promiscuous mode" and primes it for rx - * This is not an actual mode of the nrf24, but this function exploits a few bugs in the chip that allows it to act as if it were. - * See http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html for details. - * @param handle - pointer to FuriHalSpiHandle - * @param channel - channel to tune to - * @param rate - transfer rate in Mbps (1 or 2) - */ -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate); - -/** Listens for a packet and returns first possible address sniffed - * Call this only after calling nrf24_init_promisc_mode - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length of target mac address - * @param[out] addresses - sniffed address - * - * @return success - */ -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address); - -/** Sends ping packet on each channel for designated tx mac looking for ack - * - * @param handle - pointer to FuriHalSpiHandle - * @param srcmac - source address - * @param dstmac - destination address - * @param maclen - length of address - * @param rate - transfer rate in Mbps (1 or 2) - * @param min_channel - channel to start with - * @param max_channel - channel to end at - * @param autoinit - if true, automatically configure radio for this channel - * - * @return channel that the address is listening on, if this value is above the max_channel param, it failed - */ -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit); - -/** Converts 64 bit value into uint8_t array - * @param val - 64-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian); - -/** Converts 32 bit value into uint8_t array - * @param val - 32-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian); - -/** Converts uint8_t array into 32 bit value - * @param bytes - uint8_t array - * @param bigendian - if true, convert as big endian, otherwise little endian - * - * @return 32-bit value - */ -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/nrf24scan/nrf24_packet_decoder.py b/applications/external/nrf24scan/nrf24_packet_decoder.py deleted file mode 100644 index d0ebc9c24..000000000 --- a/applications/external/nrf24scan/nrf24_packet_decoder.py +++ /dev/null @@ -1,131 +0,0 @@ -# -# NRF24L01+ Enhanced ShockBurst packets decoder -# -payload_len_default = 4 -packets = \ -( - '10101010 11101110 00000011 00001000 00001011 01000111 000100 10 0 10101010 10101010 10101010 10101010 00011101', - '10101010 11001000 11001000 11000011 110011 10 0 00001011 00000011 00000101 00000000 0010001100100000', - '10101010 11001000 11001000 11000100 000100 11 1 00001011 00000011 00000101 00000000 0010010011100010', - '10101010 11001000 11001000 11000100 00001011 00000011 00000101 00000010 1000010101000010', - '10101010 11001000 11001000 11000000 110011 10 0 11110101 00000010 00000011 00000000 0000111001000000', - '01010101 01000000 01101000 00010101 000000 00 0 0100100000100000', -# '01010101 01000010 11100100 10100110 01010101 01000100 110011 00 0 10010101 10110011 01100100 10101100 10101011 01010010 01111100 01001010 1100110100110001', - -) - -def bin2hex(x): - def bin2hex_helper(r): - while r: - yield r[0:2].upper() - r = r[2:] - if len(x) == 0: return - fmt = "{0:0" + str(int(len(x) / 8 * 2)) + "X}" - hex_data = fmt.format(int(x, 2)) - return list(bin2hex_helper(hex_data)) - -def bin2hexlong(b): - b = b.replace(" ", "") - out = ""; - n = 8 - for i in range(0, len(b), n): - b2 = b[i:i+n] - out = out + "{0:02X}".format(int(b2.ljust(8, '0'),2)) - return out - - -def split_packet(packet, parts): - """Split a string of 1s and 0s into multiple substrings as specified by parts. - Example: "111000011000", (3, 4, 2) -> ["111", "0000", "11", "000"] - :param packet: String of 1s and 0s - :param parts: Tuple of length of substrings - :return: list of substrings - """ - out = [] - packet = packet.replace(' ', '') - for part_length in parts: - out.append(packet[0:part_length]) - packet = packet[part_length:] - out.append(packet) - return out - - -def parse_packet(packet, address_length, ESB): - """Split a packet into its fields and return them as tuple.""" - if ESB: - preamble, address, payload_length, pid, no_ack, rest = split_packet(packet=packet, parts=(8, 8 * address_length, 6, 2, 1)) - payload, crc = split_packet(packet=rest, parts=((payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2)) * 8,)) - else: - preamble, address, rest = split_packet(packet=packet, parts=(8, 8 * address_length)) - crc = packet.rsplit(' ', 1)[1] - payload = rest[0:len(rest) - len(crc)] - payload_length = pid = no_ack = '' - - assert preamble in ('10101010', '01010101') - assert len(crc) in (8, 16) - - return preamble, address, payload_length, pid, no_ack, payload, crc - - -def crc(bits, size=8): - """Calculate the crc value for the polynomial initialized with 0xFF/0xFFFF) - :param size: 8 or 16 bit crc - :param bits: String of 1s and 0s - :return: - :polynomial: 1 byte CRC - standard is 0x107 = 0b100000111 = x^8+x^2+x^1+1, result the same for 0x07 - :polynomial: 2 byte CRC - standard is 0x11021 = X^16+X^12+X^5+1, result the same for 0x1021 - """ - if size == 8: - polynomial = 0x107 - crc = 0xFF - else: - polynomial = 0x11021 - crc = 0xFFFF - max_crc_value = (1 << size) - 1 # e.g. 0xFF for mode 8bit-crc - for bit in bits: - bit = int(bit, 2) - crc <<= 1 - if (crc >> size) ^ bit: # top most lfsr bit xor current data bit - crc ^= polynomial - crc &= max_crc_value # trim the crc to reject carry over bits -# print('{:X}'.format(crc)) - return crc - - -if __name__ == '__main__': - for packet in packets: - fld = packet.split(' '); - address_length = -1 - ESB = True - for f in fld: - if len(f) == 6 : break - if len(f) == 0 : - ESB = False - break - address_length += 1 - preamble, address, payload_length, pid, no_ack, payload, crc_received = \ - parse_packet(packet=packet, address_length=address_length, ESB=ESB) - crc_size = len(crc_received) - crc_received = '0x' + '{:X}'.format(int(crc_received, 2)) - print(f"Packet: {packet}") - print('\n'.join(( - f'Hex: {bin2hexlong(packet)}', - 'Preamble: 0x%X' % int(preamble,2), - f'Address: {address_length} bytes - {bin2hex(address)}'))) - if ESB: - print('\n'.join(( - f'Payload length in packet: {int(payload_length, 2)}, used: {(payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2))}', - f'Payload: {bin2hex(payload)}', - f'Pid: {int(pid, 2)}', - f'No_ack: {int(no_ack, 2) == 1}'))) - else: - print(f'Not Enhanced ShockBurst packet, payload length: {int(len(payload) / 8)}') - print(f'Payload: {bin2hex(payload)}') - print(f'CRC{crc_size}: {crc_received}') - crc_calculated = '0x' + '{:X}'.format(crc(address + payload_length + pid + no_ack + payload, size=crc_size)) - if crc_received == crc_calculated: - print('CRC is valid!') - else: - print(f'CRC mismatch! Calculated CRC is {crc_calculated}.') - print('-------------') - diff --git a/applications/external/nrf24scan/nrf24scan.c b/applications/external/nrf24scan/nrf24scan.c deleted file mode 100644 index 1a60ce36d..000000000 --- a/applications/external/nrf24scan/nrf24scan.c +++ /dev/null @@ -1,1662 +0,0 @@ -// -// Written by vad7, 20.11.2022. -// -#include "nrf24scan.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TAG "nrf24scan" -#define VERSION "2.2" -#define MAX_CHANNEL 125 -#define MAX_ADDR 6 - -#define SCAN_APP_PATH_FOLDER STORAGE_APP_DATA_PATH_PREFIX -#define SETTINGS_FILENAME "addresses.txt" // Settings file format (1 parameter per line): -// SNIFF - if present then sniff mode -// Rate: 0/1/2 - rate in Mbps (=0.25/1/2) -// Ch: 0..125 - default channel -// ESB: 0/1 (1 - Enhanced ShockBurst) -// DPL: 0/1 (1 - Dynamic Payload Length) -// CRC: 0/1/2 (CRC length) -// Payload: 1..32 (bytes) -// P0: address P0 in hex (5 byte, LSB last) -// P1: address P1 in hex (5 byte, LSB last) -// P2: address P2, LSB in hex (1 byte) -// P3: address P3, LSB in hex (1 byte) -// P4: address P4, LSB in hex (1 byte) -// P5: address P5, LSB in hex (1 byte) -// captured data: -// first byte = { RAW packet flag (0x80/0x00) } + { channel number } -// second byte = { Payload len 5 bits, 0 = 32 } + {{ RAW packet: ESB flag 0x04/0x00 + address size-2 if RAW packet } or { pipe #(0..5) }}, -// ... up to MAX_LOG_RECORDS-1 -#define SNIFF_FILENAME "sniff.txt" // settings for sniff mode -#define LOG_FILENAME "log" -#define LOG_FILEEXT ".txt" -#define MAX_LOG_RECORDS 200 -#define MAX_FOUND_RECORDS 70 -#define LOG_REC_SIZE 34 // max packet size -#define VIEW_LOG_MAX_X 22 -#define VIEW_LOG_WIDTH_B 10 // bytes - -const char SettingsFld_Rate[] = "Rate:"; -const char SettingsFld_Ch[] = "Ch:"; -const char SettingsFld_ESB[] = "ESB:"; -const char SettingsFld_DPL[] = "DPL:"; -const char SettingsFld_CRC[] = "CRC:"; -const char SettingsFld_Payload[] = "Payload:"; -const char SettingsFld_Sniff[] = "SNIFF"; -char SettingsFld_Addr = 'P'; - -Nrf24Scan* APP; -uint8_t what_doing = 0; // 0 - setup, 1 - view log, 2 - view addresses -uint8_t what_to_do = - 1; // 0 - view, 1 - view & sniff, 2 - view & read, 3 - view & read selected addr -uint8_t save_settings = 0; -char screen_buf[64]; -char addr_file_name[32]; -uint8_t NRF_rate = 2; // 0 - 250Kbps, 1 - 1Mbps, 2 - 2Mbps -uint8_t NRF_channel = 0; // 0..125 -uint8_t NRF_ESB = 1; // 0 - ShockBurst, 1 - Enhanced ShockBurst -uint8_t NRF_DPL = 0; // 1 - Dynamic Payload Length -uint8_t NRF_CRC = 2; // 1 - No, 1 - CRC 1byte, 2 - CRC 2byte -uint8_t NRF_Payload = 32; // Payload len in bytes or Minimum payload in sniff mode, 0..32 -uint8_t NRF_Payload_sniff_min = 0; -uint8_t NRF_AA_OFF = 0; // Disable Auto Acknowledgement -bool NRF_ERROR = 0; -bool NRF_BOARD_POWER_5V = false; - -struct ADDRS { - uint8_t addr_P0[5]; // MSB first - uint8_t addr_P1[5]; // MSB first - uint8_t addr_P2; // LSB only, MSB bytes equal addr_P1 - uint8_t addr_P3; // LSB only, MSB bytes equal addr_P1 - uint8_t addr_P4; // LSB only, MSB bytes equal addr_P1 - uint8_t addr_P5; // LSB only, MSB bytes equal addr_P1 - uint8_t addr_len; // 2..5 - uint8_t addr_count; -}; - -struct ADDRS addrs; -struct ADDRS addrs_sniff; -bool sniff_loaded = 0; -int16_t found_total; -int16_t view_found; - -int8_t log_to_file = 0; // 0 - no, 1 - yes(new), 2 - append, -1 - only clear -uint16_t log_arr_idx; -uint16_t view_log_arr_idx = 0; -uint16_t view_log_arr_x = 0; -bool save_to_new_log = true; -uint16_t last_packet_send = -1; -uint8_t last_packet_send_st = 0; -int16_t find_channel_period = 0; // sec -uint8_t menu_selected = 0; -uint32_t start_time; -uint8_t view_log_decode_PCF = - 0; // view log: 1 - decode packet control field (9b) when ESB off. After pipe # (hex): -uint8_t view_log_decode_CRC = 0; // CRC bytes - 1/2, 0 - none - -#define menu_selected_max 5 -enum { - Menu_open_file = 0, - Menu_enter_channel, - Menu_enter_rate, - Menu_enter_scan_period, - Menu_log, - Menu_ok -}; - -//#define MIN(a, b) ((a> 7)); - arr++; - out += 2; - } while(--bytes); -} - -void clear_log() { - log_arr_idx = 0; - view_log_arr_idx = 0; - last_packet_send = -1; - found_total = 0; - view_found = -1; -} - -void write_to_log_file(Storage* storage, bool f_settings) { - if(log_arr_idx == 0 && !f_settings) return; - Stream* file_stream = file_stream_alloc(storage); - FuriString* str = furi_string_alloc(); - furi_string_set(str, SCAN_APP_PATH_FOLDER); - furi_string_cat(str, "/"); - bool fl; - if(f_settings) { - furi_string_cat(str, SETTINGS_FILENAME); - fl = file_stream_open( - file_stream, furi_string_get_cstr(str), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS); - if(!fl) file_stream_close(file_stream); - } else { - furi_string_cat(str, LOG_FILENAME); - furi_string_cat(str, LOG_FILEEXT); - if(save_to_new_log) { - int cnt = 1; - do { - fl = file_stream_open( - file_stream, furi_string_get_cstr(str), FSAM_READ_WRITE, FSOM_CREATE_NEW); - if(fl) break; - file_stream_close(file_stream); - furi_string_set(str, SCAN_APP_PATH_FOLDER); - furi_string_cat(str, "/"); - furi_string_cat(str, LOG_FILENAME); - furi_string_cat_printf(str, "-%02d", cnt); - furi_string_cat(str, LOG_FILEEXT); - } while(++cnt < 100); - if(!fl) { - FURI_LOG_E(TAG, "Failed to create new log file"); - notification_message(APP->notification, &sequence_blink_red_100); - } - } else { - fl = file_stream_open( - file_stream, furi_string_get_cstr(str), FSAM_READ_WRITE, FSOM_OPEN_APPEND); - if(fl) { - if(stream_size(file_stream) == 0) save_to_new_log = true; - } else - file_stream_close(file_stream); - } - } - if(fl) { - FURI_LOG_D(TAG, "Save to %s", furi_string_get_cstr(str)); - if(save_to_new_log || f_settings) { - if(what_to_do == 1) - furi_string_printf(str, "%s\n", SettingsFld_Sniff); - else - furi_string_reset(str); - furi_string_cat_printf( - str, - "%s %d\n%s %d\n%s %d\n", - SettingsFld_Rate, - NRF_rate, - SettingsFld_Ch, - NRF_channel, - SettingsFld_ESB, - NRF_ESB); - furi_string_cat_printf( - str, - "%s %d\n%s %d\n%s %d\n", - SettingsFld_DPL, - NRF_DPL, - SettingsFld_CRC, - NRF_CRC, - SettingsFld_Payload, - what_to_do == 1 ? NRF_Payload_sniff_min : NRF_Payload); - if(addrs.addr_count > 0) { - furi_string_cat_printf(str, "P0: "); - add_to_furi_str_hex_bytes(str, (char*)addrs.addr_P0, addrs.addr_len); - furi_string_cat(str, "\n"); - } - if(addrs.addr_count > 1) { - furi_string_cat_printf(str, "P1: "); - add_to_furi_str_hex_bytes(str, (char*)addrs.addr_P1, addrs.addr_len); - furi_string_cat(str, "\n"); - } - if(addrs.addr_count > 2) { - furi_string_cat_printf(str, "P2: "); - furi_string_cat_printf(str, "%02X\n", addrs.addr_P2); - } - if(addrs.addr_count > 3) { - furi_string_cat_printf(str, "P3: "); - furi_string_cat_printf(str, "%02X\n", addrs.addr_P3); - } - if(addrs.addr_count > 4) { - furi_string_cat_printf(str, "P4: "); - furi_string_cat_printf(str, "%02X\n", addrs.addr_P4); - } - if(addrs.addr_count > 5) { - furi_string_cat_printf(str, "P5: "); - furi_string_cat_printf(str, "%02X\n", addrs.addr_P5); - } - if(!(fl = stream_write_string(file_stream, str) == furi_string_size(str))) { - FURI_LOG_E(TAG, "Failed to write header to file!"); - notification_message(APP->notification, &sequence_blink_red_100); - } - } - if(fl) { - if(f_settings) { - save_settings = 0; - if(strcmp(addr_file_name, "NONE") == 0) strcpy(addr_file_name, SETTINGS_FILENAME); - } else { - int i = 0; - for(; i < log_arr_idx; i++) { - furi_string_reset(str); - uint8_t* ptr = APP->log_arr + i * LOG_REC_SIZE; - int len; - if(ptr[0] & 0x80) { // RAW - len = (ptr[1] & 0b11) + 2 + ((ptr[1] & 0b100) ? 2 : 0) + (ptr[1] >> 3) + - 2; // addr + PCF? + payload + crcmax - } else { - len = (ptr[1] >> 3); - if(len == 0) len = 32; - } - //if(len < NRF_Payload) len = NRF_Payload; - add_to_furi_str_hex_bytes(str, (char*)ptr, len + 2); - furi_string_cat(str, "\n"); - if(stream_write_string(file_stream, str) != furi_string_size(str)) { - FURI_LOG_E(TAG, "Failed to write to file!"); - break; - } - } - if(i == log_arr_idx) { - notification_message(APP->notification, &sequence_blink_yellow_100); - FURI_LOG_D(TAG, "File saved"); - } - save_to_new_log = false; - } - } - file_stream_close(file_stream); - } else { - FURI_LOG_E(TAG, "Failed to open file %s", furi_string_get_cstr(str)); - notification_message(APP->notification, &sequence_blink_red_100); - } - stream_free(file_stream); - furi_string_free(str); -} - -static bool select_settings_file(Stream* stream) { - DialogsApp* dialogs = furi_record_open("dialogs"); - bool result = false; - FuriString* path; - path = furi_string_alloc(); - furi_string_set(path, SCAN_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, ".txt", NULL); - browser_options.hide_ext = false; - - bool ret = dialog_file_browser_show(dialogs, path, path, &browser_options); - - furi_record_close("dialogs"); - if(ret) { - if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path)); - file_stream_close(stream); - } else { - FURI_LOG_D(TAG, "Open file \"%s\"", furi_string_get_cstr(path)); - strncpy( - addr_file_name, - furi_string_get_cstr(path) + sizeof(SCAN_APP_PATH_FOLDER), - sizeof(addr_file_name)); - result = true; - } - } - furi_string_free(path); - return result; -} - -// 0 - success, otherwise an error -static uint8_t load_settings_file(Stream* file_stream) { - size_t file_size = 0; - char* file_buf; - uint8_t err = 5; - file_size = stream_size(file_stream); - if(file_size == (size_t)0) { - FURI_LOG_D(TAG, "load failed. file_size: %d", file_size); - return 1; - } - file_size = MIN(file_size, (size_t)LOG_REC_SIZE * MAX_LOG_RECORDS * 2 + 100); - file_buf = malloc(file_size + 1); - if(file_buf == NULL) { - FURI_LOG_D(TAG, "Memory low, need: %d", file_size); - return 2; - } - memset(file_buf, 0, file_size + 1); - if(stream_read(file_stream, (uint8_t*)file_buf, file_size) == file_size) { - FURI_LOG_D(TAG, "Loading settings file"); - char* line_ptr = file_buf; - int16_t line_num = 0; - what_to_do = 2; - sniff_loaded = 0; - bool log_loaded = false; - while(line_ptr && (size_t)(line_ptr - file_buf) < file_size) { - char* end_ptr = strstr((char*)line_ptr, "\n"); - if(end_ptr == NULL) - end_ptr = file_buf + file_size; - else - *end_ptr = '\0'; - int line_len = end_ptr - line_ptr; - if(*line_ptr == '\r' || line_len == 0) { - line_ptr = end_ptr + 1; - continue; - } - if(*(end_ptr - 1) < '0') { - *(end_ptr - 1) = '\0'; - line_len--; - } - //FURI_LOG_D(TAG, " L#%d: [%d]%s", line_num, line_len, line_ptr); - if(strncmp(line_ptr, SettingsFld_Rate, sizeof(SettingsFld_Rate) - 1) == 0) { - NRF_rate = atoi(line_ptr + sizeof(SettingsFld_Rate)); - } else if(strncmp(line_ptr, SettingsFld_Ch, sizeof(SettingsFld_Ch) - 1) == 0) { - NRF_channel = atoi(line_ptr + sizeof(SettingsFld_Ch)); - } else if(strncmp(line_ptr, SettingsFld_ESB, sizeof(SettingsFld_ESB) - 1) == 0) { - NRF_ESB = atoi(line_ptr + sizeof(SettingsFld_ESB)); - } else if(strncmp(line_ptr, SettingsFld_DPL, sizeof(SettingsFld_DPL) - 1) == 0) { - NRF_DPL = atoi(line_ptr + sizeof(SettingsFld_DPL)); - } else if(strncmp(line_ptr, SettingsFld_CRC, sizeof(SettingsFld_CRC) - 1) == 0) { - NRF_CRC = atoi(line_ptr + sizeof(SettingsFld_CRC)); - if(what_to_do == 1) view_log_decode_CRC = NRF_CRC; - } else if(strncmp(line_ptr, SettingsFld_Payload, sizeof(SettingsFld_Payload) - 1) == 0) { - uint8_t pld = atoi(line_ptr + sizeof(SettingsFld_Payload)); - if(pld > 32) pld = 32; - if(sniff_loaded) { - NRF_Payload_sniff_min = pld; - } else { - if(pld == 0) pld = 32; - NRF_Payload = pld; - } - } else if(strncmp(line_ptr, SettingsFld_Sniff, sizeof(SettingsFld_Sniff) - 1) == 0) { - what_to_do = 1; - sniff_loaded = 1; - } else if(*line_ptr == SettingsFld_Addr) { - char a = *(++line_ptr); - struct ADDRS* adr = sniff_loaded ? &addrs_sniff : &addrs; - line_ptr += 3; - switch(a) { - case '0': - memset(adr, 0, sizeof(addrs)); - adr->addr_len = - ConvertHexToArray(line_ptr, adr->addr_P0, sniff_loaded ? 3 : 5); - if(adr->addr_len >= 2) err = 0; - break; - case '1': - ConvertHexToArray(line_ptr, adr->addr_P1, what_to_do == 1 ? 3 : 5); - break; - case '2': - ConvertHexToArray(line_ptr, &adr->addr_P2, 1); - break; - case '3': - ConvertHexToArray(line_ptr, &adr->addr_P3, 1); - break; - case '4': - ConvertHexToArray(line_ptr, &adr->addr_P4, 1); - break; - case '5': - ConvertHexToArray(line_ptr, &adr->addr_P5, 1); - break; - default: - a = 0; - break; - } - if(err == 0 && a) adr->addr_count = a - '0' + 1; - } else if(line_len >= 3 * 2) { // data - if(!log_loaded) { - log_loaded = true; - clear_log(); - what_to_do = 0; - } - if(log_arr_idx < MAX_LOG_RECORDS - 1) { - if(ConvertHexToArray( - line_ptr, APP->log_arr + log_arr_idx * LOG_REC_SIZE, LOG_REC_SIZE) > 0) - err = 0; - log_arr_idx++; - } - } - line_ptr = end_ptr + 1; - line_num++; - } - } else { - FURI_LOG_D(TAG, "load failed. file size: %d", file_size); - err = 4; - } - free(file_buf); - return err; -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -void check_add_addr(uint8_t* pkt) { - if(addrs.addr_count > 0 && memcmp(addrs.addr_P0, pkt, addrs.addr_len) == 0) return; - if(addrs.addr_count > 1 && memcmp(addrs.addr_P1, pkt, addrs.addr_len - 1) == 0) { - if(addrs.addr_P1[addrs.addr_len - 1] == pkt[addrs.addr_len - 1]) return; - if(addrs.addr_count > 2 && addrs.addr_P2 == pkt[addrs.addr_len - 1]) return; - if(addrs.addr_count > 3 && addrs.addr_P3 == pkt[addrs.addr_len - 1]) return; - if(addrs.addr_count > 4 && addrs.addr_P4 == pkt[addrs.addr_len - 1]) return; - if(addrs.addr_count > 5 && addrs.addr_P5 == pkt[addrs.addr_len - 1]) return; - } - if(addrs.addr_count == 1) - memcpy(addrs.addr_P1, pkt, addrs.addr_len); - else if(addrs.addr_count == 2) - addrs.addr_P2 = pkt[addrs.addr_len - 1]; - else if(addrs.addr_count == 3) - addrs.addr_P3 = pkt[addrs.addr_len - 1]; - else if(addrs.addr_count == 4) - addrs.addr_P4 = pkt[addrs.addr_len - 1]; - else if(addrs.addr_count == 5) - addrs.addr_P5 = pkt[addrs.addr_len - 1]; - addrs.addr_count++; -} - -static void prepare_nrf24(bool fsend_packet) { - nrf24_write_reg(nrf24_HANDLE, REG_STATUS, 0x70); // clear interrupts - nrf24_write_reg( - nrf24_HANDLE, - REG_RF_SETUP, - (NRF_rate == 0 ? 0b00100000 : - NRF_rate == 1 ? 0 : - 0b00001000) | - 0b111); // +TX high power - uint8_t erx_addr = (1 << 0); // Enable RX_P0 - struct ADDRS* adr = what_to_do == 1 ? &addrs_sniff : &addrs; - if(!fsend_packet) { - uint8_t payload = NRF_Payload; - uint8_t* rec = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; - uint8_t addr_size = (*(rec + 1) & 0b11) + 2; - bool setup_from_log = false; - if(what_to_do >= 2) { - if(log_arr_idx && (*rec & 0x80)) { - setup_from_log = true; - memcpy(addrs.addr_P0, rec + 2, addr_size); - addrs.addr_count = 1; - addrs.addr_len = addr_size; - payload = *(rec + 1) >> 3; - if(what_to_do == 2) { - uint8_t* p = APP->log_arr + 2; - int16_t i = 0; - for(i = 0; i < log_arr_idx; i++, p += LOG_REC_SIZE) { - if((*(p - 2) & 0x80) && (*(p - 1) & 0b11) + 2 == addr_size && - rec + 2 != p) { - if(memcmp(p, addrs.addr_P0, addr_size - 1) == 0) { - check_add_addr(p); - if(addrs.addr_count >= 6) break; - } - } - } - } - } - } - if(what_to_do == 1) { // SNIFF - payload = 32; - nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70); // Mask all interrupts - nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement - nrf24_write_reg( - nrf24_HANDLE, - REG_FEATURE, - 0); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload - // EN_DYN_ACK(0x01) for W_TX_PAYLOAD_NOACK cmd broke AA on some fake nRF24l01+ modules - } else if(setup_from_log) { // Scan - nrf24_write_reg( - nrf24_HANDLE, - REG_CONFIG, - 0x70 | ((NRF_CRC == 1 ? 0b1000 : - NRF_CRC == 2 ? 0b1100 : - 0))); // Mask all interrupts - nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *rec & 0x7F); - nrf24_write_reg( - nrf24_HANDLE, - REG_FEATURE, - *(rec + 2 + addr_size) >> 2 != 0x33 ? - 4 : - 0); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload - if(*(rec + 1) & 0b100) { // ESB - nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0x01); // Automatic Retransmission - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x3F); // Auto acknowledgement - } else { - nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement - } - } else { - nrf24_write_reg( - nrf24_HANDLE, - REG_CONFIG, - 0x70 | ((NRF_CRC == 1 ? 0b1000 : - NRF_CRC == 2 ? 0b1100 : - 0))); // Mask all interrupts - nrf24_write_reg( - nrf24_HANDLE, REG_SETUP_RETR, NRF_ESB ? 0x01 : 0); // Automatic Retransmission - nrf24_write_reg( - nrf24_HANDLE, - REG_EN_AA, - NRF_AA_OFF || !NRF_ESB ? 0 : 0x3F); // Auto acknowledgement - nrf24_write_reg( - nrf24_HANDLE, - REG_FEATURE, - NRF_DPL ? - 4 : - 0); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload - nrf24_write_reg( - nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg - nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel); - } - if(adr->addr_count == 0) return; - nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload); - nrf24_set_maclen(nrf24_HANDLE, adr->addr_len); - nrf24_set_mac(REG_RX_ADDR_P0, adr->addr_P0, adr->addr_len); - uint8_t tmp[5] = {0}; - nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adr->addr_len); - for(uint8_t i = 0; i < adr->addr_len / 2; i++) { - uint8_t tb = tmp[i]; - tmp[i] = tmp[adr->addr_len - i - 1]; - tmp[adr->addr_len - i - 1] = tb; - } - NRF_ERROR = memcmp(adr->addr_P0, tmp, adr->addr_len) != 0; - FURI_LOG_D(TAG, "Payload: %d", payload); - nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload); - if(adr->addr_count > 1) { - nrf24_set_mac(REG_RX_ADDR_P1, adr->addr_P1, adr->addr_len); - nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload); - erx_addr |= (1 << 1); // Enable RX_P1 - } else - nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0); - if(adr->addr_count > 2) { - nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &adr->addr_P2, 1); - nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload); - erx_addr |= (1 << 2); // Enable RX_P2 - } else - nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0); - if(adr->addr_count > 3) { - nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &adr->addr_P3, 1); - nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload); - erx_addr |= (1 << 3); // Enable RX_P3 - } else - nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0); - if(adr->addr_count > 4) { - nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &adr->addr_P4, 1); - nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload); - erx_addr |= (1 << 4); // Enable RX_P4 - } else - nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0); - if(adr->addr_count > 5) { - nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &adr->addr_P5, 1); - nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload); - erx_addr |= (1 << 5); // Enable RX_P5 - } else - nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0); - nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr); - } - nrf24_flush_rx(nrf24_HANDLE); - nrf24_flush_tx(nrf24_HANDLE); - nrf24_set_idle(nrf24_HANDLE); -} - -void correct_NRF_Payload_sniff_min() { - uint8_t pld = 32 - 3 - (NRF_ESB ? 2 : 0) - NRF_CRC + (addrs_sniff.addr_len - 2); - if(NRF_Payload_sniff_min > pld) NRF_Payload_sniff_min = pld; -} - -static void start_scanning() { - FURI_LOG_D(TAG, "Start proc-%d: Ch=%d Rate=%d", what_to_do, NRF_channel, NRF_rate); - if(what_to_do == 1) { // SNIFF - correct_NRF_Payload_sniff_min(); - view_log_decode_CRC = NRF_CRC; - } else if(sniff_loaded) { // Switch from sniff to scan/view - // to do... - } - prepare_nrf24(false); - if(NRF_ERROR) { - FURI_LOG_E(TAG, "NRF R/W ERROR!"); - return; - } - nrf24_set_rx_mode(nrf24_HANDLE); - start_time = furi_get_tick(); -} - -// start bitnum = 7 -uint32_t calc_crc(uint32_t crc, uint8_t* ptr, uint8_t bitnum, uint16_t bits) { - //uint8_t bitnum = 7; - uint32_t crc_high, polynom; - if(view_log_decode_CRC == 2) { - crc_high = (1 << 16); - polynom = 0x1021; // X^16+X^12+X^5+1 => 0x11021 & 0xFFFF = 0x1021 - } else { - crc_high = (1 << 8); - polynom = 0x07; // x^8+x^2+x^1+1 => 0x107 & 0xFF = 0x07 - } - while(bits--) { - crc <<= 1; - if(((crc & crc_high) != 0) ^ ((*ptr >> bitnum) & 1)) crc ^= polynom; - if(bitnum == 0) { - ptr++; - bitnum = 7; - } else - bitnum--; - } - return crc & (view_log_decode_CRC == 2 ? 0xFFFF : 0xFF); -} - -// shifted 1 bit right -uint32_t get_shifted_crc(uint8_t* pcrc) { - uint32_t crc = ((*pcrc << 1) & 0xFF) | (*(pcrc + 1) >> 7); - if(view_log_decode_CRC == 2) { - crc = (crc << 8) | ((*(pcrc + 1) << 1) & 0xFF) | (*(pcrc + 2) >> 7); - } - return crc; -} - -bool check_packet(uint8_t* pkt, uint16_t size) { - if(size < 3 || size > 32) return false; - uint8_t b = *pkt; - if(b == 0x55 || b == 0xAA || b == 0x00 || b == 0xFF) - return false; // skip pkt when address begin with - uint32_t prevcrc = 0xFFFFFFFF; - bool found = false; - uint8_t addr_size = 3; - for(; addr_size <= 5; addr_size++) { - if(NRF_ESB) { - uint8_t _payload = *(pkt + addr_size) >> 2; - if((_payload > size - addr_size - 2 - view_log_decode_CRC && _payload != 0x33)) - continue; - uint8_t* p = pkt + addr_size; - if(prevcrc == 0xFFFFFFFF) { - prevcrc = calc_crc( - view_log_decode_CRC == 2 ? 0xFFFF : 0xFF, - pkt, - 7, - 3 * 8); // crc for smallest addr - } - uint32_t crc; - if(addr_size > 3) - crc = calc_crc(prevcrc, p - (addr_size - 3), 7, 8 * (addr_size - 3)); - else - crc = prevcrc; - if(_payload != 0x33) { // DPL - crc = calc_crc(crc, p, 7, 9 + _payload * 8); - if(crc == get_shifted_crc(p + _payload + 1)) { - *(pkt - 1) = ((_payload & 0x1F) << 3) + 0b100 + (addr_size - 2); - FURI_LOG_D( - TAG, "VALID CRC %X: dpl: %d, addr: %d", (uint16_t)crc, _payload, addr_size); - found = true; - break; - } - } else { - crc = calc_crc(crc, p++, 7, 9); // PCF - if(crc == get_shifted_crc(p)) { - _payload = 0; - found = true; - } else { - for(uint8_t i = 1; i < size - addr_size - view_log_decode_CRC; i++) { - crc = calc_crc(crc, p++, 6, 8); - if(crc == get_shifted_crc(p)) { - _payload = i; - found = true; - break; - } - } - } - if(found) { - *(pkt - 1) = ((_payload & 0x1F) << 3) + 0b100 + (addr_size - 2); - FURI_LOG_D( - TAG, "VALID CRC %X: pl: %d, addr: %d", (uint16_t)crc, _payload, addr_size); - break; - } - } - } else { - uint8_t* p; - if(addr_size == 3) { - prevcrc = calc_crc( - view_log_decode_CRC == 2 ? 0xFFFF : 0xFF, - pkt, - 7, - 3 * 8); // crc for smallest addr - p = pkt + addr_size; - } else { - p = pkt + addr_size - 1; - prevcrc = calc_crc(prevcrc, p++, 7, 8); - } - uint32_t crc = prevcrc; - if((view_log_decode_CRC == 1 && crc == *p) || - (view_log_decode_CRC == 2 && crc == (uint32_t)((*p << 8) | *(p + 1)))) { - *(pkt - 1) = ((0 & 0x1F) << 3) + 0b000 + (addr_size - 2); - FURI_LOG_D(TAG, "VALID CRC %X: pl: %d, addr: %d", (uint16_t)crc, 0, addr_size); - found = true; - break; - } - for(uint8_t i = 1; i <= size - addr_size - view_log_decode_CRC; i++) { - crc = calc_crc(crc, p++, 7, 8); - if((view_log_decode_CRC == 1 && crc == *p) || - (view_log_decode_CRC == 2 && crc == (uint32_t)((*p << 8) | *(p + 1)))) { - *(pkt - 1) = ((i & 0x1F) << 3) + 0b000 + (addr_size - 2); - FURI_LOG_D(TAG, "VALID CRC %X: pl: %d, addr: %d", (uint16_t)crc, i, addr_size); - found = true; - break; - } - } - if(found) break; - } - } - if(found) { - if(furi_log_get_level() == FuriLogLevelDebug) { - char dbuf[65]; - dbuf[0] = 0; - add_to_str_hex_bytes(dbuf, (char*)pkt, size); - FURI_LOG_D(TAG, "PKT%02X: %s (%d)", *(pkt - 1), dbuf, size); - } - int16_t i = 0; - for(; i < found_total; i++) { - if(APP->found[i].addr_size != addr_size) continue; - if(memcmp(APP->found[i].addr, pkt, addr_size) == 0) break; - } - if(i != found_total) { // found - APP->found[i].total++; - } else { - uint8_t* p = APP->log_arr + 2; - for(i = 0; i < log_arr_idx; i++, p += LOG_REC_SIZE) { - if((*(p - 2) & 0x80) && (*(p - 1) & 0b11) + 2 == addr_size && pkt != p) { - if(memcmp(p, pkt, addr_size) == 0) break; - } - } - if(i != log_arr_idx && found_total < MAX_FOUND_RECORDS) { // found -> 2 - memset(&APP->found[found_total], 0, sizeof(struct FOUND)); - memcpy(APP->found[found_total].addr, pkt, addr_size); - APP->found[found_total].addr_size = addr_size; - APP->found[found_total].total = 2; - if(found_total == 0) view_found = 0; - found_total++; - } - } - } - - return found; -} - -bool nrf24_read_newpacket() { - if(APP->log_arr == NULL) return false; - bool found = false; - uint8_t packetsize; - uint8_t* ptr = APP->log_arr + log_arr_idx * LOG_REC_SIZE; - uint8_t st; - /* test pkts - static int iii = 0; - char ppp[][65] = { "54A545109411544BAAE50110A3282512A9A1152A565B22AAA48AB751A5", - "C8C8C0CE7A81018007202FFFFC", - "EAEC8C8C2CE3C0101006FB737A", - "BEBFFFEC8C8C1CC00542AF7CFF7DBEAFE3397FEAFEF1DDFA4AEF7FDBB7CDEABC", - "FEAAAABEAAFEAAC8C8C28E1C810080490ABAF7FEEB76B7FDFEF7DFFB47FB97FE", - "A8AAC8C8C1CE20163DF7DFFD00", - "AFFEEFEC8C8C2CE4001010062F037F9BFFDF1DAD5EDBEF55DD9AB535FCB67F55", - "AC8C8C1CE5F8102000D503D7ABF", - "EE03080B4712555555550E80", - "C8C8C41385818280127100", - "AAC8C8C3CE05818280119000" - "AC8C8C413858182801271000", - "AAC8C8C40B0305028542" - }; - if(iii < 13) { - ConvertHexToArray(ppp[iii], ptr + 2, 32); - st = RX_DR; - packetsize = 32; - iii++; - } else -//*/ - st = nrf24_rxpacket( - nrf24_HANDLE, - ptr + 2 + (what_to_do == 1 ? addrs_sniff.addr_len - 2 : 0), - &packetsize, - what_to_do == 1 ? 32 : !NRF_DPL); - if(st & RX_DR) { - st = (st >> 1) & 7; // pipe # - if(what_to_do == 1) { // SNIFF - *ptr++ = NRF_channel | 0x80; - *ptr++ = st; // pipe # - if(addrs_sniff.addr_len > 2) { - *ptr = st == 0 ? addrs_sniff.addr_P0[2] : - st == 1 ? addrs_sniff.addr_P1[2] : - st == 2 ? addrs_sniff.addr_P2 : - st == 3 ? addrs_sniff.addr_P3 : - st == 4 ? addrs_sniff.addr_P4 : - addrs_sniff.addr_P5; - } - if(!check_packet(ptr, packetsize)) { - if(addrs_sniff.addr_len > 2) return false; // skip if mac MSB added to preamble - uint8_t shifted = 0; - uint8_t shift_max = (32 - 3 - NRF_Payload_sniff_min - NRF_CRC) * 8 - 1; - while(shifted++ < - shift_max) { // Shift packet left by one bit if minimum payload fits - uint8_t i = 0; - for(; i < packetsize - 1; i++) ptr[i] = (ptr[i] << 1) | (ptr[i + 1] >> 7); - ptr[i] <<= 1; - if(check_packet(ptr, packetsize - (shifted >> 3) - 1)) goto x_valid; - } - return false; - } - } else { - *ptr++ = NRF_channel; - *ptr++ = ((packetsize & 0x1F) << 3) | st; // payload size + pipe # - } - x_valid: - if(packetsize < 32) memset(ptr + packetsize, 0, 32 - packetsize); - if(log_arr_idx < MAX_LOG_RECORDS - 1) { - log_arr_idx++; - } else { - if(log_to_file == 1 || log_to_file == 2) { - write_to_log_file(APP->storage, false); - clear_log(); - } else { - memmove(APP->log_arr, APP->log_arr + LOG_REC_SIZE, log_arr_idx * LOG_REC_SIZE); - } - } - FURI_LOG_D(TAG, "Found packet #%d pipe %d", log_arr_idx, st); - notification_message(APP->notification, &sequence_blink_white_100); - found = true; - } - return found; -} - -bool nrf24_send_packet() { - if(log_arr_idx == 0) return false; - prepare_nrf24(!what_to_do); - uint8_t* ptr = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; - nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *ptr & 0x7F); - if(*ptr & 0x80) { // RAW packet - //uint8_t pktinfo = *(ptr + 1); - //nrf24_set_maclen(nrf24_HANDLE, (pktinfo & 0b11) + 2); - //if(pktinfo & 0b100) { // ESB - nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // No Automatic Retransmission - nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // No Auto acknowledgement - //} - //uint8_t alen = (*(ptr + 2) & 0b11) + 2; - uint8_t adr[2]; - adr[0] = ptr[2]; - adr[1] = ptr[3]; - nrf24_set_maclen(nrf24_HANDLE, 2); - nrf24_set_mac(REG_RX_ADDR_P0, adr, 2); - nrf24_set_mac(REG_TX_ADDR, adr, 2); - last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, ptr + 2 + 2, 32 - 2, true); - } else { - nrf24_write_reg( - nrf24_HANDLE, REG_SETUP_RETR, NRF_ESB ? 0x11 : 0); // Automatic Retransmission - nrf24_write_reg( - nrf24_HANDLE, REG_EN_AA, NRF_AA_OFF || !NRF_ESB ? 0 : 0x3F); // Auto acknowledgement - uint8_t* adr; - uint8_t a = *(ptr + 1) & 0b111; - if(a < 2) { - if(a == 0) - adr = addrs.addr_P0; - else - adr = addrs.addr_P1; - nrf24_set_mac(REG_RX_ADDR_P0, adr, addrs.addr_len); - nrf24_set_mac(REG_TX_ADDR, adr, addrs.addr_len); - } else { - uint8_t buf[5]; - memcpy(buf, addrs.addr_P1, addrs.addr_len - 1); - buf[addrs.addr_len - 1] = a == 2 ? addrs.addr_P2 : - a == 3 ? addrs.addr_P3 : - a == 4 ? addrs.addr_P4 : - addrs.addr_P5; - nrf24_set_mac(REG_RX_ADDR_P0, buf, addrs.addr_len); - nrf24_set_mac(REG_TX_ADDR, buf, addrs.addr_len); - } - a = *(ptr + 1) >> 3; - if(a == 0) a = 32; - nrf24_write_reg( - nrf24_HANDLE, - REG_CONFIG, - 0x70 | ((NRF_CRC == 1 ? 0b1000 : - NRF_CRC == 2 ? 0b1100 : - 0))); // Mask all interrupts - nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg - last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, ptr + 2, a, true); - } - last_packet_send = view_log_arr_idx; - notification_message( - APP->notification, - last_packet_send_st ? &sequence_blink_blue_100 : &sequence_blink_red_100); - if(what_to_do) start_scanning(); - return last_packet_send_st; -} - -static void render_callback(Canvas* const canvas, void* ctx) { - const PluginState* plugin_state = ctx; - if(plugin_state == NULL) return; - if(furi_mutex_acquire(plugin_state->mutex, 25) != FuriStatusOk) return; - //canvas_draw_frame(canvas, 0, 0, 128, 64); // border around the edge of the screen - if(what_doing == 0) { - canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines - if(save_settings) - snprintf( - screen_buf, sizeof(screen_buf), "Save: %s", SETTINGS_FILENAME); // menu_selected = 0 - else - snprintf(screen_buf, sizeof(screen_buf), "Load: %s", addr_file_name); - canvas_draw_str(canvas, 10, 10, screen_buf); - snprintf(screen_buf, sizeof(screen_buf), "Ch: %d", NRF_channel); // menu_selected = 1 - canvas_draw_str(canvas, 10, 20, screen_buf); - if(NRF_ESB) { - strcpy(screen_buf, "ESB"); - if(NRF_DPL) strcat(screen_buf, " DPL"); - canvas_draw_str(canvas, 78, 20, screen_buf); - } - if(NRF_AA_OFF) { - canvas_draw_str(canvas, 61, 20, "AA"); - canvas_draw_line(canvas, 60, 21, 72, 12); - } - snprintf( - screen_buf, - sizeof(screen_buf), - "Rate: %sbps", - NRF_rate == 2 ? "2M" : - NRF_rate == 1 ? "1M" : - "250K"); // menu_selected = 2 - canvas_draw_str(canvas, 10, 30, screen_buf); - if(what_to_do == 1) - snprintf(screen_buf, sizeof(screen_buf), "Min Payl: %d", NRF_Payload_sniff_min); - else if(what_to_do >= 2) { - uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; - snprintf( - screen_buf, - sizeof(screen_buf), - "Payload: %d", - log_arr_idx && (*p & 0x80) ? *(p + 1) >> 3 : NRF_Payload); - } else - snprintf(screen_buf, sizeof(screen_buf), "Payload: %d", NRF_Payload); - canvas_draw_str(canvas, 78, 30, screen_buf); - strcpy(screen_buf, "Next Ch time: "); // menu_selected = 3 - if(find_channel_period == 0) - strcat(screen_buf, "off"); - else - snprintf( - screen_buf + strlen(screen_buf), sizeof(screen_buf), "%d s", find_channel_period); - canvas_draw_str(canvas, 10, 40, screen_buf); - if(NRF_CRC == 1) - canvas_draw_str(canvas, 99, 40, "CRC1"); - else if(NRF_CRC == 2) - canvas_draw_str(canvas, 99, 40, "CRC2"); - snprintf( - screen_buf, - sizeof(screen_buf), - "Log: %s", - log_to_file == 0 ? "No" : - log_to_file == 1 ? "Yes" : - log_to_file == 2 ? "Append" : - "Clear"); // menu_selected = 4 - canvas_draw_str(canvas, 10, 50, screen_buf); - if(what_to_do) { // menu_selected = 5 - if(NRF_ERROR) - snprintf(screen_buf, sizeof(screen_buf), "nRF24L01+ r/w ERROR!"); - else { - if(what_to_do == 1) - snprintf(screen_buf, sizeof(screen_buf), "Start sniff"); - else { - uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; - if(log_arr_idx && (*p & 0x80)) { // +RAW - snprintf(screen_buf, sizeof(screen_buf), "Start read: "); - add_to_str_hex_bytes(screen_buf, (char*)p + 2, (*(p + 1) & 0b11) + 2); - if(what_to_do == 2) strcpy(screen_buf + strlen(screen_buf) - 2, "* "); - } else - snprintf( - screen_buf, - sizeof(screen_buf), - "Start scan (pipes: %d)", - addrs.addr_count); - } - } - } else - snprintf(screen_buf, sizeof(screen_buf), "View log (pipes: %d)", addrs.addr_count); - canvas_draw_str(canvas, 10, 60, screen_buf); - canvas_draw_str(canvas, 0, menu_selected * 10 + 10, ">"); - } else if(what_doing == 1) { - canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines - bool ch2 = false; - screen_buf[0] = '\0'; - if(view_log_arr_x == 0) { - strcat(screen_buf, " "); - ch2 = true; - } else { - snprintf(screen_buf, sizeof(screen_buf), "<%d", view_log_arr_x); - if(view_log_arr_x < VIEW_LOG_MAX_X) ch2 = true; - } - snprintf( - screen_buf + strlen(screen_buf), - sizeof(screen_buf), - " %s ch: %d - %d.", - what_to_do == 1 ? "Sniff" : - what_to_do == 0 ? "View" : - "Read", - NRF_channel, - log_arr_idx); - canvas_draw_str(canvas, 0, 7, screen_buf); - if(ch2) canvas_draw_str(canvas, 121, 7, ">"); - if(log_arr_idx) { - if(view_log_arr_idx >= log_arr_idx) view_log_arr_idx = log_arr_idx - 1; - uint16_t page = view_log_arr_idx & ~7; - for(uint8_t i = 0; i < 8 && page + i < log_arr_idx; i++) { - screen_buf[0] = (view_log_arr_idx & 7) != i ? ' ' : - last_packet_send != view_log_arr_idx ? '>' : - last_packet_send_st ? '*' : - '!'; - screen_buf[1] = '\0'; - uint8_t* ptr = APP->log_arr + (page + i) * LOG_REC_SIZE; - uint8_t channel = *ptr++; - uint8_t* crcptr = NULL; - uint8_t pre = 0; - int count = 0; - if(channel & 0x80) { // RAW packet: nn:>{.address..}-xxxxxxxx - uint8_t pktinfo = *ptr++; - bool _PCF = pktinfo & 0b100; - uint8_t plen = count = (pktinfo >> 3); - uint8_t adrsize = (pktinfo & 0b11) + 2; - plen += adrsize; - count += view_log_decode_CRC; - if(view_log_arr_x > 0) count -= view_log_arr_x - 1; - uint8_t max_width = VIEW_LOG_WIDTH_B; - if(view_log_arr_x == 0) max_width -= 5; - if(count > max_width) count = max_width; - if(count > 0) { - uint8_t* pcrc = ptr; - uint32_t crc; - crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF; - crc = calc_crc(crc, pcrc, 7, (_PCF ? 9 : 0) + plen * 8); - pcrc += plen; - if(_PCF) { //ESB - pcrc++; - if(crc == get_shifted_crc(pcrc)) crcptr = pcrc; - } else { - if((view_log_decode_CRC == 1 && crc == *pcrc) || - (view_log_decode_CRC == 2 && - crc == (uint32_t)((*pcrc << 8) | *(pcrc + 1)))) { - crcptr = pcrc; - } - } - if(view_log_arr_x == 0) { - add_to_str_hex_bytes(screen_buf, (char*)ptr, adrsize); - for(int8_t j = 5 - adrsize; j > 0; j--) strcat(screen_buf, " "); - strcat(screen_buf, "-"); - pre += 5 * 2 + 1; - } else { - ptr += view_log_arr_x - 1; - } - ptr += adrsize; - if(_PCF) - add_to_str_hex_bytes_shift_9b(screen_buf, (char*)ptr++, count); - else - add_to_str_hex_bytes(screen_buf, (char*)ptr, count); - } - } else { - uint8_t dpl = *ptr++; - uint8_t pipe = dpl & 0b111; - dpl >>= 3; - if(dpl == 0) dpl = 32; - count = dpl - view_log_arr_x; - if(view_log_decode_PCF) count--; - uint8_t max_width = VIEW_LOG_WIDTH_B; - if(view_log_arr_x == 0) { - if(addrs.addr_count > 1) max_width--; - if(view_log_decode_PCF) max_width -= 2; - } - if(count > max_width) count = max_width; - if(count > 0) { - if(view_log_decode_CRC) { - static uint16_t prev_addr_CRC; - static int8_t prev_pipe = -1; - uint8_t* pcrc = ptr; - uint32_t crc; - if(prev_pipe == pipe) { - crc = prev_addr_CRC; - } else { - crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF; - if(pipe <= 1) { - crc = calc_crc( - crc, - pipe == 0 ? addrs.addr_P0 : addrs.addr_P1, - 7, - addrs.addr_len * 8); - } else { - crc = - calc_crc(crc, addrs.addr_P1, 7, (addrs.addr_len - 1) * 8); - crc = calc_crc( - crc, - pipe == 2 ? &addrs.addr_P2 : - pipe == 3 ? &addrs.addr_P3 : - pipe == 4 ? &addrs.addr_P4 : - &addrs.addr_P5, - 7, - 8); - } - prev_addr_CRC = crc; - prev_pipe = pipe; - } - if(view_log_decode_PCF) { - crc = calc_crc(crc, pcrc++, 7, 9); - if(crc == get_shifted_crc(pcrc)) crcptr = pcrc; - if(crcptr == NULL) { - for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC - 1; - j++) { - crc = calc_crc(crc, pcrc++, 6, 8); - if(crc == get_shifted_crc(pcrc)) { - crcptr = pcrc; - break; - } - } - } - } else { - for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC; j++) { - crc = calc_crc(crc, pcrc++, 7, 8); - if((view_log_decode_CRC == 1 && crc == *pcrc) || - (view_log_decode_CRC == 2 && - crc == (uint32_t)((*pcrc << 8) | *(pcrc + 1)))) { - crcptr = pcrc; - break; - } - } - } - } - } - ptr += view_log_arr_x; - if(max_width < VIEW_LOG_WIDTH_B) { - pre += snprintf(screen_buf + 1, 10, "%X-", pipe); - if(view_log_decode_PCF) { - pre += snprintf( - screen_buf + strlen(screen_buf), - 10, - "%02X%01X-", - *ptr >> 2, - ((*ptr & 3) << 1) | (*(ptr + 1) >> 7)); - } - } - if(view_log_decode_PCF) - add_to_str_hex_bytes_shift_9b(screen_buf, (char*)ptr++, count); - else - add_to_str_hex_bytes(screen_buf, (char*)ptr, count); - } - uint16_t y = 14 + i * 7; - canvas_draw_str(canvas, 3 * 5, y, screen_buf); - uint16_t x = page + i + 1; - if(x > 99) { - snprintf(screen_buf, 16, "%d", x); - canvas_draw_str(canvas, 1, y, screen_buf + 1); - canvas_draw_frame(canvas, 0, y - 2, 1, 2); - x = 2; - } else { - x = snprintf(screen_buf, 16, "%d", x); - canvas_draw_str(canvas, 0, y, screen_buf); - } - if(crcptr) { // 5x7 font, 9 lines - canvas_draw_str(canvas, x * 5, y, "="); - int n = crcptr - (uint8_t*)ptr; - if(n > -view_log_decode_CRC && n < count) { - int len; - x = (4 + pre) * 5; - if(n < 0) { - len = view_log_decode_CRC + n; - n = 0; - } else { - len = MIN(view_log_decode_CRC, count - n); - x += n * 2 * 5; - canvas_draw_line(canvas, x - 1, y, x - 1, y - 1); - } - canvas_draw_line(canvas, x - 1, y, n = x + len * 2 * 5 - 1, y); - canvas_draw_line(canvas, n, y, n, y - 1); - } - } else - canvas_draw_str(canvas, x * 5, y, ":"); - } - } - } else { - canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines - if(view_found >= 0) { - snprintf(screen_buf, 50, "Found > 1: %d", found_total); - canvas_draw_str(canvas, 0, 1 * 7, screen_buf); - int16_t idx = view_found * 7; - for(uint8_t i = 0; i < 7; i++, idx++) { - if(idx >= found_total) break; - snprintf(screen_buf, 16, "%d. ", idx + 1); - add_to_str_hex_bytes( - screen_buf, (char*)APP->found[idx].addr, APP->found[idx].addr_size); - if(APP->found[idx].addr_size == 3) - strcat(screen_buf, " "); - else if(APP->found[idx].addr_size == 4) - strcat(screen_buf, " "); - snprintf(screen_buf + strlen(screen_buf), 16, " - %d", APP->found[idx].total); - canvas_draw_str(canvas, 0, (2 + i) * 7, screen_buf); - } - } else { - struct ADDRS* a; - if(what_to_do == 1) { - a = &addrs_sniff; - canvas_draw_str(canvas, 0, 1 * 7, "Sniff prefix:"); - } else { - a = &addrs; - canvas_draw_str(canvas, 0, 1 * 7, "Addresses:"); - } - if(a->addr_count > 0) { - snprintf(screen_buf, sizeof(screen_buf), "P0: "); - add_to_str_hex_bytes(screen_buf, (char*)a->addr_P0, a->addr_len); - canvas_draw_str(canvas, 0, 2 * 7, screen_buf); - } - if(a->addr_count > 1) { - snprintf(screen_buf, sizeof(screen_buf), "P1: "); - add_to_str_hex_bytes(screen_buf, (char*)a->addr_P1, a->addr_len); - canvas_draw_str(canvas, 0, 3 * 7, screen_buf); - } - if(a->addr_count > 2) { - canvas_draw_str(canvas, 0, 4 * 7, "P2: "); - snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P2); - canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 4 * 7, screen_buf); - } - if(a->addr_count > 3) { - canvas_draw_str(canvas, 0, 5 * 7, "P3: "); - snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P3); - canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 5 * 7, screen_buf); - } - if(a->addr_count > 4) { - canvas_draw_str(canvas, 0, 6 * 7, "P4: "); - snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P4); - canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 6 * 7, screen_buf); - } - if(a->addr_count > 5) { - canvas_draw_str(canvas, 0, 7 * 7, "P5: "); - snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P5); - canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 7 * 7, screen_buf); - } - } - if(log_arr_idx) { - uint8_t* ptr = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; - uint8_t pktinfo = *(ptr + 1); - snprintf(screen_buf, 32, ">Ch: %d L: %d", *ptr & 0x7F, pktinfo >> 3); - if(*ptr & 0x80) { - strcat(screen_buf, " RAW"); - if(pktinfo & 0b100) { - snprintf( - screen_buf + strlen(screen_buf), - 16, - " ESB %s", - *(ptr + 2 + (pktinfo & 0b11) + 2) >> 2 != 0x33 ? "DPL" : ""); - } - } - canvas_draw_str(canvas, 0, 8 * 7, screen_buf); - } - screen_buf[0] = 'v'; - strcpy(screen_buf + 1, VERSION); - canvas_draw_str(canvas, 105, 7, screen_buf); - if(view_log_decode_PCF || view_log_decode_CRC) { - strcpy(screen_buf, "Decode: "); - if(view_log_decode_PCF) strcat(screen_buf, "ESB "); - if(view_log_decode_CRC == 1) - strcat(screen_buf, "CRC1"); - else if(view_log_decode_CRC == 2) - strcat(screen_buf, "CRC2"); - canvas_draw_str(canvas, 0, 64, screen_buf); - } - } - furi_mutex_release(plugin_state->mutex); -} - -int32_t nrf24scan_app(void* p) { - UNUSED(p); - APP = malloc(sizeof(Nrf24Scan)); - APP->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - PluginState* plugin_state = malloc(sizeof(PluginState)); - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!plugin_state->mutex) { - furi_message_queue_free(APP->event_queue); - FURI_LOG_E(TAG, "cannot create mutex"); - free(plugin_state); - return 255; - } - APP->log_arr = malloc(LOG_REC_SIZE * MAX_LOG_RECORDS); - if(APP->log_arr == NULL) { - FURI_LOG_E(TAG, "Not enouch memory: %d", LOG_REC_SIZE * MAX_LOG_RECORDS); - strcpy(addr_file_name, "MEMORY LOW!"); - } - clear_log(); - APP->found = malloc(sizeof(struct FOUND) * MAX_FOUND_RECORDS); - if(APP->found == NULL) { - FURI_LOG_E(TAG, "Not enouch memory: %d", sizeof(struct FOUND) * MAX_FOUND_RECORDS); - strcpy(addr_file_name, "MEMORY LOW!!"); - } - - memset((uint8_t*)&addrs, 0, sizeof(addrs)); - memset((uint8_t*)&addrs_sniff, 0, sizeof(addrs_sniff)); - if(!furi_hal_power_is_otg_enabled()) { - furi_hal_power_enable_otg(); - NRF_BOARD_POWER_5V = true; - furi_delay_ms(100); - } - nrf24_init(); - - // Set system callbacks - APP->view_port = view_port_alloc(); - view_port_draw_callback_set(APP->view_port, render_callback, plugin_state); - view_port_input_callback_set(APP->view_port, input_callback, APP->event_queue); - - // Open GUI and register view_port - APP->gui = furi_record_open(RECORD_GUI); - gui_add_view_port(APP->gui, APP->view_port, GuiLayerFullscreen); - APP->notification = furi_record_open(RECORD_NOTIFICATION); - APP->storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(APP->storage, EXT_PATH("nrf24scan"), SCAN_APP_PATH_FOLDER); - storage_common_mkdir(APP->storage, SCAN_APP_PATH_FOLDER); - Stream* file_stream = file_stream_alloc(APP->storage); - FuriString* path = furi_string_alloc(); - furi_string_set(path, SCAN_APP_PATH_FOLDER); - furi_string_cat(path, "/"); - furi_string_cat(path, SNIFF_FILENAME); - if(file_stream_open(file_stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - uint8_t err = load_settings_file(file_stream); - if(!err) - strncpy( - addr_file_name, - furi_string_get_cstr(path) + sizeof(SCAN_APP_PATH_FOLDER), - sizeof(addr_file_name)); - else - snprintf(addr_file_name, sizeof(addr_file_name), "LOAD ERROR#%d", err); - } else { - strcpy(addr_file_name, "NONE"); - if(what_to_do == 1) { - addrs.addr_P0[0] = 0; - addrs.addr_P0[1] = 0x55; - addrs.addr_len = 2; - addrs.addr_count = 1; - view_log_decode_CRC = NRF_CRC = 2; - NRF_Payload_sniff_min = 0; // Min - } - } - file_stream_close(file_stream); - stream_free(file_stream); - furi_string_free(path); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(APP->event_queue, &event, 100); - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - //FURI_LOG_D(TAG, "Key: %d Type: %d Sec: %u", event.input.key, event.input.type, event.input.sequence); - switch(event.input.key) { - case InputKeyUp: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(what_doing == 0) { - if(menu_selected > 0) - menu_selected--; - else - menu_selected = menu_selected_max; - } else if(what_doing == 1) { - view_log_arr_idx -= event.input.type == InputTypeRepeat ? 10 : 1; - if(view_log_arr_idx >= log_arr_idx) view_log_arr_idx = 0; - } else if(what_doing == 2) { - if(view_found > -1) view_found--; - } - } - break; - case InputKeyDown: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(what_doing == 0) { - if(menu_selected < menu_selected_max) - menu_selected++; - else - menu_selected = 0; - } else if(what_doing == 1) { - if(log_arr_idx == 0) - view_log_arr_idx = 0; - else { - view_log_arr_idx += event.input.type == InputTypeRepeat ? 10 : 1; - if(view_log_arr_idx >= log_arr_idx) - view_log_arr_idx = log_arr_idx - 1; - } - } else if(what_doing == 2) { - if(view_found < found_total / 7) view_found++; - } - } - break; - case InputKeyLeft: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(what_doing == 0) { - switch(menu_selected) { - case Menu_enter_channel: - NRF_channel -= event.input.type == InputTypeRepeat ? 10 : 1; - if(NRF_channel > MAX_CHANNEL) NRF_channel = MAX_CHANNEL; - break; - case Menu_enter_rate: - if(what_to_do == 1) { // SNIFF - NRF_Payload_sniff_min -= - event.input.type == InputTypeRepeat ? 10 : 1; - correct_NRF_Payload_sniff_min(); - } else { - NRF_Payload -= event.input.type == InputTypeRepeat ? 10 : 1; - if(NRF_Payload > 32) NRF_Payload = 0; - } - break; - case Menu_enter_scan_period: - find_channel_period -= event.input.type == InputTypeRepeat ? 10 : - 1; - if(find_channel_period < 0) find_channel_period = 0; - break; - case Menu_log: - if(--log_to_file < -1) log_to_file = 2; - break; - case Menu_ok: - if(--what_to_do > 3) what_to_do = 3; - break; - } - } else if(what_doing == 1) { - if(view_log_arr_x > 0) view_log_arr_x--; - } else if(what_doing == 2) { - //if(NRF_ESB == 0) - view_log_decode_PCF ^= 1; - } - } - break; - case InputKeyRight: - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - if(what_doing == 0) { - switch(menu_selected) { - case Menu_open_file: - save_settings ^= 1; - break; - case Menu_enter_channel: - NRF_channel += event.input.type == InputTypeRepeat ? 10 : 1; - if(NRF_channel > MAX_CHANNEL) NRF_channel = 0; - break; - case Menu_enter_rate: - if(what_to_do == 1) { // SNIFF - NRF_Payload_sniff_min += - event.input.type == InputTypeRepeat ? 10 : 1; - correct_NRF_Payload_sniff_min(); - } else { - NRF_Payload += event.input.type == InputTypeRepeat ? 10 : 1; - if(NRF_Payload > 32) NRF_Payload = 32; - } - break; - case Menu_enter_scan_period: - find_channel_period += event.input.type == InputTypeRepeat ? 10 : - 1; - break; - case Menu_log: - if(++log_to_file > 2) log_to_file = -1; - break; - case Menu_ok: - if(++what_to_do > 3) what_to_do = 0; - break; - } - } else if(what_doing == 1) { - if(view_log_arr_x < VIEW_LOG_MAX_X) view_log_arr_x++; - } else if(what_doing == 2) { - if(++view_log_decode_CRC > 2) view_log_decode_CRC = 0; - } - } - break; - case InputKeyOk: - if(event.input.type == InputTypeShort) { - if(what_doing == 0) { - switch(menu_selected) { - case Menu_open_file: - if(save_settings) { - write_to_log_file(APP->storage, true); - } else { - file_stream = file_stream_alloc(APP->storage); - if(select_settings_file(file_stream)) { - uint8_t err = load_settings_file(file_stream); - if(!err) - save_to_new_log = true; - else - snprintf( - addr_file_name, - sizeof(addr_file_name), - "LOAD ERROR#%d", - err); - file_stream_close(file_stream); - menu_selected = Menu_ok; - } - stream_free(file_stream); - } - break; - case Menu_enter_channel: - if(what_to_do == 1) { - if(NRF_ESB) - NRF_DPL = NRF_ESB = 0; - else - NRF_ESB = 1; - } else { - if(NRF_ESB) { - if(NRF_DPL) - NRF_DPL = NRF_ESB = 0; - else - NRF_DPL = 1; - } else - NRF_ESB = 1; - } - break; - case Menu_enter_rate: - NRF_rate++; - if(NRF_rate > 2) NRF_rate = 0; - break; - case Menu_enter_scan_period: - if(++NRF_CRC > 2) NRF_CRC = what_to_do == 1 ? 1 : 0; - break; - case Menu_ok: - if(what_to_do) { - if((addrs.addr_count || - (what_to_do >= 2 && log_arr_idx && - *(APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) & - 0x80)) || - what_to_do == 1) { - if(log_to_file == -1) { - log_to_file = 0; - clear_log(); - save_to_new_log = true; - } else if(log_to_file == 1) - save_to_new_log = true; - start_scanning(); - if(!NRF_ERROR) what_doing = 1; - } - } else - what_doing = 1; - break; - } - } else if(what_doing == 1) { - what_doing = 2; - } else if(what_doing == 2) { - what_doing = 1; - } - } else if(event.input.type == InputTypeLong) { - if(what_doing == 0) { - if(menu_selected == Menu_enter_channel) { - NRF_AA_OFF ^= 1; - } else if(menu_selected == Menu_log) { // Log - if(log_arr_idx && (log_to_file == 1 || log_to_file == 2)) { - write_to_log_file(APP->storage, false); - clear_log(); - } - } - } else if(what_doing == 1 || what_doing == 2) { - nrf24_send_packet(); - } - } - break; - case InputKeyBack: - if(event.input.type == InputTypeLong) - processing = false; - else if(event.input.type == InputTypeShort) { - if(what_doing) what_doing--; - if(what_doing == 0) { - nrf24_set_idle(nrf24_HANDLE); - } - } - break; - default: - break; - } - } - } - if(what_doing && what_to_do) { - nrf24_read_newpacket(); - if(find_channel_period && - furi_get_tick() - start_time >= (uint32_t)find_channel_period * 1000UL) { - if(++NRF_channel > MAX_CHANNEL) NRF_channel = 0; - start_scanning(); - } - } - - view_port_update(APP->view_port); - furi_mutex_release(plugin_state->mutex); - } - nrf24_set_idle(nrf24_HANDLE); - if(log_arr_idx && (log_to_file == 1 || log_to_file == 2)) { - write_to_log_file(APP->storage, false); - } - nrf24_deinit(); - if(NRF_BOARD_POWER_5V) furi_hal_power_disable_otg(); - - view_port_enabled_set(APP->view_port, false); - gui_remove_view_port(APP->gui, APP->view_port); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_STORAGE); - view_port_free(APP->view_port); - furi_message_queue_free(APP->event_queue); - if(APP->log_arr) free(APP->log_arr); - if(APP->found) free(APP->found); - furi_mutex_free(plugin_state->mutex); - free(plugin_state); - free(APP); - return 0; -} diff --git a/applications/external/nrf24scan/nrf24scan.h b/applications/external/nrf24scan/nrf24scan.h deleted file mode 100644 index 86e34856d..000000000 --- a/applications/external/nrf24scan/nrf24scan.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - FuriMutex* mutex; -} PluginState; - -struct FOUND { - uint8_t addr_size; - uint8_t addr[5]; - uint16_t total; -}; - -typedef struct { - Gui* gui; - FuriMessageQueue* event_queue; - ViewPort* view_port; - Storage* storage; - NotificationApp* notification; - uint8_t* log_arr; - struct FOUND* found; -} Nrf24Scan; diff --git a/applications/external/nrf24scan/nrf24scan_10px.png b/applications/external/nrf24scan/nrf24scan_10px.png deleted file mode 100644 index 348b35eca7599d1c72a7b1efea9fd7f263e4606f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1771 zcmcIlO>f*p7x-sRO- zS0zchJlO8D=?T@&96%@6B`l63J-Ivmxb=!1apOvRMP zOl`6P(2{h0y(uu+XSE!&ahiw9U%&jS$SDn#+fJlM#U`7i+s7rlb-Xhq$NR*m%K8oY zdJ_Oa#%e4#*)*?$CRFCU0gT0CO_Ar2dOuV)L_v8J?aG_HWU{B4i0Ha5d%kMKu7f@Q z9of`PQ`23|u#n*ewi_6>+%ZF;gS$|f)O8VP+H5vcXO_y#v1a(buj!^{ zng|f6I?8L@puAe^82YRtWm?oJ&t<`gV}4MF3P@e7AuE=&dDZ#^j%f`pG(*+JnmS+< zoej;hCAzA&4xvh`_p!v)@Tg$g9;^64N!ZpQ%j>nSSTW%>uO|En+LnL+MyFy@;}*Nuj;5(R4_$zX z$a<&{(PT!I_Hp_c_s*wtK|7l;AU&h`3s}XIdWK83F$Slf8ZPZg;wyZ3w)FEg{uxSd zZ6y<&j~VQonj#jXi7jT)6z%{0df4wSGaHa*(aoy0;U*q04Y|>U31f>wFfsDno`rl9 z!qiLj7!jJ7)btGECGMi`H0=~Dh_tgS&b2!ap z0w+mt(BBwd`-Gwau&+ngqv~uO^Yk#kNGO$cD{`nQ-o0Att`WFvA{_gdY i=ihk$!R+PXOVW$?Uc1=*arGZ@91XU1`aj;h``Nz$VJy}F diff --git a/applications/external/rootoflife/LICENSE b/applications/external/rootoflife/LICENSE deleted file mode 100644 index 765f2a64b..000000000 --- a/applications/external/rootoflife/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Kirill Korepanov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/external/rootoflife/application.fam b/applications/external/rootoflife/application.fam deleted file mode 100644 index c335f77aa..000000000 --- a/applications/external/rootoflife/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="roots_of_life", - name="Roots of Life", - apptype=FlipperAppType.EXTERNAL, - entry_point="roots_of_life_game_app", - cdefines=["APP_ROOTS_OF_LIFE_GAME"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="roots_of_life_10px.png", - fap_category="Games", - fap_icon_assets="images", - fap_icon_assets_symbol="roots_of_life_game", - fap_author="@Xorboo", - fap_weburl="https://github.com/Xorboo/root-of-life", - fap_version="1.0", - fap_description="A zen-puzzle game for FlipperZero, puzzle made on GlobalGameJam23 (theme: Roots)", -) diff --git a/applications/external/rootoflife/images/place_error.png b/applications/external/rootoflife/images/place_error.png deleted file mode 100644 index 9032c65322a0a85f7364c67737cdc56a4b721fbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4v7|ftIx;Y9?C1WI$O`0h7I;J! zGcfQS0b$0e+I-SLK}Sy)#}JL+CQSej~LyBFO(}d#0NeWUo ze@cWM7FqmT&{@$(aMMf4v7|ftIx;Y9?C1WI$O`0h7I;J! zGcfQS0b$0e+I-SLL03-~#}JL+wdWoA7zB7+E?)clzDF>4%9PgqnM(dEp3SnE@@vmG z{#9AC6gTe~ HDWM4fl&>_% diff --git a/applications/external/rootoflife/images/root_reroll.png b/applications/external/rootoflife/images/root_reroll.png deleted file mode 100644 index 996b5ff8110079f1df73192e97512fad71417ac9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4v7|ftIx;Y9?C1WI$O`0h7I;J! zGcfQS0b$0e+I-SL!2nMe#}JL+-U*(33$yQE#-Ur_Jv4$-pWrDz0u?uVU&0j5v{#Uc(CKE4{j(G3H Se^x-V89ZJ6T-G@yGywn@BsNa~ diff --git a/applications/external/rootoflife/images/score.png b/applications/external/rootoflife/images/score.png deleted file mode 100644 index 73bf140d4db41eafb435c50e99c24713dc4485f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^AT~D#8<2F%laT;YEa{HEjtmSN`?>!lvI6;>1s;*b z3=DinK$vl=HlH+5Fv-)!F+?M{bb_N$g8~n8^#A|qsoBboh5UY=(+!g6HD?%YUM?Md zR9WdKla2K~#?7-%ntYahuKD-u)g8{0B3!23xmJ8`xnQLD9M?Ohoxf~3wuD^RH2*cL k3;&#@4oWM0&x9UfZL9HS;(TiJ6lfcRr>mdKI;Vst0L7_2=Kufz diff --git a/applications/external/rootoflife/images/tree.png b/applications/external/rootoflife/images/tree.png deleted file mode 100644 index 4f424270ca65e9fd59ecc276244a6da07f2c7c8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4v7|ftIx;Y9?C1WI$O`0h7I;J! zGcfQS0b$0e+I-SLL3d9V#}JL+-X2CS1_ci0zyFu}uDv;>g>Ti)buRo$*1t|lx;$Dm zxxb>qaew&9=L>&}2yV(qx;M4a<=vy6yDx;qcAT7{@;o>swrQvE@9Rg*{D4L>c)I$z JtaD0e0ssaIHrfCH diff --git a/applications/external/rootoflife/roots_of_life_10px.png b/applications/external/rootoflife/roots_of_life_10px.png deleted file mode 100644 index 49d72986ddd0ed5bd1b7fccab89e796b1ef23339..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1679 zcmcIlOOM-B6m|uz+Nmm`@(@CmFz#j$WBdBXkJ!`9f`q99lBk-3ijby2&pR9%MKg4kFYkhvQtw@fv(_+S z>ITdBPDz%me~&0Hm2p7X5B?-9rB^(>misi%zO zJZ*8_n-*$q$|7Q{AaVXm7zezcJy|F!4OoNZ%$1;OSVp$2=`CDwG}|%oQ>fw~G=X~1 z2LZ{+(ZD)=k-G*q1A&Rn-W! z81m^@7uYvA-6_&n*iYIv;1oD!8FDPW9U#-9ahS<_UMad6*un2gm_g}=<@d44UMW|-P#ia%Luk?Ku0)F>vp^~zhj+=| z(R5B|`&|a4hZKJT%XmBQla$pukm>(yF7;mGGqQWQ^rIF2f0SOPm3B$oVK6vVsR%|b zM$Dur>c8tXes{+>n!;hm70cOhh0Sa{vlysT7`_jz|MoHr?zLv4)|%gZ@A~>#;fa$= z2Y>wd`TO6!_2O%Li{^c&Zr*;Kw*PY8zV=i0;rzAH$B%!q{;gNj(o6f#{_ynKhtpSY s9lUw<(_#Jl(dgWz=fD2!cYflL(XR`CK4dN2DE -#include -#include -#include -#include -#include -#include - -#include "roots_of_life_game_icons.h" -#include - -#define TAG "RootsOfLife" - -// Flipper -#define FLIPPER_LCD_WIDTH 128 -#define FLIPPER_LCD_HEIGHT 64 - -// General -#define GROUND_HEIGHT 10 -#define CELL_SIZE 3 -#define FIELD_START_X 0 -#define FIELD_START_Y (GROUND_HEIGHT + 1) -#define CELLS_X (FLIPPER_LCD_WIDTH / CELL_SIZE) -#define CELLS_Y ((FLIPPER_LCD_HEIGHT - GROUND_HEIGHT) / CELL_SIZE) -#define CELLS_TOTAL (CELLS_Y * CELLS_X) -#define CELL(Y, X) (Y * CELLS_X + X) - -// Root Spawn -#define ROOT_SIZE_X 7 -#define ROOT_SIZE_Y 7 -#define ROOT(Y, X) ((Y)*ROOT_SIZE_X + (X)) - -#define SPAWN_DIRECTIONS 2 -#define GROW_STEPS 4 -#define GROW_SAME_DIRECTION_CHANCE 70 -#define RANDOM_GROW_ATTEMPTS 4 -#define RANDOM_GROW_CHANCE 50 - -// UI -#define BLINK_PERIOD 12 -#define BLINK_HIDE_FRAMES 5 -#define TREE_HEIGHT 10 -#define PICKUP_FREQUENCY 10 - -// Game -#define REROLLS_MAX 5 -#define SCORE_FACTOR 10 - -#define PICKUPS_MIN 1 -#define PICKUPS_MAX 5 -#define PICKUPS_POINTS_FACTOR 10 - -typedef enum { EventTypeTick, EventTypeKey } EventType; - -typedef enum { - R_NONE = 0, - R_UP = 0b1000, - R_DOWN = 0b0100, - R_LEFT = 0b0010, - R_RIGHT = 0b0001 -} Direction; - -typedef enum { StageStart, StageRun, StageOver } GameStage; - -typedef struct { - bool initialDraw; - - GameStage stage; - int tick; - - bool* filledCells; - char* cells; - bool* pickups; - int collectedPickups; - - bool* filledRootBase; - char* rootBase; - - int rootSizeX; - int rootSizeY; - bool* filledRoot; - char* root; - - int pX, pY; - - int rerolls; - int score; - FuriMutex* mutex; -} GameState; - -typedef struct { - EventType type; - InputEvent input; -} GameEvent; - -static Direction rand_dir() { - int r = rand() % 4; - return 1 << r; -} - -static Direction reverse_dir(Direction dir) { - switch(dir) { - case R_UP: - return R_DOWN; - case R_DOWN: - return R_UP; - case R_LEFT: - return R_RIGHT; - case R_RIGHT: - return R_LEFT; - - default: - return R_NONE; - } -} - -static int rand_range(int min, int max) { - return min + rand() % (max - min); -} -static bool rand_chance(int chance) { - return (rand() % 100) < chance; -} - -static bool has_intersection(char cellA, char cellB) { - return cellA & cellB; -} - -static int root_index(GameState* state, int y, int x) { - return y * state->rootSizeX + x; -} - -static void set_cell(GameState* state, int y, int x, char cellRoot) { - int c = CELL(y, x); - state->filledCells[c] = true; - state->cells[c] = cellRoot; -} - -static void game_state_init(GameState* state) { - state->initialDraw = false; - state->tick = 0; - - // Init field arrays - state->filledCells = (bool*)malloc(CELLS_TOTAL * sizeof(bool)); - state->cells = (char*)malloc(CELLS_TOTAL * sizeof(char)); - state->pickups = (bool*)malloc(CELLS_TOTAL * sizeof(char)); - - state->rootBase = (char*)malloc(ROOT_SIZE_X * ROOT_SIZE_Y * sizeof(char)); - state->filledRootBase = (bool*)malloc(ROOT_SIZE_X * ROOT_SIZE_Y * sizeof(bool)); - state->root = NULL; - state->filledRoot = NULL; - - for(int i = 0; i < CELLS_TOTAL; i++) { - state->filledCells[i] = false; - state->cells[i] = R_NONE; - state->pickups[i] = false; - } -} - -static void free_root(GameState* state) { - if(state->root) free(state->root); - if(state->filledRoot) free(state->filledRoot); -} - -static void game_state_free(GameState* state) { - free(state->filledCells); - free(state->cells); - free(state->pickups); - - free(state->rootBase); - free(state->filledRootBase); - - free_root(state); -} - -/*static bool has_root(GameState* state, int x, int y) { - return x >= 0 && x < ROOT_SIZE_X && y >= 0 && y < ROOT_SIZE_Y && - state->filledRootBase[ROOT(y, x)]; -}*/ - -static void generate_new_root(GameState* state) { - for(int i = 0; i < ROOT_SIZE_X * ROOT_SIZE_Y; i++) { - state->filledRootBase[i] = false; - state->rootBase[i] = R_NONE; - } - - int cX = ROOT_SIZE_X / 2; - int cY = ROOT_SIZE_Y / 2; - int c = ROOT(cY, cX); - state->filledRootBase[c] = true; - - for(int i = 0; i < SPAWN_DIRECTIONS; i++) { - int pX = cX, pY = cY; - Direction oldDir = rand_dir(); - for(int g = 0; g < GROW_STEPS; g++) { - Direction dir = rand_chance(GROW_SAME_DIRECTION_CHANCE) ? oldDir : rand_dir(); - oldDir = dir; - - int nX = pX - (dir & R_LEFT ? 1 : 0) + (dir & R_RIGHT ? 1 : 0); - int nY = pY - (dir & R_UP ? 1 : 0) + (dir & R_DOWN ? 1 : 0); - if(nX < 0 || nY < 0 || nX >= ROOT_SIZE_X || nY >= ROOT_SIZE_Y) continue; - - int n = ROOT(nY, nX); - state->filledRootBase[n] = true; - - // Connect points - int p = ROOT(pY, pX); - state->rootBase[p] |= dir; - state->rootBase[n] |= reverse_dir(dir); - - // Grow from new point - pX = nX; - pY = nY; - } - } - - for(int y = 0; y < ROOT_SIZE_Y; y++) { - for(int x = 0; x < ROOT_SIZE_X; x++) { - int c = ROOT(y, x); - if(!state->filledRootBase[c]) continue; - - /* - if(has_root(state, x - 1, y)) state->rootBase[c] |= R_LEFT; - if(has_root(state, x + 1, y)) state->rootBase[c] |= R_RIGHT; - if(has_root(state, x, y - 1)) state->rootBase[c] |= R_UP; - if(has_root(state, x, y + 1)) state->rootBase[c] |= R_DOWN; - */ - - for(int r = 0; r < RANDOM_GROW_ATTEMPTS; r++) { - if(!rand_chance(RANDOM_GROW_CHANCE)) continue; - state->rootBase[c] |= rand_dir(); - } - } - } - - // Copy root to real root - int minX = cX, maxX = cX, minY = cY, maxY = cY; - for(int y = 0; y < ROOT_SIZE_Y; y++) { - for(int x = 0; x < ROOT_SIZE_X; x++) { - int r = ROOT(y, x); - if(!state->filledRootBase[r]) continue; - - minX = MIN(minX, x); - maxX = MAX(maxX, x); - minY = MIN(minY, y); - maxY = MAX(maxY, y); - } - } - - // Clone to real root - state->rootSizeX = maxX - minX + 1; - state->rootSizeY = maxY - minY + 1; - free_root(state); - - state->root = (char*)malloc(state->rootSizeX * state->rootSizeY * sizeof(char)); - state->filledRoot = (bool*)malloc(state->rootSizeX * state->rootSizeY * sizeof(bool)); - for(int y = 0; y < state->rootSizeY; y++) { - for(int x = 0; x < state->rootSizeX; x++) { - int c = root_index(state, y, x); - int r = ROOT(y + minY, x + minX); - state->filledRoot[c] = state->filledRootBase[r]; - state->root[c] = state->rootBase[r]; - } - } -} - -static bool in_borders(int x, int y) { - return x >= 0 && y >= 0 && x < CELLS_X && y < CELLS_Y; -} -static char get_cell(GameState* state, int x, int y) { - if(!in_borders(x, y)) return R_NONE; - return state->cells[CELL(y, x)]; -} - -static bool get_filled_cell(GameState* state, int x, int y) { - if(!in_borders(x, y)) return false; - return state->filledCells[CELL(y, x)]; -} - -static bool can_place_root(GameState* state) { - bool hasConnection = false; - for(int y = 0; y < state->rootSizeY; y++) { - for(int x = 0; x < state->rootSizeX; x++) { - int r = root_index(state, y, x); - if(!state->filledRoot[r]) { - continue; - } - char root = state->root[r]; - - int rY = y + state->pY; - int rX = x + state->pX; - - // Check if colliding - if(get_filled_cell(state, rX, rY)) { - char cell = get_cell(state, rX, rY); - if(has_intersection(cell, root)) { - return false; - } - hasConnection = true; - } - - // Check neighbours - hasConnection |= (root & R_RIGHT) && (get_cell(state, rX + 1, rY) & R_LEFT); - hasConnection |= (root & R_LEFT) && (get_cell(state, rX - 1, rY) & R_RIGHT); - hasConnection |= (root & R_UP) && (get_cell(state, rX, rY - 1) & R_DOWN); - hasConnection |= (root & R_DOWN) && (get_cell(state, rX, rY + 1) & R_UP); - } - } - - return hasConnection; -} - -static bool try_place_root(GameState* state) { - if(!can_place_root(state)) return false; - - for(int y = 0; y < state->rootSizeY; y++) { - for(int x = 0; x < state->rootSizeX; x++) { - int r = root_index(state, y, x); - if(!state->filledRoot[r]) continue; - - int rY = y + state->pY; - int rX = x + state->pX; - - // Root may be out of borders in rare cases (after new cpawn changed its size), just ignore that part - if(in_borders(rX, rY)) { - int c = CELL(rY, rX); - - state->filledCells[c] = true; - state->cells[c] |= state->root[r]; - } - } - } - - return true; -} - -static void reset_level(GameState* state) { - state->stage = StageStart; - state->tick = 0; - - for(int i = 0; i < CELLS_TOTAL; i++) { - state->filledCells[i] = false; - state->cells[i] = R_NONE; - } - - generate_new_root(state); - - // Starting cells - int midX = CELLS_X / 2; - set_cell(state, 0, midX, R_UP | R_DOWN); - set_cell(state, 1, midX, R_UP | R_DOWN | R_LEFT | R_RIGHT); - set_cell(state, 1, midX - 1, R_RIGHT | R_DOWN); - set_cell(state, 1, midX + 1, R_LEFT | R_DOWN); - set_cell(state, 2, midX, R_UP); - - state->pX = midX; - state->pY = 4; - - state->rerolls = REROLLS_MAX; - state->score = 0; - - state->collectedPickups = 0; - for(int i = 0, n = rand_range(PICKUPS_MIN, PICKUPS_MAX); i < n; i++) { - int x = rand_range(0, CELLS_X); - int y = rand_range(0, CELLS_Y); - state->pickups[CELL(y, x)] = true; - } -} - -static void recalculate_score(GameState* state) { - int score = 0; - for(int i = 0; i < CELLS_TOTAL; i++) { - if(state->filledCells[i]) score++; - } - - for(int i = 0; i < CELLS_TOTAL; i++) { - if(!state->pickups[i] || !state->filledCells[i]) continue; - - state->pickups[i] = false; - state->collectedPickups++; - state->rerolls++; - } - - state->score = (score + state->collectedPickups * PICKUPS_POINTS_FACTOR) * SCORE_FACTOR; -} - -static void draw_root_cell(Canvas* canvas, char root, int y, int x, bool isHidden) { - int posX = FIELD_START_X + x * CELL_SIZE + 1, posY = FIELD_START_Y + y * CELL_SIZE + 1; - canvas_draw_dot(canvas, posX, posY); - - if(isHidden) { - canvas_set_color(canvas, ColorXOR); - } - - if(root & R_UP) canvas_draw_dot(canvas, posX, posY - 1); - if(root & R_DOWN) canvas_draw_dot(canvas, posX, posY + 1); - if(root & R_LEFT) canvas_draw_dot(canvas, posX - 1, posY); - if(root & R_RIGHT) canvas_draw_dot(canvas, posX + 1, posY); - - if(isHidden) { - canvas_set_color(canvas, ColorBlack); - } -} - -static void draw_placed_roots(Canvas* canvas, GameState* state) { - for(int y = 0; y < CELLS_Y; y++) { - for(int x = 0; x < CELLS_X; x++) { - int c = CELL(y, x); - if(!state->filledCells[c]) continue; - draw_root_cell(canvas, state->cells[c], y, x, false); - } - } -} - -static void draw_pickup(Canvas* canvas, GameState* state, int y, int x) { - int posX = FIELD_START_X + x * CELL_SIZE + 1, posY = FIELD_START_Y + y * CELL_SIZE + 1; - - int stage = state->tick / PICKUP_FREQUENCY; - - if(stage++ % 4 < 3) canvas_draw_dot(canvas, posX + 1, posY); - if(stage++ % 4 < 3) canvas_draw_dot(canvas, posX, posY + 1); - if(stage++ % 4 < 3) canvas_draw_dot(canvas, posX - 1, posY); - if(stage++ % 4 < 3) canvas_draw_dot(canvas, posX, posY - 1); -} - -static void draw_pickups(Canvas* canvas, GameState* state) { - for(int y = 0; y < CELLS_Y; y++) { - for(int x = 0; x < CELLS_X; x++) { - int c = CELL(y, x); - if(!state->pickups[c]) continue; - draw_pickup(canvas, state, y, x); - } - } -} - -static void draw_active_root(Canvas* canvas, GameState* state) { - bool isHidden = (state->tick % BLINK_PERIOD) < BLINK_HIDE_FRAMES; - - for(int y = 0; y < state->rootSizeY; y++) { - for(int x = 0; x < state->rootSizeX; x++) { - int c = root_index(state, y, x); - if(!state->filledRoot[c]) continue; - - int realX = x + state->pX; - int realY = y + state->pY; - draw_root_cell(canvas, state->root[c], realY, realX, isHidden); - } - } -} - -#if DRAW_DEBUG -static void draw_generated_root(Canvas* canvas, GameState* state) { - bool isHidden = (state->tick % BLINK_PERIOD) < BLINK_HIDE_FRAMES; - - for(int y = 0; y < ROOT_SIZE_Y; y++) { - for(int x = 0; x < ROOT_SIZE_X; x++) { - int c = ROOT(y, x); - if(!state->filledRootBase[c]) continue; - - int realX = x + 1; - int realY = y + 1; - draw_root_cell(canvas, state->rootBase[c], realY, realX, isHidden); - } - } -} -#endif - -static void draw_ground(Canvas* canvas, GameState* state) { - canvas_draw_line(canvas, 0, GROUND_HEIGHT, FLIPPER_LCD_WIDTH, GROUND_HEIGHT); - UNUSED(state); -} - -static void draw_tree(Canvas* canvas, GameState* state) { - canvas_draw_icon(canvas, FLIPPER_LCD_WIDTH / 2 - 5, GROUND_HEIGHT - TREE_HEIGHT, &I_tree); - UNUSED(state); -} - -static void draw_placement(Canvas* canvas, GameState* state) { - bool canPlace = can_place_root(state); - canvas_draw_icon(canvas, FLIPPER_LCD_WIDTH - 10, 0, canPlace ? &I_place_ok : &I_place_error); -} - -static void draw_rerolls(Canvas* canvas, GameState* state) { - UNUSED(canvas); - UNUSED(state); - - canvas_draw_icon(canvas, 0, 0, &I_root_reroll); - - // Ugh - FuriString* tmp_string = furi_string_alloc(); - furi_string_printf(tmp_string, "%d", MAX(0, state->rerolls)); - canvas_draw_str(canvas, 11, 9, furi_string_get_cstr(tmp_string)); - furi_string_free(tmp_string); -} - -static void draw_score(Canvas* canvas, GameState* state) { - UNUSED(canvas); - UNUSED(state); - - int x = FLIPPER_LCD_WIDTH / 2 + 15; - canvas_draw_icon(canvas, x, 0, &I_score); - - // Ugh - FuriString* tmp_string = furi_string_alloc(); - furi_string_printf(tmp_string, "%d", MAX(0, state->score)); - canvas_draw_str(canvas, x + 11, 9, furi_string_get_cstr(tmp_string)); - furi_string_free(tmp_string); -} - -static void draw_gui(Canvas* canvas, GameState* state) { - draw_ground(canvas, state); - draw_tree(canvas, state); - draw_placement(canvas, state); - draw_rerolls(canvas, state); - draw_score(canvas, state); -} - -static void draw_center_box(Canvas* canvas, int w2, int h2, int margin) { - int x = FLIPPER_LCD_WIDTH / 2 - w2; - int y = FLIPPER_LCD_HEIGHT / 2 - h2; - - canvas_set_color(canvas, ColorWhite); - canvas_draw_box( - canvas, x - margin - 1, y - margin - 1, (w2 + margin + 1) * 2, (h2 + margin + 1) * 2); - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, x - margin, y - margin, (w2 + margin) * 2, (h2 + margin) * 2); -} - -static void draw_start_ui(Canvas* canvas, GameState* state) { - int w2 = 40; - int margin = 3; - int h2 = 10; - draw_center_box(canvas, w2, h2, margin); - - int x = FLIPPER_LCD_WIDTH / 2 - w2; - int y = FLIPPER_LCD_HEIGHT / 2 - h2; - canvas_draw_str(canvas, x + 1, y + 9, " Grow your roots "); - canvas_draw_str(canvas, x + 1, y + 18, "Press [OK] to start"); - - UNUSED(state); -} - -static void draw_end_ui(Canvas* canvas, GameState* state) { - int w2 = 46; - int margin = 3; - int h2 = 15; - draw_center_box(canvas, w2, h2, margin); - - int x = FLIPPER_LCD_WIDTH / 2 - w2; - int y = FLIPPER_LCD_HEIGHT / 2 - h2; - - canvas_draw_str(canvas, x + 1, y + 9, " Game Over "); - - FuriString* tmp_string = furi_string_alloc(); - furi_string_printf(tmp_string, "You've got %d points", MAX(0, state->score)); - canvas_draw_str(canvas, x + 1, y + 19, furi_string_get_cstr(tmp_string)); - furi_string_free(tmp_string); - - canvas_draw_str(canvas, x + 2, y + 29, "Press [OK] to restart"); - - int h = 13, w = 54; - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 0, FLIPPER_LCD_HEIGHT - h, w + 1, h + 1); - canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, 0, FLIPPER_LCD_HEIGHT - h, w, h); - canvas_draw_str(canvas, 2, FLIPPER_LCD_HEIGHT - 3, "by @Xorboo"); - UNUSED(state); -} - -static void roots_draw_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - GameState* state = ctx; - furi_mutex_acquire(state->mutex, FuriWaitForever); - - if(!state->initialDraw) { - state->initialDraw = true; - - canvas_set_font(canvas, FontSecondary); - reset_level(state); - } - - state->tick++; - - draw_gui(canvas, state); - draw_placed_roots(canvas, state); - draw_pickups(canvas, state); - - switch(state->stage) { - case StageStart: - draw_start_ui(canvas, state); - break; - - case StageRun: - draw_active_root(canvas, state); -#if DRAW_DEBUG - draw_generated_root(canvas, state); -#endif - break; - - case StageOver: - draw_end_ui(canvas, state); - break; - } - - furi_mutex_release(state->mutex); -} - -static void roots_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - GameEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void roots_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - GameEvent event = {.type = EventTypeTick}; - furi_message_queue_put(event_queue, &event, 0); -} - -static void ProcessStartInput(GameState* state, InputKey key) { - if(key == InputKeyOk) { - state->stage = StageRun; - } -} - -static void ProcessRunInput(GameState* state, InputKey key) { - switch(key) { - case InputKeyRight: - state->pX = MIN(state->pX + 1, CELLS_X - state->rootSizeX); - break; - case InputKeyLeft: - state->pX = MAX(state->pX - 1, 0); - break; - case InputKeyUp: - state->pY = MAX(state->pY - 1, 0); - break; - case InputKeyDown: - state->pY = MIN(state->pY + 1, CELLS_Y - state->rootSizeY); - break; - case InputKeyOk: { - bool rootPlaced = try_place_root(state); - if(rootPlaced) { - recalculate_score(state); - generate_new_root(state); - } else { - state->rerolls--; - if(state->rerolls >= 0) { - generate_new_root(state); - } else { - state->stage = StageOver; - } - } - break; - } - default: - break; - } -} - -static void ProcessOverInput(GameState* state, InputKey key) { - if(key == InputKeyOk) { - state->stage = StageStart; - reset_level(state); - } -} - -int32_t roots_of_life_game_app(void* p) { - FURI_LOG_D(TAG, "Starting game..."); - - UNUSED(p); - int32_t return_code = 0; - - // Set random seed from interrR_UPts - srand(DWT->CYCCNT); - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(GameEvent)); - - GameState* state = malloc(sizeof(GameState)); - game_state_init(state); - - state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!state->mutex) { - FURI_LOG_E(TAG, "Cannot create mutex\r\n"); - return_code = 255; - goto free_and_exit; - } - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, roots_draw_callback, state); - view_port_input_callback_set(view_port, roots_input_callback, event_queue); - - FuriTimer* timer = - furi_timer_alloc(roots_update_timer_callback, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, furi_kernel_get_tick_frequency() / 22); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - FURI_LOG_D(TAG, "Entering game loop..."); - GameEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // Key events - if(event.type == EventTypeKey) { - //FURI_LOG_D(TAG, "Got key: %d", event.input.key); - if(event.input.type == InputTypePress || event.input.type == InputTypeLong || - event.input.type == InputTypeRepeat) { - if(event.input.key == InputKeyBack) { - processing = false; - } - - switch(state->stage) { - case StageStart: - ProcessStartInput(state, event.input.key); - break; - case StageRun: - ProcessRunInput(state, event.input.key); - break; - case StageOver: - ProcessOverInput(state, event.input.key); - break; - } - } - } - } - - view_port_update(view_port); - furi_mutex_release(state->mutex); - } - - furi_timer_free(timer); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - view_port_free(view_port); - furi_mutex_free(state->mutex); -free_and_exit: - furi_message_queue_free(event_queue); - //FURI_LOG_D(TAG, "Quitting game..."); - game_state_free(state); - free(state); - - return return_code; -} \ No newline at end of file diff --git a/applications/external/scorched_tanks/LICENSE b/applications/external/scorched_tanks/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/scorched_tanks/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/scorched_tanks/application.fam b/applications/external/scorched_tanks/application.fam deleted file mode 100644 index 6256a3c47..000000000 --- a/applications/external/scorched_tanks/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="scorched_tanks", - name="Scorched Tanks", - apptype=FlipperAppType.EXTERNAL, - entry_point="scorched_tanks_game_app", - cdefines=["APP_SCORCHED_TANKS_GAME"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="scorchedTanks_10px.png", - fap_category="Games", - fap_author="@jasniec", - fap_weburl="https://github.com/jasniec/flipper-scorched-tanks-game", - fap_version="1.1", - fap_description="A Flipper Zero game inspired by scorched earth", -) diff --git a/applications/external/scorched_tanks/scorchedTanks_10px.png b/applications/external/scorched_tanks/scorchedTanks_10px.png deleted file mode 100644 index a37b16cd6ab8f2d1b99158d3a51e8b62fd96c0e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536 zcmV+z0_XjSP)}?mh0_0Yam~RI_UWP&La)#baVNw<`9$ zB7gyeFoUSXOg)ia%)oPe-NVP%y9m$nKKJM7Q}QMQd?N82(+!JwgE+cr>74h8L#!kz z#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLjvch?bvs$UK z);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAwsK0iis5M$2|PQjz38*nOtQsax9<<6_Voz z|AXJ%nuV!JHz^ncx?gPjV-)Dw1)6o+{yw(t<_X|`2ClTWzuEw1KS{5*weS(pzYSbm zw>5bWxZDATo^;8O9LY~pC=`JAGy0|+Fn9|D*4*A&`#607GSt=b4RCM>j1?(+-Q(T8 zoxS~grq$mM6zy{8&N2sE00009a7bBm001r{001r{0eGc9b^rhXLPfw;KnA`dRA$0000 -#include -#include -#include -#include -#include -#include - -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 -#define PLAYER_INIT_LOCATION_X 20 -#define PLAYER_INIT_AIM 45 -#define PLAYER_INIT_POWER 50 -#define ENEMY_INIT_LOCATION_X 108 -#define TANK_BARREL_LENGTH 8 -#define GRAVITY_FORCE (double)0.5 -#define MIN_GROUND_HEIGHT 35 -#define MAX_GROUND_HEIGHT 55 -#define MAX_FIRE_POWER 100 -#define MIN_FIRE_POWER 0 -#define TANK_COLLIDER_SIZE 3 -#define MAX_WIND 10 -#define MAX_PLAYER_DIFF_X 20 -#define MAX_ENEMY_DIFF_X 20 - -// That's a filthy workaround but sin(player.aimAngle) breaks it all... If you're able to fix it, please do create a PR! -double scorched_tanks_sin[91] = { - 0.000, -0.017, -0.035, -0.052, -0.070, -0.087, -0.105, -0.122, -0.139, -0.156, -0.174, -0.191, - -0.208, -0.225, -0.242, -0.259, -0.276, -0.292, -0.309, -0.326, -0.342, -0.358, -0.375, -0.391, - -0.407, -0.423, -0.438, -0.454, -0.469, -0.485, -0.500, -0.515, -0.530, -0.545, -0.559, -0.574, - -0.588, -0.602, -0.616, -0.629, -0.643, -0.656, -0.669, -0.682, -0.695, -0.707, -0.719, -0.731, - -0.743, -0.755, -0.766, -0.777, -0.788, -0.799, -0.809, -0.819, -0.829, -0.839, -0.848, -0.857, - -0.866, -0.875, -0.883, -0.891, -0.899, -0.906, -0.914, -0.921, -0.927, -0.934, -0.940, -0.946, - -0.951, -0.956, -0.961, -0.966, -0.970, -0.974, -0.978, -0.982, -0.985, -0.988, -0.990, -0.993, - -0.995, -0.996, -0.998, -0.999, -0.999, -1.000, -1.000}; -double scorched_tanks_cos[91] = { - 1.000, 1.000, 0.999, 0.999, 0.998, 0.996, 0.995, 0.993, 0.990, 0.988, 0.985, 0.982, 0.978, - 0.974, 0.970, 0.966, 0.961, 0.956, 0.951, 0.946, 0.940, 0.934, 0.927, 0.921, 0.914, 0.906, - 0.899, 0.891, 0.883, 0.875, 0.866, 0.857, 0.848, 0.839, 0.829, 0.819, 0.809, 0.799, 0.788, - 0.777, 0.766, 0.755, 0.743, 0.731, 0.719, 0.707, 0.695, 0.682, 0.669, 0.656, 0.643, 0.629, - 0.616, 0.602, 0.588, 0.574, 0.559, 0.545, 0.530, 0.515, 0.500, 0.485, 0.469, 0.454, 0.438, - 0.423, 0.407, 0.391, 0.375, 0.358, 0.342, 0.326, 0.309, 0.292, 0.276, 0.259, 0.242, 0.225, - 0.208, 0.191, 0.174, 0.156, 0.139, 0.122, 0.105, 0.087, 0.070, 0.052, 0.035, 0.017, 0.000}; -double scorched_tanks_tan[91] = { - 0.000, -0.017, -0.035, -0.052, -0.070, -0.087, -0.105, -0.123, -0.141, -0.158, -0.176, - -0.194, -0.213, -0.231, -0.249, -0.268, -0.287, -0.306, -0.325, -0.344, -0.364, -0.384, - -0.404, -0.424, -0.445, -0.466, -0.488, -0.510, -0.532, -0.554, -0.577, -0.601, -0.625, - -0.649, -0.674, -0.700, -0.727, -0.754, -0.781, -0.810, -0.839, -0.869, -0.900, -0.932, - -0.966, -1.000, -1.036, -1.072, -1.111, -1.150, -1.192, -1.235, -1.280, -1.327, -1.376, - -1.428, -1.483, -1.540, -1.600, -1.664, -1.732, -1.804, -1.881, -1.963, -2.050, -2.144, - -2.246, -2.356, -2.475, -2.605, -2.747, -2.904, -3.078, -3.271, -3.487, -3.732, -4.011, - -4.331, -4.704, -5.144, -5.671, -6.313, -7.115, -8.144, -9.513, -11.429, -14.298, -19.077, - -28.627, -57.254, -90747.269}; -uint8_t scorched_tanks_ground_modifiers[SCREEN_WIDTH] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 28, 26, 24, 22, 20, - 18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -typedef struct { - // +-----x - // | - // | - // y - uint8_t x; - uint8_t y; -} Point; - -typedef struct { - // +-----x - // | - // | - // y - double x; - double y; -} PointDetailed; - -typedef struct { - uint8_t locationX; - uint8_t hp; - int aimAngle; - uint8_t firePower; -} Tank; - -typedef struct { - Point ground[SCREEN_WIDTH]; - Tank player; - Tank enemy; - bool isPlayerTurn; - bool isShooting; - int windSpeed; - Point trajectory[SCREEN_WIDTH]; - uint8_t trajectoryAnimationStep; - PointDetailed bulletPosition; - PointDetailed bulletVector; - FuriMutex* mutex; -} Game; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} ScorchedTanksEvent; - -int scorched_tanks_random(int min, int max) { - return min + rand() % ((max + 1) - min); -} - -void scorched_tanks_generate_ground(Game* game_state) { - int lastHeight = 45; - - for(uint8_t a = 0; a < SCREEN_WIDTH; a++) { - int diffHeight = scorched_tanks_random(-2, 3); - int changeLength = scorched_tanks_random(1, 6); - - if(diffHeight == 0) { - changeLength = 1; - } - - for(int b = 0; b < changeLength; b++) { - if(a + b < SCREEN_WIDTH) { - int index = a + b; - int newPoint = lastHeight + diffHeight; - newPoint = newPoint < MIN_GROUND_HEIGHT ? MIN_GROUND_HEIGHT : newPoint; - newPoint = newPoint > MAX_GROUND_HEIGHT ? MAX_GROUND_HEIGHT : newPoint; - game_state->ground[index].x = index; - game_state->ground[index].y = newPoint - scorched_tanks_ground_modifiers[a]; - lastHeight = newPoint; - } else { - a += b; - break; - } - } - - a += changeLength - 1; - } -} - -void scorched_tanks_init_game(Game* game_state) { - game_state->player.locationX = PLAYER_INIT_LOCATION_X + - scorched_tanks_random(0, MAX_PLAYER_DIFF_X) - - MAX_PLAYER_DIFF_X / 2; - game_state->player.aimAngle = PLAYER_INIT_AIM; - game_state->player.firePower = PLAYER_INIT_POWER; - game_state->enemy.aimAngle = PLAYER_INIT_AIM; - game_state->enemy.firePower = PLAYER_INIT_POWER; - game_state->enemy.locationX = - ENEMY_INIT_LOCATION_X + scorched_tanks_random(0, MAX_ENEMY_DIFF_X) - MAX_ENEMY_DIFF_X / 2; - game_state->isPlayerTurn = true; - - game_state->windSpeed = scorched_tanks_random(0, MAX_WIND); - - for(int x = 0; x < SCREEN_WIDTH; x++) { - game_state->trajectory[x].x = 0; - game_state->trajectory[x].y = 0; - } - - scorched_tanks_generate_ground(game_state); -} - -void scorched_tanks_calculate_trajectory(Game* game_state) { - if(game_state->isShooting) { - game_state->bulletVector.x += ((double)game_state->windSpeed - MAX_WIND / 2) / 40; - game_state->bulletVector.y += GRAVITY_FORCE; - - game_state->bulletPosition.x += game_state->bulletVector.x; - game_state->bulletPosition.y += game_state->bulletVector.y; - - int totalDistanceToEnemy = 100; - - if(game_state->isPlayerTurn) { - double distanceToEnemyX = game_state->enemy.locationX - game_state->bulletPosition.x; - double distanceToEnemyY = game_state->ground[game_state->enemy.locationX].y - - TANK_COLLIDER_SIZE - game_state->bulletPosition.y; - totalDistanceToEnemy = - sqrt(distanceToEnemyX * distanceToEnemyX + distanceToEnemyY * distanceToEnemyY); - } else { - double distanceToEnemyX = game_state->player.locationX - game_state->bulletPosition.x; - double distanceToEnemyY = game_state->ground[game_state->player.locationX].y - - TANK_COLLIDER_SIZE - game_state->bulletPosition.y; - totalDistanceToEnemy = - sqrt(distanceToEnemyX * distanceToEnemyX + distanceToEnemyY * distanceToEnemyY); - } - - if(totalDistanceToEnemy <= TANK_COLLIDER_SIZE) { - game_state->isShooting = false; - scorched_tanks_init_game(game_state); - game_state->isPlayerTurn = !game_state->isPlayerTurn; - return; - } - - if(game_state->bulletPosition.x > SCREEN_WIDTH || - game_state->bulletPosition.y > - game_state->ground[(int)round(game_state->bulletPosition.x)].y) { - game_state->isShooting = false; - game_state->bulletPosition.x = 0; - game_state->bulletPosition.y = 0; - game_state->windSpeed = scorched_tanks_random(0, MAX_WIND); - game_state->isPlayerTurn = !game_state->isPlayerTurn; - return; - } - - if(game_state->bulletPosition.y > 0) { - game_state->trajectory[game_state->trajectoryAnimationStep].x = - round(game_state->bulletPosition.x); - game_state->trajectory[game_state->trajectoryAnimationStep].y = - round(game_state->bulletPosition.y); - game_state->trajectoryAnimationStep++; - } - } -} - -static void scorched_tanks_draw_tank(Canvas* const canvas, uint8_t x, uint8_t y, bool isPlayer) { - uint8_t lineIndex = 0; - - if(isPlayer) { - // Draw tank base - canvas_draw_line(canvas, x - 3, y - lineIndex, x + 3, y - lineIndex); - lineIndex++; - canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex); - lineIndex++; - canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex); - lineIndex++; - - // draw turret - canvas_draw_line(canvas, x - 2, y - lineIndex, x + 1, y - lineIndex); - lineIndex++; - canvas_draw_line(canvas, x - 2, y - lineIndex, x, y - lineIndex); - lineIndex++; - } else { - // Draw tank base - canvas_draw_line(canvas, x - 3, y - lineIndex, x + 3, y - lineIndex); - lineIndex++; - canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex); - lineIndex++; - canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex); - lineIndex++; - - // draw turret - canvas_draw_line(canvas, x - 1, y - lineIndex, x + 2, y - lineIndex); - lineIndex++; - canvas_draw_line(canvas, x, y - lineIndex, x + 2, y - lineIndex); - lineIndex++; - } -} - -static void scorched_tanks_render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const Game* game_state = ctx; - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - - canvas_draw_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - - canvas_set_color(canvas, ColorBlack); - - if(game_state->isShooting) { - canvas_draw_dot(canvas, game_state->bulletPosition.x, game_state->bulletPosition.y); - } - - for(int a = 1; a < SCREEN_WIDTH; a++) { - canvas_draw_line( - canvas, - game_state->ground[a - 1].x, - game_state->ground[a - 1].y, - game_state->ground[a].x, - game_state->ground[a].y); - - if(game_state->trajectory[a].y != 0) { - canvas_draw_dot(canvas, game_state->trajectory[a].x, game_state->trajectory[a].y); - } - } - - scorched_tanks_draw_tank( - canvas, - game_state->enemy.locationX, - game_state->ground[game_state->enemy.locationX].y - TANK_COLLIDER_SIZE, - true); - - scorched_tanks_draw_tank( - canvas, - game_state->player.locationX, - game_state->ground[game_state->player.locationX].y - TANK_COLLIDER_SIZE, - false); - - int aimX1 = 0; - int aimY1 = 0; - int aimX2 = 0; - int aimY2 = 0; - - if(game_state->isPlayerTurn) { - aimX1 = game_state->player.locationX; - aimY1 = game_state->ground[game_state->player.locationX].y - TANK_COLLIDER_SIZE; - - double sinFromAngle = scorched_tanks_sin[game_state->player.aimAngle]; - double cosFromAngle = scorched_tanks_cos[game_state->player.aimAngle]; - aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; - aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; - - aimX1 += 1; - aimX2 += 1; - } else { - aimX1 = game_state->enemy.locationX; - aimY1 = game_state->ground[game_state->enemy.locationX].y - TANK_COLLIDER_SIZE; - - double sinFromAngle = scorched_tanks_sin[game_state->enemy.aimAngle]; - double cosFromAngle = scorched_tanks_cos[game_state->enemy.aimAngle]; - aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; - aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; - - aimX2 = aimX1 - (aimX2 - aimX1); - - aimX1 -= 1; - aimX2 -= 1; - } - - canvas_draw_line(canvas, aimX1, aimY1 - 3, aimX2, aimY2 - 3); - - canvas_set_font(canvas, FontSecondary); - - char buffer2[18]; - snprintf(buffer2, sizeof(buffer2), "wind: %i", game_state->windSpeed - MAX_WIND / 2); - canvas_draw_str(canvas, 55, 10, buffer2); - - if(game_state->isPlayerTurn) { - canvas_draw_str(canvas, 93, 10, "player1"); - - char buffer[12]; - snprintf(buffer, sizeof(buffer), "a: %u", game_state->player.aimAngle); - canvas_draw_str(canvas, 2, 10, buffer); - - snprintf(buffer, sizeof(buffer), "p: %u", game_state->player.firePower); - canvas_draw_str(canvas, 27, 10, buffer); - } else { - canvas_draw_str(canvas, 93, 10, "player2"); - - char buffer[12]; - snprintf(buffer, sizeof(buffer), "a: %u", game_state->enemy.aimAngle); - canvas_draw_str(canvas, 2, 10, buffer); - - snprintf(buffer, sizeof(buffer), "p: %u", game_state->enemy.firePower); - canvas_draw_str(canvas, 27, 10, buffer); - } - - furi_mutex_release(game_state->mutex); -} - -static void scorched_tanks_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - ScorchedTanksEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void scorched_tanks_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - ScorchedTanksEvent event = {.type = EventTypeTick}; - furi_message_queue_put(event_queue, &event, 0); -} - -static void scorched_tanks_increase_power(Game* game_state) { - if(game_state->player.firePower < MAX_FIRE_POWER && !game_state->isShooting) { - if(game_state->isPlayerTurn && game_state->player.firePower < MAX_FIRE_POWER) { - game_state->player.firePower++; - } - - if(!game_state->isPlayerTurn && game_state->enemy.firePower < MAX_FIRE_POWER) { - game_state->enemy.firePower++; - } - } -} - -static void scorched_tanks_decrease_power(Game* game_state) { - if(game_state->player.firePower > MIN_FIRE_POWER && !game_state->isShooting) { - if(game_state->isPlayerTurn && game_state->player.firePower > MIN_FIRE_POWER) { - game_state->player.firePower--; - } - - if(!game_state->isPlayerTurn && game_state->enemy.firePower > MIN_FIRE_POWER) { - game_state->enemy.firePower--; - } - } -} - -static void scorched_tanks_aim_up(Game* game_state) { - if(!game_state->isShooting) { - if(game_state->isPlayerTurn && game_state->player.aimAngle < 90) { - game_state->player.aimAngle++; - } - - if(!game_state->isPlayerTurn && game_state->enemy.aimAngle < 90) { - game_state->enemy.aimAngle++; - } - } -} - -static void scorched_tanks_aim_down(Game* game_state) { - if(game_state->player.aimAngle > 0 && !game_state->isShooting) { - if(game_state->isPlayerTurn) { - game_state->player.aimAngle--; - } else { - game_state->enemy.aimAngle--; - } - } -} - -const NotificationSequence sequence_long_vibro = { - &message_vibro_on, - &message_delay_500, - &message_vibro_off, - NULL, -}; - -static void scorched_tanks_fire(Game* game_state) { - if(!game_state->isShooting) { - if(game_state->isPlayerTurn) { - double sinFromAngle = scorched_tanks_sin[game_state->player.aimAngle]; - double cosFromAngle = scorched_tanks_cos[game_state->player.aimAngle]; - uint8_t aimX1 = game_state->player.locationX; - uint8_t aimY1 = - game_state->ground[game_state->player.locationX].y - TANK_COLLIDER_SIZE; - int aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; - int aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; - game_state->bulletPosition.x = aimX2; - game_state->bulletPosition.y = aimY2; - game_state->bulletVector.x = scorched_tanks_cos[game_state->player.aimAngle] * - ((double)game_state->player.firePower / 10); - game_state->bulletVector.y = scorched_tanks_sin[game_state->player.aimAngle] * - ((double)game_state->player.firePower / 10); - } else { - double sinFromAngle = scorched_tanks_sin[game_state->enemy.aimAngle]; - double cosFromAngle = scorched_tanks_cos[game_state->enemy.aimAngle]; - uint8_t aimX1 = game_state->enemy.locationX; - uint8_t aimY1 = game_state->ground[game_state->enemy.locationX].y - TANK_COLLIDER_SIZE; - int aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; - int aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; - aimX2 = aimX1 - (aimX2 - aimX1); - - game_state->bulletPosition.x = aimX2; - game_state->bulletPosition.y = aimY2; - game_state->bulletVector.x = -scorched_tanks_cos[game_state->enemy.aimAngle] * - ((double)game_state->enemy.firePower / 10); - game_state->bulletVector.y = scorched_tanks_sin[game_state->enemy.aimAngle] * - ((double)game_state->enemy.firePower / 10); - } - - game_state->trajectoryAnimationStep = 0; - - for(int x = 0; x < SCREEN_WIDTH; x++) { - game_state->trajectory[x].x = 0; - game_state->trajectory[x].y = 0; - } - - game_state->isShooting = true; - - NotificationApp* notification = furi_record_open("notification"); - notification_message(notification, &sequence_long_vibro); - notification_message(notification, &sequence_blink_white_100); - furi_record_close("notification"); - } -} - -int32_t scorched_tanks_game_app(void* p) { - UNUSED(p); - srand(DWT->CYCCNT); - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(ScorchedTanksEvent)); - - Game* game_state = malloc(sizeof(Game)); - scorched_tanks_init_game(game_state); - - game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!game_state->mutex) { - FURI_LOG_E("ScorchedTanks", "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); - free(game_state); - return 255; - } - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, scorched_tanks_render_callback, game_state); - view_port_input_callback_set(view_port, scorched_tanks_input_callback, event_queue); - - FuriTimer* timer = - furi_timer_alloc(scorched_tanks_update_timer_callback, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, 2000); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - ScorchedTanksEvent event; - for(bool processing = true; processing;) { - furi_message_queue_get(event_queue, &event, 50); - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - - if(event.type == EventTypeKey) { // && game->isPlayerTurn - if(event.input.type == InputTypeRepeat || event.input.type == InputTypeShort) { - switch(event.input.key) { - case InputKeyUp: - scorched_tanks_aim_up(game_state); - break; - case InputKeyDown: - scorched_tanks_aim_down(game_state); - break; - case InputKeyRight: - scorched_tanks_increase_power(game_state); - break; - case InputKeyLeft: - scorched_tanks_decrease_power(game_state); - break; - case InputKeyOk: - scorched_tanks_fire(game_state); - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } - } else if(event.type == EventTypeTick) { - scorched_tanks_calculate_trajectory(game_state); - } - - view_port_update(view_port); - furi_mutex_release(game_state->mutex); - } - - furi_timer_free(timer); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(game_state->mutex); - free(game_state); - - return 0; -} diff --git a/applications/external/signal_generator/application.fam b/applications/external/signal_generator/application.fam deleted file mode 100644 index 4a5877a7c..000000000 --- a/applications/external/signal_generator/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="signal_generator", - name="[GPIO] Signal Generator", - apptype=FlipperAppType.EXTERNAL, - entry_point="signal_gen_app", - requires=["gui"], - stack_size=1 * 1024, - fap_description="Control GPIO pins to generate digital signals", - fap_version="1.0", - fap_icon="signal_gen_10px.png", - fap_category="GPIO", - fap_icon_assets="icons", -) diff --git a/applications/external/signal_generator/scenes/signal_gen_scene.c b/applications/external/signal_generator/scenes/signal_gen_scene.c deleted file mode 100644 index 29b11ee3f..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../signal_gen_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const signal_gen_scene_on_enter_handlers[])(void*) = { -#include "signal_gen_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const signal_gen_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "signal_gen_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const signal_gen_scene_on_exit_handlers[])(void* context) = { -#include "signal_gen_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers signal_gen_scene_handlers = { - .on_enter_handlers = signal_gen_scene_on_enter_handlers, - .on_event_handlers = signal_gen_scene_on_event_handlers, - .on_exit_handlers = signal_gen_scene_on_exit_handlers, - .scene_num = SignalGenSceneNum, -}; diff --git a/applications/external/signal_generator/scenes/signal_gen_scene.h b/applications/external/signal_generator/scenes/signal_gen_scene.h deleted file mode 100644 index c139afa3b..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) SignalGenScene##id, -typedef enum { -#include "signal_gen_scene_config.h" - SignalGenSceneNum, -} SignalGenScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers signal_gen_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "signal_gen_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "signal_gen_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "signal_gen_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_config.h b/applications/external/signal_generator/scenes/signal_gen_scene_config.h deleted file mode 100644 index b6c750256..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_config.h +++ /dev/null @@ -1,3 +0,0 @@ -ADD_SCENE(signal_gen, start, Start) -ADD_SCENE(signal_gen, pwm, Pwm) -ADD_SCENE(signal_gen, mco, Mco) diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_mco.c b/applications/external/signal_generator/scenes/signal_gen_scene_mco.c deleted file mode 100644 index 0855cde0a..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_mco.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "../signal_gen_app_i.h" - -typedef enum { - LineIndexPin, - LineIndexSource, - LineIndexDivision, -} LineIndex; - -static const char* const mco_pin_names[] = { - "13(Tx)", -}; - -static const char* const mco_source_names[] = { - "32768Hz", - "64MHz", - "~100K", - "~200K", - "~400K", - "~800K", - "~1MHz", - "~2MHz", - "~4MHz", - "~8MHz", - "~16MHz", - "~24MHz", - "~32MHz", - "~48MHz", -}; - -static const FuriHalClockMcoSourceId mco_sources[] = { - FuriHalClockMcoLse, - FuriHalClockMcoSysclk, - FuriHalClockMcoMsi100k, - FuriHalClockMcoMsi200k, - FuriHalClockMcoMsi400k, - FuriHalClockMcoMsi800k, - FuriHalClockMcoMsi1m, - FuriHalClockMcoMsi2m, - FuriHalClockMcoMsi4m, - FuriHalClockMcoMsi8m, - FuriHalClockMcoMsi16m, - FuriHalClockMcoMsi24m, - FuriHalClockMcoMsi32m, - FuriHalClockMcoMsi48m, -}; - -static const char* const mco_divisor_names[] = { - "1", - "2", - "4", - "8", - "16", -}; - -static const FuriHalClockMcoDivisorId mco_divisors[] = { - FuriHalClockMcoDiv1, - FuriHalClockMcoDiv2, - FuriHalClockMcoDiv4, - FuriHalClockMcoDiv8, - FuriHalClockMcoDiv16, -}; - -static void mco_source_list_change_callback(VariableItem* item) { - SignalGenApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, mco_source_names[index]); - - app->mco_src = mco_sources[index]; - - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); -} - -static void mco_divisor_list_change_callback(VariableItem* item) { - SignalGenApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, mco_divisor_names[index]); - - app->mco_div = mco_divisors[index]; - - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); -} - -void signal_gen_scene_mco_on_enter(void* context) { - SignalGenApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - - VariableItem* item; - - item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL); - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, mco_pin_names[0]); - - item = variable_item_list_add( - var_item_list, - "Frequency", - COUNT_OF(mco_source_names), - mco_source_list_change_callback, - app); - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, mco_source_names[0]); - - item = variable_item_list_add( - var_item_list, - "Freq. divider", - COUNT_OF(mco_divisor_names), - mco_divisor_list_change_callback, - app); - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, mco_divisor_names[0]); - - variable_item_list_set_selected_item(var_item_list, LineIndexSource); - - view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewVarItemList); - - app->mco_src = FuriHalClockMcoLse; - app->mco_div = FuriHalClockMcoDiv1; - furi_hal_clock_mco_enable(app->mco_src, app->mco_div); - furi_hal_gpio_init_ex( - &gpio_usart_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn0MCO); -} - -bool signal_gen_scene_mco_on_event(void* context, SceneManagerEvent event) { - SignalGenApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SignalGenMcoEventUpdate) { - consumed = true; - furi_hal_clock_mco_enable(app->mco_src, app->mco_div); - } - } - return consumed; -} - -void signal_gen_scene_mco_on_exit(void* context) { - SignalGenApp* app = context; - variable_item_list_reset(app->var_item_list); - furi_hal_gpio_init_ex( - &gpio_usart_tx, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn7USART1); - furi_hal_clock_mco_disable(); -} diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c b/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c deleted file mode 100644 index 1cadb3a1a..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "../signal_gen_app_i.h" - -static const FuriHalPwmOutputId pwm_ch_id[] = { - FuriHalPwmOutputIdTim1PA7, - FuriHalPwmOutputIdLptim2PA4, -}; - -#define DEFAULT_FREQ 1000 -#define DEFAULT_DUTY 50 - -static void - signal_gen_pwm_callback(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context) { - SignalGenApp* app = context; - - app->pwm_freq = freq; - app->pwm_duty = duty; - - if(app->pwm_ch != pwm_ch_id[channel_id]) { //-V1051 - app->pwm_ch_prev = app->pwm_ch; - app->pwm_ch = pwm_ch_id[channel_id]; - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventChannelChange); - } else { - app->pwm_ch = pwm_ch_id[channel_id]; //-V1048 - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventUpdate); - } -} - -void signal_gen_scene_pwm_on_enter(void* context) { - SignalGenApp* app = context; - - view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewPwm); - - signal_gen_pwm_set_callback(app->pwm_view, signal_gen_pwm_callback, app); - - signal_gen_pwm_set_params(app->pwm_view, 0, DEFAULT_FREQ, DEFAULT_DUTY); - - if(!furi_hal_pwm_is_running(pwm_ch_id[0])) { - furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); - } else { - furi_hal_pwm_stop(pwm_ch_id[0]); - furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); - } -} - -bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { - SignalGenApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SignalGenPwmEventUpdate) { - consumed = true; - furi_hal_pwm_set_params(app->pwm_ch, app->pwm_freq, app->pwm_duty); - } else if(event.event == SignalGenPwmEventChannelChange) { - consumed = true; - // Stop previous channel PWM - if(furi_hal_pwm_is_running(app->pwm_ch_prev)) { - furi_hal_pwm_stop(app->pwm_ch_prev); - } - - // Start PWM and restart if it was starter already - if(furi_hal_pwm_is_running(app->pwm_ch)) { - furi_hal_pwm_stop(app->pwm_ch); - furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); - } else { - furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); - } - } - } - return consumed; -} - -void signal_gen_scene_pwm_on_exit(void* context) { - SignalGenApp* app = context; - variable_item_list_reset(app->var_item_list); - - if(furi_hal_pwm_is_running(app->pwm_ch)) { - furi_hal_pwm_stop(app->pwm_ch); - } -} diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_start.c b/applications/external/signal_generator/scenes/signal_gen_scene_start.c deleted file mode 100644 index 3c7b9cc32..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_start.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "../signal_gen_app_i.h" - -typedef enum { - SubmenuIndexPwm, - SubmenuIndexClockOutput, -} SubmenuIndex; - -void signal_gen_scene_start_submenu_callback(void* context, uint32_t index) { - SignalGenApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void signal_gen_scene_start_on_enter(void* context) { - SignalGenApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); - submenu_add_item( - submenu, - "Clock Generator", - SubmenuIndexClockOutput, - signal_gen_scene_start_submenu_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, SignalGenSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewSubmenu); -} - -bool signal_gen_scene_start_on_event(void* context, SceneManagerEvent event) { - SignalGenApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexPwm) { - scene_manager_next_scene(app->scene_manager, SignalGenScenePwm); - consumed = true; - } else if(event.event == SubmenuIndexClockOutput) { - scene_manager_next_scene(app->scene_manager, SignalGenSceneMco); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, SignalGenSceneStart, event.event); - } - - return consumed; -} - -void signal_gen_scene_start_on_exit(void* context) { - SignalGenApp* app = context; - - submenu_reset(app->submenu); -} diff --git a/applications/external/signal_generator/signal_gen_10px.png b/applications/external/signal_generator/signal_gen_10px.png deleted file mode 100644 index 9f6dcc5d0d9a9c1fbc54b7459b46c50c16c7e863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6082 zcmeHKcTiK?)(=H`Q&6fHBZ{aY4MGygMWibMM0!yU$q58VF$pA85d={Xy<8FL0s>M6 z5%JoPD<~ogTpJ=FRzRgH*x@_Da`k&}=8ZG&{by!!&fcs1_FBKa_L_b6I6K-Z%4x~L zU@%2{J1ZCHEgH*-NkGrWkAAZ-n2chit0&(D5WqQHHk}a)!ubDp3%bQnz7JL>Hd z{+Oin@yZ&yZ1hfe=A|K`K)U{;!GUzuwPUXv@|yN6PB~$<;ZyW_a@s2C&xh3}JyGL$*zs+)7Y5Zs;95jL_9?e)5}zAdt=0pGrM)qodxPbdP23TyBFDvE%D1sL|4X6zO?BaK$j(n zE9A0Hi5m{x>WM4t7}4#I$8Oii$lTdE`hN3PvIec;M3P++@M6j4d$Ba}rsSF7wjhCm z_sDM8VHr!@MNeg^i&{m0*@UzZ>y{)rz>mSsylQqs`)Bz{+o`J%2Uii7YBj?17#>%Y z%4COr@3<(r;(}x!d~ChDjKbXS2L>$@$KT;eZVbP-g27Gm;V1A)g$JKk952M)_ADvQ4q=Eo z+du1)>Jeo!l_R?{a4OGMd!h|Dis|$k1g^TLl8Y_N&3dV__$4eoqn?$4L2D$1rFNO0 zUeT!O_H5wMKE1xlXIsIvgJ<-!KD6Ioap#PqB@=V1*m+;DS&?$g-c4^W`A#>KnEMG& z#ke^$!<9NGvd~D~Whw~8JJO$8(_8{~wVqJMU95;T(z}z}YD$~!3$`daX(9DWMNcO$ zyi#Ger5RNo&Z!TGyHoEQzwTZ}T&-2ncyZ&y-D;H$cTx_e}9>)ypAMAQ6Pv{`%pHm!* zlTwk_i8@txU68}^2f;Hb4T^5 zo%@q*o3=(LE>{VO@Iqv#A3`iY)qcrISEfr#a^{-Y{*~AA6*axD_wlL}8TQM19#EER zM9w&L1vVR8bBX%{qjzyaTBG2ZltjGRUe(0(z0VJJ(ri0>9-891aN%gs!MrN-N${}n zy#x}3zYv7$H3WQ0-*}DcY1lT^QLZK17s@V)*tK)K;cWItAg%KbAymxVg(pcB#4>be z?6jS@zDW+g&L&QN-C0SpE$hI&VmC_QEsqv4f@*`8)EcE%Pf`Z-852?W20HJ5P|nga zTJr~-pK`7(YRR&GiRh)DA2ER!11Gu#QqjrB?ep<+xm7J$acas24QNG&xbuyy4Xux? z9bPQ5VR$Ou@=n^rS({Tkpb_I5hTOS---Z6xy5`~pT{p|rDniQss?K;jL`^tsKPiKr zIngIRaW$iM5nA^=n%s$0ocLXBx%`g$^oO-o;$AG!r6oQov*!4mpJ{!X1LLLM{$}+; zl9|n4gEbGNb{uJUQ;l@Xs9g2BVvPr7*v+jbyQ{Lo*SOHb?a$y1$1AwEcWrfh+WYtS zvZ?hAcU>XvxXq_>+4I`dWvgDZZWUyAo!z|S{|V<(hIia(8ty-4Zd@oRp4}Ndp4dJv z`Oeg0*6~1->Jwi$dhb%nuwA++Atz@~1y&&PqfcGSR!Gnc}O3&Np?sN#e zUKM6W6RsBcCa^Blh4oHdmrp9NkR2V-_?P zGW|&{gpEP^Cly1Ri$;CbJs)_#bl)j$?!8m6b?wBhHNsbg9nVjntXe5-!L&K9Jeghp z>V{Rw7O8-&(|Y?;I$k$EfA#LYe3p%0!=34wO{J@r=GVD9atc=P~A zzEmuS);2nQS0cxkvf;7qxnuC#v&rgviVG$YpPUXYn=E>Ipul0~@>#`==996DC(2*! zc>Ylto;nd#HF#DB1{2%Gu(Wixx3v6vF@UZExiPHny}ngj*{#6{$+7pd~HnhcIjH?cb&ykCJ>Fss7k& zc4$_oKlnz#`t^GGKoUdsxT+JgS86Eck<8lmHIu~2WA^HLu}{uCn$#YOzh;rIiMd%$ zd?Zun83dFhdUfAQ*56ZHQMx4-{kX0@BBkEFqV_WRoqS^Mg>x-o*$H<3VkrmU8!Q%R zuWq(Ub%CM&~4Uv2*_^sv$Ej zK3(xRdYP%?CrKHygh%AfZ8c&y3yyl^c)ykzz9(f^laqZy+II{V9 z4eovEx~?dBes$z|%*=%xfEohw;Q?SEgGEM+pKU_G88kA&!NN{tMm5@`tY-{j1MBnW^B@&UMz8Oq|3gk;1#E(sco#3%%O-h>}Q zMtD-3;g)PJ2sbh`GDIV-g^X}4;x{?C8J9*UxmekJfq-UYL=d0PA)!zLfxu9JGh}lE zQ5YhTh(cpgSS%8^eCu!ss;EXc9oA(P;rDNE!wJ zkVXK2LjpuJ7Kx^tfOG(3VuB}7zk{-8@%R9X3W}g0a6<-!6M)45bQ%^7K|qd1cnAyt z@pz;$9b^^V?=IRF5|j)?EFh{= z2w+|g0k?mieV&Fg=8qB_K7S}k z0QGYUJRlsT&BqC0eO6I}09GIfb&oIQ`c=;OH>E%&V2!Cp7%UQp!y6-wa8wL3fKCWN zLYx9P0)|ecVevnr^VoF00N{cafe?=nS5SG*a|K^LzflH1S_^_e(JnxQA<;zSzY>P} zk}yitGrneQhWZyy%;pWgYci1EXBpJIpk9dj)(pRJCTctX!{3*^_#dtSLH}Chr}+Iv z*Dtz$ih-Xp{#9MS==v!Je#-b)b^X`qlKba#3S>dIAOZBTG?n(K5BkuOa&~aFo|~J4 zhHih|jD=oe0h?^CV95)X+CdXpj-3||29sA6{l#F}xf+mAnr~0BmVPFyt)Qnu-8CEz vi5A;iS-8sFrTY8(*9Q7Kx2#uIhJi56XX0g^pLAD41~7YTN2{6*{_+0@Ugv#> diff --git a/applications/external/signal_generator/signal_gen_app.c b/applications/external/signal_generator/signal_gen_app.c deleted file mode 100644 index ca065d330..000000000 --- a/applications/external/signal_generator/signal_gen_app.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "signal_gen_app_i.h" - -#include -#include - -static bool signal_gen_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - SignalGenApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool signal_gen_app_back_event_callback(void* context) { - furi_assert(context); - SignalGenApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void signal_gen_app_tick_event_callback(void* context) { - furi_assert(context); - SignalGenApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -SignalGenApp* signal_gen_app_alloc() { - SignalGenApp* app = malloc(sizeof(SignalGenApp)); - - app->gui = furi_record_open(RECORD_GUI); - - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&signal_gen_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, signal_gen_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, signal_gen_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, signal_gen_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->var_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - SignalGenViewVarItemList, - variable_item_list_get_view(app->var_item_list)); - - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SignalGenViewSubmenu, submenu_get_view(app->submenu)); - - app->pwm_view = signal_gen_pwm_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SignalGenViewPwm, signal_gen_pwm_get_view(app->pwm_view)); - - scene_manager_next_scene(app->scene_manager, SignalGenSceneStart); - - return app; -} - -void signal_gen_app_free(SignalGenApp* app) { - furi_assert(app); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewVarItemList); - view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewSubmenu); - view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewPwm); - - submenu_free(app->submenu); - variable_item_list_free(app->var_item_list); - signal_gen_pwm_free(app->pwm_view); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Close records - furi_record_close(RECORD_GUI); - - free(app); -} - -int32_t signal_gen_app(void* p) { - UNUSED(p); - SignalGenApp* signal_gen_app = signal_gen_app_alloc(); - - view_dispatcher_run(signal_gen_app->view_dispatcher); - - signal_gen_app_free(signal_gen_app); - - return 0; -} diff --git a/applications/external/signal_generator/signal_gen_app_i.h b/applications/external/signal_generator/signal_gen_app_i.h deleted file mode 100644 index 60e4d7ed9..000000000 --- a/applications/external/signal_generator/signal_gen_app_i.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "scenes/signal_gen_scene.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include "views/signal_gen_pwm.h" - -typedef struct SignalGenApp SignalGenApp; - -struct SignalGenApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - - VariableItemList* var_item_list; - Submenu* submenu; - SignalGenPwm* pwm_view; - - FuriHalClockMcoSourceId mco_src; - FuriHalClockMcoDivisorId mco_div; - - FuriHalPwmOutputId pwm_ch_prev; - FuriHalPwmOutputId pwm_ch; - uint32_t pwm_freq; - uint8_t pwm_duty; -}; - -typedef enum { - SignalGenViewVarItemList, - SignalGenViewSubmenu, - SignalGenViewPwm, -} SignalGenAppView; - -typedef enum { - SignalGenMcoEventUpdate, - SignalGenPwmEventUpdate, - SignalGenPwmEventChannelChange, -} SignalGenCustomEvent; diff --git a/applications/external/signal_generator/views/signal_gen_pwm.c b/applications/external/signal_generator/views/signal_gen_pwm.c deleted file mode 100644 index 63669a937..000000000 --- a/applications/external/signal_generator/views/signal_gen_pwm.c +++ /dev/null @@ -1,311 +0,0 @@ -#include "../signal_gen_app_i.h" -#include -#include -#include "signal_generator_icons.h" -#include - -typedef enum { - LineIndexChannel, - LineIndexFrequency, - LineIndexDuty, - LineIndexTotalCount -} LineIndex; - -static const char* const pwm_ch_names[] = {"2(A7)", "4(A4)"}; - -struct SignalGenPwm { - View* view; - SignalGenPwmViewCallback callback; - void* context; -}; - -typedef struct { - LineIndex line_sel; - bool edit_mode; - uint8_t edit_digit; - - uint8_t channel_id; - uint32_t freq; - uint8_t duty; - -} SignalGenPwmViewModel; - -#define ITEM_H 64 / 3 -#define ITEM_W 128 - -#define VALUE_X 100 -#define VALUE_W 45 - -#define FREQ_VALUE_X 62 -#define FREQ_MAX 1000000UL -#define FREQ_DIGITS_NB 7 - -static void pwm_set_config(SignalGenPwm* pwm) { - FuriHalPwmOutputId channel; - uint32_t freq; - uint8_t duty; - - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - channel = model->channel_id; - freq = model->freq; - duty = model->duty; - }, - false); - - furi_assert(pwm->callback); - pwm->callback(channel, freq, duty, pwm->context); -} - -static void pwm_channel_change(SignalGenPwmViewModel* model, InputEvent* event) { - if(event->key == InputKeyLeft) { - if(model->channel_id > 0) { - model->channel_id--; - } - } else if(event->key == InputKeyRight) { - if(model->channel_id < (COUNT_OF(pwm_ch_names) - 1)) { - model->channel_id++; - } - } -} - -static void pwm_duty_change(SignalGenPwmViewModel* model, InputEvent* event) { - if(event->key == InputKeyLeft) { - if(model->duty > 0) { - model->duty--; - } - } else if(event->key == InputKeyRight) { - if(model->duty < 100) { - model->duty++; - } - } -} - -static bool pwm_freq_edit(SignalGenPwmViewModel* model, InputEvent* event) { - bool consumed = false; - if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { - if(event->key == InputKeyRight) { - if(model->edit_digit > 0) { - model->edit_digit--; - } - consumed = true; - } else if(event->key == InputKeyLeft) { - if(model->edit_digit < (FREQ_DIGITS_NB - 1)) { - model->edit_digit++; - } - consumed = true; - } else if(event->key == InputKeyUp) { - uint32_t step = 1; - for(uint8_t i = 0; i < model->edit_digit; i++) { - step *= 10; - } - if((model->freq + step) < FREQ_MAX) { - model->freq += step; - } else { - model->freq = FREQ_MAX; - } - consumed = true; - } else if(event->key == InputKeyDown) { - uint32_t step = 1; - for(uint8_t i = 0; i < model->edit_digit; i++) { - step *= 10; - } - if(model->freq > (step + 1)) { - model->freq -= step; - } else { - model->freq = 1; - } - consumed = true; - } - } - return consumed; -} - -static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { - SignalGenPwmViewModel* model = _model; - char* line_label = NULL; - char val_text[16]; - - for(size_t line = 0; line < LineIndexTotalCount; line++) { - if(line == LineIndexChannel) { - line_label = "GPIO Pin"; - } else if(line == LineIndexFrequency) { - line_label = "Frequency"; - } else if(line == LineIndexDuty) { //-V547 - line_label = "Pulse width"; - } - - canvas_set_color(canvas, ColorBlack); - if(line == model->line_sel) { - elements_slightly_rounded_box(canvas, 0, ITEM_H * line + 1, ITEM_W, ITEM_H - 1); - canvas_set_color(canvas, ColorWhite); - } - - uint8_t text_y = ITEM_H * line + ITEM_H / 2 + 2; - - canvas_draw_str_aligned(canvas, 6, text_y, AlignLeft, AlignCenter, line_label); - - if(line == LineIndexChannel) { - snprintf(val_text, sizeof(val_text), "%s", pwm_ch_names[model->channel_id]); - canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); - if(model->channel_id != 0) { - canvas_draw_str_aligned( - canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); - } - if(model->channel_id != (COUNT_OF(pwm_ch_names) - 1)) { - canvas_draw_str_aligned( - canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); - } - } else if(line == LineIndexFrequency) { - snprintf(val_text, sizeof(val_text), "%7lu Hz", model->freq); - canvas_set_font(canvas, FontKeyboard); - canvas_draw_str_aligned( - canvas, FREQ_VALUE_X, text_y, AlignLeft, AlignCenter, val_text); - canvas_set_font(canvas, FontSecondary); - - if(model->edit_mode) { - uint8_t icon_x = (FREQ_VALUE_X) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; - canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_3x5); - canvas_draw_icon(canvas, icon_x, text_y + 5, &I_SmallArrowDown_3x5); - } - } else if(line == LineIndexDuty) { //-V547 - snprintf(val_text, sizeof(val_text), "%d%%", model->duty); - canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); - if(model->duty != 0) { - canvas_draw_str_aligned( - canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); - } - if(model->duty != 100) { - canvas_draw_str_aligned( - canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); - } - } - } -} - -static bool signal_gen_pwm_input_callback(InputEvent* event, void* context) { - furi_assert(context); - SignalGenPwm* pwm = context; - bool consumed = false; - bool need_update = false; - - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - if(model->edit_mode == false) { - if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { - if(event->key == InputKeyUp) { - if(model->line_sel == 0) { - model->line_sel = LineIndexTotalCount - 1; - } else { - model->line_sel = - CLAMP(model->line_sel - 1, LineIndexTotalCount - 1, 0); - } - consumed = true; - } else if(event->key == InputKeyDown) { - if(model->line_sel == LineIndexTotalCount - 1) { - model->line_sel = 0; - } else { - model->line_sel = - CLAMP(model->line_sel + 1, LineIndexTotalCount - 1, 0); - } - consumed = true; - } else if((event->key == InputKeyLeft) || (event->key == InputKeyRight)) { - if(model->line_sel == LineIndexChannel) { - pwm_channel_change(model, event); - need_update = true; - } else if(model->line_sel == LineIndexDuty) { - pwm_duty_change(model, event); - need_update = true; - } else if(model->line_sel == LineIndexFrequency) { - model->edit_mode = true; - } - consumed = true; - } else if(event->key == InputKeyOk) { - if(model->line_sel == LineIndexFrequency) { - model->edit_mode = true; - } - consumed = true; - } - } - } else { - if((event->key == InputKeyOk) || (event->key == InputKeyBack)) { - if(event->type == InputTypeShort) { - model->edit_mode = false; - consumed = true; - } - } else { - if(model->line_sel == LineIndexFrequency) { - consumed = pwm_freq_edit(model, event); - need_update = consumed; - } - } - } - }, - true); - - if(need_update) { - pwm_set_config(pwm); - } - - return consumed; -} - -SignalGenPwm* signal_gen_pwm_alloc() { - SignalGenPwm* pwm = malloc(sizeof(SignalGenPwm)); - - pwm->view = view_alloc(); - view_allocate_model(pwm->view, ViewModelTypeLocking, sizeof(SignalGenPwmViewModel)); - view_set_context(pwm->view, pwm); - view_set_draw_callback(pwm->view, signal_gen_pwm_draw_callback); - view_set_input_callback(pwm->view, signal_gen_pwm_input_callback); - - return pwm; -} - -void signal_gen_pwm_free(SignalGenPwm* pwm) { - furi_assert(pwm); - view_free(pwm->view); - free(pwm); -} - -View* signal_gen_pwm_get_view(SignalGenPwm* pwm) { - furi_assert(pwm); - return pwm->view; -} - -void signal_gen_pwm_set_callback( - SignalGenPwm* pwm, - SignalGenPwmViewCallback callback, - void* context) { - furi_assert(pwm); - furi_assert(callback); - - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - UNUSED(model); - pwm->callback = callback; - pwm->context = context; - }, - false); -} - -void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty) { - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - model->channel_id = channel_id; - model->freq = freq; - model->duty = duty; - }, - true); - - furi_assert(pwm->callback); - pwm->callback(channel_id, freq, duty, pwm->context); -} diff --git a/applications/external/signal_generator/views/signal_gen_pwm.h b/applications/external/signal_generator/views/signal_gen_pwm.h deleted file mode 100644 index 986794e7a..000000000 --- a/applications/external/signal_generator/views/signal_gen_pwm.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include "../signal_gen_app_i.h" - -typedef struct SignalGenPwm SignalGenPwm; -typedef void ( - *SignalGenPwmViewCallback)(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context); - -SignalGenPwm* signal_gen_pwm_alloc(); - -void signal_gen_pwm_free(SignalGenPwm* pwm); - -View* signal_gen_pwm_get_view(SignalGenPwm* pwm); - -void signal_gen_pwm_set_callback( - SignalGenPwm* pwm, - SignalGenPwmViewCallback callback, - void* context); - -void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty); diff --git a/applications/external/simonsays/LICENSE b/applications/external/simonsays/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/simonsays/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/simonsays/application.fam b/applications/external/simonsays/application.fam deleted file mode 100644 index d8df4793f..000000000 --- a/applications/external/simonsays/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="simon_says", # Must be unique - name="Simon Says", # Displayed in UI - apptype=FlipperAppType.EXTERNAL, - entry_point="simon_says_app_entry", - stack_size=2 * 1024, - fap_category="Games", - # Optional values - # fap_version=(0, 1), # (major, minor) - fap_icon="simon_says.png", # 10x10 1-bit PNG - fap_description="A Simon Says Game", - fap_author="@SimplyMinimal & @ShehabAttia96", - fap_weburl="https://github.com/SimplyMinimal/FlipperZero-SimonSays", - fap_icon_assets="images", # Image assets to compile for this application -) diff --git a/applications/external/simonsays/images/DolphinLeft_56x48.png b/applications/external/simonsays/images/DolphinLeft_56x48.png deleted file mode 100644 index 089aaed83507431993a76ca25d32fdd9664c1c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1416 zcmaJ>eNYr-7(dh;KXS5&nWVIBjS_NizYg|x=Pr^vz*7zxJO|P-dw2IeZq?gec9-rD zoPZchQ_6}yP{Slc4I!!28K==nodOJ_nsCY-(wOq2uZbLx!rlYU{KIi)_Wj!D_j`WN z^FGgREXdEDF)ewT&1Re7Tj(uBvlG44lnH3;I%IzsO|z`*Vr!`uv?9QOwgs{#Ld+Ki zC9n_zxxBOkx@@+IwMwAaD)#3Ik`}gun2kLe))Crfb7e+#AgzHGCc+X$b>qJuIf`S7 z?8b}I{ghw#z>uiaLknQh@LJUrqHcVYS3v97F^OZN zCe|7^J|?QzUx0Zu17e(=CM1fYFpjtLk|a4~$g}e?hGH0!VoBOT&<=s(1ct%J9~?O} z$)jW_dkX9yTX~%W*i_IM%0{ z7EmP^_pKn`<5>E(SixgJU};7`)7Hidp&+DLnizsebUk}_-GfgbN^il9b`v)f+ z{o5Zry)d<7`fHQ^uw_;+x>mcPw0&8iW69x{k92O{Q}`yFdH=5d$pbf49w1&NS)G+vhr6y}5TMsofQirRDUmKilk5=(KGouJ{H9hW=$X zgi;)vI!jl!_4H3jD(?Jz=8By|i47I&tKA1y9{nfp;_|FxKBDNWp{hN9hJ1nU?z%J6 z?>UxyzWvO}Pgc~rCZ#5%Eq+_hNS~bBdiGlT&f%%e`hHjSySR2=JuK2^+%;$R3#Wz~ z=e_mfqW23bPa0fhe)HdE5+GelU&!jS3ckUZOQ)CC5?mo zo=tzG_4|RuvPUO|mhCwA>y)1c%SWC%a4?a-x|J*?ch~+n=R7o@>p6J2dE=$stKZmK z-xoTRwET2^Wu)&1U7!Ebw!!D?x`xwQX3pMnrRwCT?`4GHt4&?|cIiI{_^XYp-np>6 xE^lPSXzOYCC4X`6tl@OB1M5_S7jml-Y~(TPp{aTIejNKZ`m*!Atyxdk{0EAy49frj diff --git a/applications/external/simonsays/images/DolphinNiceLeft_96x59.png b/applications/external/simonsays/images/DolphinNiceLeft_96x59.png deleted file mode 100644 index a299d3630239b4486e249cc501872bed5996df3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2459 zcmbVO3s4i+8V(M(gEFORwSrA`4O0uPn|M|5y* zB*aMDxC&7(gP9JN;POOi-9khrC>Z9YJs2U!LnVcQEEC0fDtKo&ILlzb30%M}3J^;~ zv7RzcsilOs4Mq@tD*&R;!LMSk2A~{(`HK9|hQBqEX)3sQr9Je6SZU*F-^fD-p+~Hs; zHLkO%v?>ZoxEv+F#whudr%615FkA0DYR0tMEo}3OOY#xecLWe>xV?u5KtSmC^ z7)Fmj6gjfKstiEV-*Cxbbb+&rRWuI_rBJ)ybs_f1Rn&f2>q3pYwI^|J(hdn{j{0EZIm_F zpIyIWLsRUgOItR-dUbVd|6Zo=_BU_Tj4|{{jxO#=JH4o8er(5{!nZD_j4}MH&zh~9 zVLC~y(0-D6GO0ghZD8BYzP?o{>22~lT6^d@X{SwQ8vrNY-PPIMajIwC)`s14Ep72@ zeq7YOzM`?U{+W)ocXBr`eSOcpk?Rxc=ou5&)fWW|pD};-Z0mvk9}=&`Rb&y<77W~a z(>6YM;6Y5aIU~JKZ}mQZynKHiSTQ#Bczn@&jTiN^?vPJ(jhm7cXLx0oum5P$`TceG zU+wR;OO^)8CVlnM)5p$CO&e94KJt>HccCaHGusmW_b`T6m| z-R6V6Db1pErTot?^d22ojm+2>_)FbD`_+WbDGMx9f@hO27maS2`csiV(D&Fs`PS2& zvrq18du_&zXID(!KIxsU$)iuTYuZ?zmYiP&n&i@Be{IdbS-jA2c0QAlu5NXQv_0K< z3Hvs4eeu6B7yD&CNT~gIkMV&UkRU=V!iQ(+_(O&u^ah$+s{_yn(yBYeD40HeU{xGsIT6W Zfq!wOp!QPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1HVZ`K~#8N)t2F6 zBOwTcn|uFv&P{g+A+EZhxHaDoPgG!>+U`A`&*x7nkHB!heHqV5>*uGU)#2vyVsDH}AVsy~ezoEL*Kpbe!+iXUd?~Rwtzo6LrLj)?o;W z%B}S*E^b1t5`5Cx0{z`8Oesd$bKHNRqlaG6PD{IGuR*vKQq03T%4+akggQEz{fhB2 zkVWib2;?%WTF?p3547%+^O>KQHRH=tcKLr$mMokh|q`fz5XzF(Mj!9;jWZ>LNB{745!LW$pD zkadJ}O#GL$L~Z>7gVYy}SQ)m4MI`o7H;6j^7HZ&?>gY2!p)=#O&x04p+kp$E=eQP@#}!k|J2nC}-w9XXHK)ky)? zWi|(UNpSEHpL=IDPQiMlBeznh7JPrj3U{`$Mmf7v$R4KZ4yb?TsX&5lDBPjK>aC)* z+yP>cwL=w1ycy~aM_HYqf7$W{+1^+Ss^Ce3gNuqN9m$B8+)qUj0$sJ@{B+6{erZg9c6DntWH_-f%8n1_=>N5 zLBQ(NkXs#`$1LCaf`ID8{8B28@w~)t#2{v}pB=foCw`qg1|*K~@fFj4I?Bd=oONQt zEejU)z!>HGWH}wNGE;piDz9ommiS5)b*I&P6RHXka*`#xG{|;kv#d@lusTV)+7J6l k;Zb_aMAVv9B7c7V17g|vS5K+|GXMYp07*qoM6N<$f|p|O7XSbN diff --git a/applications/external/simonsays/images/DolphinRight_56x48.png b/applications/external/simonsays/images/DolphinRight_56x48.png deleted file mode 100644 index a0fcba21838c09095daae8551025b8e2f8030a90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 601 zcmV-f0;c_mP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0q#jeK~!i%&6Haf zgD?mMwfo<*rQRHhfCPr0+Hl$M=O-~xWa1riV$rM9qJP`7MI@V}uDQTO}5Xl9QS% nZe`HUO%wHVx9HqBw{80Z5rL-iUB=Na00000NkvXXu0mjfU|j(! diff --git a/applications/external/simonsays/images/DolphinTalking_59x63.png b/applications/external/simonsays/images/DolphinTalking_59x63.png deleted file mode 100644 index 46f559f65f11194c94c15bb7f195a1d72ef2a295..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1177 zcmeAS@N?(olHy`uVBq!ia0vp^)DSr z1<%~X^wgl##FWaylc_cg49qH-ArU1JzCKpT`MG+DAT@dwxdlMo3=B5*6$OdO*{LN8 zNvY|XdA3ULckfqH$V{%1*XSQL?vFu&J;D8jzb> zlBiITo0C^;Rbi_HHrEQs1_|pcDS(xfWZNo192Makpx~Tel&WB+XP}#GU|^lpi<;HsXMd|v6mX? zCgqow*eU^?3h_g30o>TUVrV!4LrlLSu|VHY&j92nm_lD){7Q3k;i`*Ef>IIg#cFVI zNM%8)eo$(0erZuMFy_*fK~@!5ITxiSmgEfrKz*2sj;DkpMZknD6wv4b%oJ<^ zJ|V9E|NjRvLl0f915!UdT^vIyZe6(^E!Jef<9czm0A z3tiQZTzK79dS605C-KUauQq03?HktYO@Gah6}dWL!K=tEQF6i?wpZ6>D42{4Kw06Cgbx4xeweJDDGS}F({`j)7X?o}J zyX`DecdFHnf1Yl!OLgg{#J>1HY(M3>ay__X{YpODaR^Nc-<&V5lUuWQxzBn#x3aK( p%=f=fPd;t;X_5T?htnCD8BU8cnRk73T?7mS22WQ%mvv4FO#oZ0m5TrX diff --git a/applications/external/simonsays/images/board.png b/applications/external/simonsays/images/board.png deleted file mode 100644 index 7640db5946908dfced504134d72fc6bad481f55b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 826 zcmV-A1I7G_P)KtS*B?{IK%KR-Wze}9jUkH5daZ*OleFE0=f z5Km7}udlCPUtgb}pF~7NBqSv6?(QQaBRV=dCnqO4IXUg^?IX*~ zHd19_~QlfI^JY$IVs^?Hr zpE*W(SHf;L~KfQf`yD`fR5J0xEm6%3hd4wL#L`75b}( zTb&z<#5$d%vFshBm5Vie?)j734R_-}T6FeWxcX9loNLyF5xa>Tn}^Z3`brMhMywJe z#UzhYM&WR9d2QOJn#;Ho#T^d+uIzAB7+{osZX;l`A%bWe$YR96Q7L1?a@NJcR(#V- zwEQz*-TQZ>lmA1>*cX7MGXOHtVgjWGYb)HbPG8|pE*Re2Y8xb%P~*Vj#7^azos`17 zaE<%o+}+F12lL`I`!#&m^cF7MW2Sx7qPh3ab`A2Dpw-z9*C|0rO6n|ldtBNn zc&fZUJIbrV^~x*D8gDU2+>87*ou;Z<$1g|gKpb^b=Dvm_aSO6hG4>nu0~ZV%^ebg~ z14~RdVSL^Ep;yF4%cFkFkGR9bR`PeWZ$AuO_OV6fdyfrcPSFy^(^2?WN;pz)FJ5?_ zGjNKE6H*<1uO&reW18adQ?1=nlPx#1ZP1_K>z@;j|==^1poj5%uq~JMgRZ*&(F`0kdRRV zDVqm3=V2p__fz;0dlK(OBPn_kSilYV#j$?tD2hJEe!}zk!I2zJ#DJq?I1ciKt8efk zsujog;MGjIRqO8wU3G2Z!Mv2b#256m>#9Qvozt`S*MZk-R(?(BMD?~h;3PB&1vQMQ z&vu=t4lAX2?cJH?isH|1)zvDMkuf)o40pB>OLWJcu2GrSH`Tx&4Nr8pcgA5{mAt_8;!;ED{M}#Vw6PRR0 zJH9$$)qbdwodUB}COhS3i!A!cr>x?#M}y^z8ex(ZPRXf=i0kx}#0&7oXqc6+qXn>Q zOm)44DO|mVM7Z#DbT`;8oDIN~uS~w>($$e~2gJM2DP=xVJkA>(&q%$$hwjFa1@k$r zbyU7XnC1Y&SDIxGIfl;PrtF#SY*B^0G&=uKsE?qOO6wP_3yvV^j`l-ZrS)^t(E_`j z;dt#*Y5godUR6nxsZob1IAs`Is{Gl1L9|okqS}#In&_f3C8qZ!nxd`=7jr{*@C1ng z=E_f!yr8pPWVEo;@kdjRkrXlR_?;mN``hC&@@k`%V!-R_FdS?b30dBg{}(zpdU?l~ c{%Mr@1JGzPQsxqccK`qY07*qoM6N<$f~Y5<(EtDd diff --git a/applications/external/simonsays/images/left.png b/applications/external/simonsays/images/left.png deleted file mode 100644 index 1eb6b58ee05def3c5e0fac6c7a8300a487fdd540..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 921 zcmV;K17`e*P)Px#1ZP1_K>z@;j|==^1poj5%uq~JMgRZ*&(F`0kdRx zK~zXf)s|~_(=ZH%9Ux(3tQ2PnD}j}*<+9NY1}k?Mm;e8tkYu^BBzNKP3Ep$sW664w z*pe^qzg6M;SxK5rmlZolRJA(+iCX({vg$clsJ|YpTaJ6)d*3wP_qW*5)*O;i5k60h zr&>f3*7w&g#8PyBy zH{V&Hw=55~aP`N~uZB?Xf$uK-@*Gj8@cSVefe|){>9)cB7!W(lyjK- zf}JRu->A7Nhz&&(&<7_feHln{^#^bf6_PYm!)=Nlv`Dzi3ve(+&mTsoR!UhuJK-L8 z@)pcPrksN^TXQq!EY%C1mk!@`v7y`#Fyo})#A>}Ht~-F{`%8)<)nG5VP1UIN1URDh z-fsHrKM~a z&eKhx;?jjIuumO;p3AnNWAW`q7qJTc(lC+Ju(z? zs}83?o-H+Qvbcnv7jAAP<}COzV%DX5!npgs;2KfVNzo vvLhCPx#1ZP1_K>z@;j|==^1poj5%uq~JMgRZ*&(F`0kdRV~azOuQVbdXR(y4jd9;@yd2D%0*8Cvsr zi#dGZcp-z+7JkB9;^_m`=D~x1=GfubEIV$R<4(chd-KM)PGgCU`$feD3| z^quPTLs1y~@^E3;&+7Ce$pvQm&l)-_B^Jtkq0Lsl#+^c$0s11V&svLlm{11V(1GMUUV zkV959C89dYPCtR9qyQ+KzH8DVYyqg;))YSOQBcYqHNU}@o14p9>=&QNM{~WD#1Q*J zVJmOeqIsPmT?HoU9~WwdxdX5MaVL^bFR=o4(OZZprRpxdR-UKGaB zkyp9rOin*JN>4{rq?7*49H>`3-oZ(byMXP+fNva`Wl#224&jlb)*Shl!4xyKxhsqu z`R;!9PT>PE7i72^|!gs5V(Ux+;DkfYV{XaHG$p-7sJC_Ukv{_isCn% WhcZ%O?_L)G0000KtS*B?^IM&1qB5V5D=fApF~7NPft%98ykOr zf4{%KBqStnZ*T7I?i?H(IyyQ(KR+!kEni<>EG#T5D=R4}DK<7XC@3heudgR3CnY5% zkB^TgCMFIJ4lge+3JMD2~83_pq=H})f zA0Of2;Rpx_Dk>^FJ3H;|?NCrqIXO8!Jv~Q9M>I4v4-XHpu&{7&aKOO84JNt}00009 za7bBm000ie000ie0hKEb8vp5@T+hkj%i zhNyAK!E^S-N6i=v$}yGj7jr_`S06>lod4r|DH^xgHyLAJKa{0ve zZPWpi-QJTdf)qs>?!2aUHA=&#MCUGm zI@2kUC_Ze0!|cNJ`eQRCsa#I#k^psiVBrupHv$0E1rvWWX8?Gj#Rl~&X&P5bxMP{V zrIuVU_&VvDH@C76lB;amfuc$6T3bh(FrS*rUBOkjaMT6;zT=PgxNxfO8@Nn$8E&um zi$9t4QHqW>1yj6-eaWqPT9TehHb+UGQJ-1RFXKb$|<6_by z2i0&;^Obg}Hb;k9DTuRGia4lN4vKSPpRgRL;ZP>U7)_q8Oi tRHn-NuWI#_<#<^m%W?V1i{U?Le*q}3GEzALUP}M~002ovPDHLkV1iojbSeM< diff --git a/applications/external/simonsays/simon_says.c b/applications/external/simonsays/simon_says.c deleted file mode 100644 index a583ff115..000000000 --- a/applications/external/simonsays/simon_says.c +++ /dev/null @@ -1,661 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // Header-file for boolean data-type. -#include -#include - -/* generated by fbt from .png files in images folder */ -#include "simon_says_icons.h" -#include - -#define TAG "Simon" // Used for logging -#define DEBUG_MSG 1 -#define SCREEN_XRES 128 -#define SCREEN_YRES 64 -#define BOARD_X 72 // Used for board placement -#define BOARD_Y 8 -#define GAME_START_LIVES 3 -#define SAVING_FILENAME APP_DATA_PATH("game_simon_says.save") - -// Define Notes -// Shamelessly stolen from Ocarina application -// https://github.com/invalidna-me/flipperzero-ocarina -#define NOTE_UP 587.33f -#define NOTE_LEFT 493.88f -#define NOTE_RIGHT 440.00f -#define NOTE_DOWN 349.23 -#define NOTE_OK 293.66f - -/* ============================ Data structures ============================= */ - -typedef enum game_state { preloading, mainMenu, inGame, gameOver, gameVictory } game_state; - -typedef enum difficulty_mode { normal, hard } difficulty_mode; - -typedef enum shape_names { up, down, left, right, number_of_shapes } Direction; - -typedef enum currently_playing { simon, player } currently_playing; - -typedef struct { - /* Game state. */ - enum game_state gameState; // This is the current game state - bool gameover; /* if true then switch to the game over state */ - bool is_wrong_direction; /* Is the last direction wrong? */ - enum currently_playing activePlayer; // This is used to track who is playing at the moment - uint32_t lives; /* Number of lives in the current game. */ - - enum difficulty_mode difficultyMode; // This is the difficulty mode for the current game - bool sound_enabled; // This is the sound enabled flag for the current game - float volume; // This is the volume for the current game - - /* Handle Score */ - int currentScore; // This is the score for the current - int highScore; /* Highscore. Shown on Game Over Screen */ - bool is_new_highscore; /* Is the last score a new highscore? */ - - /* Handle Shape Display */ - uint32_t numberOfMillisecondsBeforeShapeDisappears; // This defines the speed of the game - enum shape_names simonMoves[1000]; // Store the sequence of shapes that Simon plays - enum shape_names selectedShape; // This is used to track the shape that the player has selected - bool set_board_neutral; // This is used to track if the board should be neutral or not - int moveIndex; // This is used to track the current move in the sequence - - uint32_t last_button_press_tick; - NotificationApp* notification; - FuriMutex* mutex; -} SimonData; - -/* ============================== Sequences ============================== */ - -const NotificationSequence sequence_wrong_move = { - &message_red_255, - - &message_vibro_on, - // &message_note_g5, // Play sound but currently disabled - &message_delay_25, - // &message_note_e5, - &message_vibro_off, - &message_sound_off, - NULL, -}; - -const NotificationSequence sequence_player_submit_move = { - &message_vibro_on, - // &message_note_g5, // Play sound but currently disabled. Need On/Off menu setting - &message_delay_10, - &message_delay_1, - &message_delay_1, - &message_delay_1, - &message_delay_1, - &message_delay_1, - - // &message_note_e5, - &message_vibro_off, - &message_sound_off, - NULL, -}; - -const NotificationSequence sequence_up = { - // &message_vibro_on, - &message_note_g4, - &message_delay_100, - // &message_vibro_off, - &message_sound_off, - NULL, -}; - -const NotificationSequence sequence_down = { - // &message_vibro_on, - &message_note_c3, - &message_delay_100, - // &message_vibro_off, - &message_sound_off, - NULL, -}; - -const NotificationSequence sequence_left = { - // &message_vibro_on, - &message_note_e3, - &message_delay_100, - // &message_vibro_off, - &message_sound_off, - NULL, -}; - -const NotificationSequence sequence_right = { - // &message_vibro_on, - &message_note_g3, - &message_delay_100, - // &message_vibro_off, - &message_sound_off, - NULL, -}; - -// Indicate that it's Simon's turn -const NotificationSequence sequence_simon_is_playing = { - &message_red_255, - &message_do_not_reset, - NULL, -}; - -// Indicate that it's the Player's turn -const NotificationSequence sequence_player_is_playing = { - &message_red_0, - &message_do_not_reset, - NULL, -}; - -const NotificationSequence sequence_cleanup = { - &message_red_0, - &message_green_0, - &message_blue_0, - &message_sound_off, - &message_vibro_off, - NULL, -}; - -/* ============================ 2D drawing ================================== */ - -/* Display remaining lives in the center of the board */ -void draw_remaining_lives(Canvas* canvas, const SimonData* simon_state) { - // Convert score to string - // int length = snprintf(NULL, 0, "%lu", simon_state->lives); - // char* str_lives_remaining = malloc(length + 1); - // snprintf(str_lives_remaining, length + 1, "%lu", simon_state->lives); - - // TODO: Make it a Simon Says icon on top right - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - int x = SCREEN_XRES - 6; - int lives = simon_state->lives; - while(lives--) { - canvas_draw_str(canvas, x, 8, "*"); - x -= 7; - } -} - -void draw_current_score(Canvas* canvas, const SimonData* simon_data) { - /* Draw Game Score. */ - canvas_set_color(canvas, ColorXOR); - canvas_set_font(canvas, FontSecondary); - char str_score[32]; - snprintf(str_score, sizeof(str_score), "%i", simon_data->currentScore); - canvas_draw_str_aligned(canvas, SCREEN_XRES / 2 + 4, 2, AlignCenter, AlignTop, str_score); -} - -void play_sound_up(const SimonData* app) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { - furi_hal_speaker_start(NOTE_UP, app->volume); - } -} - -void play_sound_down(const SimonData* app) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { - furi_hal_speaker_start(NOTE_DOWN, app->volume); - } -} - -void play_sound_left(const SimonData* app) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { - furi_hal_speaker_start(NOTE_LEFT, app->volume); - } -} - -void play_sound_right(const SimonData* app) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { - furi_hal_speaker_start(NOTE_RIGHT, app->volume); - } -} - -void stop_sound() { - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } -} - -/* Main Render Function */ -void simon_draw_callback(Canvas* canvas, void* ctx) { - furi_assert(ctx); - const SimonData* simon_state = ctx; - furi_mutex_acquire(simon_state->mutex, FuriWaitForever); - - canvas_clear(canvas); - - // ######################### Main Menu ######################### - // Show Main Menu - if(simon_state->gameState == mainMenu) { - // Draw border frame - canvas_draw_frame(canvas, 1, 1, SCREEN_XRES - 1, SCREEN_YRES - 1); // Border - - // Draw Simon text banner - canvas_set_font(canvas, FontSecondary); - canvas_set_color(canvas, ColorBlack); - canvas_draw_str_aligned( - canvas, - SCREEN_XRES / 2, - SCREEN_YRES / 2 - 4, - AlignCenter, - AlignCenter, - "Welcome to Simon Says"); - - // Display Press OK to start below title - canvas_set_color(canvas, ColorXOR); - canvas_draw_str_aligned( - canvas, - SCREEN_XRES / 2, - SCREEN_YRES / 2 + 10, - AlignCenter, - AlignCenter, - "Press OK to start"); - } - - // ######################### in Game ######################### - //@todo Render Callback - // We're in an active game - if(simon_state->gameState == inGame) { - // Draw Current Score - draw_current_score(canvas, simon_state); - - // Draw Lives - draw_remaining_lives(canvas, simon_state); - - // Draw Simon Pose - if(simon_state->activePlayer == player) { - // Player's turn - canvas_draw_icon(canvas, 0, 4, &I_DolphinWait_61x59); - } else { - // Simon's turn - canvas_draw_icon(canvas, 0, 4, &I_DolphinTalking_59x63); - } - - if(simon_state->set_board_neutral) { - // Draw Neutral Board - canvas_draw_icon(canvas, BOARD_X, BOARD_Y, &I_board); // Draw Board - - // Stop Sound TODO: Move this to a better place - //@todo Sound - stop_sound(); - } else { - switch(simon_state->selectedShape) { - case up: - canvas_draw_icon(canvas, BOARD_X, BOARD_Y, &I_up); // Draw Up - play_sound_up(simon_state); - break; - case down: - canvas_draw_icon(canvas, BOARD_X, BOARD_Y, &I_down); // Draw Down - play_sound_down(simon_state); - break; - case left: - canvas_draw_icon(canvas, BOARD_X, BOARD_Y, &I_left); // Draw Left - play_sound_left(simon_state); - break; - case right: - canvas_draw_icon(canvas, BOARD_X, BOARD_Y, &I_right); // Draw Right - play_sound_right(simon_state); - break; - default: - if(DEBUG_MSG) - FURI_LOG_E( - TAG, "Invalid shape: %d", simon_state->simonMoves[simon_state->moveIndex]); - break; - } - } - } - - // ######################### Game Over ######################### - if(simon_state->gameState == gameOver) { - stop_sound(); //TODO: Make a game over sequence - canvas_set_color(canvas, ColorXOR); - canvas_set_font(canvas, FontPrimary); - - // TODO: if new highscore, display blinking "New High Score" - // Display High Score Text - if(simon_state->is_new_highscore) { - canvas_draw_str_aligned( - canvas, SCREEN_XRES / 2, 6, AlignCenter, AlignTop, "New High Score!"); - } else { - canvas_draw_str_aligned( - canvas, SCREEN_XRES / 2, 6, AlignCenter, AlignTop, "High Score"); - } - - // Convert highscore to string - int length = snprintf(NULL, 0, "%i", simon_state->highScore); - char* str_high_score = malloc(length + 1); - snprintf(str_high_score, length + 1, "%i", simon_state->highScore); - - // Display High Score - canvas_draw_str_aligned( - canvas, SCREEN_XRES / 2, 22, AlignCenter, AlignCenter, str_high_score); - free(str_high_score); - - // Display Game Over - canvas_draw_str_aligned( - canvas, SCREEN_XRES / 2, SCREEN_YRES / 2 + 2, AlignCenter, AlignCenter, "GAME OVER"); - - // Display Press OK to restart below title - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - SCREEN_XRES / 2, - SCREEN_YRES / 2 + 15, - AlignCenter, - AlignCenter, - "Press OK to restart"); - } - - // ######################### Victory ######################### - //Player Beat Simon beyond limit! A word record holder here! - //TODO - - //release the mutex - furi_mutex_release(simon_state->mutex); -} - -/* ======================== Input Handling ============================== */ - -void simon_input_callback(InputEvent* input_event, void* ctx) { - furi_assert(ctx); - FuriMessageQueue* event_queue = ctx; - furi_message_queue_put(event_queue, input_event, FuriWaitForever); -} - -/* ======================== Simon Game Engine ======================== */ - -bool load_game(SimonData* app) { - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(storage, EXT_PATH("apps/Games/game_simon_says.save"), SAVING_FILENAME); - - File* file = storage_file_alloc(storage); - - uint16_t bytes_readed = 0; - if(storage_file_open(file, SAVING_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) { - if(storage_file_size(file) > sizeof(SimonData)) { - storage_simply_remove(storage, SAVING_FILENAME); - FURI_LOG_E( - TAG, "Error: file is larger than the data structure! The file has been deleted."); - } else { - bytes_readed = storage_file_read(file, app, sizeof(SimonData)); - } - storage_file_close(file); - storage_file_free(file); - } - - furi_record_close(RECORD_STORAGE); - return bytes_readed == sizeof(SimonData); -} - -void save_game(SimonData* app) { - Storage* storage = furi_record_open(RECORD_STORAGE); - - File* file = storage_file_alloc(storage); - if(storage_file_open(file, SAVING_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - storage_file_write(file, app, sizeof(SimonData)); - } - storage_file_close(file); - storage_file_free(file); - - furi_record_close(RECORD_STORAGE); -} - -int getRandomIntInRange(int lower, int upper) { - return (rand() % (upper - lower + 1)) + lower; -} - -void play_sound_sequence_correct() { - notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_success); -} - -void play_sound_wrong_move() { - //TODO: play wrong sound: Try sequence_audiovisual_alert - notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_error); -} - -/* Restart game and give player a chance to try again on same sequence */ -// @todo restartGame -void resetGame(SimonData* app) { - app->moveIndex = 0; - app->numberOfMillisecondsBeforeShapeDisappears = 500; - app->activePlayer = simon; - app->is_wrong_direction = false; - app->last_button_press_tick = 0; - app->set_board_neutral = true; - app->activePlayer = simon; -} - -/* Set gameover state */ -void game_over(SimonData* app) { - if(app->is_new_highscore) save_game(app); // Save highscore but only on change - app->gameover = true; - app->lives = GAME_START_LIVES; // Show 3 lives in game over screen to match new game start - app->gameState = gameOver; -} - -/* Called after gameover to restart the game. This function - * also calls restart_game(). */ -void restart_game_after_gameover(SimonData* app) { - app->volume = 1.0f; //TODO: make this a setting - app->gameState = inGame; - app->gameover = false; - app->currentScore = 0; - app->is_new_highscore = false; - app->lives = GAME_START_LIVES; - app->simonMoves[0] = rand() % number_of_shapes; - resetGame(app); -} - -void addNewSimonMove(int addAtIndex, SimonData* app) { - app->simonMoves[addAtIndex] = getRandomIntInRange(0, 3); -} - -void startNewRound(SimonData* app) { - addNewSimonMove(app->currentScore, app); - app->moveIndex = 0; - app->activePlayer = simon; -} - -void onPlayerAnsweredCorrect(SimonData* app) { - app->moveIndex++; -} - -void onPlayerAnsweredWrong(SimonData* app) { - if(app->lives > 0) { - app->lives--; - - // Play the wrong sound - if(app->sound_enabled) { - play_sound_wrong_move(); - } - resetGame(app); - } else { - // The player has no lives left - // Game over - game_over(app); - //TODO: Play unique game over sound - } -} - -bool isRoundComplete(SimonData* app) { - return app->moveIndex == app->currentScore; -} - -enum shape_names getCurrentSimonMove(SimonData* app) { - return app->simonMoves[app->moveIndex]; -} - -void onPlayerSelectedShapeCallback(enum shape_names shape, SimonData* app) { - if(shape == getCurrentSimonMove(app)) { - onPlayerAnsweredCorrect(app); - } else { - onPlayerAnsweredWrong(app); - } -} - -//@todo gametick -void game_tick(SimonData* simon_state) { - if(simon_state->gameState == inGame) { - if(simon_state->activePlayer == simon) { - // ############### Simon Turn ############### - notification_message(simon_state->notification, &sequence_simon_is_playing); - - //@todo Gameplay - if(simon_state->set_board_neutral) { - if(simon_state->moveIndex < simon_state->currentScore) { - simon_state->selectedShape = getCurrentSimonMove(simon_state); - simon_state->set_board_neutral = false; - simon_state->moveIndex++; - } else { - simon_state->activePlayer = player; - simon_state->set_board_neutral = true; - simon_state->moveIndex = 0; - } - } else { - simon_state->set_board_neutral = true; - } - } else { - // ############### Player Turn ############### - notification_message(simon_state->notification, &sequence_player_is_playing); - - // It's Player's Turn - if(isRoundComplete(simon_state)) { - simon_state->activePlayer = simon; - simon_state->currentScore++; - // app->numberOfMillisecondsBeforeShapeDisappears -= 50; - //TODO: Hacky way of handling highscore by subtracting 1 to account for the first move - if(simon_state->currentScore - 1 > simon_state->highScore) { - simon_state->highScore = simon_state->currentScore - 1; - simon_state->is_new_highscore = true; - } - if(simon_state->sound_enabled) { - play_sound_sequence_correct(); - } - startNewRound(simon_state); - } - } - } -} - -/* ======================== Main Entry Point ============================== */ - -int32_t simon_says_app_entry(void* p) { - UNUSED(p); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - SimonData* simon_state = malloc(sizeof(SimonData)); - - simon_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!simon_state->mutex) { - FURI_LOG_E(TAG, "cannot create mutex\r\n"); - free(simon_state); - return -1; - } - - // Configure view port - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, simon_draw_callback, simon_state); - view_port_input_callback_set(view_port, simon_input_callback, event_queue); - - // Register view port in GUI - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - simon_state->notification = notification; - - InputEvent input; - - // Show Main Menu Screen - //load_game(simon_state); - restart_game_after_gameover(simon_state); - simon_state->gameState = mainMenu; - - while(true) { - game_tick(simon_state); - - FuriStatus q_status = furi_message_queue_get( - event_queue, &input, simon_state->numberOfMillisecondsBeforeShapeDisappears); - furi_mutex_acquire(simon_state->mutex, FuriWaitForever); - - if(q_status == FuriStatusOk) { - //FURI_LOG_D(TAG, "Got input event: %d", input.key); - //break out of the loop if the back key is pressed - if(input.key == InputKeyBack && input.type == InputTypeLong) { - // Save high score before quitting - //if(simon_state->is_new_highscore) { - // save_game(simon_state); - //} - break; - } - - //@todo Set Game States - if(input.key == InputKeyOk && simon_state->gameState != inGame) { - restart_game_after_gameover(simon_state); - // Set Simon Board state - startNewRound(simon_state); - view_port_update(view_port); - } - - // Keep LED on if it is Simon's turn - if(simon_state->activePlayer == player) { - notification_message(notification, &sequence_player_is_playing); - - if(input.type == InputTypePress) { - simon_state->set_board_neutral = false; - - switch(input.key) { - case InputKeyUp: - simon_state->selectedShape = up; - onPlayerSelectedShapeCallback(up, simon_state); - break; - case InputKeyDown: - simon_state->selectedShape = down; - onPlayerSelectedShapeCallback(down, simon_state); - break; - case InputKeyLeft: - simon_state->selectedShape = left; - onPlayerSelectedShapeCallback(left, simon_state); - break; - case InputKeyRight: - simon_state->selectedShape = right; - onPlayerSelectedShapeCallback(right, simon_state); - break; - default: - simon_state->set_board_neutral = true; - break; - } - } else { - //FURI_LOG_D(TAG, "Input type is not short"); - simon_state->set_board_neutral = true; - } - } - } - - // @todo Animation Loop for debug - // if(simon_state->gameState == inGame && simon_state->activePlayer == simon) { - // simon_state->currentScore++; - // simon_state->set_board_neutral = !simon_state->set_board_neutral; - // } - - view_port_update(view_port); - furi_mutex_release(simon_state->mutex); - } - - stop_sound(); - notification_message(notification, &sequence_cleanup); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(simon_state->mutex); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - free(simon_state); - - return 0; -} diff --git a/applications/external/simonsays/simon_says.png b/applications/external/simonsays/simon_says.png deleted file mode 100644 index 6fe9ba3e6f2acf28e94bdb001606248d1ea0e96a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>vG;Uw4ABTq z{`3F;|9Unh24x>bWo6~Crv}9VB1+PHmpuX$cYRzE-FvoC;dSRGspU=+R=$usl%-_$ f+E7G@tC(San8)KerT;B~MlpE0`njxgN@xNAKO-r( diff --git a/applications/external/slots/application.fam b/applications/external/slots/application.fam deleted file mode 100644 index 9a2e244d8..000000000 --- a/applications/external/slots/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="slotmachine", - name="Slot Machine", - apptype=FlipperAppType.EXTERNAL, - entry_point="slotmachine_app", - cdefines=["APP_SLOTMACHINE"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="ddgame_icon.png", - fap_category="Games", - fap_icon_assets="assets", - fap_author="@Daniel-dev-s", - fap_weburl="https://github.com/Daniel-dev-s/flipperzero-slots", - fap_version="1.1", - fap_description="Simple Slots simulator game", -) diff --git a/applications/external/slots/assets/little_coin.png b/applications/external/slots/assets/little_coin.png deleted file mode 100644 index 34ef4f8e7d7be7455d630e78a88cfc2207d5f78b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^>>$j+1SGu;4zvI%#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!ps}ZmV~9j}@{j-j?U}V0x(u8&IOLfmBpsVH y773UMw=lDuDB=iQ;bw3kQE!%jz@PvBT(avwr#xid&w6D@s)qSr}Lk$H4}3v{l>vx={lFC zMUiuA#!ZRYHjKiL7q-79b3hZo~!!q8F1ho(18q|u6{1-oD!M$ diff --git a/applications/external/slots/assets/x2_2.png b/applications/external/slots/assets/x2_2.png deleted file mode 100644 index 6808d7212097730116823a0dc6836e3ceae19896..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1SD^+kpz+qjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!AwsV#}Etut&;-z4k&OqCw|{={79iE=S9Pj ze;FJ2GetT%@)Q^4m>GRm^=?bFHOrnLu6)}2P}zUyTEqB@Iqaf6Z@m*&ZLm;fH+8#` z9=Gg}?XllUVb#li=G{GimE*t(nN2QTk(*ULw=(j~{2OzC$za z(-gK$i;T*Cs=gs)eT2-)t2*CY`O}+D8=Sp-A-*(Y=e%V?pIJBeUa$Da)pgcQ^W46Z zY_XH%JP%JiQ5yS8wM9zImX}?uI%eAbCm*M2&eEN5OQGOq_TvN3xZQmBJ(-v%Z5*63 t*F5)e&wc~lnO2M0efT|+7G!ztWc=fwCUYYAPZ`i{44$rjF6*2UngE_pTYvxn diff --git a/applications/external/slots/assets/x4.png b/applications/external/slots/assets/x4.png deleted file mode 100644 index 48b3cb4077c156c9ffdabe7f4490650b72a35ed3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1SD^+kpz+qjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!BS5b#}EtusS~657!)~}5B|P?b8Ta&iruR} z89wd-Tdrx@ugaQTA@Q;?iTi~+&pJcDGbXy0yZMxNp7>g&d-jV|sD%f{?d(yCMua(j##>X=D!UsNw RSOXov;OXk;vd$@?2>=+DPr3jA diff --git a/applications/external/slots/assets/x5.png b/applications/external/slots/assets/x5.png deleted file mode 100644 index 8aaf5401f2006ac2af81144b83645bf657404bba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1SD^+kpz+qjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!5&W+#}Etuy%Riz8Wea~8vp;7TcO9jqj+xDg zFDcDr{zopr00|RXO8@`> diff --git a/applications/external/slots/ddgame_icon.png b/applications/external/slots/ddgame_icon.png deleted file mode 100644 index aa2aa5b353e020189fe88e67a9902b502ceb144f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl}2EbxddW?X?_wfUrhf^MEJjv*SsYbRXfVlZHFz4`zD=AGH)hPN*J zd0GTrkqH&`zjW}XV7!W;D|>qKb#9Ynmq{JI$9#o2&%1Wr@LbR_m!)q1@f0S;C$@i1 T_BFWzO=R$N^>bP0l+XkKmeMu% diff --git a/applications/external/slots/slotmachine.c b/applications/external/slots/slotmachine.c deleted file mode 100644 index fa85b99ba..000000000 --- a/applications/external/slots/slotmachine.c +++ /dev/null @@ -1,273 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "slotmachine_icons.h" -#include - -const Icon* slot_frames[] = {&I_x2, &I_x3, &I_x4, &I_x2_2, &I_x5}; - -const uint8_t slot_coef[] = {2, 3, 4, 2, 5}; - -typedef struct { - uint8_t x, y, value, times, speed; - bool spining; -} SlotColumn; - -int COLUMNS_COUNT = 4; -int MAX_COLUMNS_COUNT = 4; - -typedef struct { - Gui* gui; // container gui - ViewPort* view_port; // current viewport - FuriMessageQueue* input_queue; // Input Events queue - FuriMutex** model_mutex; // mutex for safe threads - uint16_t bet; - double money, winamount; - SlotColumn* columns[4]; - bool winview; -} SlotMachineApp; - -#define START_MONEY 1500; -#define START_BET 300; -#define SSRAND_MAX 5; -#define DEFAULT_SPEED 16; - -uint8_t DEFAULT_SPINNING_TIMES = 10; - -void game_results(SlotMachineApp* app) { - int matches[] = {0, 0, 0, 0, 0}; - - double total = 0; - - for(int i = 0; i < COLUMNS_COUNT; i++) { - matches[app->columns[i]->value]++; - } - - for(int i = 0; i < 5; i++) { - if(matches[i] >= 2) { - total += app->bet * (slot_coef[i] / (double)(MAX_COLUMNS_COUNT + 1 - matches[i])); - } - } - - if(total > 0) { - app->money += total; - app->winamount = total; - app->winview = true; - } -} - -void draw_container(Canvas* canvas) { - canvas_draw_rframe(canvas, 2, 12, 120, 34, 3); - canvas_draw_rframe(canvas, 2, 13, 120, 34, 3); - canvas_draw_rframe(canvas, 2, 14, 120, 34, 3); - canvas_draw_rframe(canvas, 2, 15, 120, 34, 3); - canvas_draw_rframe(canvas, 2, 16, 120, 34, 3); - canvas_draw_rframe(canvas, 2, 17, 120, 34, 3); - canvas_draw_line(canvas, 31, 16, 31, 48); - canvas_draw_line(canvas, 61, 16, 61, 48); - canvas_draw_line(canvas, 91, 16, 91, 48); -} - -bool checkIsSpinning(SlotMachineApp* slotmachine) { - for(int i = 0; i < COLUMNS_COUNT; i++) { - if(slotmachine->columns[i]->spining) return true; - } - - return false; -} - -void drawButton(Canvas* canvas, uint8_t x, uint8_t y, char* str, bool invert) { - const uint8_t string_width = canvas_string_width(canvas, str); - canvas_set_font(canvas, FontSecondary); - if(invert) { - canvas_draw_rbox(canvas, x, y, string_width + 15, 11, 3); - canvas_invert_color(canvas); - } else { - canvas_draw_rframe(canvas, x, y, string_width + 15, 11, 3); - } - canvas_draw_circle(canvas, x + 5, y + 5, 3); - canvas_draw_circle(canvas, x + 5, y + 5, 1); - canvas_draw_str(canvas, x + 13, y + 9, str); - canvas_invert_color(canvas); -} - -// viewport callback -void slotmachine_draw_callback(Canvas* canvas, void* ctx) { - SlotMachineApp* slotmachine = (SlotMachineApp*)ctx; - furi_check(furi_mutex_acquire(slotmachine->model_mutex, FuriWaitForever) == FuriStatusOk); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 10, "Slots"); - canvas_draw_icon(canvas, 30, 3, &I_little_coin); - - char moneyStr[15]; - snprintf(moneyStr, sizeof(moneyStr), "$%.0f", slotmachine->money); - - char betStr[7]; - snprintf(betStr, sizeof(betStr), "$%d", slotmachine->bet); - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 45, 10, moneyStr); - canvas_draw_str(canvas, 2, canvas_height(canvas) - 3, "Bet:"); - canvas_draw_str(canvas, 20, canvas_height(canvas) - 3, betStr); - - if(slotmachine->winview) { - char winamountStr[30]; - snprintf(winamountStr, sizeof(winamountStr), "You win: $%.2f!", slotmachine->winamount); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 35, winamountStr); - drawButton(canvas, 95, 52, "Ok", false); - - furi_mutex_release(slotmachine->model_mutex); - return; - } - - for(int i = 0; i < COLUMNS_COUNT; i++) { - if(slotmachine->columns[i]->spining) { - slotmachine->columns[i]->y += slotmachine->columns[i]->speed; - - if(slotmachine->columns[i]->y > 31) { - slotmachine->columns[i]->y = 13; - slotmachine->columns[i]->times--; - slotmachine->columns[i]->speed--; - slotmachine->columns[i]->value = rand() % SSRAND_MAX; - - if(slotmachine->columns[i]->times == 0) { - slotmachine->columns[i]->y = 23; - slotmachine->columns[i]->spining = false; - - if(i == COLUMNS_COUNT - 1) { - game_results(slotmachine); - } - } - - if(i < COLUMNS_COUNT - 1 && - slotmachine->columns[i]->times == - (DEFAULT_SPINNING_TIMES - (int)(DEFAULT_SPINNING_TIMES / 3))) { - slotmachine->columns[i + 1]->spining = true; - } - } - } - canvas_draw_icon( - canvas, - slotmachine->columns[i]->x, - slotmachine->columns[i]->y, - slot_frames[slotmachine->columns[i]->value]); - } - draw_container(canvas); - drawButton(canvas, 90, 52, "Spin", checkIsSpinning(slotmachine)); - - furi_mutex_release(slotmachine->model_mutex); -} - -// callback for viewport input events -static void slotmachine_input_callback(InputEvent* input_event, void* ctx) { - SlotMachineApp* slotmachine = ctx; - furi_message_queue_put(slotmachine->input_queue, input_event, FuriWaitForever); -} - -// allocation memory and initialization -SlotMachineApp* slotmachine_app_alloc() { - SlotMachineApp* app = malloc(sizeof(SlotMachineApp)); - app->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - app->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - app->view_port = view_port_alloc(); - view_port_draw_callback_set( - app->view_port, slotmachine_draw_callback, app); // viewport callback register - view_port_input_callback_set(app->view_port, slotmachine_input_callback, app); - - app->money = START_MONEY; - app->bet = START_BET; - app->winview = false; - app->winamount = 0; - - int x = 7; - - for(int i = 0; i < COLUMNS_COUNT; i++) { - app->columns[i] = malloc(sizeof(SlotColumn)); - app->columns[i]->x = x; - app->columns[i]->y = 25; - app->columns[i]->value = 0; - app->columns[i]->spining = false; - x += 30; - } - - app->gui = furi_record_open("gui"); // start gui and adding viewport - gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); - - return app; -} - -void slotmachine_app_free(SlotMachineApp* app) { - gui_remove_view_port(app->gui, app->view_port); - view_port_free(app->view_port); - furi_record_close("gui"); // free memory - furi_mutex_free(app->model_mutex); - for(int i = 0; i < COLUMNS_COUNT; i++) { - free(app->columns[i]); - } - free(app); -} - -// entry point -int32_t slotmachine_app(void* p) { - UNUSED(p); - - SlotMachineApp* slotmachine = slotmachine_app_alloc(); - InputEvent input; - - // endless input cycle - while(1) { - if(furi_message_queue_get(slotmachine->input_queue, &input, 100) == FuriStatusOk) { - // if thread idle - take it - furi_check( - furi_mutex_acquire(slotmachine->model_mutex, FuriWaitForever) == FuriStatusOk); - - if(!checkIsSpinning(slotmachine)) { - if(input.key == InputKeyBack) { - // exit on back button - furi_mutex_release(slotmachine->model_mutex); - break; - } else if( - input.key == InputKeyOk && input.type == InputTypeShort && - slotmachine->winview) { - slotmachine->winview = false; - } else if( - input.key == InputKeyOk && input.type == InputTypeShort && - slotmachine->bet <= slotmachine->money) { - COLUMNS_COUNT = rand() % 3 + 2; - slotmachine->money -= slotmachine->bet; - slotmachine->columns[0]->spining = true; - - for(int i = 0; i < COLUMNS_COUNT; i++) { - slotmachine->columns[i]->times = DEFAULT_SPINNING_TIMES; - slotmachine->columns[i]->speed = DEFAULT_SPEED; - } - } else if(input.key == InputKeyUp) { - if(slotmachine->bet + 10 < slotmachine->money) { - slotmachine->bet += 10; - } - } else if(input.key == InputKeyDown) { - if(slotmachine->bet - 10 > 0) { - slotmachine->bet -= 10; - } - } - } - - // release thread - furi_mutex_release(slotmachine->model_mutex); - } - // redraw viewport - view_port_update(slotmachine->view_port); - } - - slotmachine_app_free(slotmachine); - - return 0; -} diff --git a/applications/external/solitaire/LICENSE b/applications/external/solitaire/LICENSE deleted file mode 100644 index 37558e682..000000000 --- a/applications/external/solitaire/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Tibor Tálosi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/external/solitaire/application.fam b/applications/external/solitaire/application.fam deleted file mode 100644 index 9394dfc8a..000000000 --- a/applications/external/solitaire/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="solitaire", - name="Solitaire", - apptype=FlipperAppType.EXTERNAL, - entry_point="solitaire_app", - requires=["gui", "storage", "canvas"], - stack_size=2 * 1024, - fap_icon="solitaire_10px.png", - fap_category="Games", - fap_icon_assets="assets", - fap_author="@teeebor", - fap_version="1.0", - fap_description="Solitaire game", -) diff --git a/applications/external/solitaire/assets/card_graphics.png b/applications/external/solitaire/assets/card_graphics.png deleted file mode 100644 index 8b00e351fae43c2ee425b8445cc19f642eb95812..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 409 zcmV;K0cQS*P)Px$Q%OWYR7i=%R?89tAqWG<|NmusprtekbbIM?*iqyWAUf;k9CtUfbB>wCI=3Nd zkf&e|zMV0MyGy;9?L3P`+JU}vH`1-1@>YgochGRI-4)H10h(B| zu?)rikl@mNhYz!-W=#V~0KAmRK+~04F`1bkqP(mdn%5c6D6h*(rq>F9=Af6x^3-1f zL5A%URz$fnekt74ZgADU;s&o+tZ=(d4uHb%6NF*|d6@v*Hbn?_24XTYSs2`#s+{HB zt&Xj%;ir{>eoZXlre_D_j|PV6WL%OHRp!4I>_|q!^r> z=1*6(z84Z7Kc`qgR-c`O1<-b2v9y7hT^W!Oe-q>z!=01&K$^jK=yvNbnTDWEt0U-ExF~o%D-WCQ~}Km-Ad{Hoy_b3ZonT2xiD0D00000NkvXXu0mjf DEMm7A diff --git a/applications/external/solitaire/assets/solitaire_main.png b/applications/external/solitaire/assets/solitaire_main.png deleted file mode 100644 index 996556d574a887407ed223e925222a9c7996cb93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1158 zcmV;11bO?3P)Px(KuJVFRCt{2oMDgTAP9!r$^HMIJiQMaCxie3g4&iRx!lgQtG2!%pxN`fuIngX z%V+ffinWvgUe3SO11Nl)=jr}kxayYxZpe9_$4KY~f4>B9Gn(alJOCw{62Og!wERX1 z;3h;{ej`Ny*LD5WHWI89e`HvGBSiosYAtBI@3JSHS^_pF!ulmj05>4Z`j4Xour=A% ze;ic`z6Ee1xk>eUiShuOLj}|t5okR}m;i9fR~Z0Jo0zCtK8LpbFab~jq0NpV@TJvz<9#B>)Zri*Yy*MCj&T+i5>tdT2eN3%^N55ES0lfO}o^XaeLC5?d?l* zUoT*U_fGWyO|f`DJ$D?v9#i9(P0zZmXa%;#k+7YzfXJoA(pL1L87hvz{ZZGZc>s;2 z&x9M#ofuiR8e3!mvytMA5wgzhjrJ$qw>%5bR0p#xHPic8JdCs)WWR^ySpdA=yD#E& zj5qR^fTR!$AmGMqrSqFf4CLfDtWRJoF%sNIzvED}~V=1}9 z9W_mx?dOp!g4&nB-$(BoKprmuF7KCW4U~mL@b9+&Tg>D2DtNr@b7qzB@dAK&TrVuf z;Lp((x*`sEZ46+sEKBVI27Z#*qT+y2UL^o2)q?l5@8NasGuIDng9Dd*dt;Tp_wot> za0fuNMHuP6tU}JL<=_uauoHBG#gtuMXwm31GNVdIbj(FViDux1yIQR Y2UyXV= 0; i--) { - draw_card_at( - playerCardPositions[i][0], - playerCardPositions[i][1], - cards[i].pip, - cards[i].character, - canvas); - } -} - -Vector card_pos_at_index(uint8_t index) { - return (Vector){playerCardPositions[index][0], playerCardPositions[index][1]}; -} - -void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas) { - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, White); - draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - - draw_icon_clip(canvas, card_graphics, pos_x + 1, pos_y + 1, 35, 0, 15, 21, Black); -} - -void generate_deck(Deck* deck_ptr, uint8_t deck_count) { - uint16_t counter = 0; - if(deck_ptr->cards != NULL) { - free(deck_ptr->cards); - } - - deck_ptr->deck_count = deck_count; - deck_ptr->card_count = deck_count * 52; - deck_ptr->cards = malloc(sizeof(Card) * deck_ptr->card_count); - - for(uint8_t deck = 0; deck < deck_count; deck++) { - for(uint8_t pip = 0; pip < 4; pip++) { - for(uint8_t label = 0; label < 13; label++) { - deck_ptr->cards[counter] = (Card){pip, label, false, false}; - counter++; - } - } - } -} - -void shuffle_deck(Deck* deck_ptr) { - srand(DWT->CYCCNT); - deck_ptr->index = 0; - int max = deck_ptr->deck_count * 52; - for(int i = 0; i < max; i++) { - int r = i + (rand() % (max - i)); - Card tmp = deck_ptr->cards[i]; - deck_ptr->cards[i] = deck_ptr->cards[r]; - deck_ptr->cards[r] = tmp; - } -} - -uint8_t hand_count(const Card* cards, uint8_t count) { - uint8_t aceCount = 0; - uint8_t score = 0; - - for(uint8_t i = 0; i < count; i++) { - if(cards[i].character == 12) - aceCount++; - else { - if(cards[i].character > 8) - score += 10; - else - score += cards[i].character + 2; - } - } - - for(uint8_t i = 0; i < aceCount; i++) { - if((score + 11) <= 21) - score += 11; - else - score++; - } - - return score; -} - -void draw_card_animation( - Card animatingCard, - Vector from, - Vector control, - Vector to, - float t, - bool extra_margin, - Canvas* const canvas) { - float time = t; - if(extra_margin) { - time += 0.2; - } - - Vector currentPos = quadratic_2d(from, control, to, time); - if(t > 1) { - draw_card_at( - currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas); - } else { - if(t < 0.5) - draw_card_back_at(currentPos.x, currentPos.y, canvas); - else - draw_card_at( - currentPos.x, currentPos.y, animatingCard.pip, animatingCard.character, canvas); - } -} - -void init_hand(Hand* hand_ptr, uint8_t count) { - hand_ptr->cards = malloc(sizeof(Card) * count); - hand_ptr->index = 0; - hand_ptr->max = count; -} - -void free_hand(Hand* hand_ptr) { - FURI_LOG_D("CARD", "Freeing hand"); - free(hand_ptr->cards); -} - -void add_to_hand(Hand* hand_ptr, Card card) { - FURI_LOG_D("CARD", "Adding to hand"); - if(hand_ptr->index < hand_ptr->max) { - hand_ptr->cards[hand_ptr->index] = card; - hand_ptr->index++; - } -} - -void draw_card_space(int16_t pos_x, int16_t pos_y, bool highlighted, Canvas* const canvas) { - if(highlighted) { - draw_rounded_box_frame(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - draw_rounded_box_frame( - canvas, pos_x + 2, pos_y + 2, CARD_WIDTH - 4, CARD_HEIGHT - 4, White); - } else { - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Black); - draw_rounded_box_frame( - canvas, pos_x + 2, pos_y + 2, CARD_WIDTH - 4, CARD_HEIGHT - 4, White); - } -} - -int first_non_flipped_card(Hand hand) { - for(int i = 0; i < hand.index; i++) { - if(!hand.cards[i].flipped) { - return i; - } - } - return hand.index; -} - -void draw_hand_column( - Hand hand, - int16_t pos_x, - int16_t pos_y, - int8_t highlight, - Canvas* const canvas) { - if(hand.index == 0) { - draw_card_space(pos_x, pos_y, highlight > 0, canvas); - if(highlight == 0) - draw_rounded_box(canvas, pos_x, pos_y, CARD_WIDTH, CARD_HEIGHT, Inverse); - return; - } - - int loopEnd = hand.index; - int hStart = max(loopEnd - 4, 0); - int pos = 0; - int first = first_non_flipped_card(hand); - bool wastop = false; - if(first >= 0 && first <= hStart && highlight != first) { - if(first > 0) { - draw_card_back_at(pos_x, pos_y + pos, canvas); - pos += 4; - hStart++; - wastop = true; - } - draw_card_at_colored( - pos_x, pos_y + pos, hand.cards[first].pip, hand.cards[first].character, false, canvas); - pos += 8; - hStart++; - } - if(hStart > highlight && highlight >= 0) { - if(!wastop && first > 0) { - draw_card_back_at(pos_x, pos_y + pos, canvas); - pos += 4; - hStart++; - } - draw_card_at_colored( - pos_x, - pos_y + pos, - hand.cards[highlight].pip, - hand.cards[highlight].character, - true, - canvas); - pos += 8; - hStart++; - } - for(int i = hStart; i < loopEnd; i++, pos += 4) { - if(hand.cards[i].flipped) { - draw_card_back_at(pos_x, pos_y + pos, canvas); - if(i == highlight) - draw_rounded_box( - canvas, pos_x + 1, pos_y + pos + 1, CARD_WIDTH - 2, CARD_HEIGHT - 2, Inverse); - } else { - draw_card_at_colored( - pos_x, - pos_y + pos, - hand.cards[i].pip, - hand.cards[i].character, - (i == highlight), - canvas); - if(i == highlight || i == first) pos += 4; - } - } -} - -Card remove_from_deck(uint16_t index, Deck* deck) { - FURI_LOG_D("CARD", "Removing from deck"); - Card result = {0, 0, true, false}; - if(deck->card_count > 0) { - deck->card_count--; - for(int i = 0, curr_index = 0; i <= deck->card_count; i++) { - if(i != index) { - deck->cards[curr_index] = deck->cards[i]; - curr_index++; - } else { - result = deck->cards[i]; - } - } - if(deck->index >= 0) { - deck->index--; - } - } - return result; -} - -void extract_hand_region(Hand* hand, Hand* to, uint8_t start_index) { - FURI_LOG_D("CARD", "Extracting hand region"); - if(start_index >= hand->index) return; - - for(uint8_t i = start_index; i < hand->index; i++) { - add_to_hand(to, hand->cards[i]); - } - hand->index = start_index; -} - -void add_hand_region(Hand* to, Hand* from) { - FURI_LOG_D("CARD", "Adding hand region"); - if((to->index + from->index) <= to->max) { - for(int i = 0; i < from->index; i++) { - add_to_hand(to, from->cards[i]); - } - } -} \ No newline at end of file diff --git a/applications/external/solitaire/common/card.h b/applications/external/solitaire/common/card.h deleted file mode 100644 index 8e5e23bbf..000000000 --- a/applications/external/solitaire/common/card.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include -#include -#include -#include "dml.h" - -#define CARD_HEIGHT 23 -#define CARD_HALF_HEIGHT 11 -#define CARD_WIDTH 17 -#define CARD_HALF_WIDTH 8 - -//region types -typedef struct { - uint8_t pip; //Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - uint8_t character; //Card letter [0-12], 0 means 2, 12 is Ace - bool disabled; - bool flipped; -} Card; - -typedef struct { - uint8_t deck_count; //Number of decks used - Card* cards; //Cards in the deck - int card_count; - int index; //Card index (to know where we at in the deck) -} Deck; - -typedef struct { - Card* cards; //Cards in the deck - uint8_t index; //Current index - uint8_t max; //How many cards we want to store -} Hand; -//endregion - -void set_card_graphics(const Icon* graphics); - -/** - * Gets card coordinates at the index (range: 0-20). - * - * @param index Index to check 0-20 - * @return Position of the card - */ -Vector card_pos_at_index(uint8_t index); - -/** - * Draws card at a given coordinate (top-left corner) - * - * @param pos_x X position - * @param pos_y Y position - * @param pip Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - * @param character Letter [0-12] 0 is 2, 12 is A - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_at(int8_t pos_x, int8_t pos_y, uint8_t pip, uint8_t character, Canvas* const canvas); - -/** - * Draws card at a given coordinate (top-left corner) - * - * @param pos_x X position - * @param pos_y Y position - * @param pip Pip index 0:spades, 1:hearths, 2:diamonds, 3:clubs - * @param character Letter [0-12] 0 is 2, 12 is A - * @param inverted Invert colors - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_at_colored( - int8_t pos_x, - int8_t pos_y, - uint8_t pip, - uint8_t character, - bool inverted, - Canvas* const canvas); - -/** - * Draws 'count' cards at the bottom right corner - * - * @param cards List of cards - * @param count Count of cards - * @param canvas Pointer to Flipper's canvas object - */ -void draw_deck(const Card* cards, uint8_t count, Canvas* const canvas); - -/** - * Draws card back at a given coordinate (top-left corner) - * - * @param pos_x X coordinate - * @param pos_y Y coordinate - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_back_at(int8_t pos_x, int8_t pos_y, Canvas* const canvas); - -/** - * Generates the deck - * - * @param deck_ptr Pointer to the deck - * @param deck_count Number of decks - */ -void generate_deck(Deck* deck_ptr, uint8_t deck_count); - -/** - * Shuffles the deck - * - * @param deck_ptr Pointer to the deck - */ -void shuffle_deck(Deck* deck_ptr); - -/** - * Calculates the hand count for blackjack - * - * @param cards List of cards - * @param count Count of cards - * @return Hand value - */ -uint8_t hand_count(const Card* cards, uint8_t count); - -/** - * Draws card animation - * - * @param animatingCard Card to animate - * @param from Starting position - * @param control Quadratic lerp control point - * @param to End point - * @param t Current time (0-1) - * @param extra_margin Use extra margin at the end (arrives 0.2 unit before the end so it can stay there a bit) - * @param canvas Pointer to Flipper's canvas object - */ -void draw_card_animation( - Card animatingCard, - Vector from, - Vector control, - Vector to, - float t, - bool extra_margin, - Canvas* const canvas); - -/** - * Init hand pointer - * @param hand_ptr Pointer to hand - * @param count Number of cards we want to store - */ -void init_hand(Hand* hand_ptr, uint8_t count); - -/** - * Free hand resources - * @param hand_ptr Pointer to hand - */ -void free_hand(Hand* hand_ptr); - -/** - * Add card to hand - * @param hand_ptr Pointer to hand - * @param card Card to add - */ -void add_to_hand(Hand* hand_ptr, Card card); - -/** - * Draw card placement position at coordinate - * @param pos_x X coordinate - * @param pos_y Y coordinate - * @param highlighted Apply highlight effect - * @param canvas Canvas object - */ -void draw_card_space(int16_t pos_x, int16_t pos_y, bool highlighted, Canvas* const canvas); - -/** - * Draws a column of card, displaying the last [max_cards] cards on the list - * @param hand Hand object - * @param pos_x X coordinate to draw - * @param pos_y Y coordinate to draw - * @param highlight Index to highlight, negative means no highlight - * @param canvas Canvas object - */ -void draw_hand_column( - Hand hand, - int16_t pos_x, - int16_t pos_y, - int8_t highlight, - Canvas* const canvas); - -/** - * Removes a card from the deck (Be aware, if you remove the first item, the deck index will be at -1 so you have to handle that) - * @param index Index to remove - * @param deck Deck reference - * @return The removed card - */ -Card remove_from_deck(uint16_t index, Deck* deck); - -int first_non_flipped_card(Hand hand); - -void extract_hand_region(Hand* hand, Hand* to, uint8_t start_index); - -void add_hand_region(Hand* to, Hand* from); \ No newline at end of file diff --git a/applications/external/solitaire/common/dml.c b/applications/external/solitaire/common/dml.c deleted file mode 100644 index b9a0e395f..000000000 --- a/applications/external/solitaire/common/dml.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "dml.h" -#include - -float lerp(float v0, float v1, float t) { - if(t > 1) return v1; - return (1 - t) * v0 + t * v1; -} - -Vector lerp_2d(Vector start, Vector end, float t) { - return (Vector){ - lerp(start.x, end.x, t), - lerp(start.y, end.y, t), - }; -} - -Vector quadratic_2d(Vector start, Vector control, Vector end, float t) { - return lerp_2d(lerp_2d(start, control, t), lerp_2d(control, end, t), t); -} - -Vector vector_add(Vector a, Vector b) { - return (Vector){a.x + b.x, a.y + b.y}; -} - -Vector vector_sub(Vector a, Vector b) { - return (Vector){a.x - b.x, a.y - b.y}; -} - -Vector vector_mul_components(Vector a, Vector b) { - return (Vector){a.x * b.x, a.y * b.y}; -} - -Vector vector_div_components(Vector a, Vector b) { - return (Vector){a.x / b.x, a.y / b.y}; -} - -Vector vector_normalized(Vector a) { - float length = vector_magnitude(a); - return (Vector){a.x / length, a.y / length}; -} - -float vector_magnitude(Vector a) { - return sqrt(a.x * a.x + a.y * a.y); -} - -float vector_distance(Vector a, Vector b) { - return vector_magnitude(vector_sub(a, b)); -} - -float vector_dot(Vector a, Vector b) { - Vector _a = vector_normalized(a); - Vector _b = vector_normalized(b); - return _a.x * _b.x + _a.y * _b.y; -} \ No newline at end of file diff --git a/applications/external/solitaire/common/dml.h b/applications/external/solitaire/common/dml.h deleted file mode 100644 index 0e1a23e23..000000000 --- a/applications/external/solitaire/common/dml.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// Doofy's Math library -// - -#pragma once - -typedef struct { - float x; - float y; -} Vector; - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) -#define abs(x) ((x) > 0 ? (x) : -(x)) - -/** - * Lerp function - * - * @param v0 Start value - * @param v1 End value - * @param t Time (0-1 range) - * @return Point between v0-v1 at a given time - */ -float lerp(float v0, float v1, float t); - -/** - * 2D lerp function - * - * @param start Start vector - * @param end End vector - * @param t Time (0-1 range) - * @return 2d Vector between start and end at time - */ -Vector lerp_2d(Vector start, Vector end, float t); - -/** - * Quadratic lerp function - * - * @param start Start vector - * @param control Control point - * @param end End vector - * @param t Time (0-1 range) - * @return 2d Vector at time - */ -Vector quadratic_2d(Vector start, Vector control, Vector end, float t); - -/** - * Add vector components together - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_add(Vector a, Vector b); - -/** - * Subtract vector components together - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_sub(Vector a, Vector b); - -/** - * Multiplying vector components together - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_mul_components(Vector a, Vector b); - -/** - * Dividing vector components - * - * @param a First vector - * @param b Second vector - * @return Resulting vector - */ -Vector vector_div_components(Vector a, Vector b); - -/** - * Calculating Vector length - * - * @param a Direction vector - * @return Length of the vector - */ -float vector_magnitude(Vector a); - -/** - * Get a normalized vector (length of 1) - * - * @param a Direction vector - * @return Normalized vector - */ -Vector vector_normalized(Vector a); - -/** - * Calculate two vector's distance - * - * @param a First vector - * @param b Second vector - * @return Distance between vectors - */ -float vector_distance(Vector a, Vector b); - -/** - * Calculate the dot product of the vectors. - * No need to normalize, it will do it - * - * @param a First vector - * @param b Second vector - * @return value from -1 to 1 - */ -float vector_dot(Vector a, Vector b); diff --git a/applications/external/solitaire/common/menu.c b/applications/external/solitaire/common/menu.c deleted file mode 100644 index ffc3921b7..000000000 --- a/applications/external/solitaire/common/menu.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "menu.h" - -void add_menu(Menu* menu, const char* name, void (*callback)(void*)) { - MenuItem* items = menu->items; - - menu->items = malloc(sizeof(MenuItem) * (menu->menu_count + 1)); - for(uint8_t i = 0; i < menu->menu_count; i++) { - menu->items[i] = items[i]; - } - free(items); - - menu->items[menu->menu_count] = (MenuItem){name, true, callback}; - menu->menu_count++; -} - -void free_menu(Menu* menu) { - free(menu->items); - free(menu); -} - -void set_menu_state(Menu* menu, uint8_t index, bool state) { - if(menu->menu_count > index) { - menu->items[index].enabled = state; - } - if(!state && menu->current_menu == index) move_menu(menu, 1); -} - -void move_menu(Menu* menu, int8_t direction) { - if(!menu->enabled) return; - int max = menu->menu_count; - for(int8_t i = 0; i < max; i++) { - FURI_LOG_D( - "MENU", - "Iteration %i, current %i, direction %i, state %i", - i, - menu->current_menu, - direction, - menu->items[menu->current_menu].enabled ? 1 : 0); - if(direction < 0 && menu->current_menu == 0) { - menu->current_menu = menu->menu_count - 1; - } else { - menu->current_menu = (menu->current_menu + direction) % menu->menu_count; - } - FURI_LOG_D( - "MENU", - "After process current %i, direction %i, state %i", - menu->current_menu, - direction, - menu->items[menu->current_menu].enabled ? 1 : 0); - if(menu->items[menu->current_menu].enabled) { - FURI_LOG_D("MENU", "Next menu %i", menu->current_menu); - return; - } - } - FURI_LOG_D("MENU", "Not found, setting false"); - menu->enabled = false; -} - -void activate_menu(Menu* menu, void* state) { - if(!menu->enabled) return; - menu->items[menu->current_menu].callback(state); -} - -void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y) { - if(!menu->enabled) return; - canvas_set_color(canvas, ColorWhite); - canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); - - uint8_t w = pos_x + menu->menu_width; - uint8_t h = pos_y + 10; - uint8_t p1x = pos_x + 2; - uint8_t p2x = pos_x + menu->menu_width - 2; - uint8_t p1y = pos_y + 2; - uint8_t p2y = pos_y + 8; - - canvas_set_color(canvas, ColorBlack); - canvas_draw_line(canvas, p1x, pos_y, p2x, pos_y); - canvas_draw_line(canvas, p1x, h, p2x, h); - canvas_draw_line(canvas, pos_x, p1y, pos_x, p2y); - canvas_draw_line(canvas, w, p1y, w, p2y); - canvas_draw_dot(canvas, pos_x + 1, pos_y + 1); - canvas_draw_dot(canvas, w - 1, pos_y + 1); - canvas_draw_dot(canvas, w - 1, h - 1); - canvas_draw_dot(canvas, pos_x + 1, h - 1); - - // canvas_draw_rbox(canvas, pos_x, pos_y, menu->menu_width + 2, 10, 2); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - pos_x + menu->menu_width / 2, - pos_y + 6, - AlignCenter, - AlignCenter, - menu->items[menu->current_menu].name); - //9*5 - int center = pos_x + menu->menu_width / 2; - for(uint8_t i = 0; i < 4; i++) { - for(int8_t j = -i; j <= i; j++) { - canvas_draw_dot(canvas, center + j, pos_y - 4 + i); - canvas_draw_dot(canvas, center + j, pos_y + 14 - i); - } - } -} \ No newline at end of file diff --git a/applications/external/solitaire/common/menu.h b/applications/external/solitaire/common/menu.h deleted file mode 100644 index 9f2852522..000000000 --- a/applications/external/solitaire/common/menu.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include -#include - -typedef struct { - const char* name; //Name of the menu - bool enabled; //Is the menu item enabled (it will not render, you cannot select it) - - void (*callback)( - void* state); //Callback for when the activate_menu is called while this menu is selected -} MenuItem; - -typedef struct { - MenuItem* items; //list of menu items - uint8_t menu_count; //count of menu items (do not change) - uint8_t current_menu; //currently selected menu item - uint8_t menu_width; //width of the menu - bool enabled; //is the menu enabled (it will not render and accept events when disabled) -} Menu; - -/** - * Cleans up the pointers used by the menu - * - * @param menu Pointer of the menu to clean up - */ -void free_menu(Menu* menu); - -/** - * Add a new menu item - * - * @param menu Pointer of the menu - * @param name Name of the menu item - * @param callback Callback called on activation - */ -void add_menu(Menu* menu, const char* name, void (*callback)(void*)); - -/** - * Setting menu item to be enabled/disabled - * - * @param menu Pointer of the menu - * @param index Menu index to set - * @param state Enabled (true), Disabled(false) - */ -void set_menu_state(Menu* menu, uint8_t index, bool state); - -/** - * Moves selection up or down - * - * @param menu Pointer of the menu - * @param direction Direction to move -1 down, 1 up - */ -void move_menu(Menu* menu, int8_t direction); - -/** - * Triggers the current menu callback - * - * @param menu Pointer of the menu - * @param state Usually your application state - */ -void activate_menu(Menu* menu, void* state); - -/** - * Renders the menu at a coordinate (call it in your render function). - * - * Keep in mind that Flipper has a 128x64 pixel screen resolution and the coordinate - * you give is the menu's rectangle top-left corner (arrows not included). - * The rectangle height is 10 px, the arrows have a 4 pixel height. Space needed is 18px. - * The width of the menu can be configured in the menu object. - * - * - * @param menu Pointer of the menu - * @param canvas Flippers Canvas pointer - * @param pos_x X position to draw - * @param pos_y Y position to draw - */ -void render_menu(Menu* menu, Canvas* canvas, uint8_t pos_x, uint8_t pos_y); \ No newline at end of file diff --git a/applications/external/solitaire/common/queue.c b/applications/external/solitaire/common/queue.c deleted file mode 100644 index a80373460..000000000 --- a/applications/external/solitaire/common/queue.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "queue.h" - -void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas) { - if(queue_state->current != NULL && queue_state->current->render != NULL) - ((QueueItem*)queue_state->current)->render(app_state, canvas); -} - -bool run_queue(QueueState* queue_state, void* app_state) { - if(queue_state->current != NULL) { - queue_state->running = true; - if((furi_get_tick() - queue_state->start) >= queue_state->current->duration) - dequeue(queue_state, app_state); - - return true; - } - return false; -} - -void dequeue(QueueState* queue_state, void* app_state) { - ((QueueItem*)queue_state->current)->callback(app_state); - QueueItem* f = queue_state->current; - queue_state->current = f->next; - free(f); - if(queue_state->current != NULL) { - if(queue_state->current->start != NULL) queue_state->current->start(app_state); - queue_state->start = furi_get_tick(); - } else { - queue_state->running = false; - } -} - -void queue_clear(QueueState* queue_state) { - queue_state->running = false; - QueueItem* curr = queue_state->current; - while(curr != NULL) { - QueueItem* f = curr; - curr = curr->next; - free(f); - } -} - -void enqueue( - QueueState* queue_state, - void* app_state, - void (*done)(void* state), - void (*start)(void* state), - void (*render)(const void* state, Canvas* const canvas), - uint32_t duration) { - QueueItem* next; - if(queue_state->current == NULL) { - queue_state->start = furi_get_tick(); - queue_state->current = malloc(sizeof(QueueItem)); - next = queue_state->current; - if(next->start != NULL) next->start(app_state); - - } else { - next = queue_state->current; - while(next->next != NULL) { - next = (QueueItem*)(next->next); - } - next->next = malloc(sizeof(QueueItem)); - next = next->next; - } - next->callback = done; - next->render = render; - next->start = start; - next->duration = duration; - next->next = NULL; -} \ No newline at end of file diff --git a/applications/external/solitaire/common/queue.h b/applications/external/solitaire/common/queue.h deleted file mode 100644 index dcfe0c091..000000000 --- a/applications/external/solitaire/common/queue.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include - -typedef struct { - void (*callback)(void* state); //Callback for when the item is dequeued - void (*render)( - const void* state, - Canvas* const canvas); //Callback for the rendering loop while this item is running - void (*start)(void* state); //Callback when this item is started running - void* next; //Pointer to the next item - uint32_t duration; //duration of the item -} QueueItem; - -typedef struct { - unsigned int start; //current queue item start time - QueueItem* current; //current queue item - bool running; //is the queue running -} QueueState; - -/** - * Enqueue a new item. - * - * @param queue_state The queue state pointer - * @param app_state Your app state - * @param done Callback for dequeue event - * @param start Callback for when the item is activated - * @param render Callback to render loop if needed - * @param duration Length of the item - */ -void enqueue( - QueueState* queue_state, - void* app_state, - void (*done)(void* state), - void (*start)(void* state), - void (*render)(const void* state, Canvas* const canvas), - uint32_t duration); -/** - * Clears all queue items - * - * @param queue_state The queue state pointer - */ -void queue_clear(QueueState* queue_state); - -/** - * Dequeues the active queue item. Usually you don't need to call it directly. - * - * @param queue_state The queue state pointer - * @param app_state Your application state - */ -void dequeue(QueueState* queue_state, void* app_state); - -/** - * Runs the queue logic (place it in your tick function) - * - * @param queue_state The queue state pointer - * @param app_state Your application state - * @return FALSE when there is nothing to run, TRUE otherwise - */ -bool run_queue(QueueState* queue_state, void* app_state); - -/** - * Calls the currently active queue items render callback (if there is any) - * - * @param queue_state The queue state pointer - * @param app_state Your application state - * @param canvas Pointer to Flipper's canvas object - */ -void render_queue(const QueueState* queue_state, const void* app_state, Canvas* const canvas); \ No newline at end of file diff --git a/applications/external/solitaire/common/ui.c b/applications/external/solitaire/common/ui.c deleted file mode 100644 index 032877a9e..000000000 --- a/applications/external/solitaire/common/ui.c +++ /dev/null @@ -1,257 +0,0 @@ -#include "ui.h" -#include -#include -#include -#include -#include -#include - -TileMap* tileMap; -uint8_t tileMapCount = 0; - -void ui_cleanup() { - if(tileMap != NULL) { - for(uint8_t i = 0; i < tileMapCount; i++) { - if(tileMap[i].data != NULL) free(tileMap[i].data); - } - free(tileMap); - } -} - -void add_new_tilemap(uint8_t* data, unsigned long iconId) { - TileMap* old = tileMap; - tileMapCount++; - tileMap = malloc(sizeof(TileMap) * tileMapCount); - if(tileMapCount > 1) { - for(uint8_t i = 0; i < tileMapCount; i++) tileMap[i] = old[i]; - } - tileMap[tileMapCount - 1] = (TileMap){data, iconId}; -} - -uint8_t* get_tilemap(unsigned long icon_id) { - for(uint8_t i = 0; i < tileMapCount; i++) { - if(tileMap[i].iconId == icon_id) return tileMap[i].data; - } - - return NULL; -} - -uint32_t pixel_index(uint8_t x, uint8_t y) { - return y * SCREEN_WIDTH + x; -} - -bool in_screen(int16_t x, int16_t y) { - return x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT; -} - -unsigned flipBit(uint8_t x, uint8_t bit) { - return x ^ (1 << bit); -} - -unsigned setBit(uint8_t x, uint8_t bit) { - return x | (1 << bit); -} - -unsigned unsetBit(uint8_t x, uint8_t bit) { - return x & ~(1 << bit); -} - -bool test_pixel(uint8_t* data, uint8_t x, uint8_t y, uint8_t w) { - uint8_t current_bit = (y % 8); - uint8_t current_row = ((y - current_bit) / 8); - uint8_t current_value = data[current_row * w + x]; - return current_value & (1 << current_bit); -} - -uint8_t* get_buffer(Canvas* const canvas) { - return canvas->fb.tile_buf_ptr; - // return canvas_get_buffer(canvas); -} -uint8_t* make_buffer() { - return malloc(sizeof(uint8_t) * 8 * 128); -} -void clone_buffer(uint8_t* canvas, uint8_t* data) { - for(int i = 0; i < 1024; i++) { - data[i] = canvas[i]; - } -} - -bool read_pixel(Canvas* const canvas, int16_t x, int16_t y) { - if(in_screen(x, y)) { - return test_pixel(get_buffer(canvas), x, y, SCREEN_WIDTH); - } - return false; -} - -void set_pixel(Canvas* const canvas, int16_t x, int16_t y, DrawMode draw_mode) { - if(in_screen(x, y)) { - uint8_t current_bit = (y % 8); - uint8_t current_row = ((y - current_bit) / 8); - uint32_t i = pixel_index(x, current_row); - uint8_t* buffer = get_buffer(canvas); - - uint8_t current_value = buffer[i]; - if(draw_mode == Inverse) { - buffer[i] = flipBit(current_value, current_bit); - } else { - if(draw_mode == White) { - buffer[i] = unsetBit(current_value, current_bit); - } else { - buffer[i] = setBit(current_value, current_bit); - } - } - } -} - -void draw_line( - Canvas* const canvas, - int16_t x1, - int16_t y1, - int16_t x2, - int16_t y2, - DrawMode draw_mode) { - for(int16_t x = x2; x >= x1; x--) { - for(int16_t y = y2; y >= y1; y--) { - set_pixel(canvas, x, y, draw_mode); - } - } -} - -void draw_rounded_box_frame( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode draw_mode) { - int16_t xMinCorner = x + 1; - int16_t xMax = x + w - 1; - int16_t xMaxCorner = x + w - 2; - int16_t yMinCorner = y + 1; - int16_t yMax = y + h - 1; - int16_t yMaxCorner = y + h - 2; - draw_line(canvas, xMinCorner, y, xMaxCorner, y, draw_mode); - draw_line(canvas, xMinCorner, yMax, xMaxCorner, yMax, draw_mode); - draw_line(canvas, x, yMinCorner, x, yMaxCorner, draw_mode); - draw_line(canvas, xMax, yMinCorner, xMax, yMaxCorner, draw_mode); -} - -void draw_rounded_box( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode draw_mode) { - for(int16_t o = w - 2; o >= 1; o--) { - for(int16_t p = h - 2; p >= 1; p--) { - set_pixel(canvas, x + o, y + p, draw_mode); - } - } - draw_rounded_box_frame(canvas, x, y, w, h, draw_mode); -} - -void invert_shape(Canvas* const canvas, uint8_t* data, int16_t x, int16_t y, uint8_t w, uint8_t h) { - draw_pixels(canvas, data, x, y, w, h, Inverse); -} - -void draw_pixels( - Canvas* const canvas, - uint8_t* data, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - for(int8_t o = 0; o < w; o++) { - for(int8_t p = 0; p < h; p++) { - if(in_screen(o + x, p + y) && data[p * w + o] == 1) - set_pixel(canvas, o + x, p + y, drawMode); - } - } -} - -void draw_rectangle( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - for(int8_t o = 0; o < w; o++) { - for(int8_t p = 0; p < h; p++) { - if(in_screen(o + x, p + y)) { - set_pixel(canvas, o + x, p + y, drawMode); - } - } - } -} - -void invert_rectangle(Canvas* const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h) { - draw_rectangle(canvas, x, y, w, h, Inverse); -} - -uint8_t* image_data(Canvas* const canvas, const Icon* icon) { - uint8_t* data = malloc(sizeof(uint8_t) * 8 * 128); - uint8_t* screen = canvas->fb.tile_buf_ptr; - canvas->fb.tile_buf_ptr = data; - canvas_draw_icon(canvas, 0, 0, icon); - canvas->fb.tile_buf_ptr = screen; - return data; -} - -uint8_t* getOrAddIconData(Canvas* const canvas, const Icon* icon) { - uint8_t* icon_data = get_tilemap((unsigned long)icon); - if(icon_data == NULL) { - icon_data = image_data(canvas, icon); - add_new_tilemap(icon_data, (unsigned long)icon); - } - return icon_data; -} - -void draw_icon_clip( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - uint8_t* icon_data = getOrAddIconData(canvas, icon); - - for(int i = 0; i < w; i++) { - for(int j = 0; j < h; j++) { - bool on = test_pixel(icon_data, left + i, top + j, SCREEN_WIDTH); - if(drawMode == Filled) { - set_pixel(canvas, x + i, y + j, on ? Black : White); - } else if(on) - set_pixel(canvas, x + i, y + j, drawMode); - } - } -} - -void draw_icon_clip_flipped( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode) { - uint8_t* icon_data = getOrAddIconData(canvas, icon); - - for(int i = 0; i < w; i++) { - for(int j = 0; j < h; j++) { - bool on = test_pixel(icon_data, left + i, top + j, SCREEN_WIDTH); - - if(drawMode == Filled) { - set_pixel(canvas, x + w - i - 1, y + h - j - 1, on ? Black : White); - } else if(on) - set_pixel(canvas, x + w - i - 1, y + h - j - 1, drawMode); - } - } -} \ No newline at end of file diff --git a/applications/external/solitaire/common/ui.h b/applications/external/solitaire/common/ui.h deleted file mode 100644 index 13d8da257..000000000 --- a/applications/external/solitaire/common/ui.h +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include -#include - -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 - -typedef enum { - Black, - White, - Inverse, - Filled //Currently only for Icon clip drawing -} DrawMode; - -// size is the screen size - -typedef struct { - uint8_t* data; - unsigned long iconId; -} TileMap; - -bool test_pixel(uint8_t* data, uint8_t x, uint8_t y, uint8_t w); - -uint8_t* image_data(Canvas* const canvas, const Icon* icon); - -uint32_t pixel_index(uint8_t x, uint8_t y); - -void draw_icon_clip( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_icon_clip_flipped( - Canvas* const canvas, - const Icon* icon, - int16_t x, - int16_t y, - uint8_t left, - uint8_t top, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_rounded_box( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_rounded_box_frame( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void draw_rectangle( - Canvas* const canvas, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -void invert_rectangle(Canvas* const canvas, int16_t x, int16_t y, uint8_t w, uint8_t h); - -void invert_shape(Canvas* const canvas, uint8_t* data, int16_t x, int16_t y, uint8_t w, uint8_t h); - -void draw_pixels( - Canvas* const canvas, - uint8_t* data, - int16_t x, - int16_t y, - uint8_t w, - uint8_t h, - DrawMode drawMode); - -bool read_pixel(Canvas* const canvas, int16_t x, int16_t y); - -void set_pixel(Canvas* const canvas, int16_t x, int16_t y, DrawMode draw_mode); - -void draw_line( - Canvas* const canvas, - int16_t x1, - int16_t y1, - int16_t x2, - int16_t y2, - DrawMode draw_mode); - -bool in_screen(int16_t x, int16_t y); - -void ui_cleanup(); -uint8_t* get_buffer(Canvas* const canvas); -uint8_t* make_buffer(); -void clone_buffer(uint8_t* canvas, uint8_t* data); \ No newline at end of file diff --git a/applications/external/solitaire/defines.h b/applications/external/solitaire/defines.h deleted file mode 100644 index a225b7c83..000000000 --- a/applications/external/solitaire/defines.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include "common/card.h" -#include "common/queue.h" - -#define APP_NAME "Solitaire" - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} AppEvent; - -typedef enum { GameStateGameOver, GameStateStart, GameStatePlay, GameStateAnimate } PlayState; - -typedef struct { - uint8_t* buffer; - Card card; - int8_t deck; - int indexes[4]; - float x; - float y; - float vx; - float vy; - bool started; -} CardAnimation; - -typedef struct { - Deck deck; - Hand bottom_columns[7]; - Card top_cards[4]; - bool dragging_deck; - uint8_t dragging_column; - Hand dragging_hand; - - InputKey input; - - bool started; - bool had_change; - bool processing; - bool longPress; - PlayState state; - unsigned int last_tick; - uint8_t selectRow; - uint8_t selectColumn; - int8_t selected_card; - CardAnimation animation; - uint8_t* buffer; - FuriMutex* mutex; -} GameState; \ No newline at end of file diff --git a/applications/external/solitaire/solitaire.c b/applications/external/solitaire/solitaire.c deleted file mode 100644 index 9b9c8ce74..000000000 --- a/applications/external/solitaire/solitaire.c +++ /dev/null @@ -1,580 +0,0 @@ -#include -#include -#include -#include -#include "defines.h" -#include "common/ui.h" -#include "solitaire_icons.h" -#include -#include -#include -void init(GameState* game_state); - -const NotificationSequence sequence_fail = { - &message_vibro_on, - &message_note_c4, - &message_delay_10, - &message_vibro_off, - &message_sound_off, - &message_delay_10, - - &message_vibro_on, - &message_note_a3, - &message_delay_10, - &message_vibro_off, - &message_sound_off, - NULL, -}; -int8_t columns[7][3] = { - {1, 1, 25}, - {19, 1, 25}, - {37, 1, 25}, - {55, 1, 25}, - {73, 1, 25}, - {91, 1, 25}, - {109, 1, 25}, -}; - -bool can_place_card(Card where, Card what) { - bool a_black = where.pip == 0 || where.pip == 3; - bool b_black = what.pip == 0 || what.pip == 3; - if(a_black == b_black) return false; - - int8_t a_letter = (int8_t)where.character; - int8_t b_letter = (int8_t)what.character; - if(a_letter == 12) a_letter = -1; - if(b_letter == 12) b_letter = -1; - - return (a_letter - 1) == b_letter; -} - -static void draw_scene(Canvas* const canvas, const GameState* game_state) { - if(game_state->had_change) { - int deckIndex = game_state->deck.index; - if(game_state->dragging_deck) deckIndex--; - - if((game_state->deck.index < (game_state->deck.card_count - 1) || - game_state->deck.index == -1) && - game_state->deck.card_count > 0) { - draw_card_back_at(columns[0][0], columns[0][1], canvas); - if(game_state->selectRow == 0 && game_state->selectColumn == 0) { - draw_rounded_box( - canvas, - columns[0][0] + 1, - columns[0][1] + 1, - CARD_WIDTH - 2, - CARD_HEIGHT - 2, - Inverse); - } - } else - draw_card_space( - columns[0][0], - columns[0][1], - game_state->selectRow == 0 && game_state->selectColumn == 0, - canvas); - //deck side - if(deckIndex >= 0) { - Card c = game_state->deck.cards[deckIndex]; - draw_card_at_colored( - columns[1][0], - columns[1][1], - c.pip, - c.character, - game_state->selectRow == 0 && game_state->selectColumn == 1, - canvas); - } else - draw_card_space( - columns[1][0], - columns[1][1], - game_state->selectRow == 0 && game_state->selectColumn == 1, - canvas); - - for(uint8_t i = 0; i < 4; i++) { - Card current = game_state->top_cards[i]; - bool selected = game_state->selectRow == 0 && game_state->selectColumn == (i + 3); - if(current.disabled) { - draw_card_space(columns[i + 3][0], columns[i + 3][1], selected, canvas); - } else { - draw_card_at( - columns[i + 3][0], columns[i + 3][1], current.pip, current.character, canvas); - if(selected) { - draw_rounded_box( - canvas, - columns[i + 3][0], - columns[i + 3][1], - CARD_WIDTH, - CARD_HEIGHT, - Inverse); - } - } - } - - for(uint8_t i = 0; i < 7; i++) { - bool selected = game_state->selectRow == 1 && game_state->selectColumn == i; - int8_t index = (game_state->bottom_columns[i].index - 1 - game_state->selected_card); - if(index < 0) index = 0; - draw_hand_column( - game_state->bottom_columns[i], - columns[i][0], - columns[i][2], - selected ? index : -1, - canvas); - } - - int8_t pos[2] = { - columns[game_state->selectColumn][0], - columns[game_state->selectColumn][game_state->selectRow + 1]}; - - /* draw_icon_clip(canvas, &I_card_graphics, pos[0] + CARD_HALF_WIDTH, pos[1] + CARD_HALF_HEIGHT, 30, 5, 5, 5, - Filled);*/ - - if(game_state->dragging_hand.index > 0) { - draw_hand_column( - game_state->dragging_hand, - pos[0] + CARD_HALF_WIDTH + 3, - pos[1] + CARD_HALF_HEIGHT + 3, - -1, - canvas); - } - - clone_buffer(get_buffer(canvas), game_state->animation.buffer); - } else { - clone_buffer(game_state->animation.buffer, get_buffer(canvas)); - } -} - -static void draw_animation(Canvas* const canvas, const GameState* game_state) { - if(!game_state->animation.started) { - draw_scene(canvas, game_state); - } else { - clone_buffer(game_state->animation.buffer, get_buffer(canvas)); - - draw_card_at( - (int8_t)game_state->animation.x, - (int8_t)game_state->animation.y, - game_state->animation.card.pip, - game_state->animation.card.character, - canvas); - } - - clone_buffer(get_buffer(canvas), game_state->animation.buffer); -} - -static void render_callback(Canvas* const canvas, void* ctx) { - const GameState* game_state = ctx; - furi_mutex_acquire(game_state->mutex, 25); - if(game_state == NULL) { - return; - } - - switch(game_state->state) { - case GameStateAnimate: - draw_animation(canvas, game_state); - break; - case GameStateStart: - canvas_draw_icon(canvas, 0, 0, &I_solitaire_main); - break; - case GameStatePlay: - draw_scene(canvas, game_state); - break; - default: - break; - } - - furi_mutex_release(game_state->mutex); -} - -void remove_drag(GameState* game_state) { - if(game_state->dragging_deck) { - remove_from_deck(game_state->deck.index, &(game_state->deck)); - game_state->dragging_deck = false; - } else if(game_state->dragging_column < 7) { - game_state->dragging_column = 8; - } - game_state->dragging_hand.index = 0; -} - -bool handleInput(GameState* game_state) { - Hand currentHand = game_state->bottom_columns[game_state->selectColumn]; - switch(game_state->input) { - case InputKeyUp: - if(game_state->selectRow > 0) { - int first = first_non_flipped_card(currentHand); - first = currentHand.index - first; - if((first - 1) > game_state->selected_card && game_state->dragging_hand.index == 0 && - !game_state->longPress) { - game_state->selected_card++; - } else { - game_state->selectRow--; - game_state->selected_card = 0; - } - } - break; - case InputKeyDown: - if(game_state->selectRow < 1) { - game_state->selectRow++; - game_state->selected_card = 0; - } else { - if(game_state->selected_card > 0) { - if(game_state->longPress) - game_state->selected_card = 0; - else - game_state->selected_card--; - } - } - break; - case InputKeyRight: - if(game_state->selectColumn < 6) { - game_state->selectColumn++; - game_state->selected_card = 0; - } - break; - case InputKeyLeft: - if(game_state->selectColumn > 0) { - game_state->selectColumn--; - game_state->selected_card = 0; - } - break; - case InputKeyOk: - return true; - break; - default: - break; - } - if(game_state->selectRow == 0 && game_state->selectColumn == 2) { - if(game_state->input == InputKeyRight) - game_state->selectColumn++; - else - game_state->selectColumn--; - } - if(game_state->dragging_hand.index > 0) game_state->selected_card = 0; - return false; -} - -bool place_on_top(Card* where, Card what) { - if(where->disabled && what.character == 12) { - where->disabled = what.disabled; - where->pip = what.pip; - where->character = what.character; - return true; - } else if(where->pip == what.pip) { - int8_t a_letter = (int8_t)where->character; - int8_t b_letter = (int8_t)what.character; - if(a_letter == 12) a_letter = -1; - if(b_letter == 12) b_letter = -1; - if(where->disabled && b_letter != -1) return false; - - if((a_letter + 1) == b_letter) { - where->disabled = what.disabled; - where->pip = what.pip; - where->character = what.character; - return true; - } - } - return false; -} - -void tick(GameState* game_state, NotificationApp* notification) { - game_state->last_tick = furi_get_tick(); - uint8_t row = game_state->selectRow; - uint8_t column = game_state->selectColumn; - if(game_state->state != GameStatePlay && game_state->state != GameStateAnimate) return; - bool wasAction = false; - if(game_state->state == GameStatePlay) { - if(game_state->top_cards[0].character == 11 && game_state->top_cards[1].character == 11 && - game_state->top_cards[2].character == 11 && game_state->top_cards[3].character == 11) { - game_state->state = GameStateAnimate; - game_state->had_change = true; - dolphin_deed(DolphinDeedPluginGameWin); - - return; - } - } - if(handleInput(game_state)) { - if(game_state->state == GameStatePlay) { - if(game_state->longPress && game_state->dragging_hand.index == 1) { - for(uint8_t i = 0; i < 4; i++) { - if(place_on_top( - &(game_state->top_cards[i]), game_state->dragging_hand.cards[0])) { - remove_drag(game_state); - wasAction = true; - break; - } - } - } else { - if(row == 0 && column == 0 && game_state->dragging_hand.index == 0) { - FURI_LOG_D(APP_NAME, "Drawing card"); - game_state->deck.index++; - wasAction = true; - if(game_state->deck.index >= (game_state->deck.card_count)) - game_state->deck.index = -1; - } - //pick/place from deck - else if(row == 0 && column == 1) { - //place - if(game_state->dragging_deck) { - wasAction = true; - game_state->dragging_deck = false; - game_state->dragging_hand.index = 0; - } - //pick - else { - if(game_state->dragging_hand.index == 0 && game_state->deck.index >= 0) { - wasAction = true; - game_state->dragging_deck = true; - add_to_hand( - &(game_state->dragging_hand), - game_state->deck.cards[game_state->deck.index]); - } - } - } - //place on top row - else if(row == 0 && game_state->dragging_hand.index == 1) { - column -= 3; - Card currCard = game_state->dragging_hand.cards[0]; - wasAction = place_on_top(&(game_state->top_cards[column]), currCard); - if(wasAction) remove_drag(game_state); - } - //pick/place from bottom - else if(row == 1) { - Hand* curr_hand = &(game_state->bottom_columns[column]); - //pick up - if(game_state->dragging_hand.index == 0) { - Card curr_card = curr_hand->cards[curr_hand->index - 1]; - if(curr_card.flipped) { - curr_hand->cards[curr_hand->index - 1].flipped = false; - wasAction = true; - } else { - if(curr_hand->index > 0) { - extract_hand_region( - curr_hand, - &(game_state->dragging_hand), - curr_hand->index - game_state->selected_card - 1); - game_state->selected_card = 0; - game_state->dragging_column = column; - wasAction = true; - } - } - } - //place - else { - Card first = game_state->dragging_hand.cards[0]; - if(game_state->dragging_column == column || - (curr_hand->index == 0 && first.character == 11) || - can_place_card(curr_hand->cards[curr_hand->index - 1], first)) { - add_hand_region(curr_hand, &(game_state->dragging_hand)); - remove_drag(game_state); - wasAction = true; - } - } - } - } - - if(!wasAction) { - notification_message(notification, &sequence_fail); - } - } - } - if(game_state->state == GameStateAnimate) { - if(game_state->animation.started && !game_state->longPress && - game_state->input == InputKeyOk) { - init(game_state); - game_state->state = GameStateStart; - } - - game_state->animation.started = true; - if(game_state->animation.x < -20 || game_state->animation.x > 128) { - game_state->animation.deck++; - if(game_state->animation.deck > 3) game_state->animation.deck = 0; - int8_t cardIndex = 11 - game_state->animation.indexes[game_state->animation.deck]; - - if(game_state->animation.indexes[0] == 13 && game_state->animation.indexes[1] == 13 && - game_state->animation.indexes[2] == 13 && game_state->animation.indexes[3] == 13) { - init(game_state); - game_state->state = GameStateStart; - return; - } - - if(cardIndex == -1) cardIndex = 12; - game_state->animation.card = (Card){ - game_state->top_cards[game_state->animation.deck].pip, cardIndex, false, false}; - game_state->animation.indexes[game_state->animation.deck]++; - game_state->animation.vx = -(rand() % 3 + 1) * (rand() % 2 == 1 ? 1 : -1); - game_state->animation.vy = (rand() % 3 + 1); - game_state->animation.x = columns[game_state->animation.deck + 3][0]; - game_state->animation.y = columns[game_state->animation.deck + 3][1]; - } - game_state->animation.x += game_state->animation.vx; - game_state->animation.y -= game_state->animation.vy; - game_state->animation.vy -= 1; - if(game_state->animation.vy < -10) game_state->animation.vy = -10; - - if(game_state->animation.y > 41) { - game_state->animation.y = 41; - game_state->animation.vy = -(game_state->animation.vy * 0.7f); - } - } -} - -void init(GameState* game_state) { - dolphin_deed(DolphinDeedPluginGameStart); - game_state->selectColumn = 0; - game_state->selected_card = 0; - game_state->selectRow = 0; - generate_deck(&(game_state->deck), 1); - shuffle_deck(&(game_state->deck)); - game_state->dragging_deck = false; - game_state->animation.started = false; - game_state->animation.deck = -1; - game_state->animation.x = -21; - game_state->state = GameStatePlay; - game_state->dragging_column = 8; - - for(uint8_t i = 0; i < 7; i++) { - free_hand(&(game_state->bottom_columns[i])); - init_hand(&(game_state->bottom_columns[i]), 21); - game_state->bottom_columns[i].index = 0; - for(uint8_t j = 0; j <= i; j++) { - Card cur = remove_from_deck(0, &(game_state->deck)); - cur.flipped = i != j; - add_to_hand(&(game_state->bottom_columns[i]), cur); - } - } - - for(uint8_t i = 0; i < 4; i++) { - game_state->animation.indexes[i] = 0; - game_state->top_cards[i] = (Card){0, 0, true, false}; - } - game_state->deck.index = -1; -} - -void init_start(GameState* game_state) { - game_state->input = InputKeyMAX; - for(uint8_t i = 0; i < 7; i++) init_hand(&(game_state->bottom_columns[i]), 21); - - init_hand(&(game_state->dragging_hand), 13); - game_state->animation.buffer = make_buffer(); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - AppEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); - AppEvent event = {.type = EventTypeTick}; - furi_message_queue_put(event_queue, &event, 0); -} - -int32_t solitaire_app(void* p) { - UNUSED(p); - int32_t return_code = 0; - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); - GameState* game_state = malloc(sizeof(GameState)); - init_start(game_state); - set_card_graphics(&I_card_graphics); - - game_state->state = GameStateStart; - - game_state->processing = true; - game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!game_state->mutex) { - FURI_LOG_E(APP_NAME, "cannot create mutex\r\n"); - return_code = 255; - goto free_and_exit; - } - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - notification_message_block(notification, &sequence_display_backlight_enforce_on); - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, game_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - FuriTimer* timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, furi_kernel_get_tick_frequency() / 30); - - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - AppEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 150); - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - game_state->had_change = false; - if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - game_state->had_change = true; - if(event.input.type == InputTypeLong) { - game_state->longPress = true; - switch(event.input.key) { - case InputKeyUp: - case InputKeyDown: - case InputKeyRight: - case InputKeyLeft: - case InputKeyOk: - game_state->input = event.input.key; - break; - case InputKeyBack: - processing = false; - return_code = 1; - default: - break; - } - } else if(event.input.type == InputTypePress) { - game_state->longPress = false; - switch(event.input.key) { - case InputKeyUp: - case InputKeyDown: - case InputKeyRight: - case InputKeyLeft: - case InputKeyOk: - if(event.input.key == InputKeyOk && game_state->state == GameStateStart) { - game_state->state = GameStatePlay; - init(game_state); - } else { - game_state->input = event.input.key; - } - break; - case InputKeyBack: - init(game_state); - processing = false; - return_code = 1; - break; - default: - break; - } - } - } else if(event.type == EventTypeTick) { - tick(game_state, notification); - processing = game_state->processing; - game_state->input = InputKeyMAX; - } - } - - view_port_update(view_port); - furi_mutex_release(game_state->mutex); - } - - notification_message_block(notification, &sequence_display_backlight_enforce_auto); - furi_timer_free(timer); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - view_port_free(view_port); - furi_mutex_free(game_state->mutex); - -free_and_exit: - free(game_state->animation.buffer); - ui_cleanup(); - for(uint8_t i = 0; i < 7; i++) free_hand(&(game_state->bottom_columns[i])); - - free(game_state->deck.cards); - free(game_state); - furi_message_queue_free(event_queue); - - return return_code; -} \ No newline at end of file diff --git a/applications/external/solitaire/solitaire_10px.png b/applications/external/solitaire/solitaire_10px.png deleted file mode 100644 index 3c5669dd2961a7d1d55536a4386481f33e4c0fe7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&F%}28J29*~C-V}>VGHmHasB`Q zKad%E=yDy9QuK6j4B?oWoZ!IL!_hQR(5u12;K0cghYbojI|_SvRsc=2V$gm3qDTU$ On8DN4&t;ucLK6V)*&$K@ diff --git a/applications/external/t_rex_runner/LICENSE b/applications/external/t_rex_runner/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/t_rex_runner/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/t_rex_runner/application.fam b/applications/external/t_rex_runner/application.fam deleted file mode 100644 index 739a5bd07..000000000 --- a/applications/external/t_rex_runner/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="t_rex_runner", - name="T-Rex runner", - apptype=FlipperAppType.EXTERNAL, - entry_point="trexrunner_app", - cdefines=["APP_TREXRUNNER"], - requires=["gui"], - stack_size=8 * 1024, - fap_category="Games", - fap_icon="trexrunner_icon.png", - fap_icon_assets="assets", - fap_author="@Rrycbarm", - fap_weburl="https://github.com/Rrycbarm/t-rex-runner", - fap_version="1.2", - fap_description="Play the port of the Chrome browser T-Rex game on your Flipper Zero.", -) diff --git a/applications/external/t_rex_runner/assets/Cactus.png b/applications/external/t_rex_runner/assets/Cactus.png deleted file mode 100644 index 0b832932760cca3d8844bca7960926960db06ecc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIaRt)<|NmclbN*c*OWD)K zF@)oK@{ihvhl`mHyRx-)^6&^tNJz;@@W~`paEP!dGOU=$qhxGhwg{-4!PC{xWt~$( F69C)u9Nqu` diff --git a/applications/external/t_rex_runner/assets/Dino.png b/applications/external/t_rex_runner/assets/Dino.png deleted file mode 100644 index 9e33092d6e97d0bb70365d5b88d902e21173d5df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4339 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3&ca_c%0ME|jhUIOM}IT#~)2fh401yHgE+t+^g zSs{}mDWFh8Rwkt8|NgtwfB5s!TIEB^vBaqP^TiiiIm!C`mHppnzyF^P{<>$LuPYO; z8HeUmo`@s9p$;@&-9*yL>J=bp*sxr?>EIB=z z+OC26Z7KQV?eAutgM3y`7ZP3?fr*^8(;27t|9mWP^0uzZ_5DBcoVl(<#UZ%cT5-tJ z@@_}1A071M!rnpM5ybt70@|hf})Rqq+#E?Q( zp@bS;^fAO3QxuS^$t9mciYcX>N~+mqpF@s0<(x~d#TEw!h7wCExs+0?Rh5Y2jA zcyA?g5;I*aMG-7U28oRtMj}QC{WLZ#bC2CeBy4l21dN|F!8<~4_2Ev-V-v1*3c zM`=8fW1lH;%U6uuUyY^8u@=9-t!xcqcLhDV-V;{+=VRM;tQdnFsga~GVlYQ+kO>{= z_^AV!S!~jEVnlGPAs8kz_-x523x_8Bjj`LBrg3(kavEpxR6tn61hJjjy7MEg;VT~t ziO01$$Qt+s$m4^N(~qNiz3}-l^*wl#u{*Zx$q5%%V(YS0b=G@FtrlIA!Om2iuwjK>u9|t>TH_ItR`D}+p-Y2kbNblRnu3kuhM2+=_48v8uJ}N zDK?de#VIMVO6vd9yRchyw3lq1_owX0a*`bju zJ2*1bT&|NNCMKTNX6E4lfT{w+l33o@(Ou|Z)$nn4+BL43n%WK~!v_dv3mtxddnaLR zsi%Q^V-u>jqADqwO4WDVG;w)}i^i37uXwywQqjlgLBs4O8PMzee9`I~AO6a5>cxW( z{=+lkzz6qzm)q(eq0v*|zhBxf0)OJJei8WBp@oFeRfbR9Csn&Q)z9L#S7Mg(N;D1= zSMX!B;G3BNp#g9A%M$I`28L;1wHE@dcb&Uk{gk5@s=lW2h2bg4YQ$oj;yA!M!!B1{ zeVdk3zR#WFTHN=0Qb0jlXZ0Rhn}c*oyaLxGVErSNT!3{#i zCD1zocV_gs>A+65X;>E)kk3p`SSPo4+DtmxP8F|ktBeIPpAD~OXLj4yAnm&HDJF9b zPL1jlxFjSl4m_9;Ap=SkhUL*lbCx%r4bp9cgRz7r0Ku+kGkgb-g9-~aOXjACb>C6Cifd}d9DTnOE;Im1>xGE+7_P>|wH9yNL*vsx-bQc1Bn0~Kgnx}4DB z=nyZK-($k#?wKg5FWJH%_iz)graXZK+EXU}yWi#srFFA6fOsBFpup2f2|&r#7|ZtQ zOlxr87OrOepd@I7q9srgg8Dne?It(WCwe2yPB$ydNFTA$VUP?>=+XjODY!xoWB{f2 z(HbJw!)gaoxKAJ+gp#m_lmGgu0(SbdYAJxdY5Jbs>LaV4?-{fxHcYG%kfB6rPqmlB z(s-??DdIaNjZ^IcO^ei5h@PHkz zX<=Zlp%!INeb%1DirBw$nOZ+~@ApUbbsXN2Kg{>;acdsxbdMh>|8o4cdA5AG^XvnS zn`c{L&_xO!+{us+K$N$%(I)K!j5fkqSEa!V=eCsb010xBlfFT{ECm`0QSQlOG@Vpv zBJP$q%5ok2qFLboMT5cTNu&zxg{kNl5d>c}eFfn}odc`~jii0d<@+EZBP_*<{HLpr zh`6s&`drtrP)k1KDdc`ax`u5kryo-3&yFODE`#PUt4h;Bk?31!;>9WKGtee7ig-(Mjm%AtxWtcMZr!Ah5{Z$w_6f`Vq%A@>w%nur!KuKtqxQC5i>aCHF1ZIm zZ>{7l_hi?@Zn@|Gq*T>Q6WZBg4haOnmgMKiwxXP11}=b8RBD2Y9oM7^e;+JQ`Gmlr z&^_Vry|kQ1&mB$-58xzQ061;NdvuzS(!Hy+mSh({NrM!1hPt7#O^2Qeh+%r+%J9hv zlv1{clK|>7xo4({Rz_er8n`aKv3ORpdQ}a``K9JxWN@~-42Z@CvN+TX3q;0z0AyA- zyn)t`cV5)B(Vkupva#3{Ncke2p}6%PT!j+=l8`I`)d!tCn7jLzZ&uV}8M1*-n-$chfu#}G!8vW3 z;F1FBr02x5Hv-fd@n_F}0=hfkwcT=^l9Z9s!-%sbu=d`u^a(%>R)e^S6+VQ@kp=}r zs2+7H>V^(Hh*+qtIZ7lz1{=6ohyghYW|0i3{KTAxqx$>?WNXR({0h>M;BnA2t6OWK z!01qF5Ic+G<(DLjAa+?HlUP9QyN_Ir5$!zn@tFzkNWN~;-U)yRcGe7|mw9}La8N+9 z=buCMCYH$EVh9m)7*p+JwqCjgPi1ozGE(UTn-3qpO#5lVmfKNF3c8f%7O?YU`#doG?##Q)(28 z>`tRMmqnrwI0HEVP>}>s(J0#>Ede8uuCk>FL{zMtZtBZd?QC@ngznfJ2g>ZK2)sr+ zY~W|ey;TQ2MEBEmCIVNw5ZIX0pPjuyl74u$7X%R7QUn+~X1J7Bl)Of_8tL^gZ77TE z%30KeG|C%AgumeMqsvQ*C=C_mrwF8NQ4%J35k&DeXt|>Cq3dsm`Y@T+FM|5VOihp{L60{ zJIXTI6u0%H!VPtGd(FU5wBn$rMSW=`T~E|aHKg-(K~9aqZ&xzD0`aBOq)`2 znuQDe;CCys^vhcM;)gnxhbij+=k2P?-Fo~;0004nX+uL$Nkc;*aB^>EX>4Tx0C=2z zkv&MmKpe$iTeVUu73?75kfC+5AS&XhRVYG*P%E_RU~=h)(4-+rad8w}3l4rPRvlcN zb#-tR1i=pwM<*vm7b)?7NufoI2gm(*ckglc4)8ZBOf|d409CV$Oe!hl@+(5{6(RJa z2NA?2X6mz|n1<*0x`&UicL|>5eeTcErxZ*E_ypn^rW+RVI`Pz|rE}gVjPFL`jhl}TZYdCbgo&+XqU817C3V8f6F@bEt)Tibti2?Y}#`9BOxcqLxVwl}z9Sf8*V@y7v$gI^jO8zq~hZ`d2i xFg#-aBQIfhqCVk=<$vbG^M53A zBGxD1R0I(muncvmI24sy6{=_*pd#Xg50Q5hP;tHfajn;XX04lh?m6H7_TJyw=bU@j z@s}*LL`+A(U@*%7fA&)7o&jA`;6~8@#x-+1U@&7wnjl=W6i7iTRSJnT2}EjAl^_z- zNhL6t?&g!Qpd)RSh>;Zg+H551_>7>cQs?%;hw*>yyp=vI>Q9e3oFH_Yo|Q3Uvdx2- z@6v{h9ImJ3xJIfjzG>N#P+bG?4-F>_2ZY_coX+&QI|BMFA6b=KB7CvxtNX0cl6`Zs zP9!>>ci{esN39&;U%eaC?da@#lAPzbzO~YYJL9R9#<6bYvamy()AHsAU4>`Ax{&_; z%h;}yyB2r01ExO#INx+-A zE}EZO(0!$1aKRJHgLYQtr=95YhYO!)-Y3ny^&-Y~pNjiT8-3y8+~tbSm}A54O|RES z)fEH1tEew;^tfbRLJHSm;co}`HW+(qj^%~kx$azP>2+YYw%QKcT zdZq*sa%&cLZ_c4~-pF)>)5(LC%Ttx`o$0MRy?nI0G4;{RB&qQx(@e5W$*;+4X4Vf} zHSX_ox5g~%u!OzHTjBI|g6I8CTk(SIw~it8nKPe^L^cqui@`s&?734CX%@EsnPW3x zQtIpe=;=K_##EycvkK#1tc~F1T+iai9gbVf)_TG!eP5nKPq#)Ed6kP7w>#Y^ZeWYn zb$qkIhTx1Zj5Tr1CVBi=bsHACXwvAff;%i;_@-QO5PIoe@DlplOA*fzdAx{V{;vnB zIs5Bd-0abf@#wu!hCJ$PCumoZmy-_cm-?RuW}@x6sWmAfm)FG8f)VM(15M zI$^C~JE%r&<-S)fYxyhwv-~K>!>ce?WOETm z+r{ZTk#e8nk!VK$lXN~TFJI;&Kb&1~^*eXP62-2Vrqy=`qhfVihF0!q*?uji&#v3; zUFg06UN26I_`|h+6Yp)WH+p4IL$bDL*1&R_3#CZa&^;AtS0;}> zBO?zw^m#r{h(@|pwX>Nqwa4Ss`L*-5_wo1AO_pm;6>qd(VIIBh=D_INN28sEtE+;C zkT1g+Ie|8#IZJ-yk?vo)pRq0ajjs)_Xlqg<1tn~zKVDm!K;}HsoOG;A*Hz!zf5EZ9 z^GF#3`KoolC}PVCx>LUKaCTjguBLLm!#y8be#yfh)p-6XmMOdMD;@f$!SHlD_q0%j zv6B0`cUfj#7^~^_;P;1JuA9A^hac)Vi{hP0YHLjOX#L@GBy<0)h?iP7dSD^ujEQp$GTqsBdY}i4a2L9F(GdAW-UgB zn^C{FsW_bDB=mSib>_O?a8k0?=Ip?77Hzmmw%p#78uTMGW4fz(BmO*WsehA^`(N$! z>PS{cR!L~chO(OZP6v~F)}#rlVg#*OqMT#Rm;?7tn<;@EQ8%{%D|gU`5t5C~TZ44L z5#?IH@IGxPoS9{LZQzMAo-uuWRXx2p@8s>8{s;W#{Ju$3{hi)<@0+!#y6bDi4bm^J zj@6sXUDT21`h;6&_$EI#5!{efG&xDQ5?gpfpdHG#_Vrp%Z=NQtv7Kw;Fk2@solO;3 zl!2GdkXVZf_LR3}RP%G0{imG}y1)VJX{Wm^K(^&~Mqhh7=%TldcEMoqY$=Py4`8w0 z@1oG&S(aYJ^lx1-@b?ljDN+RyCohWqVl5!5D5;!`g8|11(x zkIglSnYO^H#W6Eb`0t(mILRG)Q~%w2eNn}6sk?^NFVLx*;XXyWg2!t)Cw;wZrH{*A zuWLQvif((@cF!bg<4{rGkqe5l{HYe+q$Kgu=WT$n=0>y1w06^On?T!zb|HIK&FVYS zlA2!|Syj`?d}F~%mAPHimbT`K%*|bA`Ee~lLF}wW`?-1R?4F$Ue#XTis-s<@Twic_|C}sCba34+mlWu$`uFG%Y0x?y$Nqjyu2o# z$tyn9|E$0NQujON)!wJ3^B${;?z){Sf=)X}DRioZ^Al!2E4we{UN6w(0EBr;LqJU)`8P=QD?mW;(?I67%E5#@tGdaJ|| z#!@zSoC11cqT)3gB?E^`NlC$`kgy6>9F9Pz({Xqrj!48n2#h*at^sryxq7yqVvK_g zszoZPQX^H!k$O%*sL*PdC=@h~d>@}o$>V*Xm#fEBfb_uW040uq#p7f$+(ZkthLa4D zj0g0$7HR?Xa)4V3sufz52;?M#a?R|C6k^c_d!<&DWJpIW!huPk41%g5uY^xrE)3xD zKUnA`h?B~c1}jMHPmmg^0Y^1gZeJS_8;Mpq>gM z$4Vg{8c8gn0aQAM4oV~#G8KecBtVSuBGJVX3Y9`6iAWPD0##C|DuJYlQR%6~dMXNu zK%sfjF%p0VQ2`_xhK?taFhY_=Kpcou%Hs?JdchgK z`~W73h#i9(diY6zMgkc?Yd|U&D^k=S!2+oa4Aua8Jqc7V5|v6Olj(Rb8r_Tf5flol z)KD$zSqXS7X^dGvF$^djNLoN&sSts|0?LNLQh|U*p%N$*NlcVJ1f<^5P~b@Kv1##_ zsv$(GzUIfPJ{Vjv_B6H#lB9+qB+^j03_vvIL=7Z^VuK^dZfr;t56I&{XoZiL)cbzv z-%J;t0Mdv;3I!5XOu~>wA_B&X4nRUvKnX!YBYSq zknZDRqCdr_#DjXJ^b?1tVDNMSk;ovC8F)GhH=Zm`zoy@3>y7&#J-iKo37Y_9H`WJj zF3?_u`>!p|QAN-Ba!$0T&qWUH><^ z5FbBxKsodVlmdOsH1V!ahCYN$_=^P`=>GckYuUN>7^npoe!Gwj%QbfPhaSw8{t;>z z%)(ZG!C|Fkj!>tmCV84vmPzI)zkciR+pl(3)u((lPa$P^a9S;9W#7rW-aup{^* diff --git a/applications/external/t_rex_runner/trexrunner.c b/applications/external/t_rex_runner/trexrunner.c deleted file mode 100644 index c676c407e..000000000 --- a/applications/external/t_rex_runner/trexrunner.c +++ /dev/null @@ -1,289 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "t_rex_runner_icons.h" -#include - -#define DINO_START_X 10 -#define DINO_START_Y 34 // 64 - 22 - BACKGROUND_H / 2 - 2 - -#define FPS 20 - -#define DINO_RUNNING_MS_PER_FRAME 500 - -#define GRAVITY 60 -#define JUMP_SPEED 30 - -#define CACTUS_W 10 -#define CACTUS_H 10 -#define START_x_speed 35 -#define X_INCREASE 3 - -#define BACKGROUND_W 128 -#define BACKGROUND_H 12 - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - FuriTimer* timer; - uint32_t last_tick; - const Icon* dino_icon; - int dino_frame_ms; - FuriMutex* mutex; - - // Dino info - float y_position; - float y_speed; - int y_acceleration; - float x_speed; - - // Cactus info - int cactus_position; - int has_cactus; - - // Horizontal line - int background_position; - - int lost; - - int score; -} GameState; - -static void timer_callback(void* ctx) { - GameState* game_state = ctx; - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - - if(game_state == NULL) { - return; - } - - uint32_t ticks_elapsed = furi_get_tick() - game_state->last_tick; - game_state->last_tick = furi_get_tick(); - int delta_time_ms = ticks_elapsed * 1000 / furi_kernel_get_tick_frequency(); - - // dino update - game_state->dino_frame_ms += delta_time_ms; - // TODO: switch by dino state - if(game_state->dino_frame_ms >= DINO_RUNNING_MS_PER_FRAME) { - if(game_state->dino_icon == &I_DinoRun0) { - game_state->dino_icon = &I_DinoRun1; - } else { - game_state->dino_icon = &I_DinoRun0; - } - game_state->dino_frame_ms = 0; - } - - // Compute dino dynamics - game_state->y_acceleration = game_state->y_acceleration - GRAVITY * delta_time_ms / 1000; - game_state->y_speed = game_state->y_speed + game_state->y_acceleration * delta_time_ms / 1000; - game_state->y_position = game_state->y_position - game_state->y_speed * delta_time_ms / 1000; - - // Touch ground - if(game_state->y_position >= DINO_START_Y) { - game_state->y_acceleration = 0; - game_state->y_speed = 0; - game_state->y_position = DINO_START_Y; - } - - // Update Cactus state - if(game_state->has_cactus) { - game_state->cactus_position = - game_state->cactus_position - (game_state->x_speed - 15) * delta_time_ms / 1000; - if(game_state->cactus_position <= 0) { - game_state->has_cactus = 0; - game_state->score = game_state->score + 1; - - // Increase speed - game_state->x_speed = game_state->x_speed + X_INCREASE; - } - } - // Create cactus (random frame in 1.5s) - else { - uint8_t randomuint8[1]; - furi_hal_random_fill_buf(randomuint8, 1); - if(randomuint8[0] % 30 == 0) { - game_state->has_cactus = 1; - game_state->cactus_position = 120; - } - } - - // Move horizontal line - if(game_state->background_position <= -BACKGROUND_W) - game_state->background_position += BACKGROUND_W; - game_state->background_position = - game_state->background_position - game_state->x_speed * delta_time_ms / 1000; - - // Lose condition - if(game_state->has_cactus && ((game_state->y_position + 22 >= (64 - CACTUS_H)) && - ((DINO_START_X + 20) >= game_state->cactus_position) && - (DINO_START_X <= (game_state->cactus_position + CACTUS_W)))) - game_state->lost = 1; - - furi_mutex_release(game_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void render_callback(Canvas* const canvas, void* ctx) { - const GameState* game_state = ctx; - furi_mutex_acquire(game_state->mutex, FuriWaitForever); - - if(game_state == NULL) { - return; - } - - char score_string[12]; - if(!game_state->lost) { - // Show Ground - canvas_draw_icon( - canvas, game_state->background_position, 64 - BACKGROUND_H, &I_HorizonLine0); - canvas_draw_icon( - canvas, - game_state->background_position + BACKGROUND_W, - 64 - BACKGROUND_H, - &I_HorizonLine0); - - // Show DINO - canvas_draw_icon(canvas, DINO_START_X, game_state->y_position, game_state->dino_icon); - - // Show cactus - if(game_state->has_cactus) - //canvas_draw_triangle(canvas, game_state->cactus_position, 64 - BACKGROUND_H + CACTUS_W, CACTUS_W, CACTUS_H, CanvasDirectionBottomToTop); - canvas_draw_icon( - canvas, - game_state->cactus_position, - 64 - BACKGROUND_H / 2 - CACTUS_H - 2, - &I_Cactus); - - // Show score - if(game_state->score == 0) canvas_set_font(canvas, FontSecondary); - snprintf(score_string, 12, "Score: %d", game_state->score); - canvas_draw_str_aligned(canvas, 85, 5, AlignLeft, AlignTop, score_string); - - } else { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "You lost :c"); - } - - furi_mutex_release(game_state->mutex); -} - -static void game_state_init(GameState* const game_state) { - game_state->last_tick = furi_get_tick(); - game_state->dino_frame_ms = 0; - game_state->dino_icon = &I_Dino; - game_state->y_acceleration = game_state->y_speed = 0; - game_state->y_position = DINO_START_Y; - game_state->has_cactus = 0; - game_state->background_position = 0; - game_state->lost = 0; - game_state->x_speed = START_x_speed; - game_state->score = 0; - game_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); -} - -static void game_state_reinit(GameState* const game_state) { - game_state->last_tick = furi_get_tick(); - game_state->y_acceleration = game_state->y_speed = 0; - game_state->y_position = DINO_START_Y; - game_state->has_cactus = 0; - game_state->background_position = 0; - game_state->lost = 0; - game_state->x_speed = START_x_speed; - game_state->score = 0; -} - -int32_t trexrunner_app() { - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - GameState* game_state = malloc(sizeof(GameState)); - game_state_init(game_state); - - if(!game_state->mutex) { - FURI_LOG_E("T-rex runner", "cannot create mutex\r\n"); - free(game_state); - return 255; - } - // BEGIN IMPLEMENTATION - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, game_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - game_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, game_state); - - furi_timer_start(game_state->timer, (uint32_t)furi_kernel_get_tick_frequency() / FPS); - - // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort) { - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyLeft: - break; - case InputKeyRight: - break; - case InputKeyOk: - if(game_state->lost) { - game_state_reinit(game_state); - break; - } - if(game_state->y_position == DINO_START_Y) - game_state->y_speed = JUMP_SPEED; - break; - case InputKeyMAX: - break; - case InputKeyBack: - // Exit the app - processing = false; - break; - } - } - } - } - view_port_update(view_port); - furi_mutex_release(game_state->mutex); - } - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close("gui"); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(game_state->mutex); - furi_timer_free(game_state->timer); - free(game_state); - - return 0; -} diff --git a/applications/external/t_rex_runner/trexrunner_icon.png b/applications/external/t_rex_runner/trexrunner_icon.png deleted file mode 100644 index 0b832932760cca3d8844bca7960926960db06ecc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIaRt)<|NmclbN*c*OWD)K zF@)oK@{ihvhl`mHyRx-)^6&^tNJz;@@W~`paEP!dGOU=$qhxGhwg{-4!PC{xWt~$( F69C)u9Nqu` diff --git a/applications/external/t_rex_runner/uncut_assets/HorizonLine0.png b/applications/external/t_rex_runner/uncut_assets/HorizonLine0.png deleted file mode 100644 index b326cbb7f470f4d0796e18cbe8babfd065303422..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 203 zcmeAS@N?(olHy`uVBq!ia0y~yV2S{;c^H|2WQ#^%IFMos@Ck7R(%-*-&pmM_9>{9& zba4#PIG_B(-}Zok(3wSQ5_cYcJuj#D#b552Ro}85vfC{ce0l00Ec^5CKf4}l(qHCB z`wJ%iRCx67zkI;YDvrDSYUTgxeJ=F>Pw4rsap?Jfl9R zTq{#`%DM6hk$)2UKOR2v?s1ullm7p5m5=8OE;H=iqdDtX^Y(K`N<9fa_k_4qS!W_|n# zLio)(|A#oUp8u;q|F0g^EOa3MkAcDd0Rut6|DQn~T{kv6=b!&i4!~;G0eMQy`e%<6 z+i;VPqbY93lSF`;82-Rb`TZXe>>$=ZApVQ+H;B0Z{|8ha8tVOEa_9fYIQ490km z8rA=i#2=&kaX;84hmjoc5vJhpc?_>Yfju$@lx!LJ!5)KWocp*PiO|cBoZvshO#=Xk WcPDMu%7Baj0000 - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/tuning_fork/application.fam b/applications/external/tuning_fork/application.fam deleted file mode 100644 index 5e86a6ad1..000000000 --- a/applications/external/tuning_fork/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="tuning_fork", - name="Tuning Fork", - apptype=FlipperAppType.EXTERNAL, - entry_point="tuning_fork_app", - cdefines=["APP_TUNING_FORM"], - requires=[ - "gui", - ], - fap_icon="tuning_fork_icon.png", - fap_category="Media", - stack_size=2 * 1024, - fap_author="@besya & (Fixes by @Willy-JL)", - fap_weburl="https://github.com/besya/flipperzero-tuning-fork", - fap_version="1.0", - fap_description="Tuning fork for tuning musical instruments", -) diff --git a/applications/external/tuning_fork/notes.h b/applications/external/tuning_fork/notes.h deleted file mode 100644 index c00b4f8ed..000000000 --- a/applications/external/tuning_fork/notes.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef NOTES -#define NOTES - -#define C0 16.35f -#define Cs0 17.32f -#define Db0 17.32f -#define D0 18.35f -#define Ds0 19.45f -#define Eb0 19.45f -#define E0 20.60f -#define F0 21.83f -#define Fs0 23.12f -#define Gb0 23.12f -#define G0 24.50f -#define Gs0 25.96f -#define Ab0 25.96f -#define A0 27.50f -#define As0 29.14f -#define Bb0 29.14f -#define B0 30.868f -#define C1 32.70f -#define Cs1 34.65f -#define Db1 34.65f -#define D1 36.71f -#define Ds1 38.89f -#define Eb1 38.89f -#define E1 41.203f -#define F1 43.65f -#define Fs1 46.25f -#define Gb1 46.25f -#define G1 49.00f -#define Gs1 51.91f -#define Ab1 51.91f -#define A1 55.00f -#define As1 58.27f -#define Bb1 58.27f -#define B1 61.74f -#define C2 65.41f -#define Cs2 69.30f -#define Db2 69.30f -#define D2 73.416f -#define Ds2 77.78f -#define Eb2 77.78f -#define E2 82.41f -#define F2 87.31f -#define Fs2 92.50f -#define Gb2 92.50f -#define G2 97.999f -#define Gs2 103.83f -#define Ab2 103.83f -#define A2 110.00f -#define As2 116.54f -#define Bb2 116.54f -#define B2 123.47f -#define C3 130.813f -#define Cs3 138.59f -#define Db3 138.59f -#define D3 146.83f -#define Ds3 155.56f -#define Eb3 155.56f -#define E3 164.81f -#define F3 174.61f -#define Fs3 185.00f -#define Gb3 185.00f -#define G3 196.00f -#define Gs3 207.65f -#define Ab3 207.65f -#define A3 220.00f -#define As3 233.08f -#define Bb3 233.08f -#define B3 246.94f -#define C4 261.63f -#define Cs4 277.18f -#define Db4 277.18f -#define D4 293.66f -#define Ds4 311.13f -#define Eb4 311.13f -#define E4 329.63f -#define F4 349.23f -#define Fs4 369.99f -#define Gb4 369.99f -#define G4 392.00f -#define Gs4 415.30f -#define Ab4 415.30f -#define A4 440.00f -#define As4 466.16f -#define Bb4 466.16f -#define B4 493.88f -#define C5 523.25f -#define Cs5 554.37f -#define Db5 554.37f -#define D5 587.33f -#define Ds5 622.25f -#define Eb5 622.25f -#define E5 659.25f -#define F5 698.46f -#define Fs5 739.99f -#define Gb5 739.99f -#define G5 783.99f -#define Gs5 830.61f -#define Ab5 830.61f -#define A5 880.00f -#define As5 932.33f -#define Bb5 932.33f -#define B5 987.77f -#define C6 1046.50f -#define Cs6 1108.73f -#define Db6 1108.73f -#define D6 1174.66f -#define Ds6 1244.51f -#define Eb6 1244.51f -#define E6 1318.51f -#define F6 1396.91f -#define Fs6 1479.98f -#define Gb6 1479.98f -#define G6 1567.98f -#define Gs6 1661.22f -#define Ab6 1661.22f -#define A6 1760.00f -#define As6 1864.66f -#define Bb6 1864.66f -#define B6 1975.53f -#define C7 2093.00f -#define Cs7 2217.46f -#define Db7 2217.46f -#define D7 2349.32f -#define Ds7 2489.02f -#define Eb7 2489.02f -#define E7 2637.02f -#define F7 2793.83f -#define Fs7 2959.96f -#define Gb7 2959.96f -#define G7 3135.96f -#define Gs7 3322.44f -#define Ab7 3322.44f -#define A7 3520.00f -#define As7 3729.31f -#define Bb7 3729.31f -#define B7 3951.07f -#define C8 4186.01f -#define Cs8 4434.92f -#define Db8 4434.92f -#define D8 4698.63f -#define Ds8 4978.03f -#define Eb8 4978.03f -#define E8 5274.04f -#define F8 5587.65f -#define Fs8 5919.91f -#define Gb8 5919.91f -#define G8 6271.93f -#define Gs8 6644.88f -#define Ab8 6644.88f -#define A8 7040.00f -#define As8 7458.62f -#define Bb8 7458.62f -#define B8 7902.13f - -#endif //NOTES diff --git a/applications/external/tuning_fork/tuning_fork.c b/applications/external/tuning_fork/tuning_fork.c deleted file mode 100644 index 3ff76fa9c..000000000 --- a/applications/external/tuning_fork/tuning_fork.c +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "notes.h" -#include "tunings.h" - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -enum Page { Tunings, Notes }; - -typedef struct { - FuriMutex* mutex; - bool playing; - enum Page page; - int current_tuning_note_index; - int current_tuning_index; - float volume; - TUNING tuning; -} TuningForkState; - -static TUNING current_tuning(TuningForkState* tuningForkState) { - return tuningForkState->tuning; -} - -static NOTE current_tuning_note(TuningForkState* tuningForkState) { - return current_tuning(tuningForkState).notes[tuningForkState->current_tuning_note_index]; -} - -static float current_tuning_note_freq(TuningForkState* tuningForkState) { - return current_tuning_note(tuningForkState).frequency; -} - -static void current_tuning_note_label(TuningForkState* tuningForkState, char* outNoteLabel) { - for(int i = 0; i < 20; ++i) { - outNoteLabel[i] = current_tuning_note(tuningForkState).label[i]; - } -} - -static void current_tuning_label(TuningForkState* tuningForkState, char* outTuningLabel) { - for(int i = 0; i < 20; ++i) { - outTuningLabel[i] = current_tuning(tuningForkState).label[i]; - } -} - -static void updateTuning(TuningForkState* tuning_fork_state) { - tuning_fork_state->tuning = TuningList[tuning_fork_state->current_tuning_index]; - tuning_fork_state->current_tuning_note_index = 0; -} - -static void next_tuning(TuningForkState* tuning_fork_state) { - if(tuning_fork_state->current_tuning_index == TUNINGS_COUNT - 1) { - tuning_fork_state->current_tuning_index = 0; - } else { - tuning_fork_state->current_tuning_index += 1; - } - updateTuning(tuning_fork_state); -} - -static void prev_tuning(TuningForkState* tuning_fork_state) { - if(tuning_fork_state->current_tuning_index - 1 < 0) { - tuning_fork_state->current_tuning_index = TUNINGS_COUNT - 1; - } else { - tuning_fork_state->current_tuning_index -= 1; - } - updateTuning(tuning_fork_state); -} - -static void next_note(TuningForkState* tuning_fork_state) { - if(tuning_fork_state->current_tuning_note_index == - current_tuning(tuning_fork_state).notes_length - 1) { - tuning_fork_state->current_tuning_note_index = 0; - } else { - tuning_fork_state->current_tuning_note_index += 1; - } -} - -static void prev_note(TuningForkState* tuning_fork_state) { - if(tuning_fork_state->current_tuning_note_index == 0) { - tuning_fork_state->current_tuning_note_index = - current_tuning(tuning_fork_state).notes_length - 1; - } else { - tuning_fork_state->current_tuning_note_index -= 1; - } -} - -static void increase_volume(TuningForkState* tuning_fork_state) { - if(tuning_fork_state->volume < 1.0f) { - tuning_fork_state->volume += 0.1f; - } -} - -static void decrease_volume(TuningForkState* tuning_fork_state) { - if(tuning_fork_state->volume > 0.0f) { - tuning_fork_state->volume -= 0.1f; - } -} - -static void play(TuningForkState* tuning_fork_state) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start( - current_tuning_note_freq(tuning_fork_state), tuning_fork_state->volume); - } -} - -static void stop() { - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } -} - -static void replay(TuningForkState* tuning_fork_state) { - stop(); - play(tuning_fork_state); -} - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - TuningForkState* tuning_fork_state = ctx; - furi_mutex_acquire(tuning_fork_state->mutex, FuriWaitForever); - - FuriString* tempStr = furi_string_alloc(); - - canvas_draw_frame(canvas, 0, 0, 128, 64); - - canvas_set_font(canvas, FontPrimary); - - if(tuning_fork_state->page == Tunings) { - char tuningLabel[20]; - current_tuning_label(tuning_fork_state, tuningLabel); - furi_string_printf(tempStr, "< %s >", tuningLabel); - canvas_draw_str_aligned( - canvas, 64, 28, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); - furi_string_reset(tempStr); - } else { - char tuningLabel[20]; - current_tuning_label(tuning_fork_state, tuningLabel); - furi_string_printf(tempStr, "%s", tuningLabel); - canvas_draw_str_aligned( - canvas, 64, 8, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); - furi_string_reset(tempStr); - - char tuningNoteLabel[20]; - current_tuning_note_label(tuning_fork_state, tuningNoteLabel); - furi_string_printf(tempStr, "< %s >", tuningNoteLabel); - canvas_draw_str_aligned( - canvas, 64, 24, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); - furi_string_reset(tempStr); - } - - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Prev"); - elements_button_right(canvas, "Next"); - - if(tuning_fork_state->page == Notes) { - if(tuning_fork_state->playing) { - elements_button_center(canvas, "Stop "); - } else { - elements_button_center(canvas, "Play"); - } - } else { - elements_button_center(canvas, "Select"); - } - if(tuning_fork_state->page == Notes) { - elements_progress_bar(canvas, 8, 36, 112, tuning_fork_state->volume); - } - - furi_string_free(tempStr); - furi_mutex_release(tuning_fork_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void tuning_fork_state_init(TuningForkState* const tuning_fork_state) { - tuning_fork_state->playing = false; - tuning_fork_state->page = Tunings; - tuning_fork_state->volume = 1.0f; - tuning_fork_state->tuning = GuitarStandard6; - tuning_fork_state->current_tuning_index = 2; - tuning_fork_state->current_tuning_note_index = 0; -} - -int32_t tuning_fork_app() { - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - TuningForkState* tuning_fork_state = malloc(sizeof(TuningForkState)); - tuning_fork_state_init(tuning_fork_state); - - tuning_fork_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!tuning_fork_state->mutex) { - FURI_LOG_E("TuningFork", "cannot create mutex\r\n"); - free(tuning_fork_state); - return 255; - } - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, tuning_fork_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - - furi_mutex_acquire(tuning_fork_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort) { - // push events - switch(event.input.key) { - case InputKeyUp: - if(tuning_fork_state->page == Notes) { - increase_volume(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - break; - case InputKeyDown: - if(tuning_fork_state->page == Notes) { - decrease_volume(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - break; - case InputKeyRight: - if(tuning_fork_state->page == Tunings) { - next_tuning(tuning_fork_state); - } else { - next_note(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - break; - case InputKeyLeft: - if(tuning_fork_state->page == Tunings) { - prev_tuning(tuning_fork_state); - } else { - prev_note(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - break; - case InputKeyOk: - if(tuning_fork_state->page == Tunings) { - tuning_fork_state->page = Notes; - } else { - tuning_fork_state->playing = !tuning_fork_state->playing; - if(tuning_fork_state->playing) { - play(tuning_fork_state); - } else { - stop(); - } - } - break; - case InputKeyBack: - if(tuning_fork_state->page == Tunings) { - processing = false; - } else { - tuning_fork_state->playing = false; - tuning_fork_state->current_tuning_note_index = 0; - stop(); - tuning_fork_state->page = Tunings; - } - break; - default: - break; - } - } else if(event.input.type == InputTypeLong) { - // hold events - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - if(tuning_fork_state->page == Tunings) { - next_tuning(tuning_fork_state); - } else { - next_note(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - - break; - case InputKeyLeft: - if(tuning_fork_state->page == Tunings) { - prev_tuning(tuning_fork_state); - } else { - prev_note(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - - break; - case InputKeyOk: - break; - case InputKeyBack: - if(tuning_fork_state->page == Tunings) { - processing = false; - } else { - tuning_fork_state->playing = false; - stop(); - tuning_fork_state->page = Tunings; - tuning_fork_state->current_tuning_note_index = 0; - } - break; - default: - break; - } - } else if(event.input.type == InputTypeRepeat) { - // repeat events - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - if(tuning_fork_state->page == Tunings) { - next_tuning(tuning_fork_state); - } else { - next_note(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - - break; - case InputKeyLeft: - if(tuning_fork_state->page == Tunings) { - prev_tuning(tuning_fork_state); - } else { - prev_note(tuning_fork_state); - if(tuning_fork_state->playing) { - replay(tuning_fork_state); - } - } - - break; - case InputKeyOk: - break; - case InputKeyBack: - if(tuning_fork_state->page == Tunings) { - processing = false; - } else { - tuning_fork_state->playing = false; - stop(); - tuning_fork_state->page = Tunings; - tuning_fork_state->current_tuning_note_index = 0; - } - break; - default: - break; - } - } - } - } - - view_port_update(view_port); - furi_mutex_release(tuning_fork_state->mutex); - } - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close("gui"); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(tuning_fork_state->mutex); - furi_record_close(RECORD_NOTIFICATION); - free(tuning_fork_state); - - return 0; -} diff --git a/applications/external/tuning_fork/tuning_fork_icon.png b/applications/external/tuning_fork/tuning_fork_icon.png deleted file mode 100644 index 074d9d5900e574dbac03b4e3785152c5e2cb0632..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1187 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~$C3(BM zFfiWj5?%u2aTa()7Bet#3xP1>rMq>1fP(BLp1!W^&$xKGrB$O!lIj^47*|wxlq$-qD7Njav8u=Vft-Pbg>skKI`f8C{(J)v^; z{fpYh)>fAiK3#Tl`lM=67FW{Ck)nPoH0Jll5cAEO8-*lJhCVxRZ}N5S|JyQ5m%K2X zbLK%z^6njO4Li)bPOSEsl>5Q!QH$Zh9n*C==Ls2KTJ&bd4v9ux`K>Y9pW>KZ0}s07 zT{4PUvEl<;gFa85MWX1Tj@>TL1%>CjL@LRi%rd=tIB(BkdtHH=Zo|xANhYgEmYgZ%k`ZWGAR7I| z@k+*v^&iSpL@v!|wROxB`7-D5?U!ez^4vc!nDLI&OvaY!xYD=W`OVEYT6VC;FLf0? zov8jhq3GCGy(b+O!IwHNo6EmB%+vJD=wVE&-b=|Yt2gpZpH^5^X=X?iy=BZvtA3UH zU?caO=o@VBe9x?2yY=Q?-Jtv#+g$c*rn_I>IGOboFd7;2i~K?u&o3&U1>^{Ox;Tb# zTu-(rZeZlKwK?!XvWwyMBmw4G3qGX*rCU-XJkxxA8MJ_G4hB|6AqHlU2|&oeD8&Fu zH=s1-#V8GD2Qg|u)i5zIv}ZD~K-EM6X%O%LVvrsP&AfmSVd4TNxN5Ei%m_9}+X<(u z-++{AiEBhjN@7W>RdP`(kYX@0Ff!6LG|)9P4ly*eGBUF=G1fLPure_4?BSb^q9Hdw zB{QuOO@pDim5~WVgRf&kktouW<0pIuN(+E=1G6uR=UMqqTm;IA!Q?P~*T_3%Ertpd&&AC4)c~qs N@O1TaS?83{1OV5mj{N`t diff --git a/applications/external/tuning_fork/tunings.h b/applications/external/tuning_fork/tunings.h deleted file mode 100644 index 14bf469fe..000000000 --- a/applications/external/tuning_fork/tunings.h +++ /dev/null @@ -1,151 +0,0 @@ -#include "notes.h" - -#ifndef TUNINGS -#define TUNINGS - -typedef struct { - char label[20]; - float frequency; -} NOTE; - -typedef struct { - char label[20]; - int notes_length; - NOTE notes[20]; -} TUNING; - -const TUNING TuningForks = { - "Tuning forks", - 6, - { - {"Common A4 (440)", 440.00f}, - {"Sarti's A4 (436)", 436.00f}, - {"1858 A4 (435)", 435.00f}, - {"Verdi's A4 (432)", 432.00f}, - {"1750-1820 A4 (423.5)", 423.50f}, - {"Verdi's C4 (256.00)", 256.00f}, - }}; - -const TUNING ScientificPitch = { - "Scientific pitch", - 12, - {{"C0 (16Hz)", 16.0f}, - {"C1 (32Hz)", 32.0f}, - {"C2 (64Hz)", 64.0f}, - {"C3 (128Hz)", 128.0f}, - {"C4 (256Hz)", 256.0f}, - {"C5 (512Hz)", 512.0f}, - {"C6 (1024Hz)", 1024.0f}, - {"C7 (2048Hz)", 2048.0f}, - {"C8 (4096Hz)", 4096.0f}, - {"C9 (8192Hz)", 8192.0f}, - {"C10 (16384Hz)", 16384.0f}, - {"C11 (32768Hz)", 32768.0f}}}; - -const TUNING GuitarStandard6 = { - "Guitar Standard 6", - 6, - {{"String 1", E4}, - {"String 2", B3}, - {"String 3", G3}, - {"String 4", D3}, - {"String 5", A2}, - {"String 6", E2}}}; - -const TUNING GuitarDropD6 = { - "Guitar Drop D 6", - 6, - {{"String 1", E4}, - {"String 2", B3}, - {"String 3", G3}, - {"String 4", D3}, - {"String 5", A2}, - {"String 6", D2}}}; - -const TUNING GuitarD6 = { - "Guitar D 6", - 6, - {{"String 1", D4}, - {"String 2", A3}, - {"String 3", F3}, - {"String 4", C3}, - {"String 5", G2}, - {"String 6", D2}}}; - -const TUNING GuitarDropC6 = { - "Guitar Drop C 6", - 6, - {{"String 1", D4}, - {"String 2", A3}, - {"String 3", F3}, - {"String 4", C3}, - {"String 5", G2}, - {"String 6", C2}}}; - -const TUNING GuitarStandard7 = { - "Guitar Standard 7", - 7, - {{"String 1", E4}, - {"String 2", B3}, - {"String 3", G3}, - {"String 4", D3}, - {"String 5", A2}, - {"String 6", E2}, - {"String 7", B1}}}; - -const TUNING BassStandard4 = { - "Bass Standard 4", - 4, - {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}}}; - -const TUNING BassStandardTenor4 = { - "Bass Stand Tenor 4", - 4, - {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}}}; - -const TUNING BassStandard5 = { - "Bass Standard 5", - 5, - {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", B0}}}; - -const TUNING BassStandardTenor5 = { - "Bass Stand Tenor 5", - 5, - {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}, {"String 5", E1}}}; - -const TUNING BassDropD4 = { - "Bass Drop D 4", - 4, - {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", D1}}}; - -const TUNING BassD4 = { - "Bass D 4", - 4, - {{"String 1", F2}, {"String 2", C2}, {"String 3", G1}, {"String 4", D1}}}; - -const TUNING BassDropA5 = { - "Bass Drop A 5", - 5, - {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", A0}}}; - -#define TUNINGS_COUNT 14 - -TUNING TuningList[TUNINGS_COUNT] = { - ScientificPitch, - TuningForks, - - GuitarStandard6, - GuitarDropD6, - GuitarD6, - GuitarDropC6, - GuitarStandard7, - - BassStandard4, - BassStandardTenor4, - BassStandard5, - BassStandardTenor5, - BassDropD4, - BassD4, - BassDropA5}; - -#endif //TUNINGS diff --git a/applications/external/wifi_marauder_companion/LICENSE b/applications/external/wifi_marauder_companion/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/wifi_marauder_companion/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/wifi_marauder_companion/application.fam b/applications/external/wifi_marauder_companion/application.fam deleted file mode 100644 index dab41464b..000000000 --- a/applications/external/wifi_marauder_companion/application.fam +++ /dev/null @@ -1,12 +0,0 @@ -App( - appid="esp32_wifi_marauder", - name="[ESP32] WiFi Marauder", - fap_version=(6, 0), - apptype=FlipperAppType.EXTERNAL, - entry_point="wifi_marauder_app", - requires=["gui"], - stack_size=4 * 1024, - fap_icon="wifi_10px.png", - fap_category="WiFi", - fap_icon_assets="assets", -) diff --git a/applications/external/wifi_marauder_companion/assets/Text_10x10.png b/applications/external/wifi_marauder_companion/assets/Text_10x10.png deleted file mode 100644 index 8e8a6183dd50535729dc9c9b4f220a12dd4c600f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&u?6^qxB}__|Nk$&IsYz@rRC}3 z7*a7OIiZ2U&CSi=;0cBn1vTatM&Z;3u7g(^G9`qQn09G2aWeNXaKC0S=Q~tg57Z@F z;u=vBoS#-wo>-L1;E+?AmspUPnOCA;ke9BToS%}K{MA`f4ycg9)78&qol`;+00Iau A9smFU diff --git a/applications/external/wifi_marauder_companion/file/sequential_file.c b/applications/external/wifi_marauder_companion/file/sequential_file.c deleted file mode 100644 index d780deb12..000000000 --- a/applications/external/wifi_marauder_companion/file/sequential_file.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "sequential_file.h" - -char* sequential_file_resolve_path( - Storage* storage, - const char* dir, - const char* prefix, - const char* extension) { - if(storage == NULL || dir == NULL || prefix == NULL || extension == NULL) { - return NULL; - } - - char file_path[256]; - int file_index = 0; - - do { - if(snprintf( - file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) < - 0) { - return NULL; - } - file_index++; - } while(storage_file_exists(storage, file_path)); - - return strdup(file_path); -} - -bool sequential_file_open( - Storage* storage, - File* file, - const char* dir, - const char* prefix, - const char* extension) { - if(storage == NULL || file == NULL || dir == NULL || prefix == NULL || extension == NULL) { - return false; - } - - char* file_path = sequential_file_resolve_path(storage, dir, prefix, extension); - if(file_path == NULL) { - return false; - } - - bool success = storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS); - free(file_path); - - return success; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/file/sequential_file.h b/applications/external/wifi_marauder_companion/file/sequential_file.h deleted file mode 100644 index 4fd4794c2..000000000 --- a/applications/external/wifi_marauder_companion/file/sequential_file.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -char* sequential_file_resolve_path( - Storage* storage, - const char* dir, - const char* prefix, - const char* extension); -bool sequential_file_open( - Storage* storage, - File* file, - const char* dir, - const char* prefix, - const char* extension); \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.c deleted file mode 100644 index b992cb10a..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "wifi_marauder_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const wifi_marauder_scene_on_enter_handlers[])(void*) = { -#include "wifi_marauder_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const wifi_marauder_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "wifi_marauder_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const wifi_marauder_scene_on_exit_handlers[])(void* context) = { -#include "wifi_marauder_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers wifi_marauder_scene_handlers = { - .on_enter_handlers = wifi_marauder_scene_on_enter_handlers, - .on_event_handlers = wifi_marauder_scene_on_event_handlers, - .on_exit_handlers = wifi_marauder_scene_on_exit_handlers, - .scene_num = WifiMarauderSceneNum, -}; diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.h b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.h deleted file mode 100644 index 739e30d07..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) WifiMarauderScene##id, -typedef enum { -#include "wifi_marauder_scene_config.h" - WifiMarauderSceneNum, -} WifiMarauderScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers wifi_marauder_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "wifi_marauder_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "wifi_marauder_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "wifi_marauder_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_config.h b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_config.h deleted file mode 100644 index d223af79a..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_config.h +++ /dev/null @@ -1,15 +0,0 @@ -ADD_SCENE(wifi_marauder, start, Start) -ADD_SCENE(wifi_marauder, console_output, ConsoleOutput) -ADD_SCENE(wifi_marauder, text_input, TextInput) -ADD_SCENE(wifi_marauder, settings_init, SettingsInit) -ADD_SCENE(wifi_marauder, log_viewer, LogViewer) -ADD_SCENE(wifi_marauder, user_input, UserInput) -ADD_SCENE(wifi_marauder, script_select, ScriptSelect) -ADD_SCENE(wifi_marauder, script_options, ScriptOptions) -ADD_SCENE(wifi_marauder, script_edit, ScriptEdit) -ADD_SCENE(wifi_marauder, script_settings, ScriptSettings) -ADD_SCENE(wifi_marauder, script_confirm_delete, ScriptConfirmDelete) -ADD_SCENE(wifi_marauder, script_stage_edit, ScriptStageEdit) -ADD_SCENE(wifi_marauder, script_stage_add, ScriptStageAdd) -ADD_SCENE(wifi_marauder, script_stage_edit_list, ScriptStageEditList) -ADD_SCENE(wifi_marauder, sniffpmkid_options, SniffPmkidOptions) diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c deleted file mode 100644 index 59afded1e..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c +++ /dev/null @@ -1,219 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -char* _wifi_marauder_get_prefix_from_cmd(const char* command) { - int end = strcspn(command, " "); - char* prefix = (char*)malloc(sizeof(char) * (end + 1)); - strncpy(prefix, command, end); - prefix[end] = '\0'; - return prefix; -} - -bool _wifi_marauder_is_save_pcaps_enabled(WifiMarauderApp* app) { - if(!app->ok_to_save_pcaps) { - return false; - } - // If it is a script that contains a sniff function - if(app->script != NULL) { - return wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffRaw) || - wifi_marauder_script_has_stage( - app->script, WifiMarauderScriptStageTypeSniffBeacon) || - wifi_marauder_script_has_stage( - app->script, WifiMarauderScriptStageTypeSniffDeauth) || - wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffEsp) || - wifi_marauder_script_has_stage( - app->script, WifiMarauderScriptStageTypeSniffPmkid) || - wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffPwn); - } - // If it is a sniff function - return app->is_command && app->selected_tx_string && - strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0; -} - -void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) { - furi_assert(context); - WifiMarauderApp* app = context; - - if(app->is_writing_log) { - app->has_saved_logs_this_session = true; - storage_file_write(app->log_file, buf, len); - } - - // If text box store gets too big, then truncate it - app->text_box_store_strlen += len; - if(app->text_box_store_strlen >= WIFI_MARAUDER_TEXT_BOX_STORE_SIZE - 1) { - furi_string_right(app->text_box_store, app->text_box_store_strlen / 2); - app->text_box_store_strlen = furi_string_size(app->text_box_store) + len; - } - - // Null-terminate buf and append to text box store - buf[len] = '\0'; - furi_string_cat_printf(app->text_box_store, "%s", buf); - view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventRefreshConsoleOutput); -} - -void wifi_marauder_console_output_handle_rx_packets_cb(uint8_t* buf, size_t len, void* context) { - furi_assert(context); - WifiMarauderApp* app = context; - - if(app->is_writing_pcap) { - storage_file_write(app->capture_file, buf, len); - } -} - -void wifi_marauder_scene_console_output_on_enter(void* context) { - WifiMarauderApp* app = context; - - // Reset text box and set font - TextBox* text_box = app->text_box; - text_box_reset(text_box); - text_box_set_font(text_box, TextBoxFontText); - - // Set focus on start or end - if(app->focus_console_start) { - text_box_set_focus(text_box, TextBoxFocusStart); - } else { - text_box_set_focus(text_box, TextBoxFocusEnd); - } - - // Set command-related messages - if(app->is_command) { - furi_string_reset(app->text_box_store); - app->text_box_store_strlen = 0; - // Help message - if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) { - const char* help_msg = "Marauder companion " WIFI_MARAUDER_APP_VERSION "\n"; - furi_string_cat_str(app->text_box_store, help_msg); - app->text_box_store_strlen += strlen(help_msg); - } - // Stopscan message - if(app->show_stopscan_tip) { - const char* help_msg = "Press BACK to send stopscan\n"; - furi_string_cat_str(app->text_box_store, help_msg); - app->text_box_store_strlen += strlen(help_msg); - } - } - - // Set starting text - text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); - - // Set scene state and switch view - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput); - - // Register callbacks to receive data - wifi_marauder_uart_set_handle_rx_data_cb( - app->uart, - wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread - - if(app->ok_to_save_pcaps) { - wifi_marauder_uart_set_handle_rx_data_cb( - app->pcap_uart, - wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread - } - - // Get ready to send command - if((app->is_command && app->selected_tx_string) || app->script) { - const char* prefix = - strlen(app->selected_tx_string) > 0 ? - _wifi_marauder_get_prefix_from_cmd(app->selected_tx_string) : // Function name - app->script->name; // Script name - - // Create files *before* sending command - // (it takes time to iterate through the directory) - if(app->ok_to_save_logs) { - strcpy( - app->log_file_path, - sequential_file_resolve_path( - app->storage, MARAUDER_APP_FOLDER_LOGS, prefix, "log")); - if(app->log_file_path != NULL) { - if(storage_file_open( - app->log_file, app->log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - app->is_writing_log = true; - } else { - dialog_message_show_storage_error(app->dialogs, "Cannot open log file"); - } - } else { - dialog_message_show_storage_error(app->dialogs, "Cannot resolve log path"); - } - } - - // If it is a sniff function or script, open the pcap file for recording - if(_wifi_marauder_is_save_pcaps_enabled(app)) { - if(sequential_file_open( - app->storage, app->capture_file, MARAUDER_APP_FOLDER_PCAPS, prefix, "pcap")) { - app->is_writing_pcap = true; - } else { - dialog_message_show_storage_error(app->dialogs, "Cannot open pcap file"); - } - } - - // Send command with newline '\n' - if(app->selected_tx_string) { - if(app->ok_to_save_pcaps) { - wifi_marauder_usart_tx( - (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); - wifi_marauder_usart_tx((uint8_t*)("\n"), 1); - } else { - wifi_marauder_xtreme_uart_tx( - (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); - wifi_marauder_xtreme_uart_tx((uint8_t*)("\n"), 1); - } - } - - // Run the script if the file with the script has been opened - if(app->script != NULL) { - app->script_worker = wifi_marauder_script_worker_alloc(); - app->script_worker->save_pcaps = app->ok_to_save_pcaps; - wifi_marauder_script_worker_start(app->script_worker, app->script); - } - } -} - -bool wifi_marauder_scene_console_output_on_event(void* context, SceneManagerEvent event) { - WifiMarauderApp* app = context; - - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); - consumed = true; - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - - return consumed; -} - -void wifi_marauder_scene_console_output_on_exit(void* context) { - WifiMarauderApp* app = context; - - // Automatically stop the scan when exiting view - if(app->is_command) { - if(app->ok_to_save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n")); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n")); - } - - furi_delay_ms(50); - } - - // Unregister rx callback - wifi_marauder_uart_set_handle_rx_data_cb(app->uart, NULL); - if(app->ok_to_save_pcaps) { - wifi_marauder_uart_set_handle_rx_data_cb(app->pcap_uart, NULL); - } - - wifi_marauder_script_worker_free(app->script_worker); - app->script_worker = NULL; - - app->is_writing_pcap = false; - if(app->capture_file && storage_file_is_open(app->capture_file)) { - storage_file_close(app->capture_file); - } - - app->is_writing_log = false; - if(app->log_file && storage_file_is_open(app->log_file)) { - storage_file_close(app->log_file); - } -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_log_viewer.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_log_viewer.c deleted file mode 100644 index 6edb4a49d..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_log_viewer.c +++ /dev/null @@ -1,187 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -void wifi_marauder_scene_log_viewer_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - WifiMarauderApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -static void _read_log_page_into_text_store(WifiMarauderApp* app) { - char temp[64 + 1]; - storage_file_seek( - app->log_file, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE * (app->open_log_file_page - 1), true); - furi_string_reset(app->text_box_store); - for(uint16_t i = 0; i < (WIFI_MARAUDER_TEXT_BOX_STORE_SIZE / (sizeof(temp) - 1)); i++) { - uint16_t num_bytes = storage_file_read(app->log_file, temp, sizeof(temp) - 1); - if(num_bytes == 0) { - break; - } - temp[num_bytes] = '\0'; - furi_string_cat_str(app->text_box_store, temp); - } -} - -void wifi_marauder_scene_log_viewer_setup_widget(WifiMarauderApp* app, bool called_from_browse) { - Widget* widget = app->widget; - bool is_open = storage_file_is_open(app->log_file); - bool should_open_log = (app->has_saved_logs_this_session || called_from_browse); - if(is_open) { - _read_log_page_into_text_store(app); - } else if( - should_open_log && - storage_file_open(app->log_file, app->log_file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { - uint64_t filesize = storage_file_size(app->log_file); - app->open_log_file_num_pages = filesize / WIFI_MARAUDER_TEXT_BOX_STORE_SIZE; - int extra_page = (filesize % WIFI_MARAUDER_TEXT_BOX_STORE_SIZE != 0) ? 1 : 0; - app->open_log_file_num_pages = (filesize / WIFI_MARAUDER_TEXT_BOX_STORE_SIZE) + extra_page; - app->open_log_file_page = 1; - _read_log_page_into_text_store(app); - } else { - app->open_log_file_page = 0; - app->open_log_file_num_pages = 0; - } - - widget_reset(widget); - - if(furi_string_empty(app->text_box_store)) { - char help_msg[256]; - snprintf( - help_msg, - sizeof(help_msg), - "The log is empty! :(\nTry sending a command?\n\nSaving pcaps to flipper sdcard: %s\nSaving logs to flipper sdcard: %s", - app->ok_to_save_pcaps ? "ON" : "OFF", - app->ok_to_save_logs ? "ON" : "OFF"); - furi_string_set_str(app->text_box_store, help_msg); - } - - widget_add_text_scroll_element( - widget, 0, 0, 128, 53, furi_string_get_cstr(app->text_box_store)); - - if(1 < app->open_log_file_page && app->open_log_file_page < app->open_log_file_num_pages) { - // hide "Browse" text for middle pages - widget_add_button_element( - widget, GuiButtonTypeCenter, "", wifi_marauder_scene_log_viewer_widget_callback, app); - } else { - // only show "Browse" text on first and last page - widget_add_button_element( - widget, - GuiButtonTypeCenter, - "Browse", - wifi_marauder_scene_log_viewer_widget_callback, - app); - } - - char pagecounter[100]; - snprintf( - pagecounter, - sizeof(pagecounter), - "%d/%d", - app->open_log_file_page, - app->open_log_file_num_pages); - if(app->open_log_file_page > 1) { - if(app->open_log_file_page == app->open_log_file_num_pages) { - // only show left side page-count on last page - widget_add_button_element( - widget, - GuiButtonTypeLeft, - pagecounter, - wifi_marauder_scene_log_viewer_widget_callback, - app); - } else { - widget_add_button_element( - widget, GuiButtonTypeLeft, "", wifi_marauder_scene_log_viewer_widget_callback, app); - } - } - if(app->open_log_file_page < app->open_log_file_num_pages) { - widget_add_button_element( - widget, - GuiButtonTypeRight, - pagecounter, - wifi_marauder_scene_log_viewer_widget_callback, - app); - } -} - -void wifi_marauder_scene_log_viewer_on_enter(void* context) { - WifiMarauderApp* app = context; - - app->open_log_file_page = 0; - app->open_log_file_num_pages = 0; - bool saved_logs_exist = false; - if(!app->has_saved_logs_this_session && furi_string_empty(app->text_box_store)) { - // no commands sent yet this session, find last saved log - if(storage_dir_open(app->log_file, MARAUDER_APP_FOLDER_LOGS)) { - char name[70]; - char lastname[70]; - while(storage_dir_read(app->log_file, NULL, name, sizeof(name))) { - // keep reading directory until last file is reached - strlcpy(lastname, name, sizeof(lastname)); - saved_logs_exist = true; - } - if(saved_logs_exist) { - snprintf( - app->log_file_path, - sizeof(app->log_file_path), - "%s/%s", - MARAUDER_APP_FOLDER_LOGS, - lastname); - } - } - storage_dir_close(app->log_file); - } - - wifi_marauder_scene_log_viewer_setup_widget(app, saved_logs_exist); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget); -} - -bool wifi_marauder_scene_log_viewer_on_event(void* context, SceneManagerEvent event) { - WifiMarauderApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeCenter) { - // Browse - FuriString* predefined_filepath = furi_string_alloc_set_str(MARAUDER_APP_FOLDER_LOGS); - FuriString* selected_filepath = furi_string_alloc(); - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, ".log", &I_Text_10x10); - if(dialog_file_browser_show( - app->dialogs, selected_filepath, predefined_filepath, &browser_options)) { - strncpy( - app->log_file_path, - furi_string_get_cstr(selected_filepath), - sizeof(app->log_file_path)); - if(storage_file_is_open(app->log_file)) { - storage_file_close(app->log_file); - } - wifi_marauder_scene_log_viewer_setup_widget(app, true); - } - furi_string_free(selected_filepath); - furi_string_free(predefined_filepath); - consumed = true; - } else if(event.event == GuiButtonTypeRight) { - // Advance page - ++app->open_log_file_page; - wifi_marauder_scene_log_viewer_setup_widget(app, false); - } else if(event.event == GuiButtonTypeLeft) { - // Previous page - --app->open_log_file_page; - wifi_marauder_scene_log_viewer_setup_widget(app, false); - } - } - - return consumed; -} - -void wifi_marauder_scene_log_viewer_on_exit(void* context) { - WifiMarauderApp* app = context; - widget_reset(app->widget); - if(storage_file_is_open(app->log_file)) { - storage_file_close(app->log_file); - } -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_confirm_delete.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_confirm_delete.c deleted file mode 100644 index 8e436fe2b..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_confirm_delete.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -void wifi_marauder_scene_script_confirm_delete_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - WifiMarauderApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void wifi_marauder_scene_script_confirm_delete_on_enter(void* context) { - WifiMarauderApp* app = context; - - widget_add_button_element( - app->widget, - GuiButtonTypeLeft, - "No", - wifi_marauder_scene_script_confirm_delete_widget_callback, - app); - widget_add_button_element( - app->widget, - GuiButtonTypeRight, - "Yes", - wifi_marauder_scene_script_confirm_delete_widget_callback, - app); - - widget_add_string_element( - app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Are you sure?"); - widget_add_text_box_element( - app->widget, - 0, - 12, - 128, - 38, - AlignCenter, - AlignCenter, - "The script will be\npermanently deleted", - false); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget); -} - -bool wifi_marauder_scene_script_confirm_delete_on_event(void* context, SceneManagerEvent event) { - WifiMarauderApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - // get which button press: "Yes" or "No" - if(event.event == GuiButtonTypeRight) { - // Yes - if(app->script != NULL) { - char script_path[256]; - snprintf( - script_path, - sizeof(script_path), - "%s/%s.json", - MARAUDER_APP_FOLDER_SCRIPTS, - app->script->name); - storage_simply_remove(app->storage, script_path); - wifi_marauder_script_free(app->script); - app->script = NULL; - - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_text(message, "Deleted!", 88, 32, AlignCenter, AlignCenter); - dialog_message_set_icon(message, &I_DolphinCommon_56x48, 5, 6); - dialog_message_set_buttons(message, NULL, "Ok", NULL); - dialog_message_show(app->dialogs, message); - dialog_message_free(message); - } - } - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } - - return consumed; -} - -void wifi_marauder_scene_script_confirm_delete_on_exit(void* context) { - WifiMarauderApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit.c deleted file mode 100644 index 697daba4f..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -static void wifi_marauder_scene_script_edit_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - WifiMarauderScriptStage* current_stage = app->script->first_stage; - uint32_t stage_index = 0; - - while(current_stage != NULL && stage_index < index) { - current_stage = current_stage->next_stage; - stage_index++; - } - app->script_edit_selected_stage = current_stage; - - if(app->script_edit_selected_stage != NULL) { - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEdit); - } -} - -static void wifi_marauder_scene_script_edit_add_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageAdd); -} - -void wifi_marauder_scene_script_edit_on_enter(void* context) { - WifiMarauderApp* app = context; - Submenu* submenu = app->submenu; - WifiMarauderScript* script = app->script; - submenu_set_header(submenu, script->name); - - WifiMarauderScriptStage* current_stage = script->first_stage; - int stage_index = 0; - while(current_stage != NULL) { - switch(current_stage->type) { - case WifiMarauderScriptStageTypeScan: - submenu_add_item( - submenu, "Scan", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeSelect: - submenu_add_item( - submenu, "Select", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeDeauth: - submenu_add_item( - submenu, "Deauth", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeProbe: - submenu_add_item( - submenu, "Probe", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeSniffRaw: - submenu_add_item( - submenu, "Sniff raw", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeSniffBeacon: - submenu_add_item( - submenu, - "Sniff beacon", - stage_index, - wifi_marauder_scene_script_edit_callback, - app); - break; - case WifiMarauderScriptStageTypeSniffDeauth: - submenu_add_item( - submenu, - "Sniff deauth", - stage_index, - wifi_marauder_scene_script_edit_callback, - app); - break; - case WifiMarauderScriptStageTypeSniffEsp: - submenu_add_item( - submenu, "Sniff esp", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeSniffPmkid: - submenu_add_item( - submenu, "Sniff PMKID", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeSniffPwn: - submenu_add_item( - submenu, "Sniff pwn", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeBeaconList: - submenu_add_item( - submenu, "Beacon list", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeBeaconAp: - submenu_add_item( - submenu, "Beacon AP", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - case WifiMarauderScriptStageTypeExec: - submenu_add_item( - submenu, - "Custom command", - stage_index, - wifi_marauder_scene_script_edit_callback, - app); - break; - case WifiMarauderScriptStageTypeDelay: - submenu_add_item( - submenu, "Delay", stage_index, wifi_marauder_scene_script_edit_callback, app); - break; - } - current_stage = current_stage->next_stage; - stage_index++; - } - - submenu_add_item( - submenu, "[+] ADD STAGE", stage_index++, wifi_marauder_scene_script_edit_add_callback, app); - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); -} - -bool wifi_marauder_scene_script_edit_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_script_edit_on_exit(void* context) { - WifiMarauderApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit_list.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit_list.c deleted file mode 100644 index 7a3284caf..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_edit_list.c +++ /dev/null @@ -1,188 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -static void - wifi_marauder_scene_script_stage_edit_list_add_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - - // Creates new item - WifiMarauderScriptStageListItem* new_item = - (WifiMarauderScriptStageListItem*)malloc(sizeof(WifiMarauderScriptStageListItem)); - new_item->value = malloc(64); - new_item->next_item = NULL; - - if(app->script_stage_edit_first_item == NULL) { - app->script_stage_edit_first_item = new_item; - } else { - WifiMarauderScriptStageListItem* last_item = app->script_stage_edit_first_item; - while(last_item->next_item != NULL) { - last_item = last_item->next_item; - } - last_item->next_item = new_item; - } - - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList, index); - app->user_input_type = WifiMarauderUserInputTypeString; - app->user_input_string_reference = &new_item->value; - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput); -} - -static void wifi_marauder_scene_script_stage_edit_list_deallocate_items(WifiMarauderApp* app) { - WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item; - while(current_item != NULL) { - WifiMarauderScriptStageListItem* next_item = current_item->next_item; - free(current_item->value); - free(current_item); - current_item = next_item; - } - app->script_stage_edit_first_item = NULL; -} - -static void wifi_marauder_scene_script_stage_edit_list_save_strings(WifiMarauderApp* app) { - WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item; - int array_size = 0; - - // Calculates the required array size - while(current_item != NULL) { - array_size++; - current_item = current_item->next_item; - } - - // Reallocate the array of strings if necessary - if(*app->script_stage_edit_string_count_reference < array_size) { - *app->script_stage_edit_strings_reference = - realloc(*app->script_stage_edit_strings_reference, array_size * sizeof(char*)); - } - - // Fills the array of strings - current_item = app->script_stage_edit_first_item; - int i = 0; - while(current_item != NULL) { - char* current_str = malloc(strlen(current_item->value) + 1); - strncpy(current_str, current_item->value, strlen(current_item->value) + 1); - (*app->script_stage_edit_strings_reference)[i] = current_str; - current_item = current_item->next_item; - i++; - } - - *app->script_stage_edit_string_count_reference = array_size; -} - -static void wifi_marauder_scene_script_stage_edit_list_save_numbers(WifiMarauderApp* app) { - WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item; - int array_size = 0; - - // Calculates the required array size - while(current_item != NULL) { - array_size++; - current_item = current_item->next_item; - } - - // Reallocate the array of integers if necessary - if(*app->script_stage_edit_number_count_reference < array_size) { - *app->script_stage_edit_numbers_reference = - realloc(*app->script_stage_edit_numbers_reference, array_size * sizeof(int)); - } - - // Fills the array of integers - current_item = app->script_stage_edit_first_item; - int i = 0; - while(current_item != NULL) { - (*app->script_stage_edit_numbers_reference)[i] = atoi(current_item->value); - current_item = current_item->next_item; - i++; - } - - *app->script_stage_edit_number_count_reference = array_size; -} - -static void - wifi_marauder_scene_script_stage_edit_list_save_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - if(app->script_stage_edit_strings_reference != NULL && - app->script_stage_edit_string_count_reference != NULL) { - wifi_marauder_scene_script_stage_edit_list_save_strings(app); - } - - if(app->script_stage_edit_numbers_reference != NULL && - app->script_stage_edit_number_count_reference != NULL) { - wifi_marauder_scene_script_stage_edit_list_save_numbers(app); - } - - wifi_marauder_scene_script_stage_edit_list_deallocate_items(app); - scene_manager_previous_scene(app->scene_manager); -} - -static void - wifi_marauder_scene_script_stage_edit_list_clear_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - wifi_marauder_scene_script_stage_edit_list_deallocate_items(app); - - submenu_reset(app->submenu); - submenu_add_item( - app->submenu, - "[+] ADD ITEM", - 99, - wifi_marauder_scene_script_stage_edit_list_add_callback, - app); - submenu_add_item( - app->submenu, - "[*] SAVE ITEMS", - 99, - wifi_marauder_scene_script_stage_edit_list_save_callback, - app); - submenu_add_item( - app->submenu, - "[-] CLEAR LIST", - 99, - wifi_marauder_scene_script_stage_edit_list_clear_callback, - app); -} - -void wifi_marauder_scene_script_stage_edit_list_on_enter(void* context) { - WifiMarauderApp* app = context; - int item_index = 0; - WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item; - - while(current_item != NULL) { - submenu_add_item(app->submenu, current_item->value, item_index++, NULL, app); - current_item = current_item->next_item; - } - submenu_add_item( - app->submenu, - "[+] ADD ITEM", - 99, - wifi_marauder_scene_script_stage_edit_list_add_callback, - app); - submenu_add_item( - app->submenu, - "[*] SAVE ITEMS", - 99, - wifi_marauder_scene_script_stage_edit_list_save_callback, - app); - submenu_add_item( - app->submenu, - "[-] CLEAR LIST", - 99, - wifi_marauder_scene_script_stage_edit_list_clear_callback, - app); - - submenu_set_selected_item( - app->submenu, - scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); -} - -bool wifi_marauder_scene_script_stage_edit_list_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_script_stage_edit_list_on_exit(void* context) { - WifiMarauderApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_options.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_options.c deleted file mode 100644 index 35b374f61..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_options.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -enum SubmenuIndex { - SubmenuIndexRun, - SubmenuIndexSettings, - SubmenuIndexEditStages, - SubmenuIndexSave, - SubmenuIndexDelete -}; - -void wifi_marauder_scene_script_options_save_script(WifiMarauderApp* app) { - char script_path[256]; - snprintf( - script_path, - sizeof(script_path), - "%s/%s.json", - MARAUDER_APP_FOLDER_SCRIPTS, - app->script->name); - wifi_marauder_script_save_json(app->storage, script_path, app->script); - - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_text(message, "Saved!", 88, 32, AlignCenter, AlignCenter); - dialog_message_set_icon(message, &I_DolphinCommon_56x48, 5, 6); - dialog_message_set_buttons(message, NULL, "Ok", NULL); - dialog_message_show(app->dialogs, message); - dialog_message_free(message); -} - -static void wifi_marauder_scene_script_options_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - - switch(index) { - case SubmenuIndexRun: - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - break; - case SubmenuIndexSettings: - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSettings); - break; - case SubmenuIndexEditStages: - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptEdit); - break; - case SubmenuIndexSave: - wifi_marauder_scene_script_options_save_script(app); - break; - case SubmenuIndexDelete: - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptConfirmDelete); - break; - } -} - -void wifi_marauder_scene_script_options_on_enter(void* context) { - WifiMarauderApp* app = context; - - // If returning after confirming script deletion - if(app->script == NULL) { - scene_manager_previous_scene(app->scene_manager); - return; - } - - Submenu* submenu = app->submenu; - - submenu_set_header(submenu, app->script->name); - submenu_add_item( - submenu, "[>] RUN", SubmenuIndexRun, wifi_marauder_scene_script_options_callback, app); - submenu_add_item( - submenu, - "[S] SETTINGS", - SubmenuIndexSettings, - wifi_marauder_scene_script_options_callback, - app); - submenu_add_item( - submenu, - "[+] EDIT STAGES", - SubmenuIndexEditStages, - wifi_marauder_scene_script_options_callback, - app); - submenu_add_item( - submenu, "[*] SAVE", SubmenuIndexSave, wifi_marauder_scene_script_options_callback, app); - submenu_add_item( - submenu, - "[X] DELETE", - SubmenuIndexDelete, - wifi_marauder_scene_script_options_callback, - app); - - submenu_set_selected_item( - submenu, - scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); -} - -bool wifi_marauder_scene_script_options_on_event(void* context, SceneManagerEvent event) { - WifiMarauderApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeBack) { - wifi_marauder_script_free(app->script); - app->script = NULL; - } - - return consumed; -} - -void wifi_marauder_scene_script_options_on_exit(void* context) { - WifiMarauderApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_select.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_select.c deleted file mode 100644 index ffdc2ded0..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_select.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -#define MAX_NAME_LEN 254 - -static void wifi_marauder_scene_script_select_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - - char script_path[256]; - snprintf( - script_path, - sizeof(script_path), - "%s/%s.json", - MARAUDER_APP_FOLDER_SCRIPTS, - furi_string_get_cstr(app->script_list[index])); - - app->script = wifi_marauder_script_parse_json(app->storage, script_path); - if(app->script) { - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptOptions); - } -} - -static void wifi_marauder_scene_script_select_add_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index); - - app->user_input_type = WifiMarauderUserInputTypeFileName; - app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER_SCRIPTS); - app->user_input_file_extension = strdup("json"); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput); -} - -void wifi_marauder_scene_script_select_on_enter(void* context) { - WifiMarauderApp* app = context; - Submenu* submenu = app->submenu; - - File* dir_scripts = storage_file_alloc(app->storage); - if(storage_dir_open(dir_scripts, MARAUDER_APP_FOLDER_SCRIPTS)) { - FileInfo file_info; - char file_path[MAX_NAME_LEN]; - app->script_list_count = 0; - // Goes through the files in the folder counting the ones that end with the json extension - while(storage_dir_read(dir_scripts, &file_info, file_path, MAX_NAME_LEN)) { - app->script_list_count++; - } - if(app->script_list_count > 0) { - submenu_set_header(submenu, "Select a script:"); - app->script_list = malloc(app->script_list_count * sizeof(FuriString*)); - storage_dir_close(dir_scripts); - storage_dir_open(dir_scripts, MARAUDER_APP_FOLDER_SCRIPTS); - // Read the files again from the beginning, adding the scripts in the list - int script_index = 0; - while(storage_dir_read(dir_scripts, &file_info, file_path, MAX_NAME_LEN)) { - app->script_list[script_index] = furi_string_alloc(); - path_extract_filename_no_ext(file_path, app->script_list[script_index]); - submenu_add_item( - submenu, - furi_string_get_cstr(app->script_list[script_index]), - script_index, - wifi_marauder_scene_script_select_callback, - app); - script_index++; - } - } else { - submenu_set_header(submenu, "No script found"); - } - submenu_add_item( - submenu, "[+] ADD SCRIPT", 99, wifi_marauder_scene_script_select_add_callback, app); - storage_dir_close(dir_scripts); - } - storage_file_free(dir_scripts); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); -} - -bool wifi_marauder_scene_script_select_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_script_select_on_exit(void* context) { - WifiMarauderApp* app = context; - submenu_reset(app->submenu); - - for(int i = 0; i < app->script_list_count; i++) { - furi_string_free(app->script_list[i]); - } - free(app->script_list); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_settings.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_settings.c deleted file mode 100644 index b4903af05..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_settings.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -enum ScriptSettingsOption { - ScriptSettingsOptionRepeat, - ScriptSettingsOptionSavePcap, - ScriptSettingsOptionEnableLed -}; - -const char* option_values[3] = {"No", "Yes", "Default"}; - -static void wifi_marauder_scene_script_settings_enter_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - // Accept script repeat value - if(index == ScriptSettingsOptionRepeat) { - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings, index); - app->user_input_type = WifiMarauderUserInputTypeNumber; - app->user_input_number_reference = &app->script->repeat; - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput); - } -} - -static void wifi_marauder_scene_script_settings_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - uint8_t current_option = variable_item_list_get_selected_item_index(app->var_item_list); - uint8_t option_value_index = variable_item_get_current_value_index(item); - - switch(current_option) { - case ScriptSettingsOptionSavePcap: - variable_item_set_current_value_text(item, option_values[option_value_index]); - app->script->save_pcap = option_value_index; - break; - case ScriptSettingsOptionEnableLed: - variable_item_set_current_value_text(item, option_values[option_value_index]); - app->script->enable_led = option_value_index; - break; - } -} - -void wifi_marauder_scene_script_settings_on_enter(void* context) { - WifiMarauderApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - variable_item_list_set_enter_callback( - app->var_item_list, wifi_marauder_scene_script_settings_enter_callback, app); - - // Script repeat option - VariableItem* repeat_item = variable_item_list_add(app->var_item_list, "Repeat", 1, NULL, app); - char repeat_str[32]; - snprintf(repeat_str, sizeof(repeat_str), "%d", app->script->repeat); - variable_item_set_current_value_text(repeat_item, repeat_str); - - // Save PCAP option - VariableItem* save_pcap_item = variable_item_list_add( - app->var_item_list, - "Save PCAP", - 3, - wifi_marauder_scene_script_settings_change_callback, - app); - variable_item_set_current_value_index(save_pcap_item, app->script->save_pcap); - variable_item_set_current_value_text(save_pcap_item, option_values[app->script->save_pcap]); - - // Enable board LED option - VariableItem* enable_led_item = variable_item_list_add( - app->var_item_list, - "Enable LED", - 3, - wifi_marauder_scene_script_settings_change_callback, - app); - variable_item_set_current_value_index(enable_led_item, app->script->enable_led); - variable_item_set_current_value_text(enable_led_item, option_values[app->script->enable_led]); - - variable_item_list_set_selected_item( - var_item_list, - scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList); -} - -bool wifi_marauder_scene_script_settings_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_script_settings_on_exit(void* context) { - WifiMarauderApp* app = context; - variable_item_list_reset(app->var_item_list); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_add.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_add.c deleted file mode 100644 index 33f1a2f03..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_add.c +++ /dev/null @@ -1,297 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -// Scan -static void wifi_marauder_scene_script_stage_add_scan_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageScan* stage = - (WifiMarauderScriptStageScan*)malloc(sizeof(WifiMarauderScriptStageScan)); - stage->type = WifiMarauderScriptScanTypeAp; - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeScan, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Select -static void wifi_marauder_scene_script_stage_add_select_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSelect* stage = - (WifiMarauderScriptStageSelect*)malloc(sizeof(WifiMarauderScriptStageSelect)); - stage->type = WifiMarauderScriptSelectTypeAp; - stage->filter = strdup("all"); - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSelect, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Deauth -static void wifi_marauder_scene_script_stage_add_deauth_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageDeauth* stage = - (WifiMarauderScriptStageDeauth*)malloc(sizeof(WifiMarauderScriptStageDeauth)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDeauth, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Probe -static void wifi_marauder_scene_script_stage_add_probe_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageProbe* stage = - (WifiMarauderScriptStageProbe*)malloc(sizeof(WifiMarauderScriptStageProbe)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeProbe, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Sniff RAW -static void wifi_marauder_scene_script_stage_add_sniffraw_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSniffRaw* stage = - (WifiMarauderScriptStageSniffRaw*)malloc(sizeof(WifiMarauderScriptStageSniffRaw)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffRaw, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Sniff Beacon -static void - wifi_marauder_scene_script_stage_add_sniffbeacon_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSniffBeacon* stage = - (WifiMarauderScriptStageSniffBeacon*)malloc(sizeof(WifiMarauderScriptStageSniffBeacon)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffBeacon, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Sniff Deauth -static void - wifi_marauder_scene_script_stage_add_sniffdeauth_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSniffDeauth* stage = - (WifiMarauderScriptStageSniffDeauth*)malloc(sizeof(WifiMarauderScriptStageSniffDeauth)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffDeauth, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Sniff Esp -static void wifi_marauder_scene_script_stage_add_sniffesp_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSniffEsp* stage = - (WifiMarauderScriptStageSniffEsp*)malloc(sizeof(WifiMarauderScriptStageSniffEsp)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffEsp, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Sniff PMKID -static void - wifi_marauder_scene_script_stage_add_sniffpmkid_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSniffPmkid* stage = - (WifiMarauderScriptStageSniffPmkid*)malloc(sizeof(WifiMarauderScriptStageSniffPmkid)); - stage->channel = 0; - stage->force_deauth = WifiMarauderScriptBooleanTrue; - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPmkid, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Sniff Pwn -static void wifi_marauder_scene_script_stage_add_sniffpwn_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageSniffPwn* stage = - (WifiMarauderScriptStageSniffPwn*)malloc(sizeof(WifiMarauderScriptStageSniffPwn)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPwn, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Beacon list -static void - wifi_marauder_scene_script_stage_add_beaconlist_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageBeaconList* stage = - (WifiMarauderScriptStageBeaconList*)malloc(sizeof(WifiMarauderScriptStageBeaconList)); - stage->ssids = NULL; - stage->ssid_count = 0; - stage->random_ssids = 0; - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconList, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Beacon AP -static void wifi_marauder_scene_script_stage_add_beaconap_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageBeaconAp* stage = - (WifiMarauderScriptStageBeaconAp*)malloc(sizeof(WifiMarauderScriptStageBeaconAp)); - stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconAp, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Exec -static void wifi_marauder_scene_script_stage_add_exec_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageExec* stage = - (WifiMarauderScriptStageExec*)malloc(sizeof(WifiMarauderScriptStageExec)); - stage->command = NULL; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeExec, stage); - scene_manager_previous_scene(app->scene_manager); -} - -// Delay -static void wifi_marauder_scene_script_stage_add_delay_callback(void* context, uint32_t index) { - UNUSED(index); - WifiMarauderApp* app = context; - - WifiMarauderScriptStageDelay* stage = - (WifiMarauderScriptStageDelay*)malloc(sizeof(WifiMarauderScriptStageDelay)); - stage->timeout = 0; - - wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDelay, stage); - scene_manager_previous_scene(app->scene_manager); -} - -void wifi_marauder_scene_script_stage_add_on_enter(void* context) { - WifiMarauderApp* app = context; - Submenu* submenu = app->submenu; - submenu_set_header(submenu, "Add stage"); - - int menu_index = 0; - submenu_add_item( - submenu, "[+] Scan", menu_index++, wifi_marauder_scene_script_stage_add_scan_callback, app); - submenu_add_item( - submenu, - "[+] Select", - menu_index++, - wifi_marauder_scene_script_stage_add_select_callback, - app); - submenu_add_item( - submenu, - "[+] Deauth", - menu_index++, - wifi_marauder_scene_script_stage_add_deauth_callback, - app); - submenu_add_item( - submenu, - "[+] Probe", - menu_index++, - wifi_marauder_scene_script_stage_add_probe_callback, - app); - submenu_add_item( - submenu, - "[+] Sniff RAW", - menu_index++, - wifi_marauder_scene_script_stage_add_sniffraw_callback, - app); - submenu_add_item( - submenu, - "[+] Sniff Beacon", - menu_index++, - wifi_marauder_scene_script_stage_add_sniffbeacon_callback, - app); - submenu_add_item( - submenu, - "[+] Sniff Deauth", - menu_index++, - wifi_marauder_scene_script_stage_add_sniffdeauth_callback, - app); - submenu_add_item( - submenu, - "[+] Sniff Esp", - menu_index++, - wifi_marauder_scene_script_stage_add_sniffesp_callback, - app); - submenu_add_item( - submenu, - "[+] Sniff PMKID", - menu_index++, - wifi_marauder_scene_script_stage_add_sniffpmkid_callback, - app); - submenu_add_item( - submenu, - "[+] Sniff Pwnagotchi", - menu_index++, - wifi_marauder_scene_script_stage_add_sniffpwn_callback, - app); - submenu_add_item( - submenu, - "[+] Beacon List", - menu_index++, - wifi_marauder_scene_script_stage_add_beaconlist_callback, - app); - submenu_add_item( - submenu, - "[+] Beacon AP", - menu_index++, - wifi_marauder_scene_script_stage_add_beaconap_callback, - app); - submenu_add_item( - submenu, - "[+] Custom command", - menu_index++, - wifi_marauder_scene_script_stage_add_exec_callback, - app); - submenu_add_item( - submenu, - "[+] Delay", - menu_index++, - wifi_marauder_scene_script_stage_add_delay_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); -} - -bool wifi_marauder_scene_script_stage_add_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_script_stage_add_on_exit(void* context) { - WifiMarauderApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_edit.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_edit.c deleted file mode 100644 index b8581e3e7..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_stage_edit.c +++ /dev/null @@ -1,203 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -void wifi_marauder_scene_script_stage_edit_create_list_strings( - WifiMarauderApp* app, - char** strings, - int string_count) { - // Deallocates the existing list - WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item; - while(current_item != NULL) { - WifiMarauderScriptStageListItem* next_item = current_item->next_item; - free(current_item->value); - free(current_item); - current_item = next_item; - } - - // Create a new list with numbers - WifiMarauderScriptStageListItem* first_item = NULL; - WifiMarauderScriptStageListItem* previous_item = NULL; - for(int i = 0; i < string_count; i++) { - WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem)); - item->value = strdup(strings[i]); - item->next_item = NULL; - - if(previous_item == NULL) { - first_item = item; - } else { - previous_item->next_item = item; - } - previous_item = item; - } - - app->script_stage_edit_first_item = first_item; -} - -void wifi_marauder_scene_script_stage_edit_create_list_numbers( - WifiMarauderApp* app, - int* numbers, - int number_count) { - // Deallocates the existing list - WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item; - while(current_item != NULL) { - WifiMarauderScriptStageListItem* next_item = current_item->next_item; - free(current_item->value); - free(current_item); - current_item = next_item; - } - - // Create a new list with numbers - WifiMarauderScriptStageListItem* first_item = NULL; - WifiMarauderScriptStageListItem* previous_item = NULL; - for(int i = 0; i < number_count; i++) { - char number_str[32]; - snprintf(number_str, sizeof(number_str), "%d", numbers[i]); - - WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem)); - item->value = strdup(number_str); - item->next_item = NULL; - - if(previous_item == NULL) { - first_item = item; - } else { - previous_item->next_item = item; - } - previous_item = item; - } - - app->script_stage_edit_first_item = first_item; -} - -static void - wifi_marauder_scene_script_stage_edit_list_enter_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[index]; - - // Fixed delete item - if(index == app->script_stage_menu->num_items) { - uint32_t deleted_stage_index = - scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit); - if(deleted_stage_index > 0) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneScriptEdit, deleted_stage_index - 1); - } - WifiMarauderScriptStage* previous_stage = NULL; - WifiMarauderScriptStage* current_stage = app->script->first_stage; - uint32_t current_stage_index = 0; - - while(current_stage != NULL && current_stage_index < deleted_stage_index) { - previous_stage = current_stage; - current_stage = current_stage->next_stage; - current_stage_index++; - } - - // Delete the stage - if(current_stage != NULL) { - if(previous_stage != NULL) { - if(current_stage->next_stage != NULL) { - previous_stage->next_stage = current_stage->next_stage; - } else { - previous_stage->next_stage = NULL; - app->script->last_stage = previous_stage; - } - } else { - if(current_stage->next_stage != NULL) { - app->script->first_stage = current_stage->next_stage; - } else { - app->script->first_stage = NULL; - app->script->last_stage = NULL; - } - } - } - app->script_edit_selected_stage = NULL; - - scene_manager_previous_scene(app->scene_manager); - return; - } - - if(menu_item->select_callback == NULL) { - return; - } - if(menu_item->type == WifiMarauderScriptMenuItemTypeNumber) { - // Accepts user number input, assigning the value to the reference passed as a parameter - menu_item->select_callback(app); - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index); - app->user_input_type = WifiMarauderUserInputTypeNumber; - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput); - } else if(menu_item->type == WifiMarauderScriptMenuItemTypeString) { - // Accepts user string input, assigning the value to the reference passed as a parameter - menu_item->select_callback(app); - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index); - app->user_input_type = WifiMarauderUserInputTypeString; - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput); - } else if(menu_item->type == WifiMarauderScriptMenuItemTypeListString) { - // Accepts the strings that compose the list - menu_item->select_callback(app); - wifi_marauder_scene_script_stage_edit_create_list_strings( - app, - *app->script_stage_edit_strings_reference, - *app->script_stage_edit_string_count_reference); - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList); - } else if(menu_item->type == WifiMarauderScriptMenuItemTypeListNumber) { - // Accepts the numbers that compose the list - menu_item->select_callback(app); - wifi_marauder_scene_script_stage_edit_create_list_numbers( - app, - *app->script_stage_edit_numbers_reference, - *app->script_stage_edit_number_count_reference); - scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList); - } -} - -void wifi_marauder_scene_script_stage_edit_on_enter(void* context) { - WifiMarauderApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - - variable_item_list_set_enter_callback( - app->var_item_list, wifi_marauder_scene_script_stage_edit_list_enter_callback, app); - app->script_stage_menu = - wifi_marauder_script_stage_menu_create(app->script_edit_selected_stage->type); - - if(app->script_stage_menu->items != NULL) { - for(uint32_t i = 0; i < app->script_stage_menu->num_items; i++) { - WifiMarauderScriptMenuItem* stage_item = &app->script_stage_menu->items[i]; - - // Changes the list item to handle it in callbacks - VariableItem* list_item = variable_item_list_add( - app->var_item_list, - stage_item->name, - stage_item->num_options, - stage_item->change_callback, - app); - - variable_item_list_set_selected_item(app->var_item_list, i); - if(stage_item->setup_callback != NULL) { - stage_item->setup_callback(list_item); - } - if(stage_item->change_callback != NULL) { - stage_item->change_callback(list_item); - } - } - } - - variable_item_list_add(app->var_item_list, "[-] DELETE STAGE", 0, NULL, app); - - variable_item_list_set_selected_item( - var_item_list, - scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList); -} - -bool wifi_marauder_scene_script_stage_edit_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_script_stage_edit_on_exit(void* context) { - WifiMarauderApp* app = context; - wifi_marauder_script_stage_menu_free(app->script_stage_menu); - app->script_stage_menu = NULL; - variable_item_list_reset(app->var_item_list); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_settings_init.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_settings_init.c deleted file mode 100644 index 04d099d12..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_settings_init.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -const char* Y = "Y"; -const char* N = "N"; - -#define PROMPT_PCAPS 0 -#define PROMPT_LOGS 1 - -void wifi_marauder_scene_settings_init_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - WifiMarauderApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void wifi_marauder_scene_settings_init_setup_widget(WifiMarauderApp* app) { - Widget* widget = app->widget; - - widget_reset(widget); - - widget_add_button_element( - widget, GuiButtonTypeLeft, "No", wifi_marauder_scene_settings_init_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeRight, "Yes", wifi_marauder_scene_settings_init_widget_callback, app); - - if(app->which_prompt == PROMPT_PCAPS) { - widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Save pcaps?"); - widget_add_text_scroll_element( - widget, - 0, - 12, - 128, - 38, - "With compatible marauder\nfirmware, you can choose to\nsave captures (pcaps) to the\nflipper sd card here:\n" MARAUDER_APP_FOLDER_USER_PCAPS - "\n\nYou can change this setting in the app at any time. Would\nyou like to enable this feature now?"); - } else { - widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Save logs?"); - widget_add_text_scroll_element( - widget, - 0, - 12, - 128, - 38, - "This app supports saving text\nlogs of console output to the\nflipper sd card here:\n" MARAUDER_APP_FOLDER_USER_LOGS - "\n\nYou can change this setting in the app at any time. Would\nyou like to enable this feature now?"); - } -} - -void wifi_marauder_scene_settings_init_on_enter(void* context) { - WifiMarauderApp* app = context; - - app->which_prompt = PROMPT_PCAPS; - wifi_marauder_scene_settings_init_setup_widget(app); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget); -} - -bool wifi_marauder_scene_settings_init_on_event(void* context, SceneManagerEvent event) { - WifiMarauderApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - // get which button press: "Yes" or "No" - if(event.event == GuiButtonTypeRight) { - // Yes - if(app->which_prompt == PROMPT_PCAPS) { - app->ok_to_save_pcaps = true; - } else { - app->ok_to_save_logs = true; - } - } else if(event.event == GuiButtonTypeLeft) { - // No - if(app->which_prompt == PROMPT_PCAPS) { - app->ok_to_save_pcaps = false; - } else { - app->ok_to_save_logs = false; - } - } - - // save setting to file, load next widget or scene - if(app->which_prompt == PROMPT_PCAPS) { - if(storage_file_open( - app->save_pcap_setting_file, - SAVE_PCAP_SETTING_FILEPATH, - FSAM_WRITE, - FSOM_CREATE_ALWAYS)) { - const char* ok = app->ok_to_save_pcaps ? Y : N; - storage_file_write(app->save_pcap_setting_file, ok, sizeof(ok)); - } else { - dialog_message_show_storage_error(app->dialogs, "Cannot save settings"); - } - storage_file_close(app->save_pcap_setting_file); - // same scene, different-looking widget - app->which_prompt = PROMPT_LOGS; - wifi_marauder_scene_settings_init_setup_widget(app); - } else { - if(storage_file_open( - app->save_logs_setting_file, - SAVE_LOGS_SETTING_FILEPATH, - FSAM_WRITE, - FSOM_CREATE_ALWAYS)) { - const char* ok = app->ok_to_save_logs ? Y : N; - storage_file_write(app->save_logs_setting_file, ok, sizeof(ok)); - } else { - dialog_message_show_storage_error(app->dialogs, "Cannot save settings"); - } - storage_file_close(app->save_logs_setting_file); - // go back to start scene (main menu) - app->need_to_prompt_settings_init = false; - scene_manager_previous_scene(app->scene_manager); - } - consumed = true; - } - - return consumed; -} - -void wifi_marauder_scene_settings_init_on_exit(void* context) { - WifiMarauderApp* app = context; - widget_reset(app->widget); - if(storage_file_is_open(app->save_pcap_setting_file)) { - storage_file_close(app->save_pcap_setting_file); - } - if(storage_file_is_open(app->save_logs_setting_file)) { - storage_file_close(app->save_logs_setting_file); - } -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_sniffpmkid_options.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_sniffpmkid_options.c deleted file mode 100644 index 02869030e..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_sniffpmkid_options.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -enum SubmenuIndex { - SubmenuIndexPassive, - SubmenuIndexActive, - SubmenuIndexTargetedPassive, - SubmenuIndexTargetedActive, - SubmenuIndexChannelPassive, - SubmenuIndexChannelActive, -}; - -static void wifi_marauder_scene_sniffpmkid_options_callback(void* context, uint32_t index) { - WifiMarauderApp* app = context; - - app->is_custom_tx_string = false; // this will be set if needed by text input - switch(index) { - case SubmenuIndexPassive: - app->selected_tx_string = "sniffpmkid"; - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - break; - case SubmenuIndexActive: - app->selected_tx_string = "sniffpmkid -d"; - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - break; - case SubmenuIndexTargetedPassive: - app->selected_tx_string = "sniffpmkid -l"; - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - break; - case SubmenuIndexTargetedActive: - app->selected_tx_string = "sniffpmkid -d -l"; - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - break; - case SubmenuIndexChannelPassive: - app->selected_tx_string = "sniffpmkid -c"; - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput); - break; - case SubmenuIndexChannelActive: - app->selected_tx_string = "sniffpmkid -d -c"; - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput); - break; - } -} - -void wifi_marauder_scene_sniffpmkid_options_on_enter(void* context) { - WifiMarauderApp* app = context; - - Submenu* submenu = app->submenu; - - submenu_set_header(submenu, "Sniff PMKID"); - submenu_add_item( - submenu, - "Passive", - SubmenuIndexPassive, - wifi_marauder_scene_sniffpmkid_options_callback, - app); - submenu_add_item( - submenu, - "Active (Force Deauth)", - SubmenuIndexActive, - wifi_marauder_scene_sniffpmkid_options_callback, - app); - submenu_add_item( - submenu, - "Targeted Passive (List)", - SubmenuIndexTargetedPassive, - wifi_marauder_scene_sniffpmkid_options_callback, - app); - submenu_add_item( - submenu, - "Targeted Active (List)", - SubmenuIndexTargetedActive, - wifi_marauder_scene_sniffpmkid_options_callback, - app); - submenu_add_item( - submenu, - "On Channel # - Passive", - SubmenuIndexChannelPassive, - wifi_marauder_scene_sniffpmkid_options_callback, - app); - submenu_add_item( - submenu, - "On Channel # - Active", - SubmenuIndexChannelActive, - wifi_marauder_scene_sniffpmkid_options_callback, - app); - - submenu_set_selected_item( - submenu, - scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions)); - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); -} - -bool wifi_marauder_scene_sniffpmkid_options_on_event(void* context, SceneManagerEvent event) { - //WifiMarauderApp* app = context; - UNUSED(context); - UNUSED(event); - bool consumed = false; - - return consumed; -} - -void wifi_marauder_scene_sniffpmkid_options_on_exit(void* context) { - WifiMarauderApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c deleted file mode 100644 index 6e6be90df..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c +++ /dev/null @@ -1,287 +0,0 @@ -//** Includes sniffbt and sniffskim for compatible ESP32-WROOM hardware. -//wifi_marauder_app_i.h also changed **// -#include "../wifi_marauder_app_i.h" - -// For each command, define whether additional arguments are needed -// (enabling text input to fill them out), and whether the console -// text box should focus at the start of the output or the end -typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs; - -typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole; - -#define SHOW_STOPSCAN_TIP (true) -#define NO_TIP (false) - -#define MAX_OPTIONS (9) -typedef struct { - const char* item_string; - const char* options_menu[MAX_OPTIONS]; - int num_options_menu; - const char* actual_commands[MAX_OPTIONS]; - InputArgs needs_keyboard; - FocusConsole focus_console; - bool show_stopscan_tip; -} WifiMarauderItem; - -// NUM_MENU_ITEMS defined in wifi_marauder_app_i.h - if you add an entry here, increment it! -const WifiMarauderItem items[NUM_MENU_ITEMS] = { - {"View Log from", {"start", "end"}, 2, {"", ""}, NO_ARGS, FOCUS_CONSOLE_TOGGLE, NO_TIP}, - {"Scan", - {"ap", "station"}, - 2, - {"scanap", "scansta"}, - NO_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"SSID", - {"add rand", "add name", "remove"}, - 3, - {"ssid -a -g", "ssid -a -n", "ssid -r"}, - INPUT_ARGS, - FOCUS_CONSOLE_START, - NO_TIP}, - {"List", - {"ap", "ssid", "station"}, - 3, - {"list -a", "list -s", "list -c"}, - NO_ARGS, - FOCUS_CONSOLE_START, - NO_TIP}, - {"Select", - {"ap", "ssid", "station"}, - 3, - {"select -a", "select -s", "select -c"}, - INPUT_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Clear List", - {"ap", "ssid", "station"}, - 3, - {"clearlist -a", "clearlist -s", "clearlist -c"}, - NO_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Attack", - {"deauth", "probe", "rickroll"}, - 3, - {"attack -t deauth", "attack -t probe", "attack -t rickroll"}, - NO_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"Evil Portal", - {"start"}, - 1, - {"evilportal -c start"}, - NO_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"Targeted Deauth", - {"station", "manual"}, - 2, - {"attack -t deauth -c", "attack -t deauth -s"}, - TOGGLE_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"Beacon Spam", - {"ap list", "ssid list", "random"}, - 3, - {"attack -t beacon -a", "attack -t beacon -l", "attack -t beacon -r"}, - NO_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"Sniff", - {"beacon", "deauth", "pmkid", "probe", "pwn", "raw", "bt", "skim"}, - 8, - {"sniffbeacon", - "sniffdeauth", - "sniffpmkid", - "sniffprobe", - "sniffpwn", - "sniffraw", - "sniffbt", - "sniffskim"}, - NO_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"Signal Monitor", {""}, 1, {"sigmon"}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP}, - {"Channel", - {"get", "set"}, - 2, - {"channel", "channel -s"}, - TOGGLE_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"LED", {"hex", "pattern"}, 2, {"led -s", "led -p"}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Settings", - {"display", "restore", "ForcePMKID", "ForceProbe", "SavePCAP", "EnableLED", "other"}, - 7, - {"settings", - "settings -r", - "settings -s ForcePMKID enable", - "settings -s ForceProbe enable", - "settings -s SavePCAP enable", - "settings -s EnableLED enable", - "settings -s"}, - TOGGLE_ARGS, - FOCUS_CONSOLE_START, - NO_TIP}, - {"Update", {"sd"}, 1, {"update -s"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP}, - {"Scripts", {""}, 1, {""}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Save to flipper sdcard", // keep as last entry or change logic in callback below - {""}, - 1, - {""}, - NO_ARGS, - FOCUS_CONSOLE_START, - NO_TIP}, -}; - -static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uint32_t index) { - furi_assert(context); - WifiMarauderApp* app = context; - - furi_assert(index < NUM_MENU_ITEMS); - const WifiMarauderItem* item = &items[index]; - - const int selected_option_index = app->selected_option_index[index]; - furi_assert(selected_option_index < item->num_options_menu); - app->selected_tx_string = item->actual_commands[selected_option_index]; - app->is_command = (1 <= index); - app->is_custom_tx_string = false; - app->selected_menu_index = index; - app->focus_console_start = (item->focus_console == FOCUS_CONSOLE_TOGGLE) ? - (selected_option_index == 0) : - item->focus_console; - app->show_stopscan_tip = item->show_stopscan_tip; - - if(!app->is_command && selected_option_index == 0) { - // View Log from start - view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartLogViewer); - return; - } - - if(app->selected_tx_string && - strncmp("sniffpmkid", app->selected_tx_string, strlen("sniffpmkid")) == 0) { - // sniffpmkid submenu - view_dispatcher_send_custom_event( - app->view_dispatcher, WifiMarauderEventStartSniffPmkidOptions); - return; - } - - // Select automation script - if(index == NUM_MENU_ITEMS - 2) { - view_dispatcher_send_custom_event( - app->view_dispatcher, WifiMarauderEventStartScriptSelect); - return; - } - - if(index == NUM_MENU_ITEMS - 1) { - // "Save to flipper sdcard" special case - start SettingsInit widget - view_dispatcher_send_custom_event( - app->view_dispatcher, WifiMarauderEventStartSettingsInit); - return; - } - - bool needs_keyboard = (item->needs_keyboard == TOGGLE_ARGS) ? (selected_option_index != 0) : - item->needs_keyboard; - if(needs_keyboard) { - view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartKeyboard); - } else { - view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole); - } -} - -static void wifi_marauder_scene_start_var_list_change_callback(VariableItem* item) { - furi_assert(item); - - WifiMarauderApp* app = variable_item_get_context(item); - furi_assert(app); - - const WifiMarauderItem* menu_item = &items[app->selected_menu_index]; - uint8_t item_index = variable_item_get_current_value_index(item); - furi_assert(item_index < menu_item->num_options_menu); - variable_item_set_current_value_text(item, menu_item->options_menu[item_index]); - app->selected_option_index[app->selected_menu_index] = item_index; -} - -void wifi_marauder_scene_start_on_enter(void* context) { - WifiMarauderApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - - variable_item_list_set_enter_callback( - var_item_list, wifi_marauder_scene_start_var_list_enter_callback, app); - - VariableItem* item; - for(int i = 0; i < NUM_MENU_ITEMS; ++i) { - item = variable_item_list_add( - var_item_list, - items[i].item_string, - items[i].num_options_menu, - wifi_marauder_scene_start_var_list_change_callback, - app); - variable_item_set_current_value_index(item, app->selected_option_index[i]); - variable_item_set_current_value_text( - item, items[i].options_menu[app->selected_option_index[i]]); - } - - variable_item_list_set_selected_item( - var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList); - - // Wait, if the user hasn't initialized sdcard settings, let's prompt them once (then come back here) - if(app->need_to_prompt_settings_init) { - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSettingsInit); - } -} - -bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - WifiMarauderApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == WifiMarauderEventStartKeyboard) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput); - } else if(event.event == WifiMarauderEventStartConsole) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - } else if(event.event == WifiMarauderEventStartSettingsInit) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSettingsInit); - } else if(event.event == WifiMarauderEventStartLogViewer) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneLogViewer); - } else if(event.event == WifiMarauderEventStartScriptSelect) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSelect); - } else if(event.event == WifiMarauderEventStartSniffPmkidOptions) { - scene_manager_set_scene_state( - app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSniffPmkidOptions); - } - consumed = true; - } else if(event.type == SceneManagerEventTypeTick) { - app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list); - consumed = true; - } else if(event.type == SceneManagerEventTypeBack) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - consumed = true; - } - - return consumed; -} - -void wifi_marauder_scene_start_on_exit(void* context) { - WifiMarauderApp* app = context; - variable_item_list_reset(app->var_item_list); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c deleted file mode 100644 index 185af727e..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -void wifi_marauder_scene_text_input_callback(void* context) { - WifiMarauderApp* app = context; - - switch(app->special_case_input_step) { - case 0: // most commands - view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole); - break; - case 1: // special case for deauth: save source MAC - view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventSaveSourceMac); - break; - case 2: // special case for deauth: save destination MAC - view_dispatcher_send_custom_event( - app->view_dispatcher, WifiMarauderEventSaveDestinationMac); - break; - default: - break; - } -} - -void wifi_marauder_scene_text_input_on_enter(void* context) { - WifiMarauderApp* app = context; - - if(0 == - strncmp("attack -t deauth -s", app->selected_tx_string, strlen("attack -t deauth -s"))) { - // Special case for manual deauth input - app->special_case_input_step = 1; - bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE); - } else if(false == app->is_custom_tx_string) { - // Most commands - app->special_case_input_step = 0; - - // Fill text input with selected string so that user can add to it - size_t length = strlen(app->selected_tx_string); - furi_assert(length < WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE); - bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE); - strncpy(app->text_input_store, app->selected_tx_string, length); - - // Add space - because flipper keyboard currently doesn't have a space - app->text_input_store[length] = ' '; - app->text_input_store[length + 1] = '\0'; - app->is_custom_tx_string = true; - } - - // Setup view - TextInput* text_input = app->text_input; - // Add help message to header - if(app->special_case_input_step == 1) { - text_input_set_header_text(text_input, "Enter source MAC"); - } else if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) { - text_input_set_header_text(text_input, "Enter # SSIDs to generate"); - } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) { - text_input_set_header_text(text_input, "Enter SSID name to add"); - } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) { - text_input_set_header_text(text_input, "Remove target from SSID list"); - } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) { - text_input_set_header_text(text_input, "Add target from AP list"); - } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) { - text_input_set_header_text(text_input, "Add target from SSID list"); - } else { - text_input_set_header_text(text_input, "Add command arguments"); - } - text_input_set_result_callback( - text_input, - wifi_marauder_scene_text_input_callback, - app, - app->text_input_store, - WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE, - false); - - text_input_add_illegal_symbols(text_input); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewTextInput); -} - -bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent event) { - WifiMarauderApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == WifiMarauderEventStartConsole) { - // Point to custom string to send - app->selected_tx_string = app->text_input_store; - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - consumed = true; - } else if(event.event == WifiMarauderEventSaveSourceMac) { - if(12 != strlen(app->text_input_store)) { - text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!"); - } else { - snprintf( - app->special_case_input_src_addr, - sizeof(app->special_case_input_src_addr), - "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c", - app->text_input_store[0], - app->text_input_store[1], - app->text_input_store[2], - app->text_input_store[3], - app->text_input_store[4], - app->text_input_store[5], - app->text_input_store[6], - app->text_input_store[7], - app->text_input_store[8], - app->text_input_store[9], - app->text_input_store[10], - app->text_input_store[11]); - - // Advance scene to input destination MAC, clear text input - app->special_case_input_step = 2; - bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE); - text_input_set_header_text(app->text_input, "Enter destination MAC"); - } - consumed = true; - } else if(event.event == WifiMarauderEventSaveDestinationMac) { - if(12 != strlen(app->text_input_store)) { - text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!"); - } else { - snprintf( - app->special_case_input_dst_addr, - sizeof(app->special_case_input_dst_addr), - "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c", - app->text_input_store[0], - app->text_input_store[1], - app->text_input_store[2], - app->text_input_store[3], - app->text_input_store[4], - app->text_input_store[5], - app->text_input_store[6], - app->text_input_store[7], - app->text_input_store[8], - app->text_input_store[9], - app->text_input_store[10], - app->text_input_store[11]); - - // Construct command with source and destination MACs - snprintf( - app->text_input_store, - WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE, - "attack -t deauth -s %18s -d %18s", - app->special_case_input_src_addr, - app->special_case_input_dst_addr); - app->selected_tx_string = app->text_input_store; - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput); - } - consumed = true; - } - } - - return consumed; -} - -void wifi_marauder_scene_text_input_on_exit(void* context) { - WifiMarauderApp* app = context; - - text_input_reset(app->text_input); -} diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_user_input.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_user_input.c deleted file mode 100644 index ff6b3b9a5..000000000 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_user_input.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "../wifi_marauder_app_i.h" - -bool wifi_marauder_scene_user_input_validator_number_callback( - const char* text, - FuriString* error, - void* context) { - UNUSED(context); - for(int i = 0; text[i] != '\0'; i++) { - if(text[i] < '0' || text[i] > '9') { - furi_string_printf(error, "This is not\na valid\nnumber!"); - return false; - } - } - return true; -} - -bool wifi_marauder_scene_user_input_validator_file_callback( - const char* text, - FuriString* error, - void* context) { - UNUSED(context); - if(strlen(text) == 0) { - furi_string_printf(error, "File name\ncannot be\nblank!"); - return false; - } - return true; -} - -void wifi_marauder_scene_user_input_ok_callback(void* context) { - WifiMarauderApp* app = context; - - File* file = NULL; - char* file_path = NULL; - - switch(app->user_input_type) { - // Writes the string value of the reference - case WifiMarauderUserInputTypeString: - if(app->user_input_string_reference != NULL) { - strncpy( - *app->user_input_string_reference, - app->text_input_store, - strlen(app->text_input_store) + 1); - app->user_input_string_reference = NULL; - } - break; - // Writes the numerical value of the reference - case WifiMarauderUserInputTypeNumber: - if(app->user_input_number_reference != NULL) { - *app->user_input_number_reference = atoi(app->text_input_store); - app->user_input_number_reference = NULL; - } - break; - // Creates a file with the name entered by the user, if it does not exist - case WifiMarauderUserInputTypeFileName: - file = storage_file_alloc(app->storage); - // Use application directory if not specified - if(app->user_input_file_dir == NULL) { - app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER); - } - if(app->user_input_file_extension != NULL) { - size_t file_path_len = strlen(app->user_input_file_dir) + - strlen(app->text_input_store) + - strlen(app->user_input_file_extension) + 3; - file_path = (char*)malloc(file_path_len); - snprintf( - file_path, - file_path_len, - "%s/%s.%s", - app->user_input_file_dir, - app->text_input_store, - app->user_input_file_extension); - } else { - size_t file_path_len = - strlen(app->user_input_file_dir) + strlen(app->text_input_store) + 2; - file_path = (char*)malloc(file_path_len); - snprintf( - file_path, file_path_len, "%s/%s", app->user_input_file_dir, app->text_input_store); - } - if(storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_NEW)) { - storage_file_close(file); - } - // Free memory - free(app->user_input_file_dir); - app->user_input_file_dir = NULL; - free(app->user_input_file_extension); - app->user_input_file_extension = NULL; - free(file_path); - storage_file_free(file); - break; - default: - break; - } - - scene_manager_previous_scene(app->scene_manager); -} - -void wifi_marauder_scene_user_input_on_enter(void* context) { - WifiMarauderApp* app = context; - - switch(app->user_input_type) { - // Loads the string value of the reference - case WifiMarauderUserInputTypeString: - text_input_set_header_text(app->text_input, "Enter value:"); - text_input_set_validator(app->text_input, NULL, app); - if(app->user_input_string_reference != NULL) { - strncpy( - app->text_input_store, - *app->user_input_string_reference, - strlen(*app->user_input_string_reference) + 1); - } - text_input_add_illegal_symbols(app->text_input); - break; - // Loads the numerical value of the reference - case WifiMarauderUserInputTypeNumber: - text_input_set_header_text(app->text_input, "Enter a valid number:"); - text_input_set_validator( - app->text_input, wifi_marauder_scene_user_input_validator_number_callback, app); - if(app->user_input_number_reference != NULL) { - char number_str[32]; - snprintf(number_str, sizeof(number_str), "%d", *app->user_input_number_reference); - strncpy(app->text_input_store, number_str, strlen(number_str) + 1); - } - break; - // File name - case WifiMarauderUserInputTypeFileName: - text_input_set_header_text(app->text_input, "Enter file name:"); - text_input_set_validator( - app->text_input, wifi_marauder_scene_user_input_validator_file_callback, app); - break; - default: - scene_manager_previous_scene(app->scene_manager); - return; - } - - text_input_set_result_callback( - app->text_input, - wifi_marauder_scene_user_input_ok_callback, - app, - app->text_input_store, - WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE, - false); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewTextInput); -} - -bool wifi_marauder_scene_user_input_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void wifi_marauder_scene_user_input_on_exit(void* context) { - WifiMarauderApp* app = context; - memset(app->text_input_store, 0, sizeof(app->text_input_store)); - text_input_reset(app->text_input); -} diff --git a/applications/external/wifi_marauder_companion/script/cJSON.c b/applications/external/wifi_marauder_companion/script/cJSON.c deleted file mode 100644 index 06341fe38..000000000 --- a/applications/external/wifi_marauder_companion/script/cJSON.c +++ /dev/null @@ -1,2743 +0,0 @@ -/* - Copyright (c) 2009-2017 Dave Gamble and cJSON contributors - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* cJSON */ -/* JSON parser in C. */ - -/* disable warnings about old C89 functions in MSVC */ -#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) -#define _CRT_SECURE_NO_DEPRECATE -#endif - -#ifdef __GNUC__ -#pragma GCC visibility push(default) -#endif -#if defined(_MSC_VER) -#pragma warning(push) -/* disable warning about single line comments in system headers */ -#pragma warning(disable : 4001) -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef ENABLE_LOCALES -#include -#endif - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif -#ifdef __GNUC__ -#pragma GCC visibility pop -#endif - -#include "cJSON.h" - -/* define our own boolean type */ -#ifdef true -#undef true -#endif -#define true ((cJSON_bool)1) - -#ifdef false -#undef false -#endif -#define false ((cJSON_bool)0) - -/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ -#ifndef isinf -#define isinf(d) (isnan((d - d)) && !isnan(d)) -#endif -#ifndef isnan -#define isnan(d) (d != d) -#endif - -#ifndef NAN -#ifdef _WIN32 -#define NAN sqrt(-1.0) -#else -#define NAN 0.0 / 0.0 -#endif -#endif - -typedef struct { - const unsigned char* json; - size_t position; -} error; -static error global_error = {NULL, 0}; - -CJSON_PUBLIC(const char*) cJSON_GetErrorPtr(void) { - return (const char*)(global_error.json + global_error.position); -} - -CJSON_PUBLIC(char*) cJSON_GetStringValue(const cJSON* const item) { - if(!cJSON_IsString(item)) { - return NULL; - } - - return item->valuestring; -} - -CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON* const item) { - if(!cJSON_IsNumber(item)) { - return (double)NAN; - } - - return item->valuedouble; -} - -/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ -#if(CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15) -#error cJSON.h and cJSON.c have different versions. Make sure that both have the same. -#endif - -CJSON_PUBLIC(const char*) cJSON_Version(void) { - static char version[15]; - sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); - - return version; -} - -/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ -static int case_insensitive_strcmp(const unsigned char* string1, const unsigned char* string2) { - if((string1 == NULL) || (string2 == NULL)) { - return 1; - } - - if(string1 == string2) { - return 0; - } - - for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) { - if(*string1 == '\0') { - return 0; - } - } - - return tolower(*string1) - tolower(*string2); -} - -typedef struct internal_hooks { - void*(CJSON_CDECL* allocate)(size_t size); - void(CJSON_CDECL* deallocate)(void* pointer); - void*(CJSON_CDECL* reallocate)(void* pointer, size_t size); -} internal_hooks; - -#if defined(_MSC_VER) -/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ -static void* CJSON_CDECL internal_malloc(size_t size) { - return malloc(size); -} -static void CJSON_CDECL internal_free(void* pointer) { - free(pointer); -} -static void* CJSON_CDECL internal_realloc(void* pointer, size_t size) { - return realloc(pointer, size); -} -#else -#define internal_malloc malloc -#define internal_free free -#define internal_realloc realloc -#endif - -/* strlen of character literals resolved at compile time */ -#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) - -static internal_hooks global_hooks = {internal_malloc, internal_free, internal_realloc}; - -static unsigned char* - cJSON_strdup(const unsigned char* string, const internal_hooks* const hooks) { - size_t length = 0; - unsigned char* copy = NULL; - - if(string == NULL) { - return NULL; - } - - length = strlen((const char*)string) + sizeof(""); - copy = (unsigned char*)hooks->allocate(length); - if(copy == NULL) { - return NULL; - } - memcpy(copy, string, length); - - return copy; -} - -CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) { - if(hooks == NULL) { - /* Reset hooks */ - global_hooks.allocate = malloc; - global_hooks.deallocate = free; - global_hooks.reallocate = realloc; - return; - } - - global_hooks.allocate = malloc; - if(hooks->malloc_fn != NULL) { - global_hooks.allocate = hooks->malloc_fn; - } - - global_hooks.deallocate = free; - if(hooks->free_fn != NULL) { - global_hooks.deallocate = hooks->free_fn; - } - - /* use realloc only if both free and malloc are used */ - global_hooks.reallocate = NULL; - if((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) { - global_hooks.reallocate = realloc; - } -} - -/* Internal constructor. */ -static cJSON* cJSON_New_Item(const internal_hooks* const hooks) { - cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); - if(node) { - memset(node, '\0', sizeof(cJSON)); - } - - return node; -} - -/* Delete a cJSON structure. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON* item) { - cJSON* next = NULL; - while(item != NULL) { - next = item->next; - if(!(item->type & cJSON_IsReference) && (item->child != NULL)) { - cJSON_Delete(item->child); - } - if(!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) { - global_hooks.deallocate(item->valuestring); - } - if(!(item->type & cJSON_StringIsConst) && (item->string != NULL)) { - global_hooks.deallocate(item->string); - } - global_hooks.deallocate(item); - item = next; - } -} - -/* get the decimal point character of the current locale */ -static unsigned char get_decimal_point(void) { -#ifdef ENABLE_LOCALES - struct lconv* lconv = localeconv(); - return (unsigned char)lconv->decimal_point[0]; -#else - return '.'; -#endif -} - -typedef struct { - const unsigned char* content; - size_t length; - size_t offset; - size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ - internal_hooks hooks; -} parse_buffer; - -/* check if the given size is left to read in a given parse buffer (starting with 1) */ -#define can_read(buffer, size) \ - ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) -/* check if the buffer can be accessed at the given index (starting with 0) */ -#define can_access_at_index(buffer, index) \ - ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) -#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) -/* get a pointer to the buffer at the position */ -#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) - -/* Converts an array of characters to double. Alternative implementation of strtod() */ -double string_to_double(const char* str, char** endptr) { - double result = 0.0; - int sign = 1; - const char* p = str; - - while(isspace((unsigned char)*p)) p++; - - if(*p == '-') { - sign = -1; - p++; - } else if(*p == '+') { - p++; - } - - while(isdigit((unsigned char)*p)) { - result = result * (double)(10) + ((double)(*p - '0')); - p++; - } - - if(*p == '.') { - double fraction = 0.1; - p++; - - while(isdigit((unsigned char)p[0])) { - fraction *= 0.1L; - result += (p++[0] - '0') * fraction; - } - } - - if(*p == 'e' || *p == 'E') { - int exponent = 0; - int exp_sign = 1; - p++; - - if(*p == '-') { - exp_sign = -1; - p++; - } else if(*p == '+') { - p++; - } - - while(isdigit((unsigned char)*p)) { - exponent = exponent * 10 + (*p - '0'); - p++; - } - - exponent *= exp_sign; - result *= pow(10, exponent); - } - - *endptr = (char*)p; - - return sign * result; -} - -/* Parse the input text to generate a number, and populate the result into item. */ -static cJSON_bool parse_number(cJSON* const item, parse_buffer* const input_buffer) { - double number = 0; - unsigned char* after_end = NULL; - unsigned char number_c_string[64]; - unsigned char decimal_point = get_decimal_point(); - size_t i = 0; - - if((input_buffer == NULL) || (input_buffer->content == NULL)) { - return false; - } - - /* copy the number into a temporary buffer and replace '.' with the decimal point - * of the current locale (for string_to_double) - * This also takes care of '\0' not necessarily being available for marking the end of the input */ - for(i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) { - switch(buffer_at_offset(input_buffer)[i]) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '+': - case '-': - case 'e': - case 'E': - number_c_string[i] = buffer_at_offset(input_buffer)[i]; - break; - - case '.': - number_c_string[i] = decimal_point; - break; - - default: - goto loop_end; - } - } -loop_end: - number_c_string[i] = '\0'; - - number = string_to_double((const char*)number_c_string, (char**)&after_end); - if(number_c_string == after_end) { - return false; /* parse_error */ - } - - item->valuedouble = number; - - /* use saturation in case of overflow */ - if(number >= INT_MAX) { - item->valueint = INT_MAX; - } else if(number <= (double)INT_MIN) { - item->valueint = INT_MIN; - } else { - item->valueint = (int)number; - } - - item->type = cJSON_Number; - - input_buffer->offset += (size_t)(after_end - number_c_string); - return true; -} - -/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON* object, double number) { - if(number >= INT_MAX) { - object->valueint = INT_MAX; - } else if(number <= (double)INT_MIN) { - object->valueint = INT_MIN; - } else { - object->valueint = (int)number; - } - - return object->valuedouble = number; -} - -CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON* object, const char* valuestring) { - char* copy = NULL; - /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ - if(!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) { - return NULL; - } - if(strlen(valuestring) <= strlen(object->valuestring)) { - strcpy(object->valuestring, valuestring); - return object->valuestring; - } - copy = (char*)cJSON_strdup((const unsigned char*)valuestring, &global_hooks); - if(copy == NULL) { - return NULL; - } - if(object->valuestring != NULL) { - cJSON_free(object->valuestring); - } - object->valuestring = copy; - - return copy; -} - -typedef struct { - unsigned char* buffer; - size_t length; - size_t offset; - size_t depth; /* current nesting depth (for formatted printing) */ - cJSON_bool noalloc; - cJSON_bool format; /* is this print a formatted print */ - internal_hooks hooks; -} printbuffer; - -/* realloc printbuffer if necessary to have at least "needed" bytes more */ -static unsigned char* ensure(printbuffer* const p, size_t needed) { - unsigned char* newbuffer = NULL; - size_t newsize = 0; - - if((p == NULL) || (p->buffer == NULL)) { - return NULL; - } - - if((p->length > 0) && (p->offset >= p->length)) { - /* make sure that offset is valid */ - return NULL; - } - - if(needed > INT_MAX) { - /* sizes bigger than INT_MAX are currently not supported */ - return NULL; - } - - needed += p->offset + 1; - if(needed <= p->length) { - return p->buffer + p->offset; - } - - if(p->noalloc) { - return NULL; - } - - /* calculate new buffer size */ - if(needed > (INT_MAX / 2)) { - /* overflow of int, use INT_MAX if possible */ - if(needed <= INT_MAX) { - newsize = INT_MAX; - } else { - return NULL; - } - } else { - newsize = needed * 2; - } - - if(p->hooks.reallocate != NULL) { - /* reallocate with realloc if available */ - newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); - if(newbuffer == NULL) { - p->hooks.deallocate(p->buffer); - p->length = 0; - p->buffer = NULL; - - return NULL; - } - } else { - /* otherwise reallocate manually */ - newbuffer = (unsigned char*)p->hooks.allocate(newsize); - if(!newbuffer) { - p->hooks.deallocate(p->buffer); - p->length = 0; - p->buffer = NULL; - - return NULL; - } - - memcpy(newbuffer, p->buffer, p->offset + 1); - p->hooks.deallocate(p->buffer); - } - p->length = newsize; - p->buffer = newbuffer; - - return newbuffer + p->offset; -} - -/* calculate the new length of the string in a printbuffer and update the offset */ -static void update_offset(printbuffer* const buffer) { - const unsigned char* buffer_pointer = NULL; - if((buffer == NULL) || (buffer->buffer == NULL)) { - return; - } - buffer_pointer = buffer->buffer + buffer->offset; - - buffer->offset += strlen((const char*)buffer_pointer); -} - -/* securely comparison of floating-point variables */ -static cJSON_bool compare_double(double a, double b) { - double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); - return (fabs(a - b) <= maxVal * DBL_EPSILON); -} - -/* Render the number nicely from the given item into a string. */ -static cJSON_bool print_number(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char* output_pointer = NULL; - double d = item->valuedouble; - int length = 0; - size_t i = 0; - unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ - unsigned char decimal_point = get_decimal_point(); - double test = 0.0; - - if(output_buffer == NULL) { - return false; - } - - /* This checks for NaN and Infinity */ - if(isnan(d) || isinf(d)) { - length = snprintf((char*)number_buffer, sizeof(number_buffer), "null"); - } else { - /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ - length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.15g", d); - - /* Check whether the original double can be recovered */ - if((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) { - /* If not, print with 17 decimal places of precision */ - length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.17g", d); - } - } - - /* sprintf failed or buffer overrun occurred */ - if((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) { - return false; - } - - /* reserve appropriate space in the output */ - output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); - if(output_pointer == NULL) { - return false; - } - - /* copy the printed number to the output and replace locale - * dependent decimal point with '.' */ - for(i = 0; i < ((size_t)length); i++) { - if(number_buffer[i] == decimal_point) { - output_pointer[i] = '.'; - continue; - } - - output_pointer[i] = number_buffer[i]; - } - output_pointer[i] = '\0'; - - output_buffer->offset += (size_t)length; - - return true; -} - -/* parse 4 digit hexadecimal number */ -static unsigned parse_hex4(const unsigned char* const input) { - unsigned int h = 0; - size_t i = 0; - - for(i = 0; i < 4; i++) { - /* parse digit */ - if((input[i] >= '0') && (input[i] <= '9')) { - h += (unsigned int)input[i] - '0'; - } else if((input[i] >= 'A') && (input[i] <= 'F')) { - h += (unsigned int)10 + input[i] - 'A'; - } else if((input[i] >= 'a') && (input[i] <= 'f')) { - h += (unsigned int)10 + input[i] - 'a'; - } else /* invalid */ - { - return 0; - } - - if(i < 3) { - /* shift left to make place for the next nibble */ - h = h << 4; - } - } - - return h; -} - -/* converts a UTF-16 literal to UTF-8 - * A literal can be one or two sequences of the form \uXXXX */ -static unsigned char utf16_literal_to_utf8( - const unsigned char* const input_pointer, - const unsigned char* const input_end, - unsigned char** output_pointer) { - long unsigned int codepoint = 0; - unsigned int first_code = 0; - const unsigned char* first_sequence = input_pointer; - unsigned char utf8_length = 0; - unsigned char utf8_position = 0; - unsigned char sequence_length = 0; - unsigned char first_byte_mark = 0; - - if((input_end - first_sequence) < 6) { - /* input ends unexpectedly */ - goto fail; - } - - /* get the first utf16 sequence */ - first_code = parse_hex4(first_sequence + 2); - - /* check that the code is valid */ - if(((first_code >= 0xDC00) && (first_code <= 0xDFFF))) { - goto fail; - } - - /* UTF16 surrogate pair */ - if((first_code >= 0xD800) && (first_code <= 0xDBFF)) { - const unsigned char* second_sequence = first_sequence + 6; - unsigned int second_code = 0; - sequence_length = 12; /* \uXXXX\uXXXX */ - - if((input_end - second_sequence) < 6) { - /* input ends unexpectedly */ - goto fail; - } - - if((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) { - /* missing second half of the surrogate pair */ - goto fail; - } - - /* get the second utf16 sequence */ - second_code = parse_hex4(second_sequence + 2); - /* check that the code is valid */ - if((second_code < 0xDC00) || (second_code > 0xDFFF)) { - /* invalid second half of the surrogate pair */ - goto fail; - } - - /* calculate the unicode codepoint from the surrogate pair */ - codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); - } else { - sequence_length = 6; /* \uXXXX */ - codepoint = first_code; - } - - /* encode as UTF-8 - * takes at maximum 4 bytes to encode: - * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - if(codepoint < 0x80) { - /* normal ascii, encoding 0xxxxxxx */ - utf8_length = 1; - } else if(codepoint < 0x800) { - /* two bytes, encoding 110xxxxx 10xxxxxx */ - utf8_length = 2; - first_byte_mark = 0xC0; /* 11000000 */ - } else if(codepoint < 0x10000) { - /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ - utf8_length = 3; - first_byte_mark = 0xE0; /* 11100000 */ - } else if(codepoint <= 0x10FFFF) { - /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ - utf8_length = 4; - first_byte_mark = 0xF0; /* 11110000 */ - } else { - /* invalid unicode codepoint */ - goto fail; - } - - /* encode as utf8 */ - for(utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) { - /* 10xxxxxx */ - (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); - codepoint >>= 6; - } - /* encode first byte */ - if(utf8_length > 1) { - (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); - } else { - (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); - } - - *output_pointer += utf8_length; - - return sequence_length; - -fail: - return 0; -} - -/* Parse the input text into an unescaped cinput, and populate item. */ -static cJSON_bool parse_string(cJSON* const item, parse_buffer* const input_buffer) { - const unsigned char* input_pointer = buffer_at_offset(input_buffer) + 1; - const unsigned char* input_end = buffer_at_offset(input_buffer) + 1; - unsigned char* output_pointer = NULL; - unsigned char* output = NULL; - - /* not a string */ - if(buffer_at_offset(input_buffer)[0] != '\"') { - goto fail; - } - - { - /* calculate approximate size of the output (overestimate) */ - size_t allocation_length = 0; - size_t skipped_bytes = 0; - while(((size_t)(input_end - input_buffer->content) < input_buffer->length) && - (*input_end != '\"')) { - /* is escape sequence */ - if(input_end[0] == '\\') { - if((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) { - /* prevent buffer overflow when last input character is a backslash */ - goto fail; - } - skipped_bytes++; - input_end++; - } - input_end++; - } - if(((size_t)(input_end - input_buffer->content) >= input_buffer->length) || - (*input_end != '\"')) { - goto fail; /* string ended unexpectedly */ - } - - /* This is at most how much we need for the output */ - allocation_length = (size_t)(input_end - buffer_at_offset(input_buffer)) - skipped_bytes; - output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); - if(output == NULL) { - goto fail; /* allocation failure */ - } - } - - output_pointer = output; - /* loop through the string literal */ - while(input_pointer < input_end) { - if(*input_pointer != '\\') { - *output_pointer++ = *input_pointer++; - } - /* escape sequence */ - else { - unsigned char sequence_length = 2; - if((input_end - input_pointer) < 1) { - goto fail; - } - - switch(input_pointer[1]) { - case 'b': - *output_pointer++ = '\b'; - break; - case 'f': - *output_pointer++ = '\f'; - break; - case 'n': - *output_pointer++ = '\n'; - break; - case 'r': - *output_pointer++ = '\r'; - break; - case 't': - *output_pointer++ = '\t'; - break; - case '\"': - case '\\': - case '/': - *output_pointer++ = input_pointer[1]; - break; - - /* UTF-16 literal */ - case 'u': - sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); - if(sequence_length == 0) { - /* failed to convert UTF16-literal to UTF-8 */ - goto fail; - } - break; - - default: - goto fail; - } - input_pointer += sequence_length; - } - } - - /* zero terminate the output */ - *output_pointer = '\0'; - - item->type = cJSON_String; - item->valuestring = (char*)output; - - input_buffer->offset = (size_t)(input_end - input_buffer->content); - input_buffer->offset++; - - return true; - -fail: - if(output != NULL) { - input_buffer->hooks.deallocate(output); - } - - if(input_pointer != NULL) { - input_buffer->offset = (size_t)(input_pointer - input_buffer->content); - } - - return false; -} - -/* Render the cstring provided to an escaped version that can be printed. */ -static cJSON_bool - print_string_ptr(const unsigned char* const input, printbuffer* const output_buffer) { - const unsigned char* input_pointer = NULL; - unsigned char* output = NULL; - unsigned char* output_pointer = NULL; - size_t output_length = 0; - /* numbers of additional characters needed for escaping */ - size_t escape_characters = 0; - - if(output_buffer == NULL) { - return false; - } - - /* empty string */ - if(input == NULL) { - output = ensure(output_buffer, sizeof("\"\"")); - if(output == NULL) { - return false; - } - strcpy((char*)output, "\"\""); - - return true; - } - - /* set "flag" to 1 if something needs to be escaped */ - for(input_pointer = input; *input_pointer; input_pointer++) { - switch(*input_pointer) { - case '\"': - case '\\': - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - /* one character escape sequence */ - escape_characters++; - break; - default: - if(*input_pointer < 32) { - /* UTF-16 escape sequence uXXXX */ - escape_characters += 5; - } - break; - } - } - output_length = (size_t)(input_pointer - input) + escape_characters; - - output = ensure(output_buffer, output_length + sizeof("\"\"")); - if(output == NULL) { - return false; - } - - /* no characters have to be escaped */ - if(escape_characters == 0) { - output[0] = '\"'; - memcpy(output + 1, input, output_length); - output[output_length + 1] = '\"'; - output[output_length + 2] = '\0'; - - return true; - } - - output[0] = '\"'; - output_pointer = output + 1; - /* copy the string */ - for(input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) { - if((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) { - /* normal character, copy */ - *output_pointer = *input_pointer; - } else { - /* character needs to be escaped */ - *output_pointer++ = '\\'; - switch(*input_pointer) { - case '\\': - *output_pointer = '\\'; - break; - case '\"': - *output_pointer = '\"'; - break; - case '\b': - *output_pointer = 'b'; - break; - case '\f': - *output_pointer = 'f'; - break; - case '\n': - *output_pointer = 'n'; - break; - case '\r': - *output_pointer = 'r'; - break; - case '\t': - *output_pointer = 't'; - break; - default: - /* escape and print as unicode codepoint */ - snprintf((char*)output_pointer, 6, "u%04x", *input_pointer); - output_pointer += 4; - break; - } - } - } - output[output_length + 1] = '\"'; - output[output_length + 2] = '\0'; - - return true; -} - -/* Invoke print_string_ptr (which is useful) on an item. */ -static cJSON_bool print_string(const cJSON* const item, printbuffer* const p) { - return print_string_ptr((unsigned char*)item->valuestring, p); -} - -/* Predeclare these prototypes. */ -static cJSON_bool parse_value(cJSON* const item, parse_buffer* const input_buffer); -static cJSON_bool print_value(const cJSON* const item, printbuffer* const output_buffer); -static cJSON_bool parse_array(cJSON* const item, parse_buffer* const input_buffer); -static cJSON_bool print_array(const cJSON* const item, printbuffer* const output_buffer); -static cJSON_bool parse_object(cJSON* const item, parse_buffer* const input_buffer); -static cJSON_bool print_object(const cJSON* const item, printbuffer* const output_buffer); - -/* Utility to jump whitespace and cr/lf */ -static parse_buffer* buffer_skip_whitespace(parse_buffer* const buffer) { - if((buffer == NULL) || (buffer->content == NULL)) { - return NULL; - } - - if(cannot_access_at_index(buffer, 0)) { - return buffer; - } - - while(can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) { - buffer->offset++; - } - - if(buffer->offset == buffer->length) { - buffer->offset--; - } - - return buffer; -} - -/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ -static parse_buffer* skip_utf8_bom(parse_buffer* const buffer) { - if((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) { - return NULL; - } - - if(can_access_at_index(buffer, 4) && - (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) { - buffer->offset += 3; - } - - return buffer; -} - -CJSON_PUBLIC(cJSON*) -cJSON_ParseWithOpts( - const char* value, - const char** return_parse_end, - cJSON_bool require_null_terminated) { - size_t buffer_length; - - if(NULL == value) { - return NULL; - } - - /* Adding null character size due to require_null_terminated. */ - buffer_length = strlen(value) + sizeof(""); - - return cJSON_ParseWithLengthOpts( - value, buffer_length, return_parse_end, require_null_terminated); -} - -/* Parse an object - create a new root, and populate. */ -CJSON_PUBLIC(cJSON*) -cJSON_ParseWithLengthOpts( - const char* value, - size_t buffer_length, - const char** return_parse_end, - cJSON_bool require_null_terminated) { - parse_buffer buffer = {0, 0, 0, 0, {0, 0, 0}}; - cJSON* item = NULL; - - /* reset error position */ - global_error.json = NULL; - global_error.position = 0; - - if(value == NULL || 0 == buffer_length) { - goto fail; - } - - buffer.content = (const unsigned char*)value; - buffer.length = buffer_length; - buffer.offset = 0; - buffer.hooks = global_hooks; - - item = cJSON_New_Item(&global_hooks); - if(item == NULL) /* memory fail */ - { - goto fail; - } - - if(!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) { - /* parse failure. ep is set. */ - goto fail; - } - - /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ - if(require_null_terminated) { - buffer_skip_whitespace(&buffer); - if((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') { - goto fail; - } - } - if(return_parse_end) { - *return_parse_end = (const char*)buffer_at_offset(&buffer); - } - - return item; - -fail: - if(item != NULL) { - cJSON_Delete(item); - } - - if(value != NULL) { - error local_error; - local_error.json = (const unsigned char*)value; - local_error.position = 0; - - if(buffer.offset < buffer.length) { - local_error.position = buffer.offset; - } else if(buffer.length > 0) { - local_error.position = buffer.length - 1; - } - - if(return_parse_end != NULL) { - *return_parse_end = (const char*)local_error.json + local_error.position; - } - - global_error = local_error; - } - - return NULL; -} - -/* Default options for cJSON_Parse */ -CJSON_PUBLIC(cJSON*) cJSON_Parse(const char* value) { - return cJSON_ParseWithOpts(value, 0, 0); -} - -CJSON_PUBLIC(cJSON*) cJSON_ParseWithLength(const char* value, size_t buffer_length) { - return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); -} - -#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) - -static unsigned char* - print(const cJSON* const item, cJSON_bool format, const internal_hooks* const hooks) { - static const size_t default_buffer_size = 256; - printbuffer buffer[1]; - unsigned char* printed = NULL; - - memset(buffer, 0, sizeof(buffer)); - - /* create buffer */ - buffer->buffer = (unsigned char*)hooks->allocate(default_buffer_size); - buffer->length = default_buffer_size; - buffer->format = format; - buffer->hooks = *hooks; - if(buffer->buffer == NULL) { - goto fail; - } - - /* print the value */ - if(!print_value(item, buffer)) { - goto fail; - } - update_offset(buffer); - - /* check if reallocate is available */ - if(hooks->reallocate != NULL) { - printed = (unsigned char*)hooks->reallocate(buffer->buffer, buffer->offset + 1); - if(printed == NULL) { - goto fail; - } - buffer->buffer = NULL; - } else /* otherwise copy the JSON over to a new buffer */ - { - printed = (unsigned char*)hooks->allocate(buffer->offset + 1); - if(printed == NULL) { - goto fail; - } - memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); - printed[buffer->offset] = '\0'; /* just to be sure */ - - /* free the buffer */ - hooks->deallocate(buffer->buffer); - } - - return printed; - -fail: - if(buffer->buffer != NULL) { - hooks->deallocate(buffer->buffer); - } - - if(printed != NULL) { - hooks->deallocate(printed); - } - - return NULL; -} - -/* Render a cJSON item/entity/structure to text. */ -CJSON_PUBLIC(char*) cJSON_Print(const cJSON* item) { - return (char*)print(item, true, &global_hooks); -} - -CJSON_PUBLIC(char*) cJSON_PrintUnformatted(const cJSON* item) { - return (char*)print(item, false, &global_hooks); -} - -CJSON_PUBLIC(char*) cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt) { - printbuffer p = {0, 0, 0, 0, 0, 0, {0, 0, 0}}; - - if(prebuffer < 0) { - return NULL; - } - - p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); - if(!p.buffer) { - return NULL; - } - - p.length = (size_t)prebuffer; - p.offset = 0; - p.noalloc = false; - p.format = fmt; - p.hooks = global_hooks; - - if(!print_value(item, &p)) { - global_hooks.deallocate(p.buffer); - return NULL; - } - - return (char*)p.buffer; -} - -CJSON_PUBLIC(cJSON_bool) -cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format) { - printbuffer p = {0, 0, 0, 0, 0, 0, {0, 0, 0}}; - - if((length < 0) || (buffer == NULL)) { - return false; - } - - p.buffer = (unsigned char*)buffer; - p.length = (size_t)length; - p.offset = 0; - p.noalloc = true; - p.format = format; - p.hooks = global_hooks; - - return print_value(item, &p); -} - -/* Parser core - when encountering text, process appropriately. */ -static cJSON_bool parse_value(cJSON* const item, parse_buffer* const input_buffer) { - if((input_buffer == NULL) || (input_buffer->content == NULL)) { - return false; /* no input */ - } - - /* parse the different types of values */ - /* null */ - if(can_read(input_buffer, 4) && - (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) { - item->type = cJSON_NULL; - input_buffer->offset += 4; - return true; - } - /* false */ - if(can_read(input_buffer, 5) && - (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) { - item->type = cJSON_False; - input_buffer->offset += 5; - return true; - } - /* true */ - if(can_read(input_buffer, 4) && - (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) { - item->type = cJSON_True; - item->valueint = 1; - input_buffer->offset += 4; - return true; - } - /* string */ - if(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) { - return parse_string(item, input_buffer); - } - /* number */ - if(can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || - ((buffer_at_offset(input_buffer)[0] >= '0') && - (buffer_at_offset(input_buffer)[0] <= '9')))) { - return parse_number(item, input_buffer); - } - /* array */ - if(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) { - return parse_array(item, input_buffer); - } - /* object */ - if(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) { - return parse_object(item, input_buffer); - } - - return false; -} - -/* Render a value to text. */ -static cJSON_bool print_value(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char* output = NULL; - - if((item == NULL) || (output_buffer == NULL)) { - return false; - } - - switch((item->type) & 0xFF) { - case cJSON_NULL: - output = ensure(output_buffer, 5); - if(output == NULL) { - return false; - } - strcpy((char*)output, "null"); - return true; - - case cJSON_False: - output = ensure(output_buffer, 6); - if(output == NULL) { - return false; - } - strcpy((char*)output, "false"); - return true; - - case cJSON_True: - output = ensure(output_buffer, 5); - if(output == NULL) { - return false; - } - strcpy((char*)output, "true"); - return true; - - case cJSON_Number: - return print_number(item, output_buffer); - - case cJSON_Raw: { - size_t raw_length = 0; - if(item->valuestring == NULL) { - return false; - } - - raw_length = strlen(item->valuestring) + sizeof(""); - output = ensure(output_buffer, raw_length); - if(output == NULL) { - return false; - } - memcpy(output, item->valuestring, raw_length); - return true; - } - - case cJSON_String: - return print_string(item, output_buffer); - - case cJSON_Array: - return print_array(item, output_buffer); - - case cJSON_Object: - return print_object(item, output_buffer); - - default: - return false; - } -} - -/* Build an array from input text. */ -static cJSON_bool parse_array(cJSON* const item, parse_buffer* const input_buffer) { - cJSON* head = NULL; /* head of the linked list */ - cJSON* current_item = NULL; - - if(input_buffer->depth >= CJSON_NESTING_LIMIT) { - return false; /* to deeply nested */ - } - input_buffer->depth++; - - if(buffer_at_offset(input_buffer)[0] != '[') { - /* not an array */ - goto fail; - } - - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) { - /* empty array */ - goto success; - } - - /* check if we skipped to the end of the buffer */ - if(cannot_access_at_index(input_buffer, 0)) { - input_buffer->offset--; - goto fail; - } - - /* step back to character in front of the first element */ - input_buffer->offset--; - /* loop through the comma separated array elements */ - do { - /* allocate next item */ - cJSON* new_item = cJSON_New_Item(&(input_buffer->hooks)); - if(new_item == NULL) { - goto fail; /* allocation failure */ - } - - /* attach next item to list */ - if(head == NULL) { - /* start the linked list */ - current_item = head = new_item; - } else { - /* add to the end and advance */ - current_item->next = new_item; - new_item->prev = current_item; - current_item = new_item; - } - - /* parse next value */ - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if(!parse_value(current_item, input_buffer)) { - goto fail; /* failed to parse value */ - } - buffer_skip_whitespace(input_buffer); - } while(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); - - if(cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') { - goto fail; /* expected end of array */ - } - -success: - input_buffer->depth--; - - if(head != NULL) { - head->prev = current_item; - } - - item->type = cJSON_Array; - item->child = head; - - input_buffer->offset++; - - return true; - -fail: - if(head != NULL) { - cJSON_Delete(head); - } - - return false; -} - -/* Render an array to text */ -static cJSON_bool print_array(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char* output_pointer = NULL; - size_t length = 0; - cJSON* current_element = item->child; - - if(output_buffer == NULL) { - return false; - } - - /* Compose the output array. */ - /* opening square bracket */ - output_pointer = ensure(output_buffer, 1); - if(output_pointer == NULL) { - return false; - } - - *output_pointer = '['; - output_buffer->offset++; - output_buffer->depth++; - - while(current_element != NULL) { - if(!print_value(current_element, output_buffer)) { - return false; - } - update_offset(output_buffer); - if(current_element->next) { - length = (size_t)(output_buffer->format ? 2 : 1); - output_pointer = ensure(output_buffer, length + 1); - if(output_pointer == NULL) { - return false; - } - *output_pointer++ = ','; - if(output_buffer->format) { - *output_pointer++ = ' '; - } - *output_pointer = '\0'; - output_buffer->offset += length; - } - current_element = current_element->next; - } - - output_pointer = ensure(output_buffer, 2); - if(output_pointer == NULL) { - return false; - } - *output_pointer++ = ']'; - *output_pointer = '\0'; - output_buffer->depth--; - - return true; -} - -/* Build an object from the text. */ -static cJSON_bool parse_object(cJSON* const item, parse_buffer* const input_buffer) { - cJSON* head = NULL; /* linked list head */ - cJSON* current_item = NULL; - - if(input_buffer->depth >= CJSON_NESTING_LIMIT) { - return false; /* to deeply nested */ - } - input_buffer->depth++; - - if(cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) { - goto fail; /* not an object */ - } - - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) { - goto success; /* empty object */ - } - - /* check if we skipped to the end of the buffer */ - if(cannot_access_at_index(input_buffer, 0)) { - input_buffer->offset--; - goto fail; - } - - /* step back to character in front of the first element */ - input_buffer->offset--; - /* loop through the comma separated array elements */ - do { - /* allocate next item */ - cJSON* new_item = cJSON_New_Item(&(input_buffer->hooks)); - if(new_item == NULL) { - goto fail; /* allocation failure */ - } - - /* attach next item to list */ - if(head == NULL) { - /* start the linked list */ - current_item = head = new_item; - } else { - /* add to the end and advance */ - current_item->next = new_item; - new_item->prev = current_item; - current_item = new_item; - } - - /* parse the name of the child */ - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if(!parse_string(current_item, input_buffer)) { - goto fail; /* failed to parse name */ - } - buffer_skip_whitespace(input_buffer); - - /* swap valuestring and string, because we parsed the name */ - current_item->string = current_item->valuestring; - current_item->valuestring = NULL; - - if(cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) { - goto fail; /* invalid object */ - } - - /* parse the value */ - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if(!parse_value(current_item, input_buffer)) { - goto fail; /* failed to parse value */ - } - buffer_skip_whitespace(input_buffer); - } while(can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); - - if(cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) { - goto fail; /* expected end of object */ - } - -success: - input_buffer->depth--; - - if(head != NULL) { - head->prev = current_item; - } - - item->type = cJSON_Object; - item->child = head; - - input_buffer->offset++; - return true; - -fail: - if(head != NULL) { - cJSON_Delete(head); - } - - return false; -} - -/* Render an object to text. */ -static cJSON_bool print_object(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char* output_pointer = NULL; - size_t length = 0; - cJSON* current_item = item->child; - - if(output_buffer == NULL) { - return false; - } - - /* Compose the output: */ - length = (size_t)(output_buffer->format ? 2 : 1); /* fmt: {\n */ - output_pointer = ensure(output_buffer, length + 1); - if(output_pointer == NULL) { - return false; - } - - *output_pointer++ = '{'; - output_buffer->depth++; - if(output_buffer->format) { - *output_pointer++ = '\n'; - } - output_buffer->offset += length; - - while(current_item) { - if(output_buffer->format) { - size_t i; - output_pointer = ensure(output_buffer, output_buffer->depth); - if(output_pointer == NULL) { - return false; - } - for(i = 0; i < output_buffer->depth; i++) { - *output_pointer++ = '\t'; - } - output_buffer->offset += output_buffer->depth; - } - - /* print key */ - if(!print_string_ptr((unsigned char*)current_item->string, output_buffer)) { - return false; - } - update_offset(output_buffer); - - length = (size_t)(output_buffer->format ? 2 : 1); - output_pointer = ensure(output_buffer, length); - if(output_pointer == NULL) { - return false; - } - *output_pointer++ = ':'; - if(output_buffer->format) { - *output_pointer++ = '\t'; - } - output_buffer->offset += length; - - /* print value */ - if(!print_value(current_item, output_buffer)) { - return false; - } - update_offset(output_buffer); - - /* print comma if not last */ - length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); - output_pointer = ensure(output_buffer, length + 1); - if(output_pointer == NULL) { - return false; - } - if(current_item->next) { - *output_pointer++ = ','; - } - - if(output_buffer->format) { - *output_pointer++ = '\n'; - } - *output_pointer = '\0'; - output_buffer->offset += length; - - current_item = current_item->next; - } - - output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); - if(output_pointer == NULL) { - return false; - } - if(output_buffer->format) { - size_t i; - for(i = 0; i < (output_buffer->depth - 1); i++) { - *output_pointer++ = '\t'; - } - } - *output_pointer++ = '}'; - *output_pointer = '\0'; - output_buffer->depth--; - - return true; -} - -/* Get Array size/item / object item. */ -CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON* array) { - cJSON* child = NULL; - size_t size = 0; - - if(array == NULL) { - return 0; - } - - child = array->child; - - while(child != NULL) { - size++; - child = child->next; - } - - /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ - - return (int)size; -} - -static cJSON* get_array_item(const cJSON* array, size_t index) { - cJSON* current_child = NULL; - - if(array == NULL) { - return NULL; - } - - current_child = array->child; - while((current_child != NULL) && (index > 0)) { - index--; - current_child = current_child->next; - } - - return current_child; -} - -CJSON_PUBLIC(cJSON*) cJSON_GetArrayItem(const cJSON* array, int index) { - if(index < 0) { - return NULL; - } - - return get_array_item(array, (size_t)index); -} - -static cJSON* get_object_item( - const cJSON* const object, - const char* const name, - const cJSON_bool case_sensitive) { - cJSON* current_element = NULL; - - if((object == NULL) || (name == NULL)) { - return NULL; - } - - current_element = object->child; - if(case_sensitive) { - while((current_element != NULL) && (current_element->string != NULL) && - (strcmp(name, current_element->string) != 0)) { - current_element = current_element->next; - } - } else { - while((current_element != NULL) && - (case_insensitive_strcmp( - (const unsigned char*)name, (const unsigned char*)(current_element->string)) != - 0)) { - current_element = current_element->next; - } - } - - if((current_element == NULL) || (current_element->string == NULL)) { - return NULL; - } - - return current_element; -} - -CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char* const string) { - return get_object_item(object, string, false); -} - -CJSON_PUBLIC(cJSON*) -cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string) { - return get_object_item(object, string, true); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON* object, const char* string) { - return cJSON_GetObjectItem(object, string) ? 1 : 0; -} - -/* Utility for array list handling. */ -static void suffix_object(cJSON* prev, cJSON* item) { - prev->next = item; - item->prev = prev; -} - -/* Utility for handling references. */ -static cJSON* create_reference(const cJSON* item, const internal_hooks* const hooks) { - cJSON* reference = NULL; - if(item == NULL) { - return NULL; - } - - reference = cJSON_New_Item(hooks); - if(reference == NULL) { - return NULL; - } - - memcpy(reference, item, sizeof(cJSON)); - reference->string = NULL; - reference->type |= cJSON_IsReference; - reference->next = reference->prev = NULL; - return reference; -} - -static cJSON_bool add_item_to_array(cJSON* array, cJSON* item) { - cJSON* child = NULL; - - if((item == NULL) || (array == NULL) || (array == item)) { - return false; - } - - child = array->child; - /* - * To find the last item in array quickly, we use prev in array - */ - if(child == NULL) { - /* list is empty, start new one */ - array->child = item; - item->prev = item; - item->next = NULL; - } else { - /* append to the end */ - if(child->prev) { - suffix_object(child->prev, item); - array->child->prev = item; - } - } - - return true; -} - -/* Add item to array/object. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON* array, cJSON* item) { - return add_item_to_array(array, item); -} - -#if defined(__clang__) || \ - (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) -#pragma GCC diagnostic push -#endif -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wcast-qual" -#endif -/* helper function to cast away const */ -static void* cast_away_const(const void* string) { - return (void*)string; -} -#if defined(__clang__) || \ - (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) -#pragma GCC diagnostic pop -#endif - -static cJSON_bool add_item_to_object( - cJSON* const object, - const char* const string, - cJSON* const item, - const internal_hooks* const hooks, - const cJSON_bool constant_key) { - char* new_key = NULL; - int new_type = cJSON_Invalid; - - if((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) { - return false; - } - - if(constant_key) { - new_key = (char*)cast_away_const(string); - new_type = item->type | cJSON_StringIsConst; - } else { - new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); - if(new_key == NULL) { - return false; - } - - new_type = item->type & ~cJSON_StringIsConst; - } - - if(!(item->type & cJSON_StringIsConst) && (item->string != NULL)) { - hooks->deallocate(item->string); - } - - item->string = new_key; - item->type = new_type; - - return add_item_to_array(object, item); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item) { - return add_item_to_object(object, string, item, &global_hooks, false); -} - -/* Add an item to an object with constant string as key */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item) { - return add_item_to_object(object, string, item, &global_hooks, true); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item) { - if(array == NULL) { - return false; - } - - return add_item_to_array(array, create_reference(item, &global_hooks)); -} - -CJSON_PUBLIC(cJSON_bool) -cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item) { - if((object == NULL) || (string == NULL)) { - return false; - } - - return add_item_to_object( - object, string, create_reference(item, &global_hooks), &global_hooks, false); -} - -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON* const object, const char* const name) { - cJSON* null = cJSON_CreateNull(); - if(add_item_to_object(object, name, null, &global_hooks, false)) { - return null; - } - - cJSON_Delete(null); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON* const object, const char* const name) { - cJSON* true_item = cJSON_CreateTrue(); - if(add_item_to_object(object, name, true_item, &global_hooks, false)) { - return true_item; - } - - cJSON_Delete(true_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON* const object, const char* const name) { - cJSON* false_item = cJSON_CreateFalse(); - if(add_item_to_object(object, name, false_item, &global_hooks, false)) { - return false_item; - } - - cJSON_Delete(false_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) -cJSON_AddBoolToObject(cJSON* const object, const char* const name, const cJSON_bool boolean) { - cJSON* bool_item = cJSON_CreateBool(boolean); - if(add_item_to_object(object, name, bool_item, &global_hooks, false)) { - return bool_item; - } - - cJSON_Delete(bool_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) -cJSON_AddNumberToObject(cJSON* const object, const char* const name, const double number) { - cJSON* number_item = cJSON_CreateNumber(number); - if(add_item_to_object(object, name, number_item, &global_hooks, false)) { - return number_item; - } - - cJSON_Delete(number_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) -cJSON_AddStringToObject(cJSON* const object, const char* const name, const char* const string) { - cJSON* string_item = cJSON_CreateString(string); - if(add_item_to_object(object, name, string_item, &global_hooks, false)) { - return string_item; - } - - cJSON_Delete(string_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) -cJSON_AddRawToObject(cJSON* const object, const char* const name, const char* const raw) { - cJSON* raw_item = cJSON_CreateRaw(raw); - if(add_item_to_object(object, name, raw_item, &global_hooks, false)) { - return raw_item; - } - - cJSON_Delete(raw_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON* const object, const char* const name) { - cJSON* object_item = cJSON_CreateObject(); - if(add_item_to_object(object, name, object_item, &global_hooks, false)) { - return object_item; - } - - cJSON_Delete(object_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON* const object, const char* const name) { - cJSON* array = cJSON_CreateArray(); - if(add_item_to_object(object, name, array, &global_hooks, false)) { - return array; - } - - cJSON_Delete(array); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item) { - if((parent == NULL) || (item == NULL)) { - return NULL; - } - - if(item != parent->child) { - /* not the first element */ - item->prev->next = item->next; - } - if(item->next != NULL) { - /* not the last element */ - item->next->prev = item->prev; - } - - if(item == parent->child) { - /* first element */ - parent->child = item->next; - } else if(item->next == NULL) { - /* last element */ - parent->child->prev = item->prev; - } - - /* make sure the detached item doesn't point anywhere anymore */ - item->prev = NULL; - item->next = NULL; - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromArray(cJSON* array, int which) { - if(which < 0) { - return NULL; - } - - return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); -} - -CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON* array, int which) { - cJSON_Delete(cJSON_DetachItemFromArray(array, which)); -} - -CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObject(cJSON* object, const char* string) { - cJSON* to_detach = cJSON_GetObjectItem(object, string); - - return cJSON_DetachItemViaPointer(object, to_detach); -} - -CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string) { - cJSON* to_detach = cJSON_GetObjectItemCaseSensitive(object, string); - - return cJSON_DetachItemViaPointer(object, to_detach); -} - -CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON* object, const char* string) { - cJSON_Delete(cJSON_DetachItemFromObject(object, string)); -} - -CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string) { - cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); -} - -/* Replace array/object items with new ones. */ -CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON* array, int which, cJSON* newitem) { - cJSON* after_inserted = NULL; - - if(which < 0) { - return false; - } - - after_inserted = get_array_item(array, (size_t)which); - if(after_inserted == NULL) { - return add_item_to_array(array, newitem); - } - - newitem->next = after_inserted; - newitem->prev = after_inserted->prev; - after_inserted->prev = newitem; - if(after_inserted == array->child) { - array->child = newitem; - } else { - newitem->prev->next = newitem; - } - return true; -} - -CJSON_PUBLIC(cJSON_bool) -cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement) { - if((parent == NULL) || (replacement == NULL) || (item == NULL)) { - return false; - } - - if(replacement == item) { - return true; - } - - replacement->next = item->next; - replacement->prev = item->prev; - - if(replacement->next != NULL) { - replacement->next->prev = replacement; - } - if(parent->child == item) { - if(parent->child->prev == parent->child) { - replacement->prev = replacement; - } - parent->child = replacement; - } else { /* - * To find the last item in array quickly, we use prev in array. - * We can't modify the last item's next pointer where this item was the parent's child - */ - if(replacement->prev != NULL) { - replacement->prev->next = replacement; - } - if(replacement->next == NULL) { - parent->child->prev = replacement; - } - } - - item->next = NULL; - item->prev = NULL; - cJSON_Delete(item); - - return true; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem) { - if(which < 0) { - return false; - } - - return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); -} - -static cJSON_bool replace_item_in_object( - cJSON* object, - const char* string, - cJSON* replacement, - cJSON_bool case_sensitive) { - if((replacement == NULL) || (string == NULL)) { - return false; - } - - /* replace the name in the replacement */ - if(!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) { - cJSON_free(replacement->string); - } - replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); - replacement->type &= ~cJSON_StringIsConst; - - return cJSON_ReplaceItemViaPointer( - object, get_object_item(object, string, case_sensitive), replacement); -} - -CJSON_PUBLIC(cJSON_bool) -cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem) { - return replace_item_in_object(object, string, newitem, false); -} - -CJSON_PUBLIC(cJSON_bool) -cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem) { - return replace_item_in_object(object, string, newitem, true); -} - -/* Create basic types: */ -CJSON_PUBLIC(cJSON*) cJSON_CreateNull(void) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_NULL; - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateTrue(void) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_True; - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateFalse(void) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_False; - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateBool(cJSON_bool boolean) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = boolean ? cJSON_True : cJSON_False; - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateNumber(double num) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_Number; - item->valuedouble = num; - - /* use saturation in case of overflow */ - if(num >= INT_MAX) { - item->valueint = INT_MAX; - } else if(num <= (double)INT_MIN) { - item->valueint = INT_MIN; - } else { - item->valueint = (int)num; - } - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateString(const char* string) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_String; - item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); - if(!item->valuestring) { - cJSON_Delete(item); - return NULL; - } - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateStringReference(const char* string) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item != NULL) { - item->type = cJSON_String | cJSON_IsReference; - item->valuestring = (char*)cast_away_const(string); - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateObjectReference(const cJSON* child) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item != NULL) { - item->type = cJSON_Object | cJSON_IsReference; - item->child = (cJSON*)cast_away_const(child); - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateArrayReference(const cJSON* child) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item != NULL) { - item->type = cJSON_Array | cJSON_IsReference; - item->child = (cJSON*)cast_away_const(child); - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateRaw(const char* raw) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_Raw; - item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); - if(!item->valuestring) { - cJSON_Delete(item); - return NULL; - } - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateArray(void) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_Array; - } - - return item; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void) { - cJSON* item = cJSON_New_Item(&global_hooks); - if(item) { - item->type = cJSON_Object; - } - - return item; -} - -/* Create Arrays: */ -CJSON_PUBLIC(cJSON*) cJSON_CreateIntArray(const int* numbers, int count) { - size_t i = 0; - cJSON* n = NULL; - cJSON* p = NULL; - cJSON* a = NULL; - - if((count < 0) || (numbers == NULL)) { - return NULL; - } - - a = cJSON_CreateArray(); - - for(i = 0; a && (i < (size_t)count); i++) { - n = cJSON_CreateNumber(numbers[i]); - if(!n) { - cJSON_Delete(a); - return NULL; - } - if(!i) { - a->child = n; - } else { - suffix_object(p, n); - } - p = n; - } - - if(a && a->child) { - a->child->prev = n; - } - - return a; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateFloatArray(const float* numbers, int count) { - size_t i = 0; - cJSON* n = NULL; - cJSON* p = NULL; - cJSON* a = NULL; - - if((count < 0) || (numbers == NULL)) { - return NULL; - } - - a = cJSON_CreateArray(); - - for(i = 0; a && (i < (size_t)count); i++) { - n = cJSON_CreateNumber((double)numbers[i]); - if(!n) { - cJSON_Delete(a); - return NULL; - } - if(!i) { - a->child = n; - } else { - suffix_object(p, n); - } - p = n; - } - - if(a && a->child) { - a->child->prev = n; - } - - return a; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateDoubleArray(const double* numbers, int count) { - size_t i = 0; - cJSON* n = NULL; - cJSON* p = NULL; - cJSON* a = NULL; - - if((count < 0) || (numbers == NULL)) { - return NULL; - } - - a = cJSON_CreateArray(); - - for(i = 0; a && (i < (size_t)count); i++) { - n = cJSON_CreateNumber(numbers[i]); - if(!n) { - cJSON_Delete(a); - return NULL; - } - if(!i) { - a->child = n; - } else { - suffix_object(p, n); - } - p = n; - } - - if(a && a->child) { - a->child->prev = n; - } - - return a; -} - -CJSON_PUBLIC(cJSON*) cJSON_CreateStringArray(const char* const* strings, int count) { - size_t i = 0; - cJSON* n = NULL; - cJSON* p = NULL; - cJSON* a = NULL; - - if((count < 0) || (strings == NULL)) { - return NULL; - } - - a = cJSON_CreateArray(); - - for(i = 0; a && (i < (size_t)count); i++) { - n = cJSON_CreateString(strings[i]); - if(!n) { - cJSON_Delete(a); - return NULL; - } - if(!i) { - a->child = n; - } else { - suffix_object(p, n); - } - p = n; - } - - if(a && a->child) { - a->child->prev = n; - } - - return a; -} - -/* Duplication */ -CJSON_PUBLIC(cJSON*) cJSON_Duplicate(const cJSON* item, cJSON_bool recurse) { - cJSON* newitem = NULL; - cJSON* child = NULL; - cJSON* next = NULL; - cJSON* newchild = NULL; - - /* Bail on bad ptr */ - if(!item) { - goto fail; - } - /* Create new item */ - newitem = cJSON_New_Item(&global_hooks); - if(!newitem) { - goto fail; - } - /* Copy over all vars */ - newitem->type = item->type & (~cJSON_IsReference); - newitem->valueint = item->valueint; - newitem->valuedouble = item->valuedouble; - if(item->valuestring) { - newitem->valuestring = - (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); - if(!newitem->valuestring) { - goto fail; - } - } - if(item->string) { - newitem->string = (item->type & cJSON_StringIsConst) ? - item->string : - (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); - if(!newitem->string) { - goto fail; - } - } - /* If non-recursive, then we're done! */ - if(!recurse) { - return newitem; - } - /* Walk the ->next chain for the child. */ - child = item->child; - while(child != NULL) { - newchild = cJSON_Duplicate( - child, true); /* Duplicate (with recurse) each item in the ->next chain */ - if(!newchild) { - goto fail; - } - if(next != NULL) { - /* If newitem->child already set, then crosswire ->prev and ->next and move on */ - next->next = newchild; - newchild->prev = next; - next = newchild; - } else { - /* Set newitem->child and move to it */ - newitem->child = newchild; - next = newchild; - } - child = child->next; - } - if(newitem && newitem->child) { - newitem->child->prev = newchild; - } - - return newitem; - -fail: - if(newitem != NULL) { - cJSON_Delete(newitem); - } - - return NULL; -} - -static void skip_oneline_comment(char** input) { - *input += static_strlen("//"); - - for(; (*input)[0] != '\0'; ++(*input)) { - if((*input)[0] == '\n') { - *input += static_strlen("\n"); - return; - } - } -} - -static void skip_multiline_comment(char** input) { - *input += static_strlen("/*"); - - for(; (*input)[0] != '\0'; ++(*input)) { - if(((*input)[0] == '*') && ((*input)[1] == '/')) { - *input += static_strlen("*/"); - return; - } - } -} - -static void minify_string(char** input, char** output) { - (*output)[0] = (*input)[0]; - *input += static_strlen("\""); - *output += static_strlen("\""); - - for(; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { - (*output)[0] = (*input)[0]; - - if((*input)[0] == '\"') { - (*output)[0] = '\"'; - *input += static_strlen("\""); - *output += static_strlen("\""); - return; - } else if(((*input)[0] == '\\') && ((*input)[1] == '\"')) { - (*output)[1] = (*input)[1]; - *input += static_strlen("\""); - *output += static_strlen("\""); - } - } -} - -CJSON_PUBLIC(void) cJSON_Minify(char* json) { - char* into = json; - - if(json == NULL) { - return; - } - - while(json[0] != '\0') { - switch(json[0]) { - case ' ': - case '\t': - case '\r': - case '\n': - json++; - break; - - case '/': - if(json[1] == '/') { - skip_oneline_comment(&json); - } else if(json[1] == '*') { - skip_multiline_comment(&json); - } else { - json++; - } - break; - - case '\"': - minify_string(&json, (char**)&into); - break; - - default: - into[0] = json[0]; - json++; - into++; - } - } - - /* and null-terminate. */ - *into = '\0'; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_Invalid; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_False; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xff) == cJSON_True; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & (cJSON_True | cJSON_False)) != 0; -} -CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_NULL; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_Number; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_String; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_Array; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_Object; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON* const item) { - if(item == NULL) { - return false; - } - - return (item->type & 0xFF) == cJSON_Raw; -} - -CJSON_PUBLIC(cJSON_bool) -cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive) { - if((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) { - return false; - } - - /* check if type is valid */ - switch(a->type & 0xFF) { - case cJSON_False: - case cJSON_True: - case cJSON_NULL: - case cJSON_Number: - case cJSON_String: - case cJSON_Raw: - case cJSON_Array: - case cJSON_Object: - break; - - default: - return false; - } - - /* identical objects are equal */ - if(a == b) { - return true; - } - - switch(a->type & 0xFF) { - /* in these cases and equal type is enough */ - case cJSON_False: - case cJSON_True: - case cJSON_NULL: - return true; - - case cJSON_Number: - if(compare_double(a->valuedouble, b->valuedouble)) { - return true; - } - return false; - - case cJSON_String: - case cJSON_Raw: - if((a->valuestring == NULL) || (b->valuestring == NULL)) { - return false; - } - if(strcmp(a->valuestring, b->valuestring) == 0) { - return true; - } - - return false; - - case cJSON_Array: { - cJSON* a_element = a->child; - cJSON* b_element = b->child; - - for(; (a_element != NULL) && (b_element != NULL);) { - if(!cJSON_Compare(a_element, b_element, case_sensitive)) { - return false; - } - - a_element = a_element->next; - b_element = b_element->next; - } - - /* one of the arrays is longer than the other */ - if(a_element != b_element) { - return false; - } - - return true; - } - - case cJSON_Object: { - cJSON* a_element = NULL; - cJSON* b_element = NULL; - cJSON_ArrayForEach(a_element, a) { - /* TODO This has O(n^2) runtime, which is horrible! */ - b_element = get_object_item(b, a_element->string, case_sensitive); - if(b_element == NULL) { - return false; - } - - if(!cJSON_Compare(a_element, b_element, case_sensitive)) { - return false; - } - } - - /* doing this twice, once on a and b to prevent true comparison if a subset of b - * TODO: Do this the proper way, this is just a fix for now */ - cJSON_ArrayForEach(b_element, b) { - a_element = get_object_item(a, b_element->string, case_sensitive); - if(a_element == NULL) { - return false; - } - - if(!cJSON_Compare(b_element, a_element, case_sensitive)) { - return false; - } - } - - return true; - } - - default: - return false; - } -} - -CJSON_PUBLIC(void*) cJSON_malloc(size_t size) { - return global_hooks.allocate(size); -} - -CJSON_PUBLIC(void) cJSON_free(void* object) { - global_hooks.deallocate(object); -} diff --git a/applications/external/wifi_marauder_companion/script/cJSON.h b/applications/external/wifi_marauder_companion/script/cJSON.h deleted file mode 100644 index 14ec83d9d..000000000 --- a/applications/external/wifi_marauder_companion/script/cJSON.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - Copyright (c) 2009-2017 Dave Gamble and cJSON contributors - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef cJSON__h -#define cJSON__h - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(__WINDOWS__) && \ - (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) -#define __WINDOWS__ -#endif - -#ifdef __WINDOWS__ - -/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: - -CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols -CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) -CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol - -For *nix builds that support visibility attribute, you can define similar behavior by - -setting default visibility to hidden by adding --fvisibility=hidden (for gcc) -or --xldscope=hidden (for sun cc) -to CFLAGS - -then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does - -*/ - -#define CJSON_CDECL __cdecl -#define CJSON_STDCALL __stdcall - -/* export symbols by default, this is necessary for copy pasting the C and header file */ -#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && \ - !defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_EXPORT_SYMBOLS -#endif - -#if defined(CJSON_HIDE_SYMBOLS) -#define CJSON_PUBLIC(type) type CJSON_STDCALL -#elif defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL -#elif defined(CJSON_IMPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL -#endif -#else /* !__WINDOWS__ */ -#define CJSON_CDECL -#define CJSON_STDCALL - -#if(defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && \ - defined(CJSON_API_VISIBILITY) -#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type -#else -#define CJSON_PUBLIC(type) type -#endif -#endif - -/* project version */ -#define CJSON_VERSION_MAJOR 1 -#define CJSON_VERSION_MINOR 7 -#define CJSON_VERSION_PATCH 15 - -#include - -/* cJSON Types: */ -#define cJSON_Invalid (0) -#define cJSON_False (1 << 0) -#define cJSON_True (1 << 1) -#define cJSON_NULL (1 << 2) -#define cJSON_Number (1 << 3) -#define cJSON_String (1 << 4) -#define cJSON_Array (1 << 5) -#define cJSON_Object (1 << 6) -#define cJSON_Raw (1 << 7) /* raw json */ - -#define cJSON_IsReference 256 -#define cJSON_StringIsConst 512 - -/* The cJSON structure: */ -typedef struct cJSON { - /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ - struct cJSON* next; - struct cJSON* prev; - /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ - struct cJSON* child; - - /* The type of the item, as above. */ - int type; - - /* The item's string, if type==cJSON_String and type == cJSON_Raw */ - char* valuestring; - /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ - int valueint; - /* The item's number, if type==cJSON_Number */ - double valuedouble; - - /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ - char* string; -} cJSON; - -typedef struct cJSON_Hooks { - /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ - void*(CJSON_CDECL* malloc_fn)(size_t sz); - void(CJSON_CDECL* free_fn)(void* ptr); -} cJSON_Hooks; - -typedef int cJSON_bool; - -/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. - * This is to prevent stack overflows. */ -#ifndef CJSON_NESTING_LIMIT -#define CJSON_NESTING_LIMIT 1000 -#endif - -/* returns the version of cJSON as a string */ -CJSON_PUBLIC(const char*) cJSON_Version(void); - -/* Supply malloc, realloc and free functions to cJSON */ -CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); - -/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ -/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ -CJSON_PUBLIC(cJSON*) cJSON_Parse(const char* value); -CJSON_PUBLIC(cJSON*) cJSON_ParseWithLength(const char* value, size_t buffer_length); -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ -CJSON_PUBLIC(cJSON*) -cJSON_ParseWithOpts( - const char* value, - const char** return_parse_end, - cJSON_bool require_null_terminated); -CJSON_PUBLIC(cJSON*) -cJSON_ParseWithLengthOpts( - const char* value, - size_t buffer_length, - const char** return_parse_end, - cJSON_bool require_null_terminated); - -/* Render a cJSON entity to text for transfer/storage. */ -CJSON_PUBLIC(char*) cJSON_Print(const cJSON* item); -/* Render a cJSON entity to text for transfer/storage without any formatting. */ -CJSON_PUBLIC(char*) cJSON_PrintUnformatted(const cJSON* item); -/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ -CJSON_PUBLIC(char*) cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt); -/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ -/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ -CJSON_PUBLIC(cJSON_bool) -cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format); -/* Delete a cJSON entity and all subentities. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON* item); - -/* Returns the number of items in an array (or object). */ -CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON* array); -/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ -CJSON_PUBLIC(cJSON*) cJSON_GetArrayItem(const cJSON* array, int index); -/* Get item "string" from object. Case insensitive. */ -CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char* const string); -CJSON_PUBLIC(cJSON*) -cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string); -CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON* object, const char* string); -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -CJSON_PUBLIC(const char*) cJSON_GetErrorPtr(void); - -/* Check item type and return its value */ -CJSON_PUBLIC(char*) cJSON_GetStringValue(const cJSON* const item); -CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON* const item); - -/* These functions check the type of an item */ -CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON* const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON* const item); - -/* These calls create a cJSON item of the appropriate type. */ -CJSON_PUBLIC(cJSON*) cJSON_CreateNull(void); -CJSON_PUBLIC(cJSON*) cJSON_CreateTrue(void); -CJSON_PUBLIC(cJSON*) cJSON_CreateFalse(void); -CJSON_PUBLIC(cJSON*) cJSON_CreateBool(cJSON_bool boolean); -CJSON_PUBLIC(cJSON*) cJSON_CreateNumber(double num); -CJSON_PUBLIC(cJSON*) cJSON_CreateString(const char* string); -/* raw json */ -CJSON_PUBLIC(cJSON*) cJSON_CreateRaw(const char* raw); -CJSON_PUBLIC(cJSON*) cJSON_CreateArray(void); -CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void); - -/* Create a string where valuestring references a string so - * it will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON*) cJSON_CreateStringReference(const char* string); -/* Create an object/array that only references it's elements so - * they will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON*) cJSON_CreateObjectReference(const cJSON* child); -CJSON_PUBLIC(cJSON*) cJSON_CreateArrayReference(const cJSON* child); - -/* These utilities create an Array of count items. - * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ -CJSON_PUBLIC(cJSON*) cJSON_CreateIntArray(const int* numbers, int count); -CJSON_PUBLIC(cJSON*) cJSON_CreateFloatArray(const float* numbers, int count); -CJSON_PUBLIC(cJSON*) cJSON_CreateDoubleArray(const double* numbers, int count); -CJSON_PUBLIC(cJSON*) cJSON_CreateStringArray(const char* const* strings, int count); - -/* Append item to the specified array/object. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON* array, cJSON* item); -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item); -/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. - * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before - * writing to `item->string` */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item); -/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item); -CJSON_PUBLIC(cJSON_bool) -cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item); - -/* Remove/Detach items from Arrays/Objects. */ -CJSON_PUBLIC(cJSON*) cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item); -CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromArray(cJSON* array, int which); -CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON* array, int which); -CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObject(cJSON* object, const char* string); -CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string); -CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON* object, const char* string); -CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string); - -/* Update array items. */ -CJSON_PUBLIC(cJSON_bool) -cJSON_InsertItemInArray( - cJSON* array, - int which, - cJSON* newitem); /* Shifts pre-existing items to the right. */ -CJSON_PUBLIC(cJSON_bool) -cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem); -CJSON_PUBLIC(cJSON_bool) -cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem); -CJSON_PUBLIC(cJSON_bool) -cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem); - -/* Duplicate a cJSON item */ -CJSON_PUBLIC(cJSON*) cJSON_Duplicate(const cJSON* item, cJSON_bool recurse); -/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will - * need to be released. With recurse!=0, it will duplicate any children connected to the item. - * The item->next and ->prev pointers are always zero on return from Duplicate. */ -/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. - * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ -CJSON_PUBLIC(cJSON_bool) -cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive); - -/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. - * The input pointer json cannot point to a read-only address area, such as a string constant, - * but should point to a readable and writable address area. */ -CJSON_PUBLIC(void) cJSON_Minify(char* json); - -/* Helper functions for creating and adding items to an object at the same time. - * They return the added item or NULL on failure. */ -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON* const object, const char* const name); -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON* const object, const char* const name); -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON* const object, const char* const name); -CJSON_PUBLIC(cJSON*) -cJSON_AddBoolToObject(cJSON* const object, const char* const name, const cJSON_bool boolean); -CJSON_PUBLIC(cJSON*) -cJSON_AddNumberToObject(cJSON* const object, const char* const name, const double number); -CJSON_PUBLIC(cJSON*) -cJSON_AddStringToObject(cJSON* const object, const char* const name, const char* const string); -CJSON_PUBLIC(cJSON*) -cJSON_AddRawToObject(cJSON* const object, const char* const name, const char* const raw); -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON* const object, const char* const name); -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON* const object, const char* const name); - -/* When assigning an integer value, it needs to be propagated to valuedouble too. */ -#define cJSON_SetIntValue(object, number) \ - ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) -/* helper for the cJSON_SetNumberValue macro */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON* object, double number); -#define cJSON_SetNumberValue(object, number) \ - ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) -/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ -CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON* object, const char* valuestring); - -/* Macro for iterating over an array or object */ -#define cJSON_ArrayForEach(element, array) \ - for(element = (array != NULL) ? (array)->child : NULL; element != NULL; \ - element = element->next) - -/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ -CJSON_PUBLIC(void*) cJSON_malloc(size_t size); -CJSON_PUBLIC(void) cJSON_free(void* object); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.c deleted file mode 100644 index 6fe853eb6..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "wifi_marauder_script_stage_menu.h" - -WifiMarauderScriptStageMenu* - wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type) { - WifiMarauderScriptStageMenu* script_stage_menu = malloc(sizeof(WifiMarauderScriptStageMenu)); - - switch(stage_type) { -#define ADD_STAGE(name, id) \ - case WifiMarauderScriptStageType##id: \ - wifi_marauder_script_stage_menu_##name##_load(script_stage_menu); \ - break; - -#include "wifi_marauder_script_stage_menu_config.h" -#undef ADD_STAGE - } - return script_stage_menu; -} - -void wifi_marauder_script_stage_menu_free(WifiMarauderScriptStageMenu* stage_menu) { - if(stage_menu == NULL) { - return; - } - for(uint32_t i = 0; i < stage_menu->num_items; i++) { - WifiMarauderScriptMenuItem* item = &(stage_menu->items[i]); - for(int j = 0; j < item->num_options; j++) { - free(item->options[j]); - } - free(item->name); - } - free(stage_menu->items); - free(stage_menu); -} diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.h b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.h deleted file mode 100644 index f5186526c..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include "../wifi_marauder_script.h" - -#define ITEM_EDIT_MAX_OPTIONS (12) - -typedef void (*VariableItemSetupCallback)(VariableItem* item); -typedef void (*VariableItemSelectCallback)(void* context); - -typedef enum WifiMarauderScriptMenuItemType { - WifiMarauderScriptMenuItemTypeString, - WifiMarauderScriptMenuItemTypeNumber, - WifiMarauderScriptMenuItemTypeOptionsString, - WifiMarauderScriptMenuItemTypeOptionsNumber, - WifiMarauderScriptMenuItemTypeListString, - WifiMarauderScriptMenuItemTypeListNumber -} WifiMarauderScriptMenuItemType; - -typedef struct WifiMarauderScriptMenuItem { - char* name; - WifiMarauderScriptMenuItemType type; - int num_options; - char* options[ITEM_EDIT_MAX_OPTIONS]; - VariableItemSetupCallback setup_callback; - VariableItemChangeCallback change_callback; - VariableItemSelectCallback select_callback; -} WifiMarauderScriptMenuItem; - -typedef struct WifiMarauderScriptStageMenu { - WifiMarauderScriptMenuItem* items; - uint32_t num_items; -} WifiMarauderScriptStageMenu; - -#define ADD_STAGE(name, id) \ - void wifi_marauder_script_stage_menu_##name##_load(WifiMarauderScriptStageMenu*); -#include "wifi_marauder_script_stage_menu_config.h" -#undef ADD_STAGE - -WifiMarauderScriptStageMenu* - wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type); -void wifi_marauder_script_stage_menu_free(WifiMarauderScriptStageMenu* list); diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconap.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconap.c deleted file mode 100644 index 35a74ee3d..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconap.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_beaconap_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageBeaconAp* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_beaconap_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageBeaconAp* stage_beaconap = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_beaconap->timeout; -} - -void wifi_marauder_script_stage_menu_beaconap_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = "Timeout", - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_beaconap_stage_timeout_setup_callback, - .select_callback = wifi_marauder_beaconap_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconlist.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconlist.c deleted file mode 100644 index 6f320db3e..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_beaconlist.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_beaconlist_stage_ssids_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageBeaconList* stage_beaconlist = app->script_edit_selected_stage->stage; - app->script_stage_edit_strings_reference = &stage_beaconlist->ssids; - app->script_stage_edit_string_count_reference = &stage_beaconlist->ssid_count; -} - -void wifi_marauder_beaconlist_stage_random_ssids_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageBeaconList* stage = app->script_edit_selected_stage->stage; - char random_ssids_str[32]; - snprintf(random_ssids_str, sizeof(random_ssids_str), "%d", stage->random_ssids); - variable_item_set_current_value_text(item, random_ssids_str); -} - -void wifi_marauder_beaconlist_stage_random_ssids_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageBeaconList* stage_beaconlist = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_beaconlist->random_ssids; -} - -void wifi_marauder_beaconlist_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageBeaconList* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_beaconlist_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageBeaconList* stage_beaconlist = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_beaconlist->timeout; -} - -void wifi_marauder_script_stage_menu_beaconlist_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 3; - stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("SSIDs"), - .type = WifiMarauderScriptMenuItemTypeListString, - .num_options = 1, - .select_callback = wifi_marauder_beaconlist_stage_ssids_select_callback}; - stage_menu->items[1] = (WifiMarauderScriptMenuItem){ - .name = strdup("Generate random"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_beaconlist_stage_random_ssids_setup_callback, - .select_callback = wifi_marauder_beaconlist_stage_random_ssids_select_callback}; - stage_menu->items[2] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_beaconlist_stage_timeout_setup_callback, - .select_callback = wifi_marauder_beaconlist_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_config.h b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_config.h deleted file mode 100644 index 1fd2a314b..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_config.h +++ /dev/null @@ -1,14 +0,0 @@ -ADD_STAGE(scan, Scan) -ADD_STAGE(select, Select) -ADD_STAGE(deauth, Deauth) -ADD_STAGE(probe, Probe) -ADD_STAGE(sniffraw, SniffRaw) -ADD_STAGE(sniffbeacon, SniffBeacon) -ADD_STAGE(sniffdeauth, SniffDeauth) -ADD_STAGE(sniffesp, SniffEsp) -ADD_STAGE(sniffpmkid, SniffPmkid) -ADD_STAGE(sniffpwn, SniffPwn) -ADD_STAGE(beaconlist, BeaconList) -ADD_STAGE(beaconap, BeaconAp) -ADD_STAGE(exec, Exec) -ADD_STAGE(delay, Delay) \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_deauth.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_deauth.c deleted file mode 100644 index b15b6f461..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_deauth.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_deauth_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageDeauth* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_deauth_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageDeauth* stage_deauth = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_deauth->timeout; -} - -void wifi_marauder_script_stage_menu_deauth_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_deauth_stage_timeout_setup_callback, - .select_callback = wifi_marauder_deauth_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_delay.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_delay.c deleted file mode 100644 index ffd74f720..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_delay.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_delay_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageDelay* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_delay_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageDelay* stage_delay = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_delay->timeout; -} - -void wifi_marauder_script_stage_menu_delay_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_delay_stage_timeout_setup_callback, - .select_callback = wifi_marauder_delay_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_exec.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_exec.c deleted file mode 100644 index 62afdc2f3..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_exec.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_exec_stage_filter_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageExec* stage = app->script_edit_selected_stage->stage; - if(stage->command != NULL) { - variable_item_set_current_value_text(item, stage->command); - } -} - -void wifi_marauder_exec_stage_filter_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageExec* stage_select = app->script_edit_selected_stage->stage; - if(stage_select->command == NULL) { - stage_select->command = malloc(128); - } - app->user_input_string_reference = &stage_select->command; -} - -void wifi_marauder_script_stage_menu_exec_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Command"), - .type = WifiMarauderScriptMenuItemTypeString, - .num_options = 1, - .setup_callback = wifi_marauder_exec_stage_filter_setup_callback, - .select_callback = wifi_marauder_exec_stage_filter_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_probe.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_probe.c deleted file mode 100644 index 53fa26f47..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_probe.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_probe_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageProbe* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_probe_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageProbe* stage_probe = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_probe->timeout; -} - -void wifi_marauder_script_stage_menu_probe_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_probe_stage_timeout_setup_callback, - .select_callback = wifi_marauder_probe_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_scan.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_scan.c deleted file mode 100644 index 3aab740bb..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_scan.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_scan_stage_type_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage; - variable_item_set_current_value_index(item, stage->type); -} - -void wifi_marauder_scan_stage_type_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - // Get menu item - uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list); - const WifiMarauderScriptMenuItem* menu_item = - &app->script_stage_menu->items[current_stage_index]; - - // Defines the text of the selected option - uint8_t option_index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, menu_item->options[option_index]); - - // Updates the attribute value of the current stage - WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage; - stage->type = option_index; -} - -void wifi_marauder_scan_stage_channel_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage; - if(stage->channel >= 0 && stage->channel < 12) { - variable_item_set_current_value_index(item, stage->channel); - } else { - variable_item_set_current_value_index(item, 0); - } -} - -void wifi_marauder_scan_stage_channel_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - // Get menu item - uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list); - const WifiMarauderScriptMenuItem* menu_item = - &app->script_stage_menu->items[current_stage_index]; - - // Defines the text of the selected option - uint8_t option_index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, menu_item->options[option_index]); - - // Updates the attribute value of the current stage - WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage; - stage->channel = option_index; -} - -void wifi_marauder_scan_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_scan_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageScan* stage_scan = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_scan->timeout; -} - -void wifi_marauder_script_stage_menu_scan_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 3; - stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Type"), - .type = WifiMarauderScriptMenuItemTypeOptionsString, - .num_options = 2, - .options = {"ap", "station"}, - .setup_callback = wifi_marauder_scan_stage_type_setup_callback, - .change_callback = wifi_marauder_scan_stage_type_change_callback, - }; - stage_menu->items[1] = (WifiMarauderScriptMenuItem){ - .name = strdup("Channel"), - .type = WifiMarauderScriptMenuItemTypeOptionsNumber, - .num_options = 12, - .options = {"none", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}, - .setup_callback = wifi_marauder_scan_stage_channel_setup_callback, - .change_callback = wifi_marauder_scan_stage_channel_change_callback, - }; - stage_menu->items[2] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_scan_stage_timeout_setup_callback, - .select_callback = wifi_marauder_scan_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_select.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_select.c deleted file mode 100644 index a6121db95..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_select.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_select_stage_type_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage; - variable_item_set_current_value_index(item, stage->type); -} - -void wifi_marauder_select_stage_type_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - // Get menu item - uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list); - const WifiMarauderScriptMenuItem* menu_item = - &app->script_stage_menu->items[current_stage_index]; - - // Defines the text of the selected option - uint8_t option_index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, menu_item->options[option_index]); - - // Updates the attribute value of the current stage - WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage; - stage->type = option_index; -} - -void wifi_marauder_select_stage_filter_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage; - - if(stage->filter != NULL) { - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, stage->filter); - } else { - variable_item_set_current_value_index(item, 1); - } -} - -void wifi_marauder_select_stage_filter_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage; - - // Clears the filter if you change the option. Flipper input box does not accept blank text - if(variable_item_get_current_value_index(item) == 1) { - stage->filter = NULL; - variable_item_set_current_value_index(item, 0); - variable_item_set_values_count(item, 1); - } - - if(stage->filter != NULL) { - variable_item_set_current_value_text(item, stage->filter); - } else { - variable_item_set_current_value_text(item, ""); - } -} - -void wifi_marauder_select_stage_filter_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSelect* stage_select = app->script_edit_selected_stage->stage; - if(stage_select->filter == NULL) { - stage_select->filter = malloc(128); - } - app->user_input_string_reference = &stage_select->filter; -} - -void wifi_marauder_select_stage_indexes_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSelect* stage_select = app->script_edit_selected_stage->stage; - app->script_stage_edit_numbers_reference = &stage_select->indexes; - app->script_stage_edit_number_count_reference = &stage_select->index_count; -} - -void wifi_marauder_script_stage_menu_select_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 3; - stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Type"), - .type = WifiMarauderScriptMenuItemTypeOptionsString, - .num_options = 2, - .options = {"ap", "station"}, - .setup_callback = wifi_marauder_select_stage_type_setup_callback, - .change_callback = wifi_marauder_select_stage_type_change_callback}; - stage_menu->items[1] = (WifiMarauderScriptMenuItem){ - .name = strdup("Filter"), - .type = WifiMarauderScriptMenuItemTypeString, - .num_options = 2, - .setup_callback = wifi_marauder_select_stage_filter_setup_callback, - .change_callback = wifi_marauder_select_stage_filter_change_callback, - .select_callback = wifi_marauder_select_stage_filter_select_callback}; - stage_menu->items[2] = (WifiMarauderScriptMenuItem){ - .name = strdup("Indexes"), - .type = WifiMarauderScriptMenuItemTypeListNumber, - .num_options = 1, - .select_callback = wifi_marauder_select_stage_indexes_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c deleted file mode 100644 index 11e7b3297..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_sniffbeacon_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffBeacon* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_sniffbeacon_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSniffBeacon* stage_sniffbeacon = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_sniffbeacon->timeout; -} - -void wifi_marauder_script_stage_menu_sniffbeacon_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_sniffbeacon_stage_timeout_setup_callback, - .select_callback = wifi_marauder_sniffbeacon_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c deleted file mode 100644 index 935a55936..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_sniffdeauth_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffDeauth* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_sniffdeauth_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSniffDeauth* stage_sniffdeauth = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_sniffdeauth->timeout; -} - -void wifi_marauder_script_stage_menu_sniffdeauth_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_sniffdeauth_stage_timeout_setup_callback, - .select_callback = wifi_marauder_sniffdeauth_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffesp.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffesp.c deleted file mode 100644 index e90d6b06c..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffesp.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_sniffesp_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffEsp* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_sniffesp_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSniffEsp* stage_sniffesp = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_sniffesp->timeout; -} - -void wifi_marauder_script_stage_menu_sniffesp_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_sniffesp_stage_timeout_setup_callback, - .select_callback = wifi_marauder_sniffesp_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c deleted file mode 100644 index 6a591c4e0..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -static void wifi_marauder_sniffpmkid_stage_hop_channels_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - variable_item_set_current_value_index(item, stage->hop_channels); -} - -static void wifi_marauder_sniffpmkid_stage_hop_channels_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list); - const WifiMarauderScriptMenuItem* menu_item = - &app->script_stage_menu->items[current_stage_index]; - - uint8_t option_index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, menu_item->options[option_index]); - - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - stage->hop_channels = option_index; -} - -static void wifi_marauder_sniffpmkid_stage_force_deauth_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - variable_item_set_current_value_index(item, stage->force_deauth); -} - -static void wifi_marauder_sniffpmkid_stage_force_deauth_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - // Get menu item - uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list); - const WifiMarauderScriptMenuItem* menu_item = - &app->script_stage_menu->items[current_stage_index]; - - // Defines the text of the selected option - uint8_t option_index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, menu_item->options[option_index]); - - // Updates the attribute value of the current stage - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - stage->force_deauth = option_index; -} - -static void wifi_marauder_sniffpmkid_stage_channel_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - if(stage->channel >= 0 && stage->channel < 12) { - variable_item_set_current_value_index(item, stage->channel); - } else { - variable_item_set_current_value_index(item, 0); - } -} - -static void wifi_marauder_sniffpmkid_stage_channel_change_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - - // Get menu item - uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list); - const WifiMarauderScriptMenuItem* menu_item = - &app->script_stage_menu->items[current_stage_index]; - - // Defines the text of the selected option - uint8_t option_index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, menu_item->options[option_index]); - - // Updates the attribute value of the current stage - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - stage->channel = option_index; -} - -static void wifi_marauder_sniffpmkid_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -static void wifi_marauder_sniffpmkid_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSniffPmkid* stage_sniffpmkid = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_sniffpmkid->timeout; -} - -void wifi_marauder_script_stage_menu_sniffpmkid_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 4; - stage_menu->items = malloc(4 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Force deauth"), - .type = WifiMarauderScriptMenuItemTypeOptionsString, - .num_options = 2, - .options = {"no", "yes"}, - .setup_callback = wifi_marauder_sniffpmkid_stage_force_deauth_setup_callback, - .change_callback = wifi_marauder_sniffpmkid_stage_force_deauth_change_callback}; - stage_menu->items[1] = (WifiMarauderScriptMenuItem){ - .name = strdup("Channel"), - .type = WifiMarauderScriptMenuItemTypeOptionsNumber, - .num_options = 12, - .options = {"none", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}, - .setup_callback = wifi_marauder_sniffpmkid_stage_channel_setup_callback, - .change_callback = wifi_marauder_sniffpmkid_stage_channel_change_callback}; - stage_menu->items[2] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_sniffpmkid_stage_timeout_setup_callback, - .select_callback = wifi_marauder_sniffpmkid_stage_timeout_select_callback}; - stage_menu->items[3] = (WifiMarauderScriptMenuItem){ - .name = strdup("Hop Channels"), - .type = WifiMarauderScriptMenuItemTypeOptionsString, - .num_options = 2, - .options = {"no", "yes"}, - .setup_callback = wifi_marauder_sniffpmkid_stage_hop_channels_setup_callback, - .change_callback = wifi_marauder_sniffpmkid_stage_hop_channels_change_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpwn.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpwn.c deleted file mode 100644 index d0859cd8b..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffpwn.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_sniffpwn_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffPwn* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_sniffpwn_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSniffPwn* stage_sniffpwn = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_sniffpwn->timeout; -} - -void wifi_marauder_script_stage_menu_sniffpwn_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_sniffpwn_stage_timeout_setup_callback, - .select_callback = wifi_marauder_sniffpwn_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffraw.c b/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffraw.c deleted file mode 100644 index 39641f1ee..000000000 --- a/applications/external/wifi_marauder_companion/script/menu/wifi_marauder_script_stage_menu_sniffraw.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../wifi_marauder_app_i.h" - -void wifi_marauder_sniffraw_stage_timeout_setup_callback(VariableItem* item) { - WifiMarauderApp* app = variable_item_get_context(item); - WifiMarauderScriptStageSniffRaw* stage = app->script_edit_selected_stage->stage; - char timeout_str[32]; - snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout); - variable_item_set_current_value_text(item, timeout_str); -} - -void wifi_marauder_sniffraw_stage_timeout_select_callback(void* context) { - WifiMarauderApp* app = context; - WifiMarauderScriptStageSniffRaw* stage_sniffraw = app->script_edit_selected_stage->stage; - app->user_input_number_reference = &stage_sniffraw->timeout; -} - -void wifi_marauder_script_stage_menu_sniffraw_load(WifiMarauderScriptStageMenu* stage_menu) { - stage_menu->num_items = 1; - stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem)); - - stage_menu->items[0] = (WifiMarauderScriptMenuItem){ - .name = strdup("Timeout"), - .type = WifiMarauderScriptMenuItemTypeNumber, - .num_options = 1, - .setup_callback = wifi_marauder_sniffraw_stage_timeout_setup_callback, - .select_callback = wifi_marauder_sniffraw_stage_timeout_select_callback}; -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/wifi_marauder_script.c b/applications/external/wifi_marauder_companion/script/wifi_marauder_script.c deleted file mode 100644 index a33e27cc5..000000000 --- a/applications/external/wifi_marauder_companion/script/wifi_marauder_script.c +++ /dev/null @@ -1,962 +0,0 @@ -#include "../wifi_marauder_app_i.h" -#include "wifi_marauder_script.h" - -WifiMarauderScript* wifi_marauder_script_alloc() { - WifiMarauderScript* script = (WifiMarauderScript*)malloc(sizeof(WifiMarauderScript)); - if(script == NULL) { - return NULL; - } - script->name = NULL; - script->description = NULL; - script->first_stage = NULL; - script->last_stage = NULL; - script->enable_led = WifiMarauderScriptBooleanUndefined; - script->save_pcap = WifiMarauderScriptBooleanUndefined; - script->repeat = 1; - return script; -} - -WifiMarauderScript* wifi_marauder_script_create(const char* script_name) { - WifiMarauderScript* script = wifi_marauder_script_alloc(); - script->name = strdup(script_name); - return script; -} - -void _wifi_marauder_script_load_meta(WifiMarauderScript* script, cJSON* meta_section) { - if(meta_section != NULL) { - // Script description - cJSON* description = cJSON_GetObjectItem(meta_section, "description"); - if(description != NULL) { - script->description = strdup(description->valuestring); - } - // Enable LED - cJSON* enable_led_json = cJSON_GetObjectItem(meta_section, "enableLed"); - if(cJSON_IsBool(enable_led_json)) { - script->enable_led = enable_led_json->valueint; - } - // Save PCAP - cJSON* save_pcap_json = cJSON_GetObjectItem(meta_section, "savePcap"); - if(cJSON_IsBool(save_pcap_json)) { - script->save_pcap = save_pcap_json->valueint; - } - // Times the script will be repeated - cJSON* repeat = cJSON_GetObjectItem(meta_section, "repeat"); - if(repeat != NULL) { - script->repeat = repeat->valueint; - } - } - if(script->description == NULL) { - script->description = strdup("My script"); - } -} - -WifiMarauderScriptStageScan* _wifi_marauder_script_get_stage_scan(cJSON* stages) { - cJSON* stage_scan = cJSON_GetObjectItem(stages, "scan"); - if(stage_scan == NULL) { - return NULL; - } - cJSON* type = cJSON_GetObjectItem(stage_scan, "type"); - if(type == NULL) { - return NULL; - } - WifiMarauderScriptScanType scan_type; - if(strcmp(type->valuestring, "ap") == 0) { - scan_type = WifiMarauderScriptScanTypeAp; - } else if(strcmp(type->valuestring, "station") == 0) { - scan_type = WifiMarauderScriptScanTypeStation; - } else { - return NULL; - } - cJSON* channel = cJSON_GetObjectItem(stage_scan, "channel"); - int scan_channel = channel != NULL ? (int)cJSON_GetNumberValue(channel) : 0; - cJSON* timeout = cJSON_GetObjectItem(stage_scan, "timeout"); - int scan_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN; - - WifiMarauderScriptStageScan* scan_stage = - (WifiMarauderScriptStageScan*)malloc(sizeof(WifiMarauderScriptStageScan)); - scan_stage->type = scan_type; - scan_stage->channel = scan_channel; - scan_stage->timeout = scan_timeout; - - return scan_stage; -} - -WifiMarauderScriptStageSelect* _wifi_marauder_script_get_stage_select(cJSON* stages) { - cJSON* select_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "select"); - if(select_stage_json == NULL) { - return NULL; - } - - cJSON* type_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "type"); - cJSON* filter_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "filter"); - cJSON* indexes_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "indexes"); - cJSON* allow_repeat_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "allow_repeat"); - - if(!cJSON_IsString(type_json)) { - return NULL; - } - WifiMarauderScriptSelectType select_type; - if(strcmp(type_json->valuestring, "ap") == 0) { - select_type = WifiMarauderScriptSelectTypeAp; - } else if(strcmp(type_json->valuestring, "station") == 0) { - select_type = WifiMarauderScriptSelectTypeStation; - } else if(strcmp(type_json->valuestring, "ssid") == 0) { - select_type = WifiMarauderScriptSelectTypeSsid; - } else { - return NULL; - } - char* filter_str = cJSON_IsString(filter_json) ? strdup(filter_json->valuestring) : NULL; - - WifiMarauderScriptStageSelect* stage_select = - (WifiMarauderScriptStageSelect*)malloc(sizeof(WifiMarauderScriptStageSelect)); - stage_select->type = select_type; - stage_select->allow_repeat = cJSON_IsBool(allow_repeat_json) ? allow_repeat_json->valueint : - true; - stage_select->filter = filter_str; - - if(cJSON_IsArray(indexes_json)) { - int indexes_size = cJSON_GetArraySize(indexes_json); - int* indexes = (int*)malloc(indexes_size * sizeof(int)); - for(int i = 0; i < indexes_size; i++) { - cJSON* index_item = cJSON_GetArrayItem(indexes_json, i); - if(cJSON_IsNumber(index_item)) { - indexes[i] = index_item->valueint; - } - } - stage_select->indexes = indexes; - stage_select->index_count = indexes_size; - } else { - stage_select->indexes = NULL; - stage_select->index_count = 0; - } - - return stage_select; -} - -WifiMarauderScriptStageDeauth* _wifi_marauder_script_get_stage_deauth(cJSON* stages) { - cJSON* deauth_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "deauth"); - if(deauth_stage_json == NULL) { - return NULL; - } - - cJSON* timeout = cJSON_GetObjectItem(deauth_stage_json, "timeout"); - int deauth_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH; - - WifiMarauderScriptStageDeauth* deauth_stage = - (WifiMarauderScriptStageDeauth*)malloc(sizeof(WifiMarauderScriptStageDeauth)); - deauth_stage->timeout = deauth_timeout; - - return deauth_stage; -} - -WifiMarauderScriptStageProbe* _wifi_marauder_script_get_stage_probe(cJSON* stages) { - cJSON* probe_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "probe"); - if(probe_stage_json == NULL) { - return NULL; - } - - cJSON* timeout = cJSON_GetObjectItem(probe_stage_json, "timeout"); - int probe_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE; - - WifiMarauderScriptStageProbe* probe_stage = - (WifiMarauderScriptStageProbe*)malloc(sizeof(WifiMarauderScriptStageProbe)); - probe_stage->timeout = probe_timeout; - - return probe_stage; -} - -WifiMarauderScriptStageSniffRaw* _wifi_marauder_script_get_stage_sniff_raw(cJSON* stages) { - cJSON* sniffraw_stage_json = cJSON_GetObjectItem(stages, "sniffraw"); - if(sniffraw_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(sniffraw_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - WifiMarauderScriptStageSniffRaw* sniff_raw_stage = - (WifiMarauderScriptStageSniffRaw*)malloc(sizeof(WifiMarauderScriptStageSniffRaw)); - sniff_raw_stage->timeout = timeout; - - return sniff_raw_stage; -} - -WifiMarauderScriptStageSniffBeacon* _wifi_marauder_script_get_stage_sniff_beacon(cJSON* stages) { - cJSON* sniffbeacon_stage_json = cJSON_GetObjectItem(stages, "sniffbeacon"); - if(sniffbeacon_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(sniffbeacon_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - WifiMarauderScriptStageSniffBeacon* sniff_beacon_stage = - (WifiMarauderScriptStageSniffBeacon*)malloc(sizeof(WifiMarauderScriptStageSniffBeacon)); - sniff_beacon_stage->timeout = timeout; - - return sniff_beacon_stage; -} - -WifiMarauderScriptStageSniffDeauth* _wifi_marauder_script_get_stage_sniff_deauth(cJSON* stages) { - cJSON* sniffdeauth_stage_json = cJSON_GetObjectItem(stages, "sniffdeauth"); - if(sniffdeauth_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(sniffdeauth_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - WifiMarauderScriptStageSniffDeauth* sniff_deauth_stage = - (WifiMarauderScriptStageSniffDeauth*)malloc(sizeof(WifiMarauderScriptStageSniffDeauth)); - sniff_deauth_stage->timeout = timeout; - - return sniff_deauth_stage; -} - -WifiMarauderScriptStageSniffEsp* _wifi_marauder_script_get_stage_sniff_esp(cJSON* stages) { - cJSON* sniffesp_stage_json = cJSON_GetObjectItem(stages, "sniffesp"); - if(sniffesp_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(sniffesp_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - WifiMarauderScriptStageSniffEsp* sniff_esp_stage = - (WifiMarauderScriptStageSniffEsp*)malloc(sizeof(WifiMarauderScriptStageSniffEsp)); - sniff_esp_stage->timeout = timeout; - - return sniff_esp_stage; -} - -WifiMarauderScriptStageSniffPmkid* _wifi_marauder_script_get_stage_sniff_pmkid(cJSON* stages) { - cJSON* sniffpmkid_stage_json = cJSON_GetObjectItem(stages, "sniffpmkid"); - if(sniffpmkid_stage_json == NULL) { - return NULL; - } - - cJSON* channel_json = cJSON_GetObjectItem(sniffpmkid_stage_json, "channel"); - int channel = channel_json != NULL ? (int)cJSON_GetNumberValue(channel_json) : 0; - - cJSON* timeout_json = cJSON_GetObjectItem(sniffpmkid_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - cJSON* force_deauth_json = - cJSON_GetObjectItemCaseSensitive(sniffpmkid_stage_json, "forceDeauth"); - bool force_deauth = cJSON_IsBool(force_deauth_json) ? force_deauth_json->valueint : true; - - cJSON* hop_channels_json = - cJSON_GetObjectItemCaseSensitive(sniffpmkid_stage_json, "hopChannels"); - bool hop_channels = cJSON_IsBool(hop_channels_json) ? hop_channels_json->valueint : false; - - WifiMarauderScriptStageSniffPmkid* sniff_pmkid_stage = - (WifiMarauderScriptStageSniffPmkid*)malloc(sizeof(WifiMarauderScriptStageSniffPmkid)); - - if(sniff_pmkid_stage == NULL) { - // Handle memory allocation error - return NULL; - } - sniff_pmkid_stage->channel = channel; - sniff_pmkid_stage->timeout = timeout; - sniff_pmkid_stage->force_deauth = force_deauth; - sniff_pmkid_stage->hop_channels = hop_channels; - - return sniff_pmkid_stage; -} - -WifiMarauderScriptStageSniffPwn* _wifi_marauder_script_get_stage_sniff_pwn(cJSON* stages) { - cJSON* sniffpwn_stage_json = cJSON_GetObjectItem(stages, "sniffpwn"); - if(sniffpwn_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(sniffpwn_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF; - - WifiMarauderScriptStageSniffPwn* sniff_pwn_stage = - (WifiMarauderScriptStageSniffPwn*)malloc(sizeof(WifiMarauderScriptStageSniffPwn)); - sniff_pwn_stage->timeout = timeout; - - return sniff_pwn_stage; -} - -WifiMarauderScriptStageBeaconList* _wifi_marauder_script_get_stage_beacon_list(cJSON* stages) { - cJSON* stage_beaconlist = cJSON_GetObjectItem(stages, "beaconList"); - if(stage_beaconlist == NULL) { - return NULL; - } - WifiMarauderScriptStageBeaconList* beaconlist_stage = - (WifiMarauderScriptStageBeaconList*)malloc(sizeof(WifiMarauderScriptStageBeaconList)); - if(beaconlist_stage == NULL) { - return NULL; - } - cJSON* ssids = cJSON_GetObjectItem(stage_beaconlist, "ssids"); - if(ssids == NULL) { - return NULL; - } - // SSID count - int ssid_count = cJSON_GetArraySize(ssids); - if(ssid_count == 0) { - return NULL; - } - beaconlist_stage->ssid_count = ssid_count; - // SSIDs - beaconlist_stage->ssids = (char**)malloc(sizeof(char*) * ssid_count); - if(beaconlist_stage->ssids == NULL) { - return NULL; - } - for(int i = 0; i < ssid_count; i++) { - cJSON* ssid = cJSON_GetArrayItem(ssids, i); - if(ssid == NULL) { - continue; - } - char* ssid_string = cJSON_GetStringValue(ssid); - if(ssid_string == NULL) { - continue; - } - beaconlist_stage->ssids[i] = (char*)malloc(sizeof(char) * (strlen(ssid_string) + 1)); - strcpy(beaconlist_stage->ssids[i], ssid_string); - } - // Timeout - cJSON* timeout = cJSON_GetObjectItem(stage_beaconlist, "timeout"); - beaconlist_stage->timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON; - // Random SSIDs - cJSON* random_ssids = cJSON_GetObjectItem(stage_beaconlist, "generate"); - beaconlist_stage->random_ssids = - random_ssids != NULL ? (int)cJSON_GetNumberValue(random_ssids) : 0; - - return beaconlist_stage; -} - -WifiMarauderScriptStageBeaconAp* _wifi_marauder_script_get_stage_beacon_ap(cJSON* stages) { - cJSON* beaconap_stage_json = cJSON_GetObjectItem(stages, "beaconAp"); - if(beaconap_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(beaconap_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : - WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON; - - WifiMarauderScriptStageBeaconAp* beacon_ap_stage = - (WifiMarauderScriptStageBeaconAp*)malloc(sizeof(WifiMarauderScriptStageBeaconAp)); - beacon_ap_stage->timeout = timeout; - - return beacon_ap_stage; -} - -WifiMarauderScriptStageExec* _wifi_marauder_script_get_stage_exec(cJSON* stages) { - cJSON* exec_stage_json = cJSON_GetObjectItem(stages, "exec"); - if(exec_stage_json == NULL) { - return NULL; - } - - cJSON* command_json = cJSON_GetObjectItemCaseSensitive(exec_stage_json, "command"); - char* command_str = cJSON_IsString(command_json) ? strdup(command_json->valuestring) : NULL; - - WifiMarauderScriptStageExec* exec_stage = - (WifiMarauderScriptStageExec*)malloc(sizeof(WifiMarauderScriptStageExec)); - exec_stage->command = command_str; - - return exec_stage; -} - -WifiMarauderScriptStageDelay* _wifi_marauder_script_get_stage_delay(cJSON* stages) { - cJSON* delay_stage_json = cJSON_GetObjectItem(stages, "delay"); - if(delay_stage_json == NULL) { - return NULL; - } - - cJSON* timeout_json = cJSON_GetObjectItem(delay_stage_json, "timeout"); - int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : 0; - - WifiMarauderScriptStageDelay* delay_stage = - (WifiMarauderScriptStageDelay*)malloc(sizeof(WifiMarauderScriptStageDelay)); - delay_stage->timeout = timeout; - - return delay_stage; -} - -WifiMarauderScriptStage* - _wifi_marauder_script_create_stage(WifiMarauderScriptStageType type, void* stage_data) { - WifiMarauderScriptStage* stage = - (WifiMarauderScriptStage*)malloc(sizeof(WifiMarauderScriptStage)); - stage->type = type; - stage->stage = stage_data; - stage->next_stage = NULL; - return stage; -} - -void wifi_marauder_script_add_stage( - WifiMarauderScript* script, - WifiMarauderScriptStageType stage_type, - void* stage_data) { - if(script == NULL || stage_data == NULL) { - return; - } - WifiMarauderScriptStage* stage = _wifi_marauder_script_create_stage(stage_type, stage_data); - if(script->last_stage != NULL) { - script->last_stage->next_stage = stage; - } else { - script->first_stage = stage; - } - script->last_stage = stage; -} - -void _wifi_marauder_script_load_stages(WifiMarauderScript* script, cJSON* stages) { - // Scan stage - wifi_marauder_script_add_stage( - script, WifiMarauderScriptStageTypeScan, _wifi_marauder_script_get_stage_scan(stages)); - // Select stage - wifi_marauder_script_add_stage( - script, WifiMarauderScriptStageTypeSelect, _wifi_marauder_script_get_stage_select(stages)); - // Deauth stage - wifi_marauder_script_add_stage( - script, WifiMarauderScriptStageTypeDeauth, _wifi_marauder_script_get_stage_deauth(stages)); - // Probe stage - wifi_marauder_script_add_stage( - script, WifiMarauderScriptStageTypeProbe, _wifi_marauder_script_get_stage_probe(stages)); - // Sniff raw stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeSniffRaw, - _wifi_marauder_script_get_stage_sniff_raw(stages)); - // Sniff beacon stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeSniffBeacon, - _wifi_marauder_script_get_stage_sniff_beacon(stages)); - // Sniff deauth stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeSniffDeauth, - _wifi_marauder_script_get_stage_sniff_deauth(stages)); - // Sniff esp stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeSniffEsp, - _wifi_marauder_script_get_stage_sniff_esp(stages)); - // Sniff PMKID stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeSniffPmkid, - _wifi_marauder_script_get_stage_sniff_pmkid(stages)); - // Sniff pwn stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeSniffPwn, - _wifi_marauder_script_get_stage_sniff_pwn(stages)); - // Beacon List stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeBeaconList, - _wifi_marauder_script_get_stage_beacon_list(stages)); - // Beacon Ap stage - wifi_marauder_script_add_stage( - script, - WifiMarauderScriptStageTypeBeaconAp, - _wifi_marauder_script_get_stage_beacon_ap(stages)); - // Exec stage - wifi_marauder_script_add_stage( - script, WifiMarauderScriptStageTypeExec, _wifi_marauder_script_get_stage_exec(stages)); - // Delay stage - wifi_marauder_script_add_stage( - script, WifiMarauderScriptStageTypeDelay, _wifi_marauder_script_get_stage_delay(stages)); -} - -WifiMarauderScript* wifi_marauder_script_parse_raw(const char* json_raw) { - WifiMarauderScript* script = wifi_marauder_script_alloc(); - if(script == NULL) { - return NULL; - } - cJSON* json = cJSON_Parse(json_raw); - if(json == NULL) { - return NULL; - } - cJSON* meta = cJSON_GetObjectItem(json, "meta"); - _wifi_marauder_script_load_meta(script, meta); - - cJSON* stages = cJSON_GetObjectItem(json, "stages"); - if(cJSON_IsArray(stages)) { - cJSON* stage_item = NULL; - cJSON_ArrayForEach(stage_item, stages) { - _wifi_marauder_script_load_stages(script, stage_item); - } - } else { - _wifi_marauder_script_load_stages(script, stages); - } - - return script; -} - -WifiMarauderScript* wifi_marauder_script_parse_json(Storage* storage, const char* file_path) { - WifiMarauderScript* script = NULL; - File* script_file = storage_file_alloc(storage); - FuriString* script_name = furi_string_alloc(); - path_extract_filename_no_ext(file_path, script_name); - - if(storage_file_open(script_file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { - uint32_t file_size = storage_file_size(script_file); - char* json_buffer = (char*)malloc(file_size + 1); - uint16_t bytes_read = storage_file_read(script_file, json_buffer, file_size); - json_buffer[bytes_read] = '\0'; - - script = wifi_marauder_script_parse_raw(json_buffer); - } - if(script == NULL) { - script = wifi_marauder_script_create(furi_string_get_cstr(script_name)); - } - script->name = strdup(furi_string_get_cstr(script_name)); - - furi_string_free(script_name); - storage_file_close(script_file); - storage_file_free(script_file); - return script; -} - -cJSON* _wifi_marauder_script_create_json_meta(WifiMarauderScript* script) { - cJSON* meta_json = cJSON_CreateObject(); - if(script->description != NULL) { - cJSON_AddStringToObject(meta_json, "description", script->description); - } else { - cJSON_AddStringToObject(meta_json, "description", "My Script"); - } - if(script->enable_led != WifiMarauderScriptBooleanUndefined) { - cJSON_AddBoolToObject( - meta_json, "enableLed", (script->enable_led == WifiMarauderScriptBooleanTrue)); - } - if(script->save_pcap != WifiMarauderScriptBooleanUndefined) { - cJSON_AddBoolToObject( - meta_json, "savePcap", (script->save_pcap == WifiMarauderScriptBooleanTrue)); - } - cJSON_AddNumberToObject(meta_json, "repeat", script->repeat); - return meta_json; -} - -cJSON* _wifi_marauder_script_create_json_scan(WifiMarauderScriptStageScan* scan_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "scan", cJSON_CreateObject()); - cJSON* scan_json = cJSON_GetObjectItem(stage_json, "scan"); - // Scan type - cJSON_AddStringToObject( - scan_json, "type", scan_stage->type == WifiMarauderScriptScanTypeAp ? "ap" : "station"); - // Channel - if(scan_stage->channel > 0) { - cJSON_AddNumberToObject(scan_json, "channel", scan_stage->channel); - } - // Timeout - if(scan_stage->timeout > 0) { - cJSON_AddNumberToObject(scan_json, "timeout", scan_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_select(WifiMarauderScriptStageSelect* select_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "select", cJSON_CreateObject()); - cJSON* select_json = cJSON_GetObjectItem(stage_json, "select"); - // Select type - cJSON_AddStringToObject( - select_json, - "type", - select_stage->type == WifiMarauderScriptSelectTypeAp ? "ap" : - select_stage->type == WifiMarauderScriptSelectTypeStation ? "station" : - "ssid"); - if(select_stage->filter != NULL) { - cJSON_AddStringToObject(select_json, "filter", select_stage->filter); - } - // Indexes - if(select_stage->indexes != NULL && select_stage->index_count > 0) { - cJSON* indexes_json = cJSON_CreateArray(); - for(int i = 0; i < select_stage->index_count; i++) { - cJSON_AddItemToArray(indexes_json, cJSON_CreateNumber(select_stage->indexes[i])); - } - cJSON_AddItemToObject(select_json, "indexes", indexes_json); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_deauth(WifiMarauderScriptStageDeauth* deauth_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "deauth", cJSON_CreateObject()); - cJSON* deauth_json = cJSON_GetObjectItem(stage_json, "deauth"); - // Timeout - if(deauth_stage->timeout > 0) { - cJSON_AddNumberToObject(deauth_json, "timeout", deauth_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_probe(WifiMarauderScriptStageProbe* probe_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "probe", cJSON_CreateObject()); - cJSON* probe_json = cJSON_GetObjectItem(stage_json, "probe"); - // Timeout - if(probe_stage->timeout > 0) { - cJSON_AddNumberToObject(probe_json, "timeout", probe_stage->timeout); - } - return stage_json; -} - -cJSON* - _wifi_marauder_script_create_json_sniffraw(WifiMarauderScriptStageSniffRaw* sniffraw_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "sniffRaw", cJSON_CreateObject()); - cJSON* sniffraw_json = cJSON_GetObjectItem(stage_json, "sniffRaw"); - // Timeout - if(sniffraw_stage->timeout > 0) { - cJSON_AddNumberToObject(sniffraw_json, "timeout", sniffraw_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_sniffbeacon( - WifiMarauderScriptStageSniffBeacon* sniffbeacon_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "sniffBeacon", cJSON_CreateObject()); - cJSON* sniffbeacon_json = cJSON_GetObjectItem(stage_json, "sniffBeacon"); - // Timeout - if(sniffbeacon_stage->timeout > 0) { - cJSON_AddNumberToObject(sniffbeacon_json, "timeout", sniffbeacon_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_sniffdeauth( - WifiMarauderScriptStageSniffDeauth* sniffdeauth_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "sniffDeauth", cJSON_CreateObject()); - cJSON* sniffdeauth_json = cJSON_GetObjectItem(stage_json, "sniffDeauth"); - // Timeout - if(sniffdeauth_stage->timeout > 0) { - cJSON_AddNumberToObject(sniffdeauth_json, "timeout", sniffdeauth_stage->timeout); - } - return stage_json; -} - -cJSON* - _wifi_marauder_script_create_json_sniffesp(WifiMarauderScriptStageSniffEsp* sniffesp_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "sniffEsp", cJSON_CreateObject()); - cJSON* sniffesp_json = cJSON_GetObjectItem(stage_json, "sniffEsp"); - // Timeout - if(sniffesp_stage->timeout > 0) { - cJSON_AddNumberToObject(sniffesp_json, "timeout", sniffesp_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_sniffpmkid( - WifiMarauderScriptStageSniffPmkid* sniffpmkid_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "sniffPmkid", cJSON_CreateObject()); - cJSON* sniffpmkid_json = cJSON_GetObjectItem(stage_json, "sniffPmkid"); - // Force deauth - cJSON_AddBoolToObject(sniffpmkid_json, "forceDeauth", sniffpmkid_stage->force_deauth); - // Channel - if(sniffpmkid_stage->channel > 0) { - cJSON_AddNumberToObject(sniffpmkid_json, "channel", sniffpmkid_stage->channel); - } - // Timeout - if(sniffpmkid_stage->timeout > 0) { - cJSON_AddNumberToObject(sniffpmkid_json, "timeout", sniffpmkid_stage->timeout); - } - // Hop channels - cJSON_AddBoolToObject(sniffpmkid_json, "hopChannels", sniffpmkid_stage->hop_channels); - - return stage_json; -} - -cJSON* - _wifi_marauder_script_create_json_sniffpwn(WifiMarauderScriptStageSniffPwn* sniffpwn_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "sniffPwn", cJSON_CreateObject()); - cJSON* sniffpwn_json = cJSON_GetObjectItem(stage_json, "sniffPwn"); - // Timeout - if(sniffpwn_stage->timeout > 0) { - cJSON_AddNumberToObject(sniffpwn_json, "timeout", sniffpwn_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_beaconlist( - WifiMarauderScriptStageBeaconList* beaconlist_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "beaconList", cJSON_CreateObject()); - cJSON* beaconlist_json = cJSON_GetObjectItem(stage_json, "beaconList"); - // SSIDs - if(beaconlist_stage->ssids != NULL) { - cJSON* ssids_json = cJSON_CreateStringArray( - (const char**)beaconlist_stage->ssids, beaconlist_stage->ssid_count); - cJSON_AddItemToObject(beaconlist_json, "ssids", ssids_json); - } - // Random SSIDs - if(beaconlist_stage->random_ssids > 0) { - cJSON_AddNumberToObject(beaconlist_json, "generate", beaconlist_stage->random_ssids); - } - // Timeout - if(beaconlist_stage->timeout > 0) { - cJSON_AddNumberToObject(beaconlist_json, "timeout", beaconlist_stage->timeout); - } - return stage_json; -} - -cJSON* - _wifi_marauder_script_create_json_beaconap(WifiMarauderScriptStageBeaconAp* beaconap_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "beaconAp", cJSON_CreateObject()); - cJSON* beaconap_json = cJSON_GetObjectItem(stage_json, "beaconAp"); - // Timeout - if(beaconap_stage->timeout > 0) { - cJSON_AddNumberToObject(beaconap_json, "timeout", beaconap_stage->timeout); - } - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_exec(WifiMarauderScriptStageExec* exec_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "exec", cJSON_CreateObject()); - cJSON* exec_json = cJSON_GetObjectItem(stage_json, "exec"); - // Command - cJSON_AddStringToObject( - exec_json, "command", exec_stage->command != NULL ? exec_stage->command : ""); - return stage_json; -} - -cJSON* _wifi_marauder_script_create_json_delay(WifiMarauderScriptStageDelay* delay_stage) { - cJSON* stage_json = cJSON_CreateObject(); - cJSON_AddItemToObject(stage_json, "delay", cJSON_CreateObject()); - cJSON* delay_json = cJSON_GetObjectItem(stage_json, "delay"); - // Timeout - if(delay_stage->timeout > 0) { - cJSON_AddNumberToObject(delay_json, "timeout", delay_stage->timeout); - } - return stage_json; -} - -void wifi_marauder_script_save_json( - Storage* storage, - const char* file_path, - WifiMarauderScript* script) { - File* script_file = storage_file_alloc(storage); - - if(storage_file_open(script_file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - cJSON* root_json = cJSON_CreateObject(); - - // Meta info - cJSON* meta_json = _wifi_marauder_script_create_json_meta(script); - cJSON_AddItemToObject(root_json, "meta", meta_json); - - // Create array for stages - cJSON* stages_array = cJSON_CreateArray(); - cJSON_AddItemToObject(root_json, "stages", stages_array); - - // Iterate over each stage and create the corresponding JSON object - WifiMarauderScriptStage* stage = script->first_stage; - while(stage != NULL) { - cJSON* stage_json = NULL; - - switch(stage->type) { - case WifiMarauderScriptStageTypeScan: { - WifiMarauderScriptStageScan* scan_stage = - (WifiMarauderScriptStageScan*)stage->stage; - stage_json = _wifi_marauder_script_create_json_scan(scan_stage); - break; - } - case WifiMarauderScriptStageTypeSelect: { - WifiMarauderScriptStageSelect* select_stage = - (WifiMarauderScriptStageSelect*)stage->stage; - stage_json = _wifi_marauder_script_create_json_select(select_stage); - break; - } - case WifiMarauderScriptStageTypeDeauth: { - WifiMarauderScriptStageDeauth* deauth_stage = - (WifiMarauderScriptStageDeauth*)stage->stage; - stage_json = _wifi_marauder_script_create_json_deauth(deauth_stage); - break; - } - case WifiMarauderScriptStageTypeProbe: { - WifiMarauderScriptStageProbe* probe_stage = - (WifiMarauderScriptStageProbe*)stage->stage; - stage_json = _wifi_marauder_script_create_json_probe(probe_stage); - break; - } - case WifiMarauderScriptStageTypeSniffRaw: { - WifiMarauderScriptStageSniffRaw* sniffraw_stage = - (WifiMarauderScriptStageSniffRaw*)stage->stage; - stage_json = _wifi_marauder_script_create_json_sniffraw(sniffraw_stage); - break; - } - case WifiMarauderScriptStageTypeSniffBeacon: { - WifiMarauderScriptStageSniffBeacon* sniffbeacon_stage = - (WifiMarauderScriptStageSniffBeacon*)stage->stage; - stage_json = _wifi_marauder_script_create_json_sniffbeacon(sniffbeacon_stage); - break; - } - case WifiMarauderScriptStageTypeSniffDeauth: { - WifiMarauderScriptStageSniffDeauth* sniffdeauth_stage = - (WifiMarauderScriptStageSniffDeauth*)stage->stage; - stage_json = _wifi_marauder_script_create_json_sniffdeauth(sniffdeauth_stage); - break; - } - case WifiMarauderScriptStageTypeSniffEsp: { - WifiMarauderScriptStageSniffEsp* sniffesp_stage = - (WifiMarauderScriptStageSniffEsp*)stage->stage; - stage_json = _wifi_marauder_script_create_json_sniffesp(sniffesp_stage); - break; - } - case WifiMarauderScriptStageTypeSniffPmkid: { - WifiMarauderScriptStageSniffPmkid* sniffpmkid_stage = - (WifiMarauderScriptStageSniffPmkid*)stage->stage; - stage_json = _wifi_marauder_script_create_json_sniffpmkid(sniffpmkid_stage); - break; - } - case WifiMarauderScriptStageTypeSniffPwn: { - WifiMarauderScriptStageSniffPwn* sniffpwn_stage = - (WifiMarauderScriptStageSniffPwn*)stage->stage; - stage_json = _wifi_marauder_script_create_json_sniffpwn(sniffpwn_stage); - break; - } - case WifiMarauderScriptStageTypeBeaconList: { - WifiMarauderScriptStageBeaconList* beaconlist_stage = - (WifiMarauderScriptStageBeaconList*)stage->stage; - stage_json = _wifi_marauder_script_create_json_beaconlist(beaconlist_stage); - break; - } - case WifiMarauderScriptStageTypeBeaconAp: { - WifiMarauderScriptStageBeaconAp* beaconap_stage = - (WifiMarauderScriptStageBeaconAp*)stage->stage; - stage_json = _wifi_marauder_script_create_json_beaconap(beaconap_stage); - break; - } - case WifiMarauderScriptStageTypeExec: { - WifiMarauderScriptStageExec* exec_stage = - (WifiMarauderScriptStageExec*)stage->stage; - stage_json = _wifi_marauder_script_create_json_exec(exec_stage); - break; - } - case WifiMarauderScriptStageTypeDelay: { - WifiMarauderScriptStageDelay* delay_stage = - (WifiMarauderScriptStageDelay*)stage->stage; - stage_json = _wifi_marauder_script_create_json_delay(delay_stage); - break; - } - } - - // Add the stage JSON object to the "stages" array - if(stage_json != NULL) { - cJSON_AddItemToArray(stages_array, stage_json); - } - - stage = stage->next_stage; - } - - // Write JSON to file - char* json_str = cJSON_Print(root_json); - storage_file_write(script_file, json_str, strlen(json_str)); - - //free(json_str); - storage_file_close(script_file); - } - storage_file_free(script_file); -} - -bool wifi_marauder_script_has_stage( - WifiMarauderScript* script, - WifiMarauderScriptStageType stage_type) { - if(script == NULL) { - return false; - } - WifiMarauderScriptStage* current_stage = script->first_stage; - while(current_stage != NULL) { - if(current_stage->type == stage_type) { - return true; - } - current_stage = current_stage->next_stage; - } - return false; -} - -void wifi_marauder_script_free(WifiMarauderScript* script) { - if(script == NULL) { - return; - } - WifiMarauderScriptStage* current_stage = script->first_stage; - while(current_stage != NULL) { - WifiMarauderScriptStage* next_stage = current_stage->next_stage; - switch(current_stage->type) { - case WifiMarauderScriptStageTypeScan: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSelect: - if(((WifiMarauderScriptStageSelect*)current_stage->stage)->filter != NULL) { - free(((WifiMarauderScriptStageSelect*)current_stage->stage)->filter); - } - if(((WifiMarauderScriptStageSelect*)current_stage->stage)->indexes != NULL) { - free(((WifiMarauderScriptStageSelect*)current_stage->stage)->indexes); - } - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeDeauth: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeProbe: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSniffRaw: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSniffBeacon: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSniffDeauth: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSniffEsp: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSniffPmkid: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeSniffPwn: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeBeaconList: - for(int i = 0; - i < ((WifiMarauderScriptStageBeaconList*)current_stage->stage)->ssid_count; - i++) { - free(((WifiMarauderScriptStageBeaconList*)current_stage->stage)->ssids[i]); - } - free(((WifiMarauderScriptStageBeaconList*)current_stage->stage)->ssids); - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeBeaconAp: - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeExec: - if(((WifiMarauderScriptStageExec*)current_stage->stage)->command != NULL) { - free(((WifiMarauderScriptStageExec*)current_stage->stage)->command); - } - free(current_stage->stage); - break; - case WifiMarauderScriptStageTypeDelay: - free(current_stage->stage); - break; - } - free(current_stage); - current_stage = next_stage; - } - free(script->name); - free(script->description); - free(script); -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/wifi_marauder_script.h b/applications/external/wifi_marauder_companion/script/wifi_marauder_script.h deleted file mode 100644 index 2cf52196b..000000000 --- a/applications/external/wifi_marauder_companion/script/wifi_marauder_script.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * ---------------------------------------------------------------------------------------------------- - * STEPS TO ADD A NEW STAGE: - * - * wifi_marauder_script.h - * - Complement WifiMarauderScriptStageType enum with new stage - * - Create struct WifiMarauderScriptStage???? for the new stage - * - * wifi_marauder_script.c - * - Change _wifi_marauder_script_load_stages() to load new stage - * - Change wifi_marauder_script_save_json() to support the new stage - * - Add case to free memory in wifi_marauder_script_free() - * - * wifi_marauder_script_executor.c - * - Create function "void _wifi_marauder_script_execute_????(WifiMarauderScriptStage????* stage)" - * - Add case in wifi_marauder_script_execute_stage() - * - * wifi_marauder_scene_script_edit.c - * - Add case in wifi_marauder_scene_script_edit_on_enter() - * - * wifi_marauder_scene_script_stage_add.c - * - Create stage creation function and add in wifi_marauder_scene_script_stage_add_on_enter() - * - * wifi_marauder_script_stage_menu_config.h - * - Add the new stage and implement its functions in a new file - * - * ---------------------------------------------------------------------------------------------------- - * SCRIPT SYNTAX (In order of execution): - * { - * "meta": { - * "description": "My script", - * "repeat": times the script will repeat (default 1), - * "enableLed": true (default) | false, - * "savePcap": true (default) | false - * }, - * "stages": { - * "scan": { - * "type": "ap" | "station", - * "timeout": seconds, - * "channel": 1-11 - * }, - * "select": { - * "type": "ap" | "station" | "ssid", - * "filter": "all" | "contains -f '{SSID fragment}' or equals '{SSID}' or ...", - * "indexes": [0, 1, 2, 3...], - * }, - * "deauth": { - * "timeout": seconds - * }, - * "probe": { - * "timeout": seconds - * }, - * "sniffRaw": { - * "timeout": seconds - * }, - * "sniffBeacon": { - * "timeout": seconds - * }, - * "sniffDeauth": { - * "timeout": seconds - * }, - * "sniffEsp": { - * "timeout": seconds - * }, - * "sniffPmkid": { - * "forceDeauth": true (default) | false, - * "channel": 1-11, - * "timeout": seconds - * }, - * "sniffPwn": { - * "timeout": seconds - * }, - * "beaconList": { - * "ssids": [ - * "SSID 1", - * "SSID 2", - * "SSID 3" - * ], - * "generate": number of random SSIDs that will be generated, - * "timeout": seconds - * } - * "beaconAp": { - * "timeout": seconds - * } - * "exec": { - * "command": Command (eg: "clearlist -a") - * } - * "delay": { - * "timeout": seconds - * } - * } - * } - * - * Note: It is possible to inform "stages" as an array, allowing ordering and repetition of stages of the same type: - * "stages": [ - * { - * "beaconList": { "ssids": ["SSID 1", "SSID 2"] } - * }, - * { - * "beaconList": { "generate": 4 } - * }, - * ] - * ---------------------------------------------------------------------------------------------------- - */ - -#pragma once - -#include -#include "cJSON.h" - -#define WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN 15 -#define WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH 30 -#define WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE 60 -#define WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF 60 -#define WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON 60 - -typedef enum { - WifiMarauderScriptBooleanFalse = 0, - WifiMarauderScriptBooleanTrue = 1, - WifiMarauderScriptBooleanUndefined = 2 -} WifiMarauderScriptBoolean; - -typedef enum { - WifiMarauderScriptStageTypeScan, - WifiMarauderScriptStageTypeSelect, - WifiMarauderScriptStageTypeDeauth, - WifiMarauderScriptStageTypeProbe, - WifiMarauderScriptStageTypeSniffRaw, - WifiMarauderScriptStageTypeSniffBeacon, - WifiMarauderScriptStageTypeSniffDeauth, - WifiMarauderScriptStageTypeSniffEsp, - WifiMarauderScriptStageTypeSniffPmkid, - WifiMarauderScriptStageTypeSniffPwn, - WifiMarauderScriptStageTypeBeaconList, - WifiMarauderScriptStageTypeBeaconAp, - WifiMarauderScriptStageTypeExec, - WifiMarauderScriptStageTypeDelay, -} WifiMarauderScriptStageType; - -typedef enum { - WifiMarauderScriptScanTypeAp = 0, - WifiMarauderScriptScanTypeStation = 1 -} WifiMarauderScriptScanType; - -typedef enum { - WifiMarauderScriptSelectTypeAp, - WifiMarauderScriptSelectTypeStation, - WifiMarauderScriptSelectTypeSsid -} WifiMarauderScriptSelectType; - -// Stages -typedef struct WifiMarauderScriptStage { - WifiMarauderScriptStageType type; - void* stage; - struct WifiMarauderScriptStage* next_stage; -} WifiMarauderScriptStage; - -typedef struct WifiMarauderScriptStageScan { - WifiMarauderScriptScanType type; - int channel; - int timeout; -} WifiMarauderScriptStageScan; - -typedef struct WifiMarauderScriptStageSelect { - WifiMarauderScriptSelectType type; - char* filter; - int* indexes; - int index_count; - // TODO: Implement a feature to not select the same items in the next iteration of the script - bool allow_repeat; -} WifiMarauderScriptStageSelect; - -typedef struct WifiMarauderScriptStageDeauth { - int timeout; -} WifiMarauderScriptStageDeauth; - -typedef struct WifiMarauderScriptStageProbe { - int timeout; -} WifiMarauderScriptStageProbe; - -typedef struct WifiMarauderScriptStageSniffRaw { - int timeout; -} WifiMarauderScriptStageSniffRaw; - -typedef struct WifiMarauderScriptStageSniffBeacon { - int timeout; -} WifiMarauderScriptStageSniffBeacon; - -typedef struct WifiMarauderScriptStageSniffDeauth { - int timeout; -} WifiMarauderScriptStageSniffDeauth; - -typedef struct WifiMarauderScriptStageSniffEsp { - int timeout; -} WifiMarauderScriptStageSniffEsp; - -typedef struct WifiMarauderScriptStageSniffPmkid { - bool force_deauth; - bool hop_channels; - int channel; - int timeout; -} WifiMarauderScriptStageSniffPmkid; - -typedef struct WifiMarauderScriptStageSniffPwn { - int timeout; -} WifiMarauderScriptStageSniffPwn; - -typedef struct WifiMarauderScriptStageBeaconList { - char** ssids; - int ssid_count; - int random_ssids; - int timeout; -} WifiMarauderScriptStageBeaconList; - -typedef struct WifiMarauderScriptStageBeaconAp { - int timeout; -} WifiMarauderScriptStageBeaconAp; - -typedef struct WifiMarauderScriptStageExec { - char* command; -} WifiMarauderScriptStageExec; - -typedef struct WifiMarauderScriptStageDelay { - int timeout; -} WifiMarauderScriptStageDelay; - -// Script -typedef struct WifiMarauderScript { - char* name; - char* description; - WifiMarauderScriptStage* first_stage; - WifiMarauderScriptStage* last_stage; - WifiMarauderScriptBoolean enable_led; - WifiMarauderScriptBoolean save_pcap; - int repeat; -} WifiMarauderScript; - -typedef struct WifiMarauderScriptStageListItem { - char* value; - struct WifiMarauderScriptStageListItem* next_item; -} WifiMarauderScriptStageListItem; - -WifiMarauderScript* wifi_marauder_script_alloc(); -WifiMarauderScript* wifi_marauder_script_create(const char* script_name); -WifiMarauderScript* wifi_marauder_script_parse_raw(const char* script_raw); -WifiMarauderScript* wifi_marauder_script_parse_json(Storage* storage, const char* file_path); -void wifi_marauder_script_save_json( - Storage* storage, - const char* file_path, - WifiMarauderScript* script); -void wifi_marauder_script_add_stage( - WifiMarauderScript* script, - WifiMarauderScriptStageType stage_type, - void* stage_data); -bool wifi_marauder_script_has_stage( - WifiMarauderScript* script, - WifiMarauderScriptStageType stage_type); -void wifi_marauder_script_free(WifiMarauderScript* script); diff --git a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.c b/applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.c deleted file mode 100644 index 3a0816e24..000000000 --- a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.c +++ /dev/null @@ -1,443 +0,0 @@ -#include "../wifi_marauder_app_i.h" -#include "wifi_marauder_script_executor.h" - -void _wifi_marauder_script_delay(WifiMarauderScriptWorker* worker, uint32_t delay_secs) { - for(uint32_t i = 0; i < delay_secs && worker->is_running; i++) furi_delay_ms(1000); -} - -void _send_stop(bool save_pcaps) { - const char stop_command[] = "stopscan\n"; - if(save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(stop_command), strlen(stop_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(stop_command), strlen(stop_command)); - } -} - -void _send_line_break(bool save_pcaps) { - if(save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)("\n"), 1); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)("\n"), 1); - } -} - -void _send_channel_select(int channel, bool save_pcaps) { - char command[30]; - _send_line_break(save_pcaps); - snprintf(command, sizeof(command), "channel -s %d\n", channel); - if(save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(command), strlen(command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(command), strlen(command)); - } -} - -void _wifi_marauder_script_execute_scan( - WifiMarauderScriptStageScan* stage, - WifiMarauderScriptWorker* worker) { - char command[15]; - // Set channel - if(stage->channel > 0) { - _send_channel_select(stage->channel, worker->save_pcaps); - } - // Start scan - if(stage->type == WifiMarauderScriptScanTypeAp) { - snprintf(command, sizeof(command), "scanap\n"); - } else { - snprintf(command, sizeof(command), "scansta\n"); - } - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(command), strlen(command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(command), strlen(command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_select(WifiMarauderScriptStageSelect* stage, bool save_pcaps) { - const char* select_type = NULL; - switch(stage->type) { - case WifiMarauderScriptSelectTypeAp: - select_type = "-a"; - break; - case WifiMarauderScriptSelectTypeStation: - select_type = "-c"; - break; - case WifiMarauderScriptSelectTypeSsid: - select_type = "-s"; - break; - default: - return; // invalid stage - } - - char command[256]; - size_t command_length = 0; - - if(stage->indexes != NULL && stage->index_count > 0) { - command_length = snprintf(command, sizeof(command), "select %s ", select_type); - - for(int i = 0; i < stage->index_count; i++) { - int index = stage->indexes[i]; - command_length += snprintf( - command + command_length, sizeof(command) - command_length, "%d, ", index); - } - - // Remove the trailing comma and space - command_length -= 2; - command[command_length] = '\n'; - command_length++; - } else if(stage->filter == NULL || strcmp(stage->filter, "all") == 0) { - command_length = snprintf(command, sizeof(command), "select %s all\n", select_type); - } else { - command_length = snprintf( - command, sizeof(command), "select %s -f \"%s\"\n", select_type, stage->filter); - } - - if(save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)command, command_length); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)command, command_length); - } -} - -void _wifi_marauder_script_execute_deauth( - WifiMarauderScriptStageDeauth* stage, - WifiMarauderScriptWorker* worker) { - const char attack_command[] = "attack -t deauth\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(attack_command), strlen(attack_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(attack_command), strlen(attack_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_probe( - WifiMarauderScriptStageProbe* stage, - WifiMarauderScriptWorker* worker) { - const char attack_command[] = "attack -t probe\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(attack_command), strlen(attack_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(attack_command), strlen(attack_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_sniff_raw( - WifiMarauderScriptStageSniffRaw* stage, - WifiMarauderScriptWorker* worker) { - const char sniff_command[] = "sniffraw\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_sniff_beacon( - WifiMarauderScriptStageSniffBeacon* stage, - WifiMarauderScriptWorker* worker) { - const char sniff_command[] = "sniffbeacon\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_sniff_deauth( - WifiMarauderScriptStageSniffDeauth* stage, - WifiMarauderScriptWorker* worker) { - const char sniff_command[] = "sniffdeauth\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_sniff_esp( - WifiMarauderScriptStageSniffEsp* stage, - WifiMarauderScriptWorker* worker) { - const char sniff_command[] = "sniffesp\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_sniff_pmkid( - WifiMarauderScriptStageSniffPmkid* stage, - WifiMarauderScriptWorker* worker) { - if(stage->hop_channels) { - for(int i = 1; i <= 11; i++) { - char attack_command[50] = "sniffpmkid"; - int len = strlen(attack_command); - - len += snprintf(attack_command + len, sizeof(attack_command) - len, " -c %d", i); - if(stage->force_deauth) { - len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d"); - } - - len += snprintf(attack_command + len, sizeof(attack_command) - len, "\n"); - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)attack_command, len); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)attack_command, len); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); - } - } else { - char attack_command[50] = "sniffpmkid"; - int len = strlen(attack_command); - - if(stage->channel > 0) { - len += snprintf( - attack_command + len, sizeof(attack_command) - len, " -c %d", stage->channel); - } - - if(stage->force_deauth) { - len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d"); - } - len += snprintf(attack_command + len, sizeof(attack_command) - len, "\n"); - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)attack_command, len); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)attack_command, len); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); - } -} - -void _wifi_marauder_script_execute_sniff_pwn( - WifiMarauderScriptStageSniffPwn* stage, - WifiMarauderScriptWorker* worker) { - const char sniff_command[] = "sniffpwn\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(sniff_command), strlen(sniff_command)); - } - - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_beacon_list( - WifiMarauderScriptStageBeaconList* stage, - WifiMarauderScriptWorker* worker) { - const char clearlist_command[] = "clearlist -s\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(clearlist_command), strlen(clearlist_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(clearlist_command), strlen(clearlist_command)); - } - - char command[100]; - char* ssid; - - for(int i = 0; i < stage->ssid_count; i++) { - ssid = stage->ssids[i]; - snprintf(command, sizeof(command), "ssid -a -n \"%s\"", ssid); - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(command), strlen(command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(command), strlen(command)); - } - - _send_line_break(worker->save_pcaps); - } - if(stage->random_ssids > 0) { - char add_random_command[50]; - snprintf( - add_random_command, - sizeof(add_random_command), - "ssid -a -r -g %d\n", - stage->random_ssids); - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)add_random_command, strlen(add_random_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)add_random_command, strlen(add_random_command)); - } - } - const char attack_command[] = "attack -t beacon -l\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(attack_command), strlen(attack_command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(attack_command), strlen(attack_command)); - } - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_beacon_ap( - WifiMarauderScriptStageBeaconAp* stage, - WifiMarauderScriptWorker* worker) { - const char command[] = "attack -t beacon -a\n"; - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)(command), strlen(command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)(command), strlen(command)); - } - _wifi_marauder_script_delay(worker, stage->timeout); - _send_stop(worker->save_pcaps); -} - -void _wifi_marauder_script_execute_exec(WifiMarauderScriptStageExec* stage, bool save_pcaps) { - if(stage->command != NULL) { - if(save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)stage->command, strlen(stage->command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)stage->command, strlen(stage->command)); - } - _send_line_break(save_pcaps); - } -} - -void _wifi_marauder_script_execute_delay( - WifiMarauderScriptStageDelay* stage, - WifiMarauderScriptWorker* worker) { - _wifi_marauder_script_delay(worker, stage->timeout); -} - -void wifi_marauder_script_execute_start(void* context) { - furi_assert(context); - WifiMarauderScriptWorker* worker = context; - WifiMarauderScript* script = worker->script; - char command[100]; - - // Enables or disables the LED according to script settings - if(script->enable_led != WifiMarauderScriptBooleanUndefined) { - snprintf( - command, - sizeof(command), - "settings -s EnableLED %s", - script->enable_led ? "enable" : "disable"); - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)command, strlen(command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)command, strlen(command)); - } - - _send_line_break(worker->save_pcaps); - } - - // Enables or disables PCAP saving according to script settings - if(script->save_pcap != WifiMarauderScriptBooleanUndefined) { - snprintf( - command, - sizeof(command), - "settings -s SavePCAP %s", - script->save_pcap ? "enable" : "disable"); - - if(worker->save_pcaps) { - wifi_marauder_usart_tx((uint8_t*)command, strlen(command)); - } else { - wifi_marauder_xtreme_uart_tx((uint8_t*)command, strlen(command)); - } - - _send_line_break(worker->save_pcaps); - } -} - -void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* context) { - furi_assert(context); - WifiMarauderScriptWorker* worker = context; - void* stage_data = stage->stage; - - switch(stage->type) { - case WifiMarauderScriptStageTypeScan: - _wifi_marauder_script_execute_scan((WifiMarauderScriptStageScan*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSelect: - _wifi_marauder_script_execute_select( - (WifiMarauderScriptStageSelect*)stage_data, worker->save_pcaps); - break; - case WifiMarauderScriptStageTypeDeauth: - _wifi_marauder_script_execute_deauth((WifiMarauderScriptStageDeauth*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeProbe: - _wifi_marauder_script_execute_probe((WifiMarauderScriptStageProbe*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSniffRaw: - _wifi_marauder_script_execute_sniff_raw( - (WifiMarauderScriptStageSniffRaw*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSniffBeacon: - _wifi_marauder_script_execute_sniff_beacon( - (WifiMarauderScriptStageSniffBeacon*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSniffDeauth: - _wifi_marauder_script_execute_sniff_deauth( - (WifiMarauderScriptStageSniffDeauth*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSniffEsp: - _wifi_marauder_script_execute_sniff_esp( - (WifiMarauderScriptStageSniffEsp*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSniffPmkid: - _wifi_marauder_script_execute_sniff_pmkid( - (WifiMarauderScriptStageSniffPmkid*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeSniffPwn: - _wifi_marauder_script_execute_sniff_pwn( - (WifiMarauderScriptStageSniffPwn*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeBeaconList: - _wifi_marauder_script_execute_beacon_list( - (WifiMarauderScriptStageBeaconList*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeBeaconAp: - _wifi_marauder_script_execute_beacon_ap( - (WifiMarauderScriptStageBeaconAp*)stage_data, worker); - break; - case WifiMarauderScriptStageTypeExec: - _wifi_marauder_script_execute_exec( - (WifiMarauderScriptStageExec*)stage_data, worker->save_pcaps); - break; - case WifiMarauderScriptStageTypeDelay: - _wifi_marauder_script_execute_delay((WifiMarauderScriptStageDelay*)stage_data, worker); - break; - } -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.h b/applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.h deleted file mode 100644 index 654712849..000000000 --- a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_executor.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "wifi_marauder_script.h" - -void wifi_marauder_script_execute_start(void* context); -void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* context); diff --git a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.c b/applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.c deleted file mode 100644 index 45c5b56ba..000000000 --- a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "../wifi_marauder_app_i.h" -#include "wifi_marauder_script_worker.h" - -WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc() { - WifiMarauderScriptWorker* worker = malloc(sizeof(WifiMarauderScriptWorker)); - if(worker == NULL) { - return NULL; - } - worker->callback_start = NULL; - worker->callback_stage = NULL; - worker->worker_thread = NULL; - worker->is_running = false; - return worker; -} - -int32_t _wifi_marauder_script_worker_task(void* worker) { - WifiMarauderScriptWorker* script_worker = worker; - WifiMarauderScript* script = script_worker->script; - if(script == NULL) { - return WifiMarauderScriptWorkerStatusInvalidScript; - } - - // Setup - script_worker->callback_start(script_worker->context); - if(!script_worker->is_running) { - return WifiMarauderScriptWorkerStatusForceExit; - } - - // Stages - for(int i = 0; i < script->repeat; i++) { - WifiMarauderScriptStage* current_stage = script->first_stage; - while(current_stage != NULL && script_worker->is_running) { - script_worker->callback_stage(current_stage, script_worker->context); - current_stage = current_stage->next_stage; - } - if(!script_worker->is_running) { - return WifiMarauderScriptWorkerStatusForceExit; - } - } - - script_worker->is_running = false; - return WifiMarauderScriptWorkerStatusSuccess; -} - -bool wifi_marauder_script_worker_start( - WifiMarauderScriptWorker* instance, - WifiMarauderScript* script) { - if(!instance || !script) { - return false; - } - instance->callback_start = wifi_marauder_script_execute_start; - instance->callback_stage = wifi_marauder_script_execute_stage; - instance->script = script; - instance->context = instance; - instance->is_running = true; - instance->worker_thread = furi_thread_alloc_ex( - "WifiMarauderScriptWorker", 1024, _wifi_marauder_script_worker_task, instance); - if(!instance->worker_thread) { - return false; - } - furi_thread_start(instance->worker_thread); - return true; -} - -void wifi_marauder_script_worker_free(WifiMarauderScriptWorker* worker) { - if(worker != NULL) { - if(worker->worker_thread != NULL) { - worker->is_running = false; - furi_thread_join(worker->worker_thread); - furi_thread_free(worker->worker_thread); - } - free(worker); - } -} \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.h b/applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.h deleted file mode 100644 index b000f9ed4..000000000 --- a/applications/external/wifi_marauder_companion/script/wifi_marauder_script_worker.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "wifi_marauder_script.h" - -typedef enum { - WifiMarauderScriptWorkerStatusSuccess = 0, - WifiMarauderScriptWorkerStatusInvalidScript = 1, - WifiMarauderScriptWorkerStatusForceExit = 2 -} WifiMarauderScriptWorkerStatus; - -typedef struct WifiMarauderScriptWorker { - WifiMarauderScript* script; - FuriThread* worker_thread; - void (*callback_start)(void*); - void (*callback_stage)(WifiMarauderScriptStage*, void*); - void* context; - bool is_running; - bool save_pcaps; -} WifiMarauderScriptWorker; - -/** - * @brief Allocates a new instance of WifiMarauderScriptWorker. - * - * @return A pointer to the allocated instance or NULL if allocation fails. - */ -WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc(); - -/** - * @brief Starts the execution of the worker and sets the callback function to be called after each stage is executed. - * - * @param instance A pointer to the instance of WifiMarauderScriptWorker to start. - * @param script Script to be executed - * @return True if the worker was successfully started, false otherwise. - */ -bool wifi_marauder_script_worker_start( - WifiMarauderScriptWorker* instance, - WifiMarauderScript* script); - -/** - * @brief Frees the memory used by the instance of WifiMarauderScriptWorker. - * - * @param script A pointer to the instance of WifiMarauderScriptWorker to free. - */ -void wifi_marauder_script_worker_free(WifiMarauderScriptWorker* script); diff --git a/applications/external/wifi_marauder_companion/wifi_10px.png b/applications/external/wifi_marauder_companion/wifi_10px.png deleted file mode 100644 index c13534660e188305fba6c5625ec1ce6841e238f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1781 zcmcIl&u`pB6gH`Z%BmFygoHpsmU98Y_~+VQo4O&%2C@S^in|uYPoPg;=lp^061{vuK;mH0)!Ap1aEfjZ9#3COD(NEb)27p@I<-_@3^l{^ zJWV$>(?ozk<#ATw8OqAlhM~(!QY3km@JtqrIO0cDpn%lH9@2bCo0YXs;FvbUxn`)k z*i!=x!_%Q@x?Xi*{6@+a~SXQkz!SWHWcsb$^(6;>hKME;X z2F#C&@!TFtG&W`_aF>8J=K6AfvtYR5MW6F=ld0V%qHJ2KEx&Lj$ta(eFA7EV0@lS9 z3lxzxq6WkS3up+1Kyii72Ie%0kIw=PL%)}m70w9jbpr)NsYyb8 zJMsvNA`daU;~>vzcTnUo15vl_+OF=#%yQ$(Q&5MYCuiK3ViGt#NsF`|a;%_4zM2aoS%6{;vOnh}dV&+$;la51vmz|(PT2kC7> z4aZ`UqccUm8+VhBc@c67?plgWi68SK#ZW&o;wry~ZWrzC#?D|uW^alzJy;PgX_OM8&`5>HN- zezwFvLg}@wWQ4OJgU+cbVl$d(F^i;V|IgRmd^a_-4%IBOS=Kge;NjAc%S|z1Y*Ei7 z7`aZzLY~=nQ76_TL}+YM(=~`2JBzsEq*1US(oT;!*LqKTY!*Y$6~kq>hspB1U>R(+ zfYV^|L-!V(Bpbc%djFYEuYc5QN%Dnr&;9Yw)#snQ{?-RkcJOWM!}Gms%3q(obL%Er ziEn@L-j7dhz5Vr9H}KQ1Uj1|b*V}jgzWLMVKMy{+^U80llJ&7Tn0i|~-ETJDeg9wV C&oCwc diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app.c b/applications/external/wifi_marauder_companion/wifi_marauder_app.c deleted file mode 100644 index 59fe4cb8d..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "wifi_marauder_app_i.h" - -#include -#include - -static bool wifi_marauder_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - WifiMarauderApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool wifi_marauder_app_back_event_callback(void* context) { - furi_assert(context); - WifiMarauderApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void wifi_marauder_app_tick_event_callback(void* context) { - furi_assert(context); - WifiMarauderApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -WifiMarauderApp* wifi_marauder_app_alloc() { - WifiMarauderApp* app = malloc(sizeof(WifiMarauderApp)); - - app->gui = furi_record_open(RECORD_GUI); - app->dialogs = furi_record_open(RECORD_DIALOGS); - app->storage = furi_record_open(RECORD_STORAGE); - app->capture_file = storage_file_alloc(app->storage); - app->log_file = storage_file_alloc(app->storage); - app->save_pcap_setting_file = storage_file_alloc(app->storage); - app->save_logs_setting_file = storage_file_alloc(app->storage); - - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&wifi_marauder_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, wifi_marauder_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, wifi_marauder_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, wifi_marauder_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->var_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WifiMarauderAppViewVarItemList, - variable_item_list_get_view(app->var_item_list)); - - for(int i = 0; i < NUM_MENU_ITEMS; ++i) { - app->selected_option_index[i] = 0; - } - - app->special_case_input_step = 0; - - app->text_box = text_box_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WifiMarauderAppViewConsoleOutput, text_box_get_view(app->text_box)); - app->text_box_store = furi_string_alloc(); - furi_string_reserve(app->text_box_store, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE); - - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WifiMarauderAppViewTextInput, text_input_get_view(app->text_input)); - - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WifiMarauderAppViewWidget, widget_get_view(app->widget)); - - app->has_saved_logs_this_session = false; - - // if user hasn't confirmed whether to save pcaps and logs to sdcard, then prompt when scene starts - app->need_to_prompt_settings_init = - (!storage_file_exists(app->storage, SAVE_PCAP_SETTING_FILEPATH) || - !storage_file_exists(app->storage, SAVE_LOGS_SETTING_FILEPATH)); - - // Submenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WifiMarauderAppViewSubmenu, submenu_get_view(app->submenu)); - - scene_manager_next_scene(app->scene_manager, WifiMarauderSceneStart); - - return app; -} - -void wifi_marauder_make_app_folder(WifiMarauderApp* app) { - furi_assert(app); - - if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER)) { - dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder"); - } - - if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_PCAPS)) { - dialog_message_show_storage_error(app->dialogs, "Cannot create\npcaps folder"); - } - - if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_LOGS)) { - dialog_message_show_storage_error(app->dialogs, "Cannot create\npcaps folder"); - } - - if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_SCRIPTS)) { - dialog_message_show_storage_error(app->dialogs, "Cannot create\nscripts folder"); - } -} - -void wifi_marauder_load_settings(WifiMarauderApp* app) { - if(storage_file_open( - app->save_pcap_setting_file, - SAVE_PCAP_SETTING_FILEPATH, - FSAM_READ, - FSOM_OPEN_EXISTING)) { - char ok[1]; - storage_file_read(app->save_pcap_setting_file, ok, sizeof(ok)); - app->ok_to_save_pcaps = ok[0] == 'Y'; - } - storage_file_close(app->save_pcap_setting_file); - - if(storage_file_open( - app->save_logs_setting_file, - SAVE_LOGS_SETTING_FILEPATH, - FSAM_READ, - FSOM_OPEN_EXISTING)) { - char ok[1]; - storage_file_read(app->save_logs_setting_file, ok, sizeof(ok)); - app->ok_to_save_logs = ok[0] == 'Y'; - } - storage_file_close(app->save_logs_setting_file); -} - -void wifi_marauder_app_free(WifiMarauderApp* app) { - furi_assert(app); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewVarItemList); - view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput); - view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewTextInput); - view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewWidget); - view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewSubmenu); - - widget_free(app->widget); - text_box_free(app->text_box); - furi_string_free(app->text_box_store); - text_input_free(app->text_input); - submenu_free(app->submenu); - variable_item_list_free(app->var_item_list); - storage_file_free(app->capture_file); - storage_file_free(app->log_file); - storage_file_free(app->save_pcap_setting_file); - storage_file_free(app->save_logs_setting_file); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - wifi_marauder_uart_free(app->uart); - if(app->ok_to_save_pcaps) { - wifi_marauder_uart_free(app->pcap_uart); - } - - // Close records - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_DIALOGS); - - free(app); -} - -int32_t wifi_marauder_app(void* p) { - UNUSED(p); - - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - furi_delay_ms(200); - - WifiMarauderApp* wifi_marauder_app = wifi_marauder_app_alloc(); - - wifi_marauder_make_app_folder(wifi_marauder_app); - wifi_marauder_load_settings(wifi_marauder_app); - - if(wifi_marauder_app->ok_to_save_pcaps) { - wifi_marauder_app->uart = wifi_marauder_usart_init(wifi_marauder_app); - wifi_marauder_app->pcap_uart = wifi_marauder_lp_uart_init(wifi_marauder_app); - } else { - wifi_marauder_app->uart = - wifi_marauder_uart_init(wifi_marauder_app, XTREME_UART_CH, "WifiMarauderUartRxThread"); - } - - view_dispatcher_run(wifi_marauder_app->view_dispatcher); - - wifi_marauder_app_free(wifi_marauder_app); - - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } - - return 0; -} diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app.h b/applications/external/wifi_marauder_companion/wifi_marauder_app.h deleted file mode 100644 index ceacbb489..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#define WIFI_MARAUDER_APP_VERSION "v0.6.0" - -typedef struct WifiMarauderApp WifiMarauderApp; - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h deleted file mode 100644 index 6c846023f..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h +++ /dev/null @@ -1,154 +0,0 @@ -//** Includes sniffbt and sniffskim for compatible ESP32-WROOM hardware. -// wifi_marauder_scene_start.c also changed **// -#pragma once - -#include "wifi_marauder_app.h" -#include "scenes/wifi_marauder_scene.h" -#include "wifi_marauder_custom_event.h" -#include "wifi_marauder_uart.h" -#include "file/sequential_file.h" -#include "script/wifi_marauder_script.h" -#include "script/wifi_marauder_script_worker.h" -#include "script/wifi_marauder_script_executor.h" -#include "script/menu/wifi_marauder_script_stage_menu.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define XTREME_UART_CH \ - (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) - -#define US_ART_CH (FuriHalUartIdUSART1) -#define LP_UART_CH (FuriHalUartIdLPUART1) -#define BAUDRATE (115200) - -#define NUM_MENU_ITEMS (20) - -#define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096) -#define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512) - -#define MARAUDER_APP_FOLDER_USER "apps_data/marauder" -#define MARAUDER_APP_FOLDER EXT_PATH(MARAUDER_APP_FOLDER_USER) -#define MARAUDER_APP_FOLDER_PCAPS MARAUDER_APP_FOLDER "/pcaps" -#define MARAUDER_APP_FOLDER_LOGS MARAUDER_APP_FOLDER "/logs" -#define MARAUDER_APP_FOLDER_USER_PCAPS MARAUDER_APP_FOLDER_USER "/pcaps" -#define MARAUDER_APP_FOLDER_USER_LOGS MARAUDER_APP_FOLDER_USER "/logs" -#define MARAUDER_APP_FOLDER_SCRIPTS MARAUDER_APP_FOLDER "/scripts" -#define MARAUDER_APP_SCRIPT_PATH(file_name) MARAUDER_APP_FOLDER_SCRIPTS "/" file_name ".json" -#define SAVE_PCAP_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_pcaps_here.setting" -#define SAVE_LOGS_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_logs_here.setting" - -typedef enum WifiMarauderUserInputType { - WifiMarauderUserInputTypeString, - WifiMarauderUserInputTypeNumber, - WifiMarauderUserInputTypeFileName -} WifiMarauderUserInputType; - -struct WifiMarauderApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - - char text_input_store[WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE + 1]; - FuriString* text_box_store; - size_t text_box_store_strlen; - TextBox* text_box; - TextInput* text_input; - Storage* storage; - File* capture_file; - File* log_file; - char log_file_path[100]; - File* save_pcap_setting_file; - File* save_logs_setting_file; - bool need_to_prompt_settings_init; - int which_prompt; - bool ok_to_save_pcaps; - bool ok_to_save_logs; - bool has_saved_logs_this_session; - DialogsApp* dialogs; - - VariableItemList* var_item_list; - Widget* widget; - Submenu* submenu; - int open_log_file_page; - int open_log_file_num_pages; - - WifiMarauderUart* uart; - WifiMarauderUart* pcap_uart; - int selected_menu_index; - int selected_option_index[NUM_MENU_ITEMS]; - const char* selected_tx_string; - bool is_command; - bool is_custom_tx_string; - bool focus_console_start; - bool show_stopscan_tip; - bool is_writing_pcap; - bool is_writing_log; - - // User input - WifiMarauderUserInputType user_input_type; - char** user_input_string_reference; - int* user_input_number_reference; - char* user_input_file_dir; - char* user_input_file_extension; - - // Automation script - WifiMarauderScript* script; - WifiMarauderScriptWorker* script_worker; - FuriString** script_list; - int script_list_count; - WifiMarauderScriptStage* script_edit_selected_stage; - WifiMarauderScriptStageMenu* script_stage_menu; - WifiMarauderScriptStageListItem* script_stage_edit_first_item; - char*** script_stage_edit_strings_reference; - int* script_stage_edit_string_count_reference; - int** script_stage_edit_numbers_reference; - int* script_stage_edit_number_count_reference; - - // For input source and destination MAC in targeted deauth attack - int special_case_input_step; - char special_case_input_src_addr[20]; - char special_case_input_dst_addr[20]; -}; - -// Supported commands: -// https://github.com/justcallmekoko/ESP32Marauder/wiki/cli -// Scan -// -> If list is empty, then start a new scanap. (Tap any button to stop.) -// -> If there's a list, provide option to rescan and dump list of targets to select. -// -> Press BACK to go back to top-level. -// Attack -// -> Beacon -// -> Deauth -// -> Probe -// -> Rickroll -// Sniff -// -> Beacon -// -> Deauth -// -> ESP -// -> PMKID -// -> Pwnagotchi -// Channel -// Update -// Reboot - -typedef enum { - WifiMarauderAppViewVarItemList, - WifiMarauderAppViewConsoleOutput, - WifiMarauderAppViewTextInput, - WifiMarauderAppViewWidget, - WifiMarauderAppViewSubmenu, -} WifiMarauderAppView; diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_custom_event.h b/applications/external/wifi_marauder_companion/wifi_marauder_custom_event.h deleted file mode 100644 index b6d9f8274..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_custom_event.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -typedef enum { - WifiMarauderEventRefreshConsoleOutput = 0, - WifiMarauderEventStartConsole, - WifiMarauderEventStartKeyboard, - WifiMarauderEventSaveSourceMac, - WifiMarauderEventSaveDestinationMac, - WifiMarauderEventStartSettingsInit, - WifiMarauderEventStartLogViewer, - WifiMarauderEventStartScriptSelect, - WifiMarauderEventStartSniffPmkidOptions -} WifiMarauderCustomEvent; diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_uart.c b/applications/external/wifi_marauder_companion/wifi_marauder_uart.c deleted file mode 100644 index d4a1d3ce5..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_uart.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "wifi_marauder_app_i.h" -#include "wifi_marauder_uart.h" - -struct WifiMarauderUart { - WifiMarauderApp* app; - FuriHalUartId channel; - FuriThread* rx_thread; - FuriStreamBuffer* rx_stream; - uint8_t rx_buf[RX_BUF_SIZE + 1]; - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context); -}; - -typedef enum { - WorkerEvtStop = (1 << 0), - WorkerEvtRxDone = (1 << 1), -} WorkerEvtFlags; - -void wifi_marauder_uart_set_handle_rx_data_cb( - WifiMarauderUart* uart, - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) { - furi_assert(uart); - uart->handle_rx_data_cb = handle_rx_data_cb; -} - -#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone) - -void wifi_marauder_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { - WifiMarauderUart* uart = (WifiMarauderUart*)context; - - if(ev == UartIrqEventRXNE) { - furi_stream_buffer_send(uart->rx_stream, &data, 1, 0); - furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone); - } -} - -static int32_t uart_worker(void* context) { - WifiMarauderUart* uart = (void*)context; - - while(1) { - uint32_t events = - furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); - furi_check((events & FuriFlagError) == 0); - if(events & WorkerEvtStop) break; - if(events & WorkerEvtRxDone) { - size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0); - if(len > 0) { - if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app); - } - } - } - - furi_stream_buffer_free(uart->rx_stream); - - return 0; -} - -void wifi_marauder_xtreme_uart_tx(uint8_t* data, size_t len) { - furi_hal_uart_tx(XTREME_UART_CH, data, len); -} - -void wifi_marauder_usart_tx(uint8_t* data, size_t len) { - furi_hal_uart_tx(US_ART_CH, data, len); -} - -void wifi_marauder_lp_uart_tx(uint8_t* data, size_t len) { - furi_hal_uart_tx(LP_UART_CH, data, len); -} - -WifiMarauderUart* - wifi_marauder_uart_init(WifiMarauderApp* app, FuriHalUartId channel, const char* thread_name) { - WifiMarauderUart* uart = malloc(sizeof(WifiMarauderUart)); - - uart->app = app; - uart->channel = channel; - uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1); - uart->rx_thread = furi_thread_alloc(); - furi_thread_set_name(uart->rx_thread, thread_name); - furi_thread_set_stack_size(uart->rx_thread, 1024); - furi_thread_set_context(uart->rx_thread, uart); - furi_thread_set_callback(uart->rx_thread, uart_worker); - furi_thread_start(uart->rx_thread); - if(channel == FuriHalUartIdUSART1) { - furi_hal_console_disable(); - } else if(channel == FuriHalUartIdLPUART1) { - furi_hal_uart_init(channel, BAUDRATE); - } - furi_hal_uart_set_br(channel, BAUDRATE); - furi_hal_uart_set_irq_cb(channel, wifi_marauder_uart_on_irq_cb, uart); - - return uart; -} - -WifiMarauderUart* wifi_marauder_usart_init(WifiMarauderApp* app) { - return wifi_marauder_uart_init(app, US_ART_CH, "WifiMarauderUartRxThread"); -} - -WifiMarauderUart* wifi_marauder_lp_uart_init(WifiMarauderApp* app) { - return wifi_marauder_uart_init(app, LP_UART_CH, "WifiMarauderLPUartRxThread"); -} - -void wifi_marauder_uart_free(WifiMarauderUart* uart) { - furi_assert(uart); - - furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop); - furi_thread_join(uart->rx_thread); - furi_thread_free(uart->rx_thread); - - furi_hal_uart_set_irq_cb(uart->channel, NULL, NULL); - if(uart->channel == FuriHalUartIdLPUART1) { - furi_hal_uart_deinit(uart->channel); - } else { - furi_hal_console_enable(); - } - - free(uart); -} diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_uart.h b/applications/external/wifi_marauder_companion/wifi_marauder_uart.h deleted file mode 100644 index 1a8d28c5d..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_uart.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "furi_hal.h" - -#define RX_BUF_SIZE (2048) - -typedef struct WifiMarauderUart WifiMarauderUart; - -void wifi_marauder_uart_set_handle_rx_data_cb( - WifiMarauderUart* uart, - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)); -void wifi_marauder_xtreme_uart_tx(uint8_t* data, size_t len); -void wifi_marauder_usart_tx(uint8_t* data, size_t len); -void wifi_marauder_lp_uart_tx(uint8_t* data, size_t len); -WifiMarauderUart* wifi_marauder_usart_init(WifiMarauderApp* app); -WifiMarauderUart* wifi_marauder_lp_uart_init(WifiMarauderApp* app); -void wifi_marauder_uart_free(WifiMarauderUart* uart); - -WifiMarauderUart* - wifi_marauder_uart_init(WifiMarauderApp* app, FuriHalUartId channel, const char* thread_name); \ No newline at end of file diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_validators.c b/applications/external/wifi_marauder_companion/wifi_marauder_validators.c deleted file mode 100644 index 5bec88269..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_validators.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include "wifi_marauder_validators.h" -#include - -struct ValidatorIsFile { - char* app_path_folder; - const char* app_extension; - char* current_name; -}; - -bool validator_is_file_callback(const char* text, FuriString* error, void* context) { - furi_assert(context); - ValidatorIsFile* instance = context; - - if(instance->current_name != NULL) { - if(strcmp(instance->current_name, text) == 0) { - return true; - } - } - - bool ret = true; - FuriString* path = furi_string_alloc_printf( - "%s/%s%s", instance->app_path_folder, text, instance->app_extension); - Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK) { - ret = false; - furi_string_printf(error, "This name\nexists!\nChoose\nanother one."); - } else { - ret = true; - } - furi_string_free(path); - furi_record_close(RECORD_STORAGE); - - return ret; -} - -ValidatorIsFile* validator_is_file_alloc_init( - const char* app_path_folder, - const char* app_extension, - const char* current_name) { - ValidatorIsFile* instance = malloc(sizeof(ValidatorIsFile)); - - instance->app_path_folder = strdup(app_path_folder); - instance->app_extension = app_extension; - if(current_name != NULL) { - instance->current_name = strdup(current_name); - } - - return instance; -} - -void validator_is_file_free(ValidatorIsFile* instance) { - furi_assert(instance); - free(instance->app_path_folder); - free(instance->current_name); - free(instance); -} diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_validators.h b/applications/external/wifi_marauder_companion/wifi_marauder_validators.h deleted file mode 100644 index d9200b6db..000000000 --- a/applications/external/wifi_marauder_companion/wifi_marauder_validators.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif -typedef struct ValidatorIsFile ValidatorIsFile; - -ValidatorIsFile* validator_is_file_alloc_init( - const char* app_path_folder, - const char* app_extension, - const char* current_name); - -void validator_is_file_free(ValidatorIsFile* instance); - -bool validator_is_file_callback(const char* text, FuriString* error, void* context); - -#ifdef __cplusplus -} -#endif