Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
commit
fd0dd34a03
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -127,7 +127,7 @@ jobs:
|
|||||||
**Compiled firmware for commit `${{steps.names.outputs.commit_sha}}`:**
|
**Compiled firmware for commit `${{steps.names.outputs.commit_sha}}`:**
|
||||||
- [📦 Update package](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz)
|
- [📦 Update package](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz)
|
||||||
- [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu)
|
- [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu)
|
||||||
- [☁️ Web/App updater](https://my.flipp.dev/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}})
|
- [☁️ Web/App updater](https://lab.flipper.net/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}})
|
||||||
edit-mode: replace
|
edit-mode: replace
|
||||||
|
|
||||||
compact:
|
compact:
|
||||||
|
|||||||
1
.github/workflows/pvs_studio.yml
vendored
1
.github/workflows/pvs_studio.yml
vendored
@ -65,7 +65,6 @@ jobs:
|
|||||||
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
|
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
|
||||||
pvs-studio-analyzer analyze \
|
pvs-studio-analyzer analyze \
|
||||||
@.pvsoptions \
|
@.pvsoptions \
|
||||||
--disableLicenseExpirationCheck \
|
|
||||||
-j$(grep -c processor /proc/cpuinfo) \
|
-j$(grep -c processor /proc/cpuinfo) \
|
||||||
-f build/f7-firmware-DC/compile_commands.json \
|
-f build/f7-firmware-DC/compile_commands.json \
|
||||||
-o PVS-Studio.log
|
-o PVS-Studio.log
|
||||||
|
|||||||
52
.github/workflows/unit_tests.yml
vendored
Normal file
52
.github/workflows/unit_tests.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
name: 'Unit tests'
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
env:
|
||||||
|
TARGETS: f7
|
||||||
|
DEFAULT_TARGET: f7
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
runs-on: [self-hosted, FlipperZeroTest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
|
- name: 'Get flipper from device manager (mock)'
|
||||||
|
id: device
|
||||||
|
run: |
|
||||||
|
echo "flipper=/dev/ttyACM0" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 'Compile unit tests firmware'
|
||||||
|
id: compile
|
||||||
|
run: |
|
||||||
|
FBT_TOOLCHAIN_PATH=/opt ./fbt flash OPENOCD_ADAPTER_SERIAL=2A0906016415303030303032 FIRMWARE_APP_SET=unit_tests FORCE=1
|
||||||
|
|
||||||
|
- name: 'Wait for flipper to finish updating'
|
||||||
|
id: connect
|
||||||
|
if: steps.compile.outcome == 'success'
|
||||||
|
run: |
|
||||||
|
python3 ./scripts/testing/await_flipper.py ${{steps.device.outputs.flipper}}
|
||||||
|
|
||||||
|
- name: 'Format flipper SD card'
|
||||||
|
id: format
|
||||||
|
if: steps.connect.outcome == 'success'
|
||||||
|
run: |
|
||||||
|
./scripts/storage.py -p ${{steps.device.outputs.flipper}} format_ext
|
||||||
|
|
||||||
|
- name: 'Copy assets and unit tests data to flipper'
|
||||||
|
id: copy
|
||||||
|
if: steps.format.outcome == 'success'
|
||||||
|
run: |
|
||||||
|
./scripts/storage.py -p ${{steps.device.outputs.flipper}} send assets/resources /ext
|
||||||
|
./scripts/storage.py -p ${{steps.device.outputs.flipper}} send assets/unit_tests /ext/unit_tests
|
||||||
|
|
||||||
|
- name: 'Run units and validate results'
|
||||||
|
if: steps.copy.outcome == 'success'
|
||||||
|
run: |
|
||||||
|
python3 ./scripts/testing/units.py ${{steps.device.outputs.flipper}}
|
||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -22,12 +22,12 @@
|
|||||||
[submodule "lib/microtar"]
|
[submodule "lib/microtar"]
|
||||||
path = lib/microtar
|
path = lib/microtar
|
||||||
url = https://github.com/amachronic/microtar.git
|
url = https://github.com/amachronic/microtar.git
|
||||||
[submodule "lib/scons"]
|
|
||||||
path = lib/scons
|
|
||||||
url = https://github.com/SCons/scons.git
|
|
||||||
[submodule "lib/mbedtls"]
|
[submodule "lib/mbedtls"]
|
||||||
path = lib/mbedtls
|
path = lib/mbedtls
|
||||||
url = https://github.com/Mbed-TLS/mbedtls.git
|
url = https://github.com/Mbed-TLS/mbedtls.git
|
||||||
[submodule "lib/cxxheaderparser"]
|
[submodule "lib/cxxheaderparser"]
|
||||||
path = lib/cxxheaderparser
|
path = lib/cxxheaderparser
|
||||||
url = https://github.com/robotpy/cxxheaderparser.git
|
url = https://github.com/robotpy/cxxheaderparser.git
|
||||||
|
[submodule "applications/plugins/dap_link/lib/free-dap"]
|
||||||
|
path = applications/plugins/dap_link/lib/free-dap
|
||||||
|
url = https://github.com/ataradov/free-dap.git
|
||||||
|
|||||||
2
.vscode/example/c_cpp_properties.json
vendored
2
.vscode/example/c_cpp_properties.json
vendored
@ -2,7 +2,7 @@
|
|||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Win32",
|
"name": "Win32",
|
||||||
"compilerPath": "${workspaceFolder}/toolchain/i686-windows/bin/arm-none-eabi-gcc.exe",
|
"compilerPath": "${workspaceFolder}/toolchain/x86_64-windows/bin/arm-none-eabi-gcc.exe",
|
||||||
"intelliSenseMode": "gcc-arm",
|
"intelliSenseMode": "gcc-arm",
|
||||||
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
|
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
|
||||||
"configurationProvider": "ms-vscode.cpptools",
|
"configurationProvider": "ms-vscode.cpptools",
|
||||||
|
|||||||
19
.vscode/example/launch.json
vendored
19
.vscode/example/launch.json
vendored
@ -79,6 +79,25 @@
|
|||||||
]
|
]
|
||||||
// "showDevDebugOutput": "raw",
|
// "showDevDebugOutput": "raw",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Attach FW (DAP)",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"executable": "./build/latest/firmware.elf",
|
||||||
|
"request": "attach",
|
||||||
|
"type": "cortex-debug",
|
||||||
|
"servertype": "openocd",
|
||||||
|
"device": "cmsis-dap",
|
||||||
|
"svdFile": "./debug/STM32WB55_CM4.svd",
|
||||||
|
"rtos": "FreeRTOS",
|
||||||
|
"configFiles": [
|
||||||
|
"interface/cmsis-dap.cfg",
|
||||||
|
"./debug/stm32wbx.cfg",
|
||||||
|
],
|
||||||
|
"postAttachCommands": [
|
||||||
|
"source debug/flipperapps.py",
|
||||||
|
],
|
||||||
|
// "showDevDebugOutput": "raw",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "fbt debug",
|
"name": "fbt debug",
|
||||||
"type": "python",
|
"type": "python",
|
||||||
|
|||||||
6
.vscode/example/settings.json
vendored
6
.vscode/example/settings.json
vendored
@ -6,13 +6,13 @@
|
|||||||
"cortex-debug.enableTelemetry": false,
|
"cortex-debug.enableTelemetry": false,
|
||||||
"cortex-debug.variableUseNaturalFormat": true,
|
"cortex-debug.variableUseNaturalFormat": true,
|
||||||
"cortex-debug.showRTOS": true,
|
"cortex-debug.showRTOS": true,
|
||||||
"cortex-debug.armToolchainPath.windows": "${workspaceFolder}/toolchain/i686-windows/bin",
|
"cortex-debug.armToolchainPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/bin",
|
||||||
"cortex-debug.armToolchainPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin",
|
"cortex-debug.armToolchainPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin",
|
||||||
"cortex-debug.armToolchainPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin",
|
"cortex-debug.armToolchainPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin",
|
||||||
"cortex-debug.openocdPath.windows": "${workspaceFolder}/toolchain/i686-windows/openocd/bin/openocd.exe",
|
"cortex-debug.openocdPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/openocd/bin/openocd.exe",
|
||||||
"cortex-debug.openocdPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/openocd/bin/openocd",
|
"cortex-debug.openocdPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/openocd/bin/openocd",
|
||||||
"cortex-debug.openocdPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/openocd/bin/openocd",
|
"cortex-debug.openocdPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/openocd/bin/openocd",
|
||||||
"cortex-debug.gdbPath.windows": "${workspaceFolder}/toolchain/i686-windows/bin/arm-none-eabi-gdb-py.bat",
|
"cortex-debug.gdbPath.windows": "${workspaceFolder}/toolchain/x86_64-windows/bin/arm-none-eabi-gdb-py.bat",
|
||||||
"cortex-debug.gdbPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py",
|
"cortex-debug.gdbPath.linux": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py",
|
||||||
"cortex-debug.gdbPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gdb-py",
|
"cortex-debug.gdbPath.osx": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gdb-py",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
|
|||||||
4
.vscode/example/tasks.json
vendored
4
.vscode/example/tasks.json
vendored
@ -109,13 +109,13 @@
|
|||||||
"label": "[Debug] Build FAPs",
|
"label": "[Debug] Build FAPs",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "./fbt plugin_dist"
|
"command": "./fbt fap_dist"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "[Release] Build FAPs",
|
"label": "[Release] Build FAPs",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "./fbt COMPACT=1 DEBUG=0 plugin_dist"
|
"command": "./fbt COMPACT=1 DEBUG=0 fap_dist"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "[Debug] Launch App on Flipper",
|
"label": "[Debug] Launch App on Flipper",
|
||||||
|
|||||||
16
SConstruct
16
SConstruct
@ -156,11 +156,9 @@ Depends(fap_dist, firmware_env["FW_EXTAPPS"]["validators"].values())
|
|||||||
Alias("fap_dist", fap_dist)
|
Alias("fap_dist", fap_dist)
|
||||||
# distenv.Default(fap_dist)
|
# distenv.Default(fap_dist)
|
||||||
|
|
||||||
plugin_resources_dist = list(
|
distenv.Depends(
|
||||||
distenv.Install(f"#/assets/resources/apps/{dist_entry[0]}", dist_entry[1])
|
firmware_env["FW_RESOURCES"], firmware_env["FW_EXTAPPS"]["resources_dist"]
|
||||||
for dist_entry in firmware_env["FW_EXTAPPS"]["dist"].values()
|
|
||||||
)
|
)
|
||||||
distenv.Depends(firmware_env["FW_RESOURCES"], plugin_resources_dist)
|
|
||||||
|
|
||||||
|
|
||||||
# Target for bundling core2 package for qFlipper
|
# Target for bundling core2 package for qFlipper
|
||||||
@ -291,6 +289,16 @@ distenv.PhonyTarget(
|
|||||||
"@echo $( ${BLACKMAGIC_ADDR} $)",
|
"@echo $( ${BLACKMAGIC_ADDR} $)",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Find STLink probe ids
|
||||||
|
distenv.PhonyTarget(
|
||||||
|
"get_stlink",
|
||||||
|
distenv.Action(
|
||||||
|
lambda **kw: distenv.GetDevices(),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Prepare vscode environment
|
# Prepare vscode environment
|
||||||
vscode_dist = distenv.Install("#.vscode", distenv.Glob("#.vscode/example/*"))
|
vscode_dist = distenv.Install("#.vscode", distenv.Glob("#.vscode/example/*"))
|
||||||
distenv.Precious(vscode_dist)
|
distenv.Precious(vscode_dist)
|
||||||
|
|||||||
@ -8,4 +8,5 @@ App(
|
|||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
order=150,
|
order=150,
|
||||||
fap_category="Debug",
|
fap_category="Debug",
|
||||||
|
fap_icon_assets="icons",
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "assets_icons.h"
|
#include <file_browser_test_icons.h>
|
||||||
#include "file_browser_app_i.h"
|
#include "file_browser_app_i.h"
|
||||||
#include "gui/modules/file_browser.h"
|
#include "gui/modules/file_browser.h"
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|||||||
BIN
applications/debug/file_browser_test/icons/badusb_10px.png
Normal file
BIN
applications/debug/file_browser_test/icons/badusb_10px.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 576 B |
@ -16,6 +16,7 @@
|
|||||||
#define NFC_TEST_RESOURCES_DIR EXT_PATH("unit_tests/nfc/")
|
#define NFC_TEST_RESOURCES_DIR EXT_PATH("unit_tests/nfc/")
|
||||||
#define NFC_TEST_SIGNAL_SHORT_FILE "nfc_nfca_signal_short.nfc"
|
#define NFC_TEST_SIGNAL_SHORT_FILE "nfc_nfca_signal_short.nfc"
|
||||||
#define NFC_TEST_SIGNAL_LONG_FILE "nfc_nfca_signal_long.nfc"
|
#define NFC_TEST_SIGNAL_LONG_FILE "nfc_nfca_signal_long.nfc"
|
||||||
|
#define NFC_TEST_DICT_PATH EXT_PATH("unit_tests/mf_classic_dict.nfc")
|
||||||
|
|
||||||
static const char* nfc_test_file_type = "Flipper NFC test";
|
static const char* nfc_test_file_type = "Flipper NFC test";
|
||||||
static const uint32_t nfc_test_file_version = 1;
|
static const uint32_t nfc_test_file_version = 1;
|
||||||
@ -220,11 +221,78 @@ MU_TEST(mf_classic_dict_test) {
|
|||||||
furi_string_free(temp_str);
|
furi_string_free(temp_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MU_TEST(mf_classic_dict_load_test) {
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
mu_assert(storage != NULL, "storage != NULL assert failed\r\n");
|
||||||
|
|
||||||
|
// Delete unit test dict file if exists
|
||||||
|
if(storage_file_exists(storage, NFC_TEST_DICT_PATH)) {
|
||||||
|
mu_assert(
|
||||||
|
storage_simply_remove(storage, NFC_TEST_DICT_PATH),
|
||||||
|
"remove == true assert failed\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unit test dict file
|
||||||
|
Stream* file_stream = file_stream_alloc(storage);
|
||||||
|
mu_assert(file_stream != NULL, "file_stream != NULL assert failed\r\n");
|
||||||
|
mu_assert(
|
||||||
|
file_stream_open(file_stream, NFC_TEST_DICT_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS),
|
||||||
|
"file_stream_open == true assert failed\r\n");
|
||||||
|
|
||||||
|
// Write unit test dict file
|
||||||
|
char key_str[] = "a0a1a2a3a4a5";
|
||||||
|
mu_assert(
|
||||||
|
stream_write_cstring(file_stream, key_str) == strlen(key_str),
|
||||||
|
"write == true assert failed\r\n");
|
||||||
|
// Close unit test dict file
|
||||||
|
mu_assert(file_stream_close(file_stream), "file_stream_close == true assert failed\r\n");
|
||||||
|
|
||||||
|
// Load unit test dict file
|
||||||
|
MfClassicDict* instance = NULL;
|
||||||
|
instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest);
|
||||||
|
mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n");
|
||||||
|
uint32_t total_keys = mf_classic_dict_get_total_keys(instance);
|
||||||
|
mu_assert(total_keys == 1, "total_keys == 1 assert failed\r\n");
|
||||||
|
|
||||||
|
// Read key
|
||||||
|
uint64_t key_ref = 0xa0a1a2a3a4a5;
|
||||||
|
uint64_t key_dut = 0;
|
||||||
|
FuriString* temp_str = furi_string_alloc();
|
||||||
|
mu_assert(
|
||||||
|
mf_classic_dict_get_next_key_str(instance, temp_str),
|
||||||
|
"get_next_key_str == true assert failed\r\n");
|
||||||
|
mu_assert(furi_string_cmp_str(temp_str, key_str) == 0, "invalid key loaded\r\n");
|
||||||
|
mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");
|
||||||
|
mu_assert(
|
||||||
|
mf_classic_dict_get_next_key(instance, &key_dut),
|
||||||
|
"get_next_key == true assert failed\r\n");
|
||||||
|
mu_assert(key_dut == key_ref, "invalid key loaded\r\n");
|
||||||
|
furi_string_free(temp_str);
|
||||||
|
mf_classic_dict_free(instance);
|
||||||
|
|
||||||
|
// Check that MfClassicDict added new line to the end of the file
|
||||||
|
mu_assert(
|
||||||
|
file_stream_open(file_stream, NFC_TEST_DICT_PATH, FSAM_READ, FSOM_OPEN_EXISTING),
|
||||||
|
"file_stream_open == true assert failed\r\n");
|
||||||
|
mu_assert(stream_seek(file_stream, -1, StreamOffsetFromEnd), "seek == true assert failed\r\n");
|
||||||
|
uint8_t last_char = 0;
|
||||||
|
mu_assert(stream_read(file_stream, &last_char, 1) == 1, "read == true assert failed\r\n");
|
||||||
|
mu_assert(last_char == '\n', "last_char == '\\n' assert failed\r\n");
|
||||||
|
mu_assert(file_stream_close(file_stream), "file_stream_close == true assert failed\r\n");
|
||||||
|
|
||||||
|
// Delete unit test dict file
|
||||||
|
mu_assert(
|
||||||
|
storage_simply_remove(storage, NFC_TEST_DICT_PATH), "remove == true assert failed\r\n");
|
||||||
|
stream_free(file_stream);
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
}
|
||||||
|
|
||||||
MU_TEST_SUITE(nfc) {
|
MU_TEST_SUITE(nfc) {
|
||||||
nfc_test_alloc();
|
nfc_test_alloc();
|
||||||
|
|
||||||
MU_RUN_TEST(nfc_digital_signal_test);
|
MU_RUN_TEST(nfc_digital_signal_test);
|
||||||
MU_RUN_TEST(mf_classic_dict_test);
|
MU_RUN_TEST(mf_classic_dict_test);
|
||||||
|
MU_RUN_TEST(mf_classic_dict_load_test);
|
||||||
|
|
||||||
nfc_test_free();
|
nfc_test_free();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#include <lib/subghz/transmitter.h>
|
#include <lib/subghz/transmitter.h>
|
||||||
#include <lib/subghz/subghz_keystore.h>
|
#include <lib/subghz/subghz_keystore.h>
|
||||||
#include <lib/subghz/subghz_file_encoder_worker.h>
|
#include <lib/subghz/subghz_file_encoder_worker.h>
|
||||||
#include <lib/subghz/protocols/registry.h>
|
#include <lib/subghz/protocols/protocol_items.h>
|
||||||
#include <flipper_format/flipper_format_i.h>
|
#include <flipper_format/flipper_format_i.h>
|
||||||
|
|
||||||
#define TAG "SubGhz TEST"
|
#define TAG "SubGhz TEST"
|
||||||
@ -13,7 +13,7 @@
|
|||||||
#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
|
#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
|
||||||
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
|
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
|
||||||
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
|
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
|
||||||
#define TEST_RANDOM_COUNT_PARSE 233
|
#define TEST_RANDOM_COUNT_PARSE 232
|
||||||
#define TEST_TIMEOUT 10000
|
#define TEST_TIMEOUT 10000
|
||||||
|
|
||||||
static SubGhzEnvironment* environment_handler;
|
static SubGhzEnvironment* environment_handler;
|
||||||
@ -43,6 +43,8 @@ static void subghz_test_init(void) {
|
|||||||
environment_handler, CAME_ATOMO_DIR_NAME);
|
environment_handler, CAME_ATOMO_DIR_NAME);
|
||||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||||
environment_handler, NICE_FLOR_S_DIR_NAME);
|
environment_handler, NICE_FLOR_S_DIR_NAME);
|
||||||
|
subghz_environment_set_protocol_registry(
|
||||||
|
environment_handler, (void*)&subghz_protocol_registry);
|
||||||
|
|
||||||
receiver_handler = subghz_receiver_alloc_init(environment_handler);
|
receiver_handler = subghz_receiver_alloc_init(environment_handler);
|
||||||
subghz_receiver_set_filter(receiver_handler, SubGhzProtocolFlag_Decodable);
|
subghz_receiver_set_filter(receiver_handler, SubGhzProtocolFlag_Decodable);
|
||||||
@ -413,11 +415,11 @@ MU_TEST(subghz_decoder_honeywell_wdb_test) {
|
|||||||
"Test decoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
|
"Test decoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(subghz_decoder_magellen_test) {
|
MU_TEST(subghz_decoder_magellan_test) {
|
||||||
mu_assert(
|
mu_assert(
|
||||||
subghz_decoder_test(
|
subghz_decoder_test(
|
||||||
EXT_PATH("unit_tests/subghz/magellen_raw.sub"), SUBGHZ_PROTOCOL_MAGELLEN_NAME),
|
EXT_PATH("unit_tests/subghz/magellan_raw.sub"), SUBGHZ_PROTOCOL_MAGELLAN_NAME),
|
||||||
"Test decoder " SUBGHZ_PROTOCOL_MAGELLEN_NAME " error\r\n");
|
"Test decoder " SUBGHZ_PROTOCOL_MAGELLAN_NAME " error\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(subghz_decoder_intertechno_v3_test) {
|
MU_TEST(subghz_decoder_intertechno_v3_test) {
|
||||||
@ -435,13 +437,6 @@ MU_TEST(subghz_decoder_clemsa_test) {
|
|||||||
"Test decoder " SUBGHZ_PROTOCOL_CLEMSA_NAME " error\r\n");
|
"Test decoder " SUBGHZ_PROTOCOL_CLEMSA_NAME " error\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(subghz_decoder_oregon2_test) {
|
|
||||||
mu_assert(
|
|
||||||
subghz_decoder_test(
|
|
||||||
EXT_PATH("unit_tests/subghz/oregon2_raw.sub"), SUBGHZ_PROTOCOL_OREGON2_NAME),
|
|
||||||
"Test decoder " SUBGHZ_PROTOCOL_OREGON2_NAME " error\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//test encoders
|
//test encoders
|
||||||
MU_TEST(subghz_encoder_princeton_test) {
|
MU_TEST(subghz_encoder_princeton_test) {
|
||||||
mu_assert(
|
mu_assert(
|
||||||
@ -545,10 +540,10 @@ MU_TEST(subghz_encoder_honeywell_wdb_test) {
|
|||||||
"Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
|
"Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(subghz_encoder_magellen_test) {
|
MU_TEST(subghz_encoder_magellan_test) {
|
||||||
mu_assert(
|
mu_assert(
|
||||||
subghz_encoder_test(EXT_PATH("unit_tests/subghz/magellen.sub")),
|
subghz_encoder_test(EXT_PATH("unit_tests/subghz/magellan.sub")),
|
||||||
"Test encoder " SUBGHZ_PROTOCOL_MAGELLEN_NAME " error\r\n");
|
"Test encoder " SUBGHZ_PROTOCOL_MAGELLAN_NAME " error\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(subghz_encoder_intertechno_v3_test) {
|
MU_TEST(subghz_encoder_intertechno_v3_test) {
|
||||||
@ -600,10 +595,9 @@ MU_TEST_SUITE(subghz) {
|
|||||||
MU_RUN_TEST(subghz_decoder_doitrand_test);
|
MU_RUN_TEST(subghz_decoder_doitrand_test);
|
||||||
MU_RUN_TEST(subghz_decoder_phoenix_v2_test);
|
MU_RUN_TEST(subghz_decoder_phoenix_v2_test);
|
||||||
MU_RUN_TEST(subghz_decoder_honeywell_wdb_test);
|
MU_RUN_TEST(subghz_decoder_honeywell_wdb_test);
|
||||||
MU_RUN_TEST(subghz_decoder_magellen_test);
|
MU_RUN_TEST(subghz_decoder_magellan_test);
|
||||||
MU_RUN_TEST(subghz_decoder_intertechno_v3_test);
|
MU_RUN_TEST(subghz_decoder_intertechno_v3_test);
|
||||||
MU_RUN_TEST(subghz_decoder_clemsa_test);
|
MU_RUN_TEST(subghz_decoder_clemsa_test);
|
||||||
MU_RUN_TEST(subghz_decoder_oregon2_test);
|
|
||||||
|
|
||||||
MU_RUN_TEST(subghz_encoder_princeton_test);
|
MU_RUN_TEST(subghz_encoder_princeton_test);
|
||||||
MU_RUN_TEST(subghz_encoder_came_test);
|
MU_RUN_TEST(subghz_encoder_came_test);
|
||||||
@ -622,7 +616,7 @@ MU_TEST_SUITE(subghz) {
|
|||||||
MU_RUN_TEST(subghz_encoder_doitrand_test);
|
MU_RUN_TEST(subghz_encoder_doitrand_test);
|
||||||
MU_RUN_TEST(subghz_encoder_phoenix_v2_test);
|
MU_RUN_TEST(subghz_encoder_phoenix_v2_test);
|
||||||
MU_RUN_TEST(subghz_encoder_honeywell_wdb_test);
|
MU_RUN_TEST(subghz_encoder_honeywell_wdb_test);
|
||||||
MU_RUN_TEST(subghz_encoder_magellen_test);
|
MU_RUN_TEST(subghz_encoder_magellan_test);
|
||||||
MU_RUN_TEST(subghz_encoder_intertechno_v3_test);
|
MU_RUN_TEST(subghz_encoder_intertechno_v3_test);
|
||||||
MU_RUN_TEST(subghz_encoder_clemsa_test);
|
MU_RUN_TEST(subghz_encoder_clemsa_test);
|
||||||
|
|
||||||
|
|||||||
24
applications/examples/example_images/ReadMe.md
Normal file
24
applications/examples/example_images/ReadMe.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Application icons
|
||||||
|
To use icons, do the following:
|
||||||
|
* add a line to the application manifest: `fap_icon_assets="folder"`, where `folder` points to the folder where your icons are located
|
||||||
|
* add `#include "application_id_icons.h"` to the application code, where `application_id` is the appid from the manifest
|
||||||
|
* every icon in the folder will be available as a `I_icon_name` variable, where `icon_name` is the name of the icon file without the extension
|
||||||
|
|
||||||
|
## Example
|
||||||
|
We have an application with the following manifest:
|
||||||
|
```
|
||||||
|
App(
|
||||||
|
appid="example_images",
|
||||||
|
...
|
||||||
|
fap_icon_assets="images",
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
So the icons are in the `images` folder and will be available in the generated `example_images_icons.h` file.
|
||||||
|
|
||||||
|
The example code is located in `example_images_main.c` and contains the following line:
|
||||||
|
```
|
||||||
|
#include "example_images_icons.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
Image `dolphin_71x25.png` is available as `I_dolphin_71x25`.
|
||||||
@ -5,6 +5,7 @@
|
|||||||
#include "bad_usb_script.h"
|
#include "bad_usb_script.h"
|
||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
#include <gui/modules/submenu.h>
|
#include <gui/modules/submenu.h>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "bad_usb_view.h"
|
#include "bad_usb_view.h"
|
||||||
#include "../bad_usb_script.h"
|
#include "../bad_usb_script.h"
|
||||||
#include <gui/elements.h>
|
#include <gui/elements.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
|
|
||||||
#define MAX_NAME_LEN 64
|
#define MAX_NAME_LEN 64
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
#include <gui/modules/loading.h>
|
#include <gui/modules/loading.h>
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include <gui/modules/widget.h>
|
#include <gui/modules/widget.h>
|
||||||
#include "views/gpio_test.h"
|
#include "views/gpio_test.h"
|
||||||
#include "views/gpio_usb_uart.h"
|
#include "views/gpio_usb_uart.h"
|
||||||
|
#include <assets_icons.h>
|
||||||
|
|
||||||
struct GpioApp {
|
struct GpioApp {
|
||||||
Gui* gui;
|
Gui* gui;
|
||||||
@ -24,6 +25,7 @@ struct GpioApp {
|
|||||||
Widget* widget;
|
Widget* widget;
|
||||||
|
|
||||||
VariableItemList* var_item_list;
|
VariableItemList* var_item_list;
|
||||||
|
VariableItem* var_item_flow;
|
||||||
GpioTest* gpio_test;
|
GpioTest* gpio_test;
|
||||||
GpioUsbUart* gpio_usb_uart;
|
GpioUsbUart* gpio_usb_uart;
|
||||||
UsbUartBridge* usb_uart_bridge;
|
UsbUartBridge* usb_uart_bridge;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ static UsbUartConfig* cfg_set;
|
|||||||
|
|
||||||
static const char* vcp_ch[] = {"0 (CLI)", "1"};
|
static const char* vcp_ch[] = {"0 (CLI)", "1"};
|
||||||
static const char* uart_ch[] = {"13,14", "15,16"};
|
static const char* uart_ch[] = {"13,14", "15,16"};
|
||||||
static const char* flow_pins[] = {"None", "2,3", "6,7"};
|
static const char* flow_pins[] = {"None", "2,3", "6,7", "16,15"};
|
||||||
static const char* baudrate_mode[] = {"Host"};
|
static const char* baudrate_mode[] = {"Host"};
|
||||||
static const uint32_t baudrate_list[] = {
|
static const uint32_t baudrate_list[] = {
|
||||||
2400,
|
2400,
|
||||||
@ -33,6 +33,24 @@ bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void line_ensure_flow_invariant(GpioApp* app) {
|
||||||
|
// GPIO pins PC0, PC1 (16,15) are unavailable for RTS/DTR when LPUART is
|
||||||
|
// selected. This function enforces that invariant by resetting flow_pins
|
||||||
|
// to None if it is configured to 16,15 when LPUART is selected.
|
||||||
|
|
||||||
|
uint8_t available_flow_pins = cfg_set->uart_ch == FuriHalUartIdLPUART1 ? 3 : 4;
|
||||||
|
VariableItem* item = app->var_item_flow;
|
||||||
|
variable_item_set_values_count(item, available_flow_pins);
|
||||||
|
|
||||||
|
if(cfg_set->flow_pins >= available_flow_pins) {
|
||||||
|
cfg_set->flow_pins = 0;
|
||||||
|
usb_uart_set_config(app->usb_uart_bridge, cfg_set);
|
||||||
|
|
||||||
|
variable_item_set_current_value_index(item, cfg_set->flow_pins);
|
||||||
|
variable_item_set_current_value_text(item, flow_pins[cfg_set->flow_pins]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void line_vcp_cb(VariableItem* item) {
|
static void line_vcp_cb(VariableItem* item) {
|
||||||
GpioApp* app = variable_item_get_context(item);
|
GpioApp* app = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
@ -54,6 +72,7 @@ static void line_port_cb(VariableItem* item) {
|
|||||||
else if(index == 1)
|
else if(index == 1)
|
||||||
cfg_set->uart_ch = FuriHalUartIdLPUART1;
|
cfg_set->uart_ch = FuriHalUartIdLPUART1;
|
||||||
usb_uart_set_config(app->usb_uart_bridge, cfg_set);
|
usb_uart_set_config(app->usb_uart_bridge, cfg_set);
|
||||||
|
line_ensure_flow_invariant(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void line_flow_cb(VariableItem* item) {
|
static void line_flow_cb(VariableItem* item) {
|
||||||
@ -116,9 +135,12 @@ void gpio_scene_usb_uart_cfg_on_enter(void* context) {
|
|||||||
variable_item_set_current_value_index(item, cfg_set->uart_ch);
|
variable_item_set_current_value_index(item, cfg_set->uart_ch);
|
||||||
variable_item_set_current_value_text(item, uart_ch[cfg_set->uart_ch]);
|
variable_item_set_current_value_text(item, uart_ch[cfg_set->uart_ch]);
|
||||||
|
|
||||||
item = variable_item_list_add(var_item_list, "RTS/DTR Pins", 3, line_flow_cb, app);
|
item = variable_item_list_add(
|
||||||
|
var_item_list, "RTS/DTR Pins", COUNT_OF(flow_pins), line_flow_cb, app);
|
||||||
variable_item_set_current_value_index(item, cfg_set->flow_pins);
|
variable_item_set_current_value_index(item, cfg_set->flow_pins);
|
||||||
variable_item_set_current_value_text(item, flow_pins[cfg_set->flow_pins]);
|
variable_item_set_current_value_text(item, flow_pins[cfg_set->flow_pins]);
|
||||||
|
app->var_item_flow = item;
|
||||||
|
line_ensure_flow_invariant(app);
|
||||||
|
|
||||||
variable_item_list_set_selected_item(
|
variable_item_list_set_selected_item(
|
||||||
var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg));
|
var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg));
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
static const GpioPin* flow_pins[][2] = {
|
static const GpioPin* flow_pins[][2] = {
|
||||||
{&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3
|
{&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3
|
||||||
{&gpio_ext_pb2, &gpio_ext_pc3}, // 6, 7
|
{&gpio_ext_pb2, &gpio_ext_pc3}, // 6, 7
|
||||||
|
{&gpio_ext_pc0, &gpio_ext_pc1}, // 16, 15
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
#include <flipper_format/flipper_format.h>
|
#include <flipper_format/flipper_format.h>
|
||||||
#include <rpc/rpc_app.h>
|
#include <rpc/rpc_app.h>
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
#define TAG "iButtonApp"
|
#define TAG "iButtonApp"
|
||||||
|
|
||||||
@ -337,11 +338,13 @@ int32_t ibutton_app(void* p) {
|
|||||||
view_dispatcher_attach_to_gui(
|
view_dispatcher_attach_to_gui(
|
||||||
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeDesktop);
|
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeDesktop);
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
|
||||||
} else {
|
} else {
|
||||||
view_dispatcher_attach_to_gui(
|
view_dispatcher_attach_to_gui(
|
||||||
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
|
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
|
||||||
if(key_loaded) {
|
if(key_loaded) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
|
||||||
} else {
|
} else {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
|
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void ibutton_scene_add_type_byte_input_callback(void* context) {
|
void ibutton_scene_add_type_byte_input_callback(void* context) {
|
||||||
iButton* ibutton = context;
|
iButton* ibutton = context;
|
||||||
view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventByteEditResult);
|
view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventByteEditResult);
|
||||||
@ -38,7 +36,6 @@ bool ibutton_scene_add_value_on_event(void* context, SceneManagerEvent event) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
if(event.event == iButtonCustomEventByteEditResult) {
|
if(event.event == iButtonCustomEventByteEditResult) {
|
||||||
ibutton_key_set_data(ibutton->key, new_key_data, IBUTTON_KEY_DATA_SIZE);
|
ibutton_key_set_data(ibutton->key, new_key_data, IBUTTON_KEY_DATA_SIZE);
|
||||||
DOLPHIN_DEED(DolphinDeedIbuttonAdd);
|
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
#include <core/log.h>
|
#include <core/log.h>
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
|
|
||||||
#define EMULATE_TIMEOUT_TICKS 10
|
#define EMULATE_TIMEOUT_TICKS 10
|
||||||
@ -26,8 +25,6 @@ void ibutton_scene_emulate_on_enter(void* context) {
|
|||||||
path_extract_filename(ibutton->file_path, key_name, true);
|
path_extract_filename(ibutton->file_path, key_name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
|
|
||||||
|
|
||||||
// check that stored key has name
|
// check that stored key has name
|
||||||
if(!furi_string_empty(key_name)) {
|
if(!furi_string_empty(key_name)) {
|
||||||
ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));
|
ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name));
|
||||||
|
|||||||
@ -11,7 +11,6 @@ void ibutton_scene_read_on_enter(void* context) {
|
|||||||
Popup* popup = ibutton->popup;
|
Popup* popup = ibutton->popup;
|
||||||
iButtonKey* key = ibutton->key;
|
iButtonKey* key = ibutton->key;
|
||||||
iButtonWorker* worker = ibutton->key_worker;
|
iButtonWorker* worker = ibutton->key_worker;
|
||||||
DOLPHIN_DEED(DolphinDeedIbuttonRead);
|
|
||||||
|
|
||||||
popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
|
popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
|
||||||
popup_set_text(popup, "Waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
|
popup_set_text(popup, "Waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
|
||||||
@ -54,8 +53,8 @@ bool ibutton_scene_read_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(success) {
|
if(success) {
|
||||||
ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess);
|
ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess);
|
||||||
ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn);
|
ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn);
|
||||||
DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess);
|
|
||||||
scene_manager_next_scene(scene_manager, iButtonSceneReadSuccess);
|
scene_manager_next_scene(scene_manager, iButtonSceneReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SubmenuIndexSave,
|
SubmenuIndexSave,
|
||||||
@ -49,6 +50,7 @@ bool ibutton_scene_read_key_menu_on_event(void* context, SceneManagerEvent event
|
|||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName);
|
||||||
} else if(event.event == SubmenuIndexEmulate) {
|
} else if(event.event == SubmenuIndexEmulate) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
|
||||||
} else if(event.event == SubmenuIndexWrite) {
|
} else if(event.event == SubmenuIndexWrite) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
#include <lib/toolbox/random_name.h>
|
#include <lib/toolbox/random_name.h>
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
static void ibutton_scene_save_name_text_input_callback(void* context) {
|
static void ibutton_scene_save_name_text_input_callback(void* context) {
|
||||||
iButton* ibutton = context;
|
iButton* ibutton = context;
|
||||||
@ -57,6 +58,15 @@ bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(event.event == iButtonCustomEventTextEditResult) {
|
if(event.event == iButtonCustomEventTextEditResult) {
|
||||||
if(ibutton_save_key(ibutton, ibutton->text_store)) {
|
if(ibutton_save_key(ibutton, ibutton->text_store)) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess);
|
||||||
|
if(scene_manager_has_previous_scene(
|
||||||
|
ibutton->scene_manager, iButtonSceneSavedKeyMenu)) {
|
||||||
|
// Nothing, do not count editing as saving
|
||||||
|
} else if(scene_manager_has_previous_scene(
|
||||||
|
ibutton->scene_manager, iButtonSceneAddType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonAdd);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonSave);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const uint32_t possible_scenes[] = {
|
const uint32_t possible_scenes[] = {
|
||||||
iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType};
|
iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType};
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
static void ibutton_scene_save_success_popup_callback(void* context) {
|
static void ibutton_scene_save_success_popup_callback(void* context) {
|
||||||
iButton* ibutton = context;
|
iButton* ibutton = context;
|
||||||
@ -9,7 +8,6 @@ static void ibutton_scene_save_success_popup_callback(void* context) {
|
|||||||
void ibutton_scene_save_success_on_enter(void* context) {
|
void ibutton_scene_save_success_on_enter(void* context) {
|
||||||
iButton* ibutton = context;
|
iButton* ibutton = context;
|
||||||
Popup* popup = ibutton->popup;
|
Popup* popup = ibutton->popup;
|
||||||
DOLPHIN_DEED(DolphinDeedIbuttonSave);
|
|
||||||
|
|
||||||
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||||
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexEmulate,
|
SubmenuIndexEmulate,
|
||||||
@ -58,6 +59,7 @@ bool ibutton_scene_saved_key_menu_on_event(void* context, SceneManagerEvent even
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
if(event.event == SubmenuIndexEmulate) {
|
if(event.event == SubmenuIndexEmulate) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
|
||||||
} else if(event.event == SubmenuIndexWrite) {
|
} else if(event.event == SubmenuIndexWrite) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneWrite);
|
||||||
} else if(event.event == SubmenuIndexEdit) {
|
} else if(event.event == SubmenuIndexEdit) {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
#include "ibutton/scenes/ibutton_scene.h"
|
#include "ibutton/scenes/ibutton_scene.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexRead,
|
SubmenuIndexRead,
|
||||||
@ -38,6 +39,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
if(event.event == SubmenuIndexRead) {
|
if(event.event == SubmenuIndexRead) {
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIbuttonRead);
|
||||||
} else if(event.event == SubmenuIndexSaved) {
|
} else if(event.event == SubmenuIndexSaved) {
|
||||||
furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER);
|
furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER);
|
||||||
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey);
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey);
|
||||||
|
|||||||
@ -1,17 +1,25 @@
|
|||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
|
#include <cli/cli_i.h>
|
||||||
#include <infrared.h>
|
#include <infrared.h>
|
||||||
#include <infrared_worker.h>
|
#include <infrared_worker.h>
|
||||||
#include <furi_hal_infrared.h>
|
#include <furi_hal_infrared.h>
|
||||||
#include <flipper_format.h>
|
#include <flipper_format.h>
|
||||||
#include <toolbox/args.h>
|
#include <toolbox/args.h>
|
||||||
|
#include <m-dict.h>
|
||||||
|
|
||||||
#include "infrared_signal.h"
|
#include "infrared_signal.h"
|
||||||
|
#include "infrared_brute_force.h"
|
||||||
|
|
||||||
#define INFRARED_CLI_BUF_SIZE 10
|
#define INFRARED_CLI_BUF_SIZE 10
|
||||||
|
#define INFRARED_ASSETS_FOLDER "infrared/assets"
|
||||||
|
#define INFRARED_BRUTE_FORCE_DUMMY_INDEX 0
|
||||||
|
|
||||||
|
DICT_DEF2(dict_signals, FuriString*, FURI_STRING_OPLIST, int, M_DEFAULT_OPLIST)
|
||||||
|
|
||||||
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args);
|
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args);
|
||||||
static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args);
|
static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args);
|
||||||
static void infrared_cli_process_decode(Cli* cli, FuriString* args);
|
static void infrared_cli_process_decode(Cli* cli, FuriString* args);
|
||||||
|
static void infrared_cli_process_universal(Cli* cli, FuriString* args);
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char* cmd;
|
const char* cmd;
|
||||||
@ -20,6 +28,7 @@ static const struct {
|
|||||||
{.cmd = "rx", .process_function = infrared_cli_start_ir_rx},
|
{.cmd = "rx", .process_function = infrared_cli_start_ir_rx},
|
||||||
{.cmd = "tx", .process_function = infrared_cli_start_ir_tx},
|
{.cmd = "tx", .process_function = infrared_cli_start_ir_tx},
|
||||||
{.cmd = "decode", .process_function = infrared_cli_process_decode},
|
{.cmd = "decode", .process_function = infrared_cli_process_decode},
|
||||||
|
{.cmd = "universal", .process_function = infrared_cli_process_universal},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void signal_received_callback(void* context, InfraredWorkerSignal* received_signal) {
|
static void signal_received_callback(void* context, InfraredWorkerSignal* received_signal) {
|
||||||
@ -57,25 +66,9 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(cli);
|
|
||||||
UNUSED(args);
|
|
||||||
InfraredWorker* worker = infrared_worker_alloc();
|
|
||||||
infrared_worker_rx_start(worker);
|
|
||||||
infrared_worker_rx_set_received_signal_callback(worker, signal_received_callback, cli);
|
|
||||||
|
|
||||||
printf("Receiving INFRARED...\r\nPress Ctrl+C to abort\r\n");
|
|
||||||
while(!cli_cmd_interrupt_received(cli)) {
|
|
||||||
furi_delay_ms(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
infrared_worker_rx_stop(worker);
|
|
||||||
infrared_worker_free(worker);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void infrared_cli_print_usage(void) {
|
static void infrared_cli_print_usage(void) {
|
||||||
printf("Usage:\r\n");
|
printf("Usage:\r\n");
|
||||||
printf("\tir rx\r\n");
|
printf("\tir rx [raw]\r\n");
|
||||||
printf("\tir tx <protocol> <address> <command>\r\n");
|
printf("\tir tx <protocol> <address> <command>\r\n");
|
||||||
printf("\t<command> and <address> are hex-formatted\r\n");
|
printf("\t<command> and <address> are hex-formatted\r\n");
|
||||||
printf("\tAvailable protocols:");
|
printf("\tAvailable protocols:");
|
||||||
@ -90,6 +83,39 @@ static void infrared_cli_print_usage(void) {
|
|||||||
INFRARED_MIN_FREQUENCY,
|
INFRARED_MIN_FREQUENCY,
|
||||||
INFRARED_MAX_FREQUENCY);
|
INFRARED_MAX_FREQUENCY);
|
||||||
printf("\tir decode <input_file> [<output_file>]\r\n");
|
printf("\tir decode <input_file> [<output_file>]\r\n");
|
||||||
|
printf("\tir universal <remote_name> <signal_name>\r\n");
|
||||||
|
printf("\tir universal list <remote_name>\r\n");
|
||||||
|
// TODO: Do not hardcode universal remote names
|
||||||
|
printf("\tAvailable universal remotes: tv audio ac\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args) {
|
||||||
|
UNUSED(cli);
|
||||||
|
|
||||||
|
bool enable_decoding = true;
|
||||||
|
|
||||||
|
if(!furi_string_empty(args)) {
|
||||||
|
if(!furi_string_cmp_str(args, "raw")) {
|
||||||
|
enable_decoding = false;
|
||||||
|
} else {
|
||||||
|
printf("Wrong arguments.\r\n");
|
||||||
|
infrared_cli_print_usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InfraredWorker* worker = infrared_worker_alloc();
|
||||||
|
infrared_worker_rx_enable_signal_decoding(worker, enable_decoding);
|
||||||
|
infrared_worker_rx_start(worker);
|
||||||
|
infrared_worker_rx_set_received_signal_callback(worker, signal_received_callback, cli);
|
||||||
|
|
||||||
|
printf("Receiving %s INFRARED...\r\nPress Ctrl+C to abort\r\n", enable_decoding ? "" : "RAW");
|
||||||
|
while(!cli_cmd_interrupt_received(cli)) {
|
||||||
|
furi_delay_ms(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
infrared_worker_rx_stop(worker);
|
||||||
|
infrared_worker_free(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool infrared_cli_parse_message(const char* str, InfraredSignal* signal) {
|
static bool infrared_cli_parse_message(const char* str, InfraredSignal* signal) {
|
||||||
@ -328,6 +354,131 @@ static void infrared_cli_process_decode(Cli* cli, FuriString* args) {
|
|||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void infrared_cli_list_remote_signals(FuriString* remote_name) {
|
||||||
|
if(furi_string_empty(remote_name)) {
|
||||||
|
printf("Missing remote name.\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
FlipperFormat* ff = flipper_format_buffered_file_alloc(storage);
|
||||||
|
FuriString* remote_path = furi_string_alloc_printf(
|
||||||
|
"%s/%s.ir", EXT_PATH(INFRARED_ASSETS_FOLDER), furi_string_get_cstr(remote_name));
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(remote_path))) {
|
||||||
|
printf("Invalid remote name.\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dict_signals_t signals_dict;
|
||||||
|
dict_signals_init(signals_dict);
|
||||||
|
|
||||||
|
FuriString* key = furi_string_alloc();
|
||||||
|
FuriString* signal_name = furi_string_alloc();
|
||||||
|
|
||||||
|
printf("Valid signals:\r\n");
|
||||||
|
int max = 1;
|
||||||
|
while(flipper_format_read_string(ff, "name", signal_name)) {
|
||||||
|
furi_string_set_str(key, furi_string_get_cstr(signal_name));
|
||||||
|
int* v = dict_signals_get(signals_dict, key);
|
||||||
|
if(v != NULL) {
|
||||||
|
(*v)++;
|
||||||
|
max = M_MAX(*v, max);
|
||||||
|
} else {
|
||||||
|
dict_signals_set_at(signals_dict, key, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dict_signals_it_t it;
|
||||||
|
for(dict_signals_it(it, signals_dict); !dict_signals_end_p(it); dict_signals_next(it)) {
|
||||||
|
const struct dict_signals_pair_s* pair = dict_signals_cref(it);
|
||||||
|
printf("\t%s\r\n", furi_string_get_cstr(pair->key));
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_string_free(key);
|
||||||
|
furi_string_free(signal_name);
|
||||||
|
dict_signals_clear(signals_dict);
|
||||||
|
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
flipper_format_free(ff);
|
||||||
|
furi_string_free(remote_path);
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
infrared_cli_brute_force_signals(Cli* cli, FuriString* remote_name, FuriString* signal_name) {
|
||||||
|
InfraredBruteForce* brute_force = infrared_brute_force_alloc();
|
||||||
|
FuriString* remote_path = furi_string_alloc_printf(
|
||||||
|
"%s/%s.ir", EXT_PATH(INFRARED_ASSETS_FOLDER), furi_string_get_cstr(remote_name));
|
||||||
|
|
||||||
|
infrared_brute_force_set_db_filename(brute_force, furi_string_get_cstr(remote_path));
|
||||||
|
infrared_brute_force_add_record(
|
||||||
|
brute_force, INFRARED_BRUTE_FORCE_DUMMY_INDEX, furi_string_get_cstr(signal_name));
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(furi_string_empty(signal_name)) {
|
||||||
|
printf("Missing signal name.\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!infrared_brute_force_calculate_messages(brute_force)) {
|
||||||
|
printf("Invalid remote name.\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t record_count;
|
||||||
|
bool running = infrared_brute_force_start(
|
||||||
|
brute_force, INFRARED_BRUTE_FORCE_DUMMY_INDEX, &record_count);
|
||||||
|
|
||||||
|
if(record_count <= 0) {
|
||||||
|
printf("Invalid signal name.\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Sending %ld signal(s)...\r\n", record_count);
|
||||||
|
printf("Press Ctrl-C to stop.\r\n");
|
||||||
|
|
||||||
|
int records_sent = 0;
|
||||||
|
while(running) {
|
||||||
|
running = infrared_brute_force_send_next(brute_force);
|
||||||
|
|
||||||
|
if(cli_cmd_interrupt_received(cli)) break;
|
||||||
|
|
||||||
|
printf("\r%d%% complete.", (int)((float)records_sent++ / (float)record_count * 100));
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
infrared_brute_force_stop(brute_force);
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
furi_string_free(remote_path);
|
||||||
|
infrared_brute_force_reset(brute_force);
|
||||||
|
infrared_brute_force_free(brute_force);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void infrared_cli_process_universal(Cli* cli, FuriString* args) {
|
||||||
|
FuriString* arg1 = furi_string_alloc();
|
||||||
|
FuriString* arg2 = furi_string_alloc();
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!args_read_string_and_trim(args, arg1)) break;
|
||||||
|
if(!args_read_string_and_trim(args, arg2)) break;
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
if(furi_string_empty(arg1)) {
|
||||||
|
printf("Wrong arguments.\r\n");
|
||||||
|
infrared_cli_print_usage();
|
||||||
|
} else if(furi_string_equal_str(arg1, "list")) {
|
||||||
|
infrared_cli_list_remote_signals(arg2);
|
||||||
|
} else {
|
||||||
|
infrared_cli_brute_force_signals(cli, arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_string_free(arg1);
|
||||||
|
furi_string_free(arg2);
|
||||||
|
}
|
||||||
|
|
||||||
static void infrared_cli_start_ir(Cli* cli, FuriString* args, void* context) {
|
static void infrared_cli_start_ir(Cli* cli, FuriString* args, void* context) {
|
||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
if(furi_hal_infrared_is_busy()) {
|
if(furi_hal_infrared_is_busy()) {
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/view_stack.h>
|
#include <gui/view_stack.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ ADD_SCENE(infrared, remote_list, RemoteList)
|
|||||||
ADD_SCENE(infrared, universal, Universal)
|
ADD_SCENE(infrared, universal, Universal)
|
||||||
ADD_SCENE(infrared, universal_tv, UniversalTV)
|
ADD_SCENE(infrared, universal_tv, UniversalTV)
|
||||||
ADD_SCENE(infrared, universal_ac, UniversalAC)
|
ADD_SCENE(infrared, universal_ac, UniversalAC)
|
||||||
|
ADD_SCENE(infrared, universal_audio, UniversalAudio)
|
||||||
ADD_SCENE(infrared, debug, Debug)
|
ADD_SCENE(infrared, debug, Debug)
|
||||||
ADD_SCENE(infrared, error_databases, ErrorDatabases)
|
ADD_SCENE(infrared, error_databases, ErrorDatabases)
|
||||||
ADD_SCENE(infrared, rpc, Rpc)
|
ADD_SCENE(infrared, rpc, Rpc)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../infrared_i.h"
|
#include "../infrared_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
void infrared_scene_learn_on_enter(void* context) {
|
void infrared_scene_learn_on_enter(void* context) {
|
||||||
Infrared* infrared = context;
|
Infrared* infrared = context;
|
||||||
@ -27,6 +28,7 @@ bool infrared_scene_learn_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(event.event == InfraredCustomEventTypeSignalReceived) {
|
if(event.event == InfraredCustomEventTypeSignalReceived) {
|
||||||
infrared_play_notification_message(infrared, InfraredNotificationMessageSuccess);
|
infrared_play_notification_message(infrared, InfraredNotificationMessageSuccess);
|
||||||
scene_manager_next_scene(infrared->scene_manager, InfraredSceneLearnSuccess);
|
scene_manager_next_scene(infrared->scene_manager, InfraredSceneLearnSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
#include "../infrared_i.h"
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void infrared_scene_learn_done_on_enter(void* context) {
|
void infrared_scene_learn_done_on_enter(void* context) {
|
||||||
Infrared* infrared = context;
|
Infrared* infrared = context;
|
||||||
Popup* popup = infrared->popup;
|
Popup* popup = infrared->popup;
|
||||||
|
|
||||||
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||||
DOLPHIN_DEED(DolphinDeedIrSave);
|
|
||||||
|
|
||||||
if(infrared->app_state.is_learning_new_remote) {
|
if(infrared->app_state.is_learning_new_remote) {
|
||||||
popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop);
|
popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../infrared_i.h"
|
#include "../infrared_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
void infrared_scene_learn_enter_name_on_enter(void* context) {
|
void infrared_scene_learn_enter_name_on_enter(void* context) {
|
||||||
Infrared* infrared = context;
|
Infrared* infrared = context;
|
||||||
@ -49,6 +50,7 @@ bool infrared_scene_learn_enter_name_on_event(void* context, SceneManagerEvent e
|
|||||||
|
|
||||||
if(success) {
|
if(success) {
|
||||||
scene_manager_next_scene(scene_manager, InfraredSceneLearnDone);
|
scene_manager_next_scene(scene_manager, InfraredSceneLearnDone);
|
||||||
|
DOLPHIN_DEED(DolphinDeedIrSave);
|
||||||
} else {
|
} else {
|
||||||
dialog_message_show_storage_error(infrared->dialogs, "Failed to save file");
|
dialog_message_show_storage_error(infrared->dialogs, "Failed to save file");
|
||||||
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
|
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
#include "../infrared_i.h"
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) {
|
infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) {
|
||||||
Infrared* infrared = context;
|
Infrared* infrared = context;
|
||||||
@ -13,7 +11,6 @@ void infrared_scene_learn_success_on_enter(void* context) {
|
|||||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||||
InfraredSignal* signal = infrared->received_signal;
|
InfraredSignal* signal = infrared->received_signal;
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
|
|
||||||
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
|
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
|
||||||
|
|
||||||
if(infrared_signal_is_raw(signal)) {
|
if(infrared_signal_is_raw(signal)) {
|
||||||
|
|||||||
@ -21,6 +21,12 @@ void infrared_scene_universal_on_enter(void* context) {
|
|||||||
SubmenuIndexUniversalTV,
|
SubmenuIndexUniversalTV,
|
||||||
infrared_scene_universal_submenu_callback,
|
infrared_scene_universal_submenu_callback,
|
||||||
context);
|
context);
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"Audio Players",
|
||||||
|
SubmenuIndexUniversalAudio,
|
||||||
|
infrared_scene_universal_submenu_callback,
|
||||||
|
context);
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
"Air Conditioners",
|
"Air Conditioners",
|
||||||
@ -45,7 +51,7 @@ bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) {
|
|||||||
scene_manager_next_scene(scene_manager, InfraredSceneUniversalAC);
|
scene_manager_next_scene(scene_manager, InfraredSceneUniversalAC);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexUniversalAudio) {
|
} else if(event.event == SubmenuIndexUniversalAudio) {
|
||||||
//TODO Implement Audio universal remote
|
scene_manager_next_scene(scene_manager, InfraredSceneUniversalAudio);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,133 @@
|
|||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
#include "common/infrared_scene_universal_common.h"
|
||||||
|
|
||||||
|
void infrared_scene_universal_audio_on_enter(void* context) {
|
||||||
|
infrared_scene_universal_common_on_enter(context);
|
||||||
|
|
||||||
|
Infrared* infrared = context;
|
||||||
|
ButtonPanel* button_panel = infrared->button_panel;
|
||||||
|
InfraredBruteForce* brute_force = infrared->brute_force;
|
||||||
|
|
||||||
|
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/audio.ir"));
|
||||||
|
|
||||||
|
button_panel_reserve(button_panel, 2, 4);
|
||||||
|
uint32_t i = 0;
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
3,
|
||||||
|
11,
|
||||||
|
&I_Power_25x27,
|
||||||
|
&I_Power_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Power");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
36,
|
||||||
|
11,
|
||||||
|
&I_Mute_25x27,
|
||||||
|
&I_Mute_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
41,
|
||||||
|
&I_Play_25x27,
|
||||||
|
&I_Play_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Play");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
36,
|
||||||
|
41,
|
||||||
|
&I_Pause_25x27,
|
||||||
|
&I_Pause_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
71,
|
||||||
|
&I_TrackPrev_25x27,
|
||||||
|
&I_TrackPrev_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Prev");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
36,
|
||||||
|
71,
|
||||||
|
&I_TrackNext_25x27,
|
||||||
|
&I_TrackNext_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Next");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
0,
|
||||||
|
3,
|
||||||
|
3,
|
||||||
|
101,
|
||||||
|
&I_Vol_down_25x27,
|
||||||
|
&I_Vol_down_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
36,
|
||||||
|
101,
|
||||||
|
&I_Vol_up_25x27,
|
||||||
|
&I_Vol_up_hvr_25x27,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
||||||
|
|
||||||
|
button_panel_add_label(button_panel, 1, 8, FontPrimary, "Mus. remote");
|
||||||
|
|
||||||
|
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||||
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
||||||
|
|
||||||
|
infrared_show_loading_popup(infrared, true);
|
||||||
|
bool success = infrared_brute_force_calculate_messages(brute_force);
|
||||||
|
infrared_show_loading_popup(infrared, false);
|
||||||
|
|
||||||
|
if(!success) {
|
||||||
|
scene_manager_next_scene(infrared->scene_manager, InfraredSceneErrorDatabases);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_scene_universal_audio_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
return infrared_scene_universal_common_on_event(context, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_scene_universal_audio_on_exit(void* context) {
|
||||||
|
infrared_scene_universal_common_on_exit(context);
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#include "lfrfid_i.h"
|
#include "lfrfid_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) {
|
static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -182,12 +183,14 @@ int32_t lfrfid_app(void* p) {
|
|||||||
view_dispatcher_attach_to_gui(
|
view_dispatcher_attach_to_gui(
|
||||||
app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop);
|
app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop);
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidEmulate);
|
||||||
} else {
|
} else {
|
||||||
furi_string_set(app->file_path, args);
|
furi_string_set(app->file_path, args);
|
||||||
lfrfid_load_key_data(app, app->file_path, true);
|
lfrfid_load_key_data(app, app->file_path, true);
|
||||||
view_dispatcher_attach_to_gui(
|
view_dispatcher_attach_to_gui(
|
||||||
app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidEmulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void lfrfid_scene_emulate_on_enter(void* context) {
|
void lfrfid_scene_emulate_on_enter(void* context) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
Popup* popup = app->popup;
|
Popup* popup = app->popup;
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedRfidEmulate);
|
|
||||||
|
|
||||||
popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop);
|
popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop);
|
||||||
if(!furi_string_empty(app->file_name)) {
|
if(!furi_string_empty(app->file_name)) {
|
||||||
popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);
|
popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SubmenuIndexASK,
|
SubmenuIndexASK,
|
||||||
@ -57,10 +58,12 @@ bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event)
|
|||||||
if(event.event == SubmenuIndexASK) {
|
if(event.event == SubmenuIndexASK) {
|
||||||
app->read_type = LFRFIDWorkerReadTypeASKOnly;
|
app->read_type = LFRFIDWorkerReadTypeASKOnly;
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidRead);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexPSK) {
|
} else if(event.event == SubmenuIndexPSK) {
|
||||||
app->read_type = LFRFIDWorkerReadTypePSKOnly;
|
app->read_type = LFRFIDWorkerReadTypePSKOnly;
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidRead);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexRAW) {
|
} else if(event.event == SubmenuIndexRAW) {
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ void lfrfid_scene_raw_info_on_enter(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||||
//string_clear(tmp_string);
|
//furi_string_free(tmp_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lfrfid_scene_raw_info_on_event(void* context, SceneManagerEvent event) {
|
bool lfrfid_scene_raw_info_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
|||||||
@ -46,7 +46,6 @@ static void
|
|||||||
void lfrfid_scene_read_on_enter(void* context) {
|
void lfrfid_scene_read_on_enter(void* context) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedRfidRead);
|
|
||||||
if(app->read_type == LFRFIDWorkerReadTypePSKOnly) {
|
if(app->read_type == LFRFIDWorkerReadTypePSKOnly) {
|
||||||
lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPskOnly);
|
lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPskOnly);
|
||||||
} else if(app->read_type == LFRFIDWorkerReadTypeASKOnly) {
|
} else if(app->read_type == LFRFIDWorkerReadTypeASKOnly) {
|
||||||
@ -79,10 +78,10 @@ bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == LfRfidEventReadDone) {
|
} else if(event.event == LfRfidEventReadDone) {
|
||||||
app->protocol_id = app->protocol_id_next;
|
app->protocol_id = app->protocol_id_next;
|
||||||
DOLPHIN_DEED(DolphinDeedRfidReadSuccess);
|
|
||||||
notification_message(app->notifications, &sequence_success);
|
notification_message(app->notifications, &sequence_success);
|
||||||
furi_string_reset(app->file_name);
|
furi_string_reset(app->file_name);
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == LfRfidEventReadStartPSK) {
|
} else if(event.event == LfRfidEventReadStartPSK) {
|
||||||
if(app->read_type == LFRFIDWorkerReadTypeAuto) {
|
if(app->read_type == LFRFIDWorkerReadTypeAuto) {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SubmenuIndexSave,
|
SubmenuIndexSave,
|
||||||
@ -43,6 +44,7 @@ bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event)
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexEmulate) {
|
} else if(event.event == SubmenuIndexEmulate) {
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidEmulate);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, event.event);
|
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, event.event);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void lfrfid_scene_save_data_on_enter(void* context) {
|
void lfrfid_scene_save_data_on_enter(void* context) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
@ -32,7 +31,6 @@ bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||||
protocol_dict_set_data(app->dict, app->protocol_id, app->new_key_data, size);
|
protocol_dict_set_data(app->dict, app->protocol_id, app->new_key_data, size);
|
||||||
DOLPHIN_DEED(DolphinDeedRfidAdd);
|
|
||||||
scene_manager_next_scene(scene_manager, LfRfidSceneSaveName);
|
scene_manager_next_scene(scene_manager, LfRfidSceneSaveName);
|
||||||
scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 1);
|
scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include <lib/toolbox/random_name.h>
|
#include <lib/toolbox/random_name.h>
|
||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
void lfrfid_scene_save_name_on_enter(void* context) {
|
void lfrfid_scene_save_name_on_enter(void* context) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
@ -55,6 +56,13 @@ bool lfrfid_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
if(lfrfid_save_key(app)) {
|
if(lfrfid_save_key(app)) {
|
||||||
scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess);
|
scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess);
|
||||||
|
if(scene_manager_has_previous_scene(scene_manager, LfRfidSceneSavedKeyMenu)) {
|
||||||
|
// Nothing, do not count editing as saving
|
||||||
|
} else if(scene_manager_has_previous_scene(scene_manager, LfRfidSceneSaveType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidAdd);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidSave);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scene_manager_search_and_switch_to_previous_scene(
|
scene_manager_search_and_switch_to_previous_scene(
|
||||||
scene_manager, LfRfidSceneReadKeyMenu);
|
scene_manager, LfRfidSceneReadKeyMenu);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void lfrfid_scene_save_success_on_enter(void* context) {
|
void lfrfid_scene_save_success_on_enter(void* context) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
@ -8,7 +7,6 @@ void lfrfid_scene_save_success_on_enter(void* context) {
|
|||||||
// Clear state of data enter scene
|
// Clear state of data enter scene
|
||||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0);
|
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0);
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedRfidSave);
|
|
||||||
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||||
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
||||||
popup_set_context(popup, app);
|
popup_set_context(popup, app);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SubmenuIndexEmulate,
|
SubmenuIndexEmulate,
|
||||||
@ -42,6 +43,7 @@ bool lfrfid_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event
|
|||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubmenuIndexEmulate) {
|
if(event.event == SubmenuIndexEmulate) {
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidEmulate);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexWrite) {
|
} else if(event.event == SubmenuIndexWrite) {
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../lfrfid_i.h"
|
#include "../lfrfid_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SubmenuIndexRead,
|
SubmenuIndexRead,
|
||||||
@ -47,6 +48,7 @@ bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubmenuIndexRead) {
|
if(event.event == SubmenuIndexRead) {
|
||||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
||||||
|
DOLPHIN_DEED(DolphinDeedRfidRead);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexSaved) {
|
} else if(event.event == SubmenuIndexSaved) {
|
||||||
furi_string_set(app->file_path, LFRFID_APP_FOLDER);
|
furi_string_set(app->file_path, LFRFID_APP_FOLDER);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "lfrfid_view_read.h"
|
#include "lfrfid_view_read.h"
|
||||||
#include <gui/elements.h>
|
#include <gui/elements.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
|
|
||||||
#define TEMP_STR_LEN 128
|
#define TEMP_STR_LEN 128
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "nfc_i.h"
|
#include "nfc_i.h"
|
||||||
#include "furi_hal_nfc.h"
|
#include "furi_hal_nfc.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
bool nfc_custom_event_callback(void* context, uint32_t event) {
|
bool nfc_custom_event_callback(void* context, uint32_t event) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -275,12 +276,15 @@ int32_t nfc_app(void* p) {
|
|||||||
if(nfc_device_load(nfc->dev, p, true)) {
|
if(nfc_device_load(nfc->dev, p, true)) {
|
||||||
if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
|
if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
|
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
} else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
|
} else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
|
||||||
} else {
|
} else {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Exit app
|
// Exit app
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
|
|||||||
@ -36,6 +36,12 @@ ADD_SCENE(nfc, mf_classic_keys_list, MfClassicKeysList)
|
|||||||
ADD_SCENE(nfc, mf_classic_keys_delete, MfClassicKeysDelete)
|
ADD_SCENE(nfc, mf_classic_keys_delete, MfClassicKeysDelete)
|
||||||
ADD_SCENE(nfc, mf_classic_keys_warn_duplicate, MfClassicKeysWarnDuplicate)
|
ADD_SCENE(nfc, mf_classic_keys_warn_duplicate, MfClassicKeysWarnDuplicate)
|
||||||
ADD_SCENE(nfc, mf_classic_dict_attack, MfClassicDictAttack)
|
ADD_SCENE(nfc, mf_classic_dict_attack, MfClassicDictAttack)
|
||||||
|
ADD_SCENE(nfc, mf_classic_write, MfClassicWrite)
|
||||||
|
ADD_SCENE(nfc, mf_classic_write_success, MfClassicWriteSuccess)
|
||||||
|
ADD_SCENE(nfc, mf_classic_write_fail, MfClassicWriteFail)
|
||||||
|
ADD_SCENE(nfc, mf_classic_update, MfClassicUpdate)
|
||||||
|
ADD_SCENE(nfc, mf_classic_update_success, MfClassicUpdateSuccess)
|
||||||
|
ADD_SCENE(nfc, mf_classic_wrong_card, MfClassicWrongCard)
|
||||||
ADD_SCENE(nfc, emv_read_success, EmvReadSuccess)
|
ADD_SCENE(nfc, emv_read_success, EmvReadSuccess)
|
||||||
ADD_SCENE(nfc, emv_menu, EmvMenu)
|
ADD_SCENE(nfc, emv_menu, EmvMenu)
|
||||||
ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence)
|
ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence)
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
#define NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX (10U)
|
#define NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX (10U)
|
||||||
|
|
||||||
@ -26,10 +25,14 @@ void nfc_scene_detect_reader_callback(void* context) {
|
|||||||
|
|
||||||
void nfc_scene_detect_reader_on_enter(void* context) {
|
void nfc_scene_detect_reader_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcDetectReader);
|
|
||||||
|
|
||||||
detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc);
|
detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc);
|
||||||
detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX);
|
detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX);
|
||||||
|
NfcDeviceData* dev_data = &nfc->dev->dev_data;
|
||||||
|
if(dev_data->nfc_data.uid_len) {
|
||||||
|
detect_reader_set_uid(
|
||||||
|
nfc->detect_reader, dev_data->nfc_data.uid, dev_data->nfc_data.uid_len);
|
||||||
|
}
|
||||||
|
|
||||||
// Store number of collected nonces in scene state
|
// Store number of collected nonces in scene state
|
||||||
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDetectReader, 0);
|
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDetectReader, 0);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
#define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200)
|
#define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200)
|
||||||
|
|
||||||
@ -59,7 +58,6 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) {
|
|||||||
|
|
||||||
void nfc_scene_emulate_uid_on_enter(void* context) {
|
void nfc_scene_emulate_uid_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
|
||||||
|
|
||||||
// Setup Widget
|
// Setup Widget
|
||||||
nfc_scene_emulate_uid_widget_config(nfc, false);
|
nfc_scene_emulate_uid_widget_config(nfc, false);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include "../helpers/nfc_emv_parser.h"
|
#include "../helpers/nfc_emv_parser.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_emv_read_success_widget_callback(
|
void nfc_scene_emv_read_success_widget_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@ -15,7 +14,6 @@ void nfc_scene_emv_read_success_widget_callback(
|
|||||||
void nfc_scene_emv_read_success_on_enter(void* context) {
|
void nfc_scene_emv_read_success_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
EmvData* emv_data = &nfc->dev->dev_data.emv_data;
|
EmvData* emv_data = &nfc->dev->dev_data.emv_data;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
|
||||||
|
|
||||||
// Setup Custom Widget view
|
// Setup Custom Widget view
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
#define TAG "NfcMfClassicDictAttack"
|
#define TAG "NfcMfClassicDictAttack"
|
||||||
|
|
||||||
@ -110,6 +111,7 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent
|
|||||||
} else {
|
} else {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
} else if(event.event == NfcWorkerEventAborted) {
|
} else if(event.event == NfcWorkerEventAborted) {
|
||||||
@ -119,6 +121,8 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent
|
|||||||
} else {
|
} else {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
|
||||||
|
// Counting failed attempts too
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
} else if(event.event == NfcWorkerEventCardDetected) {
|
} else if(event.event == NfcWorkerEventCardDetected) {
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
#define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL)
|
#define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL)
|
||||||
#define NFC_MF_CLASSIC_DATA_CHANGED (1UL)
|
#define NFC_MF_CLASSIC_DATA_CHANGED (1UL)
|
||||||
@ -15,7 +14,6 @@ bool nfc_mf_classic_emulate_worker_callback(NfcWorkerEvent event, void* context)
|
|||||||
|
|
||||||
void nfc_scene_mf_classic_emulate_on_enter(void* context) {
|
void nfc_scene_mf_classic_emulate_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
Popup* popup = nfc->popup;
|
Popup* popup = nfc->popup;
|
||||||
|
|||||||
@ -34,8 +34,6 @@ void nfc_scene_mf_classic_keys_on_enter(void* context) {
|
|||||||
widget_add_string_element(nfc->widget, 0, 32, AlignLeft, AlignTop, FontSecondary, temp_str);
|
widget_add_string_element(nfc->widget, 0, 32, AlignLeft, AlignTop, FontSecondary, temp_str);
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
nfc->widget, GuiButtonTypeCenter, "Add", nfc_scene_mf_classic_keys_widget_callback, nfc);
|
nfc->widget, GuiButtonTypeCenter, "Add", nfc_scene_mf_classic_keys_widget_callback, nfc);
|
||||||
widget_add_button_element(
|
|
||||||
nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_mf_classic_keys_widget_callback, nfc);
|
|
||||||
widget_add_icon_element(nfc->widget, 87, 13, &I_Keychain_39x36);
|
widget_add_icon_element(nfc->widget, 87, 13, &I_Keychain_39x36);
|
||||||
if(user_dict_keys_total > 0) {
|
if(user_dict_keys_total > 0) {
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
@ -57,9 +55,6 @@ bool nfc_scene_mf_classic_keys_on_event(void* context, SceneManagerEvent event)
|
|||||||
if(event.event == GuiButtonTypeCenter) {
|
if(event.event == GuiButtonTypeCenter) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysAdd);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysAdd);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == GuiButtonTypeLeft) {
|
|
||||||
scene_manager_previous_scene(nfc->scene_manager);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event.event == GuiButtonTypeRight) {
|
} else if(event.event == GuiButtonTypeRight) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysList);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysList);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
void nfc_scene_mf_classic_keys_add_byte_input_callback(void* context) {
|
void nfc_scene_mf_classic_keys_add_byte_input_callback(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
@ -36,6 +37,7 @@ bool nfc_scene_mf_classic_keys_add_on_event(void* context, SceneManagerEvent eve
|
|||||||
nfc->scene_manager, NfcSceneMfClassicKeysWarnDuplicate);
|
nfc->scene_manager, NfcSceneMfClassicKeysWarnDuplicate);
|
||||||
} else if(mf_classic_dict_add_key(dict, nfc->byte_input_store)) {
|
} else if(mf_classic_dict_add_key(dict, nfc->byte_input_store)) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcMfcAdd);
|
||||||
} else {
|
} else {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,8 +36,6 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event)
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubmenuIndexSave) {
|
if(event.event == SubmenuIndexSave) {
|
||||||
DOLPHIN_DEED(DolphinDeedNfcMfcAdd);
|
|
||||||
|
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexSave);
|
nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexSave);
|
||||||
nfc->dev->format = NfcDeviceSaveFormatMifareClassic;
|
nfc->dev->format = NfcDeviceSaveFormatMifareClassic;
|
||||||
@ -49,6 +47,11 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event)
|
|||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexEmulate);
|
nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexEmulate);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
|
||||||
|
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexInfo) {
|
} else if(event.event == SubmenuIndexInfo) {
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_mf_classic_read_success_widget_callback(
|
void nfc_scene_mf_classic_read_success_widget_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@ -18,8 +17,6 @@ void nfc_scene_mf_classic_read_success_on_enter(void* context) {
|
|||||||
NfcDeviceData* dev_data = &nfc->dev->dev_data;
|
NfcDeviceData* dev_data = &nfc->dev->dev_data;
|
||||||
MfClassicData* mf_data = &dev_data->mf_classic_data;
|
MfClassicData* mf_data = &dev_data->mf_classic_data;
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
Widget* widget = nfc->widget;
|
Widget* widget = nfc->widget;
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
|
|||||||
98
applications/main/nfc/scenes/nfc_scene_mf_classic_update.c
Normal file
98
applications/main/nfc/scenes/nfc_scene_mf_classic_update.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NfcSceneMfClassicUpdateStateCardSearch,
|
||||||
|
NfcSceneMfClassicUpdateStateCardFound,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool nfc_mf_classic_update_worker_callback(NfcWorkerEvent event, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
|
||||||
|
Nfc* nfc = context;
|
||||||
|
view_dispatcher_send_custom_event(nfc->view_dispatcher, event);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfc_scene_mf_classic_update_setup_view(Nfc* nfc) {
|
||||||
|
Popup* popup = nfc->popup;
|
||||||
|
popup_reset(popup);
|
||||||
|
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicUpdate);
|
||||||
|
|
||||||
|
if(state == NfcSceneMfClassicUpdateStateCardSearch) {
|
||||||
|
popup_set_text(
|
||||||
|
nfc->popup, "Apply the initial\ncard only", 128, 32, AlignRight, AlignCenter);
|
||||||
|
popup_set_icon(nfc->popup, 0, 8, &I_NFC_manual_60x50);
|
||||||
|
} else {
|
||||||
|
popup_set_header(popup, "Updating\nDon't move...", 52, 32, AlignLeft, AlignCenter);
|
||||||
|
popup_set_icon(popup, 12, 23, &A_Loading_24);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_update_on_enter(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager, NfcSceneMfClassicUpdate, NfcSceneMfClassicUpdateStateCardSearch);
|
||||||
|
nfc_scene_mf_classic_update_setup_view(nfc);
|
||||||
|
|
||||||
|
// Setup and start worker
|
||||||
|
nfc_worker_start(
|
||||||
|
nfc->worker,
|
||||||
|
NfcWorkerStateMfClassicUpdate,
|
||||||
|
&nfc->dev->dev_data,
|
||||||
|
nfc_mf_classic_update_worker_callback,
|
||||||
|
nfc);
|
||||||
|
nfc_blink_emulate_start(nfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nfc_scene_mf_classic_update_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == NfcWorkerEventSuccess) {
|
||||||
|
nfc_worker_stop(nfc->worker);
|
||||||
|
if(nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name)) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicUpdateSuccess);
|
||||||
|
} else {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicWrongCard);
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventWrongCard) {
|
||||||
|
nfc_worker_stop(nfc->worker);
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicWrongCard);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventCardDetected) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager,
|
||||||
|
NfcSceneMfClassicUpdate,
|
||||||
|
NfcSceneMfClassicUpdateStateCardFound);
|
||||||
|
nfc_scene_mf_classic_update_setup_view(nfc);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventNoCardDetected) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager,
|
||||||
|
NfcSceneMfClassicUpdate,
|
||||||
|
NfcSceneMfClassicUpdateStateCardSearch);
|
||||||
|
nfc_scene_mf_classic_update_setup_view(nfc);
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_update_on_exit(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
nfc_worker_stop(nfc->worker);
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager, NfcSceneMfClassicUpdate, NfcSceneMfClassicUpdateStateCardSearch);
|
||||||
|
// Clear view
|
||||||
|
popup_reset(nfc->popup);
|
||||||
|
|
||||||
|
nfc_blink_stop(nfc);
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_update_success_popup_callback(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_update_success_on_enter(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcSave);
|
||||||
|
|
||||||
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
|
|
||||||
|
Popup* popup = nfc->popup;
|
||||||
|
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||||
|
popup_set_header(popup, "Updated!", 11, 20, AlignLeft, AlignBottom);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_set_context(popup, nfc);
|
||||||
|
popup_set_callback(popup, nfc_scene_mf_classic_update_success_popup_callback);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nfc_scene_mf_classic_update_success_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == NfcCustomEventViewExit) {
|
||||||
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
nfc->scene_manager, NfcSceneFileSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_update_success_on_exit(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
|
||||||
|
// Clear view
|
||||||
|
popup_reset(nfc->popup);
|
||||||
|
}
|
||||||
92
applications/main/nfc/scenes/nfc_scene_mf_classic_write.c
Normal file
92
applications/main/nfc/scenes/nfc_scene_mf_classic_write.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NfcSceneMfClassicWriteStateCardSearch,
|
||||||
|
NfcSceneMfClassicWriteStateCardFound,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool nfc_mf_classic_write_worker_callback(NfcWorkerEvent event, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
|
||||||
|
Nfc* nfc = context;
|
||||||
|
view_dispatcher_send_custom_event(nfc->view_dispatcher, event);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfc_scene_mf_classic_write_setup_view(Nfc* nfc) {
|
||||||
|
Popup* popup = nfc->popup;
|
||||||
|
popup_reset(popup);
|
||||||
|
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicWrite);
|
||||||
|
|
||||||
|
if(state == NfcSceneMfClassicWriteStateCardSearch) {
|
||||||
|
popup_set_text(
|
||||||
|
nfc->popup, "Apply the initial\ncard only", 128, 32, AlignRight, AlignCenter);
|
||||||
|
popup_set_icon(nfc->popup, 0, 8, &I_NFC_manual_60x50);
|
||||||
|
} else {
|
||||||
|
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
|
||||||
|
popup_set_icon(popup, 12, 23, &A_Loading_24);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_on_enter(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager, NfcSceneMfClassicWrite, NfcSceneMfClassicWriteStateCardSearch);
|
||||||
|
nfc_scene_mf_classic_write_setup_view(nfc);
|
||||||
|
|
||||||
|
// Setup and start worker
|
||||||
|
nfc_worker_start(
|
||||||
|
nfc->worker,
|
||||||
|
NfcWorkerStateMfClassicWrite,
|
||||||
|
&nfc->dev->dev_data,
|
||||||
|
nfc_mf_classic_write_worker_callback,
|
||||||
|
nfc);
|
||||||
|
nfc_blink_emulate_start(nfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nfc_scene_mf_classic_write_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == NfcWorkerEventSuccess) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicWriteSuccess);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventFail) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicWriteFail);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventWrongCard) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicWrongCard);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventCardDetected) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager, NfcSceneMfClassicWrite, NfcSceneMfClassicWriteStateCardFound);
|
||||||
|
nfc_scene_mf_classic_write_setup_view(nfc);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == NfcWorkerEventNoCardDetected) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager, NfcSceneMfClassicWrite, NfcSceneMfClassicWriteStateCardSearch);
|
||||||
|
nfc_scene_mf_classic_write_setup_view(nfc);
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_on_exit(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
|
||||||
|
nfc_worker_stop(nfc->worker);
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
nfc->scene_manager, NfcSceneMfClassicWrite, NfcSceneMfClassicWriteStateCardSearch);
|
||||||
|
// Clear view
|
||||||
|
popup_reset(nfc->popup);
|
||||||
|
|
||||||
|
nfc_blink_stop(nfc);
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_fail_widget_callback(
|
||||||
|
GuiButtonType result,
|
||||||
|
InputType type,
|
||||||
|
void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
if(type == InputTypeShort) {
|
||||||
|
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_fail_on_enter(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
Widget* widget = nfc->widget;
|
||||||
|
|
||||||
|
notification_message(nfc->notifications, &sequence_error);
|
||||||
|
|
||||||
|
widget_add_icon_element(widget, 72, 17, &I_DolphinCommon_56x48);
|
||||||
|
widget_add_string_element(
|
||||||
|
widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!");
|
||||||
|
widget_add_string_multiline_element(
|
||||||
|
widget,
|
||||||
|
7,
|
||||||
|
17,
|
||||||
|
AlignLeft,
|
||||||
|
AlignTop,
|
||||||
|
FontSecondary,
|
||||||
|
"Not all sectors\nwere written\ncorrectly.");
|
||||||
|
|
||||||
|
widget_add_button_element(
|
||||||
|
widget, GuiButtonTypeLeft, "Finish", nfc_scene_mf_classic_write_fail_widget_callback, nfc);
|
||||||
|
|
||||||
|
// Setup and start worker
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nfc_scene_mf_classic_write_fail_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == GuiButtonTypeLeft) {
|
||||||
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
nfc->scene_manager, NfcSceneFileSelect);
|
||||||
|
}
|
||||||
|
} else if(event.type == SceneManagerEventTypeBack) {
|
||||||
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
nfc->scene_manager, NfcSceneSavedMenu);
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_fail_on_exit(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
|
||||||
|
widget_reset(nfc->widget);
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_success_popup_callback(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_success_on_enter(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcSave);
|
||||||
|
|
||||||
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
|
|
||||||
|
Popup* popup = nfc->popup;
|
||||||
|
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||||
|
popup_set_header(popup, "Successfully\nwritten", 13, 22, AlignLeft, AlignBottom);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_set_context(popup, nfc);
|
||||||
|
popup_set_callback(popup, nfc_scene_mf_classic_write_success_popup_callback);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nfc_scene_mf_classic_write_success_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == NfcCustomEventViewExit) {
|
||||||
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
nfc->scene_manager, NfcSceneFileSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_write_success_on_exit(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
|
||||||
|
// Clear view
|
||||||
|
popup_reset(nfc->popup);
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_wrong_card_widget_callback(
|
||||||
|
GuiButtonType result,
|
||||||
|
InputType type,
|
||||||
|
void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
if(type == InputTypeShort) {
|
||||||
|
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_wrong_card_on_enter(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
Widget* widget = nfc->widget;
|
||||||
|
|
||||||
|
notification_message(nfc->notifications, &sequence_error);
|
||||||
|
|
||||||
|
widget_add_icon_element(widget, 73, 17, &I_DolphinCommon_56x48);
|
||||||
|
widget_add_string_element(
|
||||||
|
widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card");
|
||||||
|
widget_add_string_multiline_element(
|
||||||
|
widget,
|
||||||
|
4,
|
||||||
|
17,
|
||||||
|
AlignLeft,
|
||||||
|
AlignTop,
|
||||||
|
FontSecondary,
|
||||||
|
"Data management\nis only possible\nwith initial card");
|
||||||
|
widget_add_button_element(
|
||||||
|
widget, GuiButtonTypeLeft, "Retry", nfc_scene_mf_classic_wrong_card_widget_callback, nfc);
|
||||||
|
|
||||||
|
// Setup and start worker
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nfc_scene_mf_classic_wrong_card_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == GuiButtonTypeLeft) {
|
||||||
|
consumed = scene_manager_previous_scene(nfc->scene_manager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_scene_mf_classic_wrong_card_on_exit(void* context) {
|
||||||
|
Nfc* nfc = context;
|
||||||
|
|
||||||
|
widget_reset(nfc->widget);
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexSave,
|
SubmenuIndexSave,
|
||||||
@ -48,6 +49,11 @@ bool nfc_scene_mf_desfire_menu_on_event(void* context, SceneManagerEvent event)
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexEmulateUid) {
|
} else if(event.event == SubmenuIndexEmulateUid) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
||||||
|
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexInfo) {
|
} else if(event.event == SubmenuIndexInfo) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
#define NFC_MF_UL_DATA_NOT_CHANGED (0UL)
|
#define NFC_MF_UL_DATA_NOT_CHANGED (0UL)
|
||||||
#define NFC_MF_UL_DATA_CHANGED (1UL)
|
#define NFC_MF_UL_DATA_CHANGED (1UL)
|
||||||
@ -15,7 +14,6 @@ bool nfc_mf_ultralight_emulate_worker_callback(NfcWorkerEvent event, void* conte
|
|||||||
|
|
||||||
void nfc_scene_mf_ultralight_emulate_on_enter(void* context) {
|
void nfc_scene_mf_ultralight_emulate_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
Popup* popup = nfc->popup;
|
Popup* popup = nfc->popup;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexUnlock,
|
SubmenuIndexUnlock,
|
||||||
@ -56,6 +57,11 @@ bool nfc_scene_mf_ultralight_menu_on_event(void* context, SceneManagerEvent even
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexEmulate) {
|
} else if(event.event == SubmenuIndexEmulate) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
|
||||||
|
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexUnlock) {
|
} else if(event.event == SubmenuIndexUnlock) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NfcSceneMfUlReadStateIdle,
|
NfcSceneMfUlReadStateIdle,
|
||||||
@ -51,7 +50,6 @@ void nfc_scene_mf_ultralight_read_auth_set_state(Nfc* nfc, NfcSceneMfUlReadState
|
|||||||
|
|
||||||
void nfc_scene_mf_ultralight_read_auth_on_enter(void* context) {
|
void nfc_scene_mf_ultralight_read_auth_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcRead);
|
|
||||||
|
|
||||||
nfc_device_clear(nfc->dev);
|
nfc_device_clear(nfc->dev);
|
||||||
// Setup view
|
// Setup view
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_mf_ultralight_read_auth_result_widget_callback(
|
void nfc_scene_mf_ultralight_read_auth_result_widget_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@ -37,7 +36,6 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
|
|||||||
widget_add_string_element(
|
widget_add_string_element(
|
||||||
widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
|
widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
|
||||||
if(mf_ul_data->auth_success) {
|
if(mf_ul_data->auth_success) {
|
||||||
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
temp_str,
|
temp_str,
|
||||||
"Password: %02X %02X %02X %02X",
|
"Password: %02X %02X %02X %02X",
|
||||||
@ -54,8 +52,6 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
|
|||||||
config_pages->auth_data.pack.raw[1]);
|
config_pages->auth_data.pack.raw[1]);
|
||||||
widget_add_string_element(
|
widget_add_string_element(
|
||||||
widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
|
widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
|
||||||
} else {
|
|
||||||
DOLPHIN_DEED(DolphinDeedNfcMfulError);
|
|
||||||
}
|
}
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4);
|
temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_mf_ultralight_read_success_widget_callback(
|
void nfc_scene_mf_ultralight_read_success_widget_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@ -14,7 +13,6 @@ void nfc_scene_mf_ultralight_read_success_widget_callback(
|
|||||||
|
|
||||||
void nfc_scene_mf_ultralight_read_success_on_enter(void* context) {
|
void nfc_scene_mf_ultralight_read_success_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
|
||||||
|
|
||||||
// Setup widget view
|
// Setup widget view
|
||||||
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
|
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
void nfc_scene_mf_ultralight_unlock_warn_dialog_callback(DialogExResult result, void* context) {
|
void nfc_scene_mf_ultralight_unlock_warn_dialog_callback(DialogExResult result, void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
@ -30,6 +31,7 @@ bool nfc_scene_mf_ultralight_unlock_warn_on_event(void* context, SceneManagerEve
|
|||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == DialogExResultCenter) {
|
if(event.event == DialogExResultCenter) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadAuth);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadAuth);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcRead);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexSaveUid,
|
SubmenuIndexSaveUid,
|
||||||
@ -41,6 +42,11 @@ bool nfc_scene_nfca_menu_on_event(void* context, SceneManagerEvent event) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexEmulateUid) {
|
} else if(event.event == SubmenuIndexEmulateUid) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
||||||
|
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcAddEmulate);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexInfo) {
|
} else if(event.event == SubmenuIndexInfo) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_nfca_read_success_widget_callback(
|
void nfc_scene_nfca_read_success_widget_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@ -16,8 +15,6 @@ void nfc_scene_nfca_read_success_widget_callback(
|
|||||||
void nfc_scene_nfca_read_success_on_enter(void* context) {
|
void nfc_scene_nfca_read_success_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
|
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
|
||||||
Widget* widget = nfc->widget;
|
Widget* widget = nfc->widget;
|
||||||
|
|||||||
@ -39,7 +39,6 @@ void nfc_scene_read_set_state(Nfc* nfc, NfcSceneReadState state) {
|
|||||||
|
|
||||||
void nfc_scene_read_on_enter(void* context) {
|
void nfc_scene_read_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcRead);
|
|
||||||
|
|
||||||
nfc_device_clear(nfc->dev);
|
nfc_device_clear(nfc->dev);
|
||||||
// Setup view
|
// Setup view
|
||||||
@ -62,26 +61,32 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) {
|
|||||||
(event.event == NfcWorkerEventReadUidNfcV)) {
|
(event.event == NfcWorkerEventReadUidNfcV)) {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == NfcWorkerEventReadUidNfcA) {
|
} else if(event.event == NfcWorkerEventReadUidNfcA) {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcaReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcaReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == NfcWorkerEventReadMfUltralight) {
|
} else if(event.event == NfcWorkerEventReadMfUltralight) {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == NfcWorkerEventReadMfClassicDone) {
|
} else if(event.event == NfcWorkerEventReadMfClassicDone) {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == NfcWorkerEventReadMfDesfire) {
|
} else if(event.event == NfcWorkerEventReadMfDesfire) {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == NfcWorkerEventReadBankCard) {
|
} else if(event.event == NfcWorkerEventReadBankCard) {
|
||||||
notification_message(nfc->notifications, &sequence_success);
|
notification_message(nfc->notifications, &sequence_success);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) {
|
} else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) {
|
||||||
if(mf_classic_dict_check_presence(MfClassicDictTypeFlipper)) {
|
if(mf_classic_dict_check_presence(MfClassicDictTypeFlipper)) {
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_read_card_success_widget_callback(
|
void nfc_scene_read_card_success_widget_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@ -18,7 +17,6 @@ void nfc_scene_read_card_success_on_enter(void* context) {
|
|||||||
|
|
||||||
FuriString* temp_str;
|
FuriString* temp_str;
|
||||||
temp_str = furi_string_alloc();
|
temp_str = furi_string_alloc();
|
||||||
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
|
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <lib/toolbox/random_name.h>
|
#include <lib/toolbox/random_name.h>
|
||||||
#include <gui/modules/validators.h>
|
#include <gui/modules/validators.h>
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
void nfc_scene_save_name_text_input_callback(void* context) {
|
void nfc_scene_save_name_text_input_callback(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
@ -63,6 +64,13 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
|||||||
strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1);
|
strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1);
|
||||||
if(nfc_device_save(nfc->dev, nfc->text_store)) {
|
if(nfc_device_save(nfc->dev, nfc->text_store)) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
|
||||||
|
if(!scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) {
|
||||||
|
// Nothing, do not count editing as saving
|
||||||
|
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcAddSave);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcSave);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else {
|
} else {
|
||||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_save_success_popup_callback(void* context) {
|
void nfc_scene_save_success_popup_callback(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
@ -8,7 +7,6 @@ void nfc_scene_save_success_popup_callback(void* context) {
|
|||||||
|
|
||||||
void nfc_scene_save_success_on_enter(void* context) {
|
void nfc_scene_save_success_on_enter(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
DOLPHIN_DEED(DolphinDeedNfcSave);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
Popup* popup = nfc->popup;
|
Popup* popup = nfc->popup;
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexEmulate,
|
SubmenuIndexEmulate,
|
||||||
SubmenuIndexEditUid,
|
SubmenuIndexEditUid,
|
||||||
|
SubmenuIndexDetectReader,
|
||||||
|
SubmenuIndexWrite,
|
||||||
|
SubmenuIndexUpdate,
|
||||||
SubmenuIndexRename,
|
SubmenuIndexRename,
|
||||||
SubmenuIndexDelete,
|
SubmenuIndexDelete,
|
||||||
SubmenuIndexInfo,
|
SubmenuIndexInfo,
|
||||||
@ -41,6 +45,28 @@ void nfc_scene_saved_menu_on_enter(void* context) {
|
|||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc);
|
submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc);
|
||||||
}
|
}
|
||||||
|
if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
|
||||||
|
if(!mf_classic_is_card_read(&nfc->dev->dev_data.mf_classic_data)) {
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"Detect reader",
|
||||||
|
SubmenuIndexDetectReader,
|
||||||
|
nfc_scene_saved_menu_submenu_callback,
|
||||||
|
nfc);
|
||||||
|
}
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"Write To Initial Card",
|
||||||
|
SubmenuIndexWrite,
|
||||||
|
nfc_scene_saved_menu_submenu_callback,
|
||||||
|
nfc);
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"Update From Initial Card",
|
||||||
|
SubmenuIndexUpdate,
|
||||||
|
nfc_scene_saved_menu_submenu_callback,
|
||||||
|
nfc);
|
||||||
|
}
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
|
submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
|
||||||
if(nfc->dev->shadow_file_exist) {
|
if(nfc->dev->shadow_file_exist) {
|
||||||
@ -76,6 +102,16 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
|
|||||||
} else {
|
} else {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
|
||||||
}
|
}
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcEmulate);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == SubmenuIndexDetectReader) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneDetectReader);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == SubmenuIndexWrite) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicWrite);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == SubmenuIndexUpdate) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicUpdate);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexRename) {
|
} else if(event.event == SubmenuIndexRename) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void nfc_scene_set_uid_byte_input_callback(void* context) {
|
void nfc_scene_set_uid_byte_input_callback(void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
@ -30,7 +29,6 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == NfcCustomEventByteInputDone) {
|
if(event.event == NfcCustomEventByteInputDone) {
|
||||||
DOLPHIN_DEED(DolphinDeedNfcAddSave);
|
|
||||||
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) {
|
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) {
|
||||||
nfc->dev->dev_data.nfc_data = nfc->dev_edit_data;
|
nfc->dev->dev_data.nfc_data = nfc->dev_edit_data;
|
||||||
if(nfc_device_save(nfc->dev, nfc->dev->dev_name)) {
|
if(nfc_device_save(nfc->dev, nfc->dev->dev_name)) {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexRead,
|
SubmenuIndexRead,
|
||||||
@ -47,11 +48,14 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubmenuIndexRead) {
|
if(event.event == SubmenuIndexRead) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcRead);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexDetectReader) {
|
} else if(event.event == SubmenuIndexDetectReader) {
|
||||||
bool sd_exist = storage_sd_status(nfc->dev->storage) == FSE_OK;
|
bool sd_exist = storage_sd_status(nfc->dev->storage) == FSE_OK;
|
||||||
if(sd_exist) {
|
if(sd_exist) {
|
||||||
|
nfc_device_data_clear(&nfc->dev->dev_data);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneDetectReader);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneDetectReader);
|
||||||
|
DOLPHIN_DEED(DolphinDeedNfcDetectReader);
|
||||||
} else {
|
} else {
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
#include "detect_reader.h"
|
#include "detect_reader.h"
|
||||||
|
#include <assets_icons.h>
|
||||||
#include <gui/elements.h>
|
#include <gui/elements.h>
|
||||||
|
|
||||||
|
#define DETECT_READER_UID_MAX_LEN (10)
|
||||||
|
|
||||||
struct DetectReader {
|
struct DetectReader {
|
||||||
View* view;
|
View* view;
|
||||||
DetectReaderDoneCallback callback;
|
DetectReaderDoneCallback callback;
|
||||||
@ -12,6 +14,7 @@ typedef struct {
|
|||||||
uint16_t nonces;
|
uint16_t nonces;
|
||||||
uint16_t nonces_max;
|
uint16_t nonces_max;
|
||||||
DetectReaderState state;
|
DetectReaderState state;
|
||||||
|
FuriString* uid_str;
|
||||||
} DetectReaderViewModel;
|
} DetectReaderViewModel;
|
||||||
|
|
||||||
static void detect_reader_draw_callback(Canvas* canvas, void* model) {
|
static void detect_reader_draw_callback(Canvas* canvas, void* model) {
|
||||||
@ -23,6 +26,10 @@ static void detect_reader_draw_callback(Canvas* canvas, void* model) {
|
|||||||
if(m->state == DetectReaderStateStart) {
|
if(m->state == DetectReaderStateStart) {
|
||||||
snprintf(text, sizeof(text), "Touch the reader");
|
snprintf(text, sizeof(text), "Touch the reader");
|
||||||
canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39);
|
canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39);
|
||||||
|
if(furi_string_size(m->uid_str)) {
|
||||||
|
elements_multiline_text_aligned(
|
||||||
|
canvas, 64, 64, AlignCenter, AlignBottom, furi_string_get_cstr(m->uid_str));
|
||||||
|
}
|
||||||
} else if(m->state == DetectReaderStateReaderDetected) {
|
} else if(m->state == DetectReaderStateReaderDetected) {
|
||||||
snprintf(text, sizeof(text), "Move the Flipper away");
|
snprintf(text, sizeof(text), "Move the Flipper away");
|
||||||
canvas_draw_icon(canvas, 24, 25, &I_Release_arrow_18x15);
|
canvas_draw_icon(canvas, 24, 25, &I_Release_arrow_18x15);
|
||||||
@ -86,12 +93,24 @@ DetectReader* detect_reader_alloc() {
|
|||||||
view_set_input_callback(detect_reader->view, detect_reader_input_callback);
|
view_set_input_callback(detect_reader->view, detect_reader_input_callback);
|
||||||
view_set_context(detect_reader->view, detect_reader);
|
view_set_context(detect_reader->view, detect_reader);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
detect_reader->view,
|
||||||
|
DetectReaderViewModel * model,
|
||||||
|
{ model->uid_str = furi_string_alloc(); },
|
||||||
|
false);
|
||||||
|
|
||||||
return detect_reader;
|
return detect_reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detect_reader_free(DetectReader* detect_reader) {
|
void detect_reader_free(DetectReader* detect_reader) {
|
||||||
furi_assert(detect_reader);
|
furi_assert(detect_reader);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
detect_reader->view,
|
||||||
|
DetectReaderViewModel * model,
|
||||||
|
{ furi_string_free(model->uid_str); },
|
||||||
|
false);
|
||||||
|
|
||||||
view_free(detect_reader->view);
|
view_free(detect_reader->view);
|
||||||
free(detect_reader);
|
free(detect_reader);
|
||||||
}
|
}
|
||||||
@ -106,6 +125,7 @@ void detect_reader_reset(DetectReader* detect_reader) {
|
|||||||
model->nonces = 0;
|
model->nonces = 0;
|
||||||
model->nonces_max = 0;
|
model->nonces_max = 0;
|
||||||
model->state = DetectReaderStateStart;
|
model->state = DetectReaderStateStart;
|
||||||
|
furi_string_reset(model->uid_str);
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
@ -152,3 +172,19 @@ void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState stat
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
detect_reader->view, DetectReaderViewModel * model, { model->state = state; }, true);
|
detect_reader->view, DetectReaderViewModel * model, { model->state = state; }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void detect_reader_set_uid(DetectReader* detect_reader, uint8_t* uid, uint8_t uid_len) {
|
||||||
|
furi_assert(detect_reader);
|
||||||
|
furi_assert(uid);
|
||||||
|
furi_assert(uid_len < DETECT_READER_UID_MAX_LEN);
|
||||||
|
with_view_model(
|
||||||
|
detect_reader->view,
|
||||||
|
DetectReaderViewModel * model,
|
||||||
|
{
|
||||||
|
furi_string_set_str(model->uid_str, "UID:");
|
||||||
|
for(size_t i = 0; i < uid_len; i++) {
|
||||||
|
furi_string_cat_printf(model->uid_str, " %02X", uid[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|||||||
@ -32,3 +32,5 @@ void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_m
|
|||||||
void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected);
|
void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected);
|
||||||
|
|
||||||
void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state);
|
void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state);
|
||||||
|
|
||||||
|
void detect_reader_set_uid(DetectReader* detect_reader, uint8_t* uid, uint8_t uid_len);
|
||||||
|
|||||||
@ -69,12 +69,3 @@ typedef enum {
|
|||||||
SubGhzViewIdTestCarrier,
|
SubGhzViewIdTestCarrier,
|
||||||
SubGhzViewIdTestPacket,
|
SubGhzViewIdTestPacket,
|
||||||
} SubGhzViewId;
|
} SubGhzViewId;
|
||||||
|
|
||||||
struct SubGhzPresetDefinition {
|
|
||||||
FuriString* name;
|
|
||||||
uint32_t frequency;
|
|
||||||
uint8_t* data;
|
|
||||||
size_t data_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct SubGhzPresetDefinition SubGhzPresetDefinition;
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
#include "../views/subghz_frequency_analyzer.h"
|
#include "../views/subghz_frequency_analyzer.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* context) {
|
void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -10,7 +9,6 @@ void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* con
|
|||||||
|
|
||||||
void subghz_scene_frequency_analyzer_on_enter(void* context) {
|
void subghz_scene_frequency_analyzer_on_enter(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer);
|
|
||||||
subghz_frequency_analyzer_set_callback(
|
subghz_frequency_analyzer_set_callback(
|
||||||
subghz->subghz_frequency_analyzer, subghz_scene_frequency_analyzer_callback, subghz);
|
subghz->subghz_frequency_analyzer, subghz_scene_frequency_analyzer_callback, subghz);
|
||||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer);
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer);
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#define RAW_FILE_NAME "Raw_signal_"
|
#define RAW_FILE_NAME "Raw_signal_"
|
||||||
#define TAG "SubGhzSceneReadRAW"
|
#define TAG "SubGhzSceneReadRAW"
|
||||||
|
#define RAW_THRESHOLD_RSSI_LOW_COUNT 10
|
||||||
|
|
||||||
bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
|
bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@ -72,24 +73,33 @@ void subghz_scene_read_raw_on_enter(void* context) {
|
|||||||
|
|
||||||
switch(subghz->txrx->rx_key_state) {
|
switch(subghz->txrx->rx_key_state) {
|
||||||
case SubGhzRxKeyStateBack:
|
case SubGhzRxKeyStateBack:
|
||||||
subghz_read_raw_set_status(subghz->subghz_read_raw, SubGhzReadRAWStatusIDLE, "");
|
subghz_read_raw_set_status(
|
||||||
|
subghz->subghz_read_raw, SubGhzReadRAWStatusIDLE, "", subghz->txrx->raw_threshold_rssi);
|
||||||
break;
|
break;
|
||||||
case SubGhzRxKeyStateRAWLoad:
|
case SubGhzRxKeyStateRAWLoad:
|
||||||
path_extract_filename(subghz->file_path, file_name, true);
|
path_extract_filename(subghz->file_path, file_name, true);
|
||||||
subghz_read_raw_set_status(
|
subghz_read_raw_set_status(
|
||||||
subghz->subghz_read_raw,
|
subghz->subghz_read_raw,
|
||||||
SubGhzReadRAWStatusLoadKeyTX,
|
SubGhzReadRAWStatusLoadKeyTX,
|
||||||
furi_string_get_cstr(file_name));
|
furi_string_get_cstr(file_name),
|
||||||
|
subghz->txrx->raw_threshold_rssi);
|
||||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
||||||
break;
|
break;
|
||||||
case SubGhzRxKeyStateRAWSave:
|
case SubGhzRxKeyStateRAWSave:
|
||||||
path_extract_filename(subghz->file_path, file_name, true);
|
path_extract_filename(subghz->file_path, file_name, true);
|
||||||
subghz_read_raw_set_status(
|
subghz_read_raw_set_status(
|
||||||
subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, furi_string_get_cstr(file_name));
|
subghz->subghz_read_raw,
|
||||||
|
SubGhzReadRAWStatusSaveKey,
|
||||||
|
furi_string_get_cstr(file_name),
|
||||||
|
subghz->txrx->raw_threshold_rssi);
|
||||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
subghz_read_raw_set_status(subghz->subghz_read_raw, SubGhzReadRAWStatusStart, "");
|
subghz_read_raw_set_status(
|
||||||
|
subghz->subghz_read_raw,
|
||||||
|
SubGhzReadRAWStatusStart,
|
||||||
|
"",
|
||||||
|
subghz->txrx->raw_threshold_rssi);
|
||||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -213,7 +223,12 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
|||||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateBack;
|
subghz->txrx->rx_key_state = SubGhzRxKeyStateBack;
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
|
||||||
} else {
|
} else {
|
||||||
DOLPHIN_DEED(DolphinDeedSubGhzSend);
|
if(scene_manager_has_previous_scene(
|
||||||
|
subghz->scene_manager, SubGhzSceneSaved) ||
|
||||||
|
!scene_manager_has_previous_scene(
|
||||||
|
subghz->scene_manager, SubGhzSceneStart)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedSubGhzSend);
|
||||||
|
}
|
||||||
// set callback end tx
|
// set callback end tx
|
||||||
subghz_protocol_raw_file_encoder_worker_set_callback_end(
|
subghz_protocol_raw_file_encoder_worker_set_callback_end(
|
||||||
(SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance(
|
(SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance(
|
||||||
@ -273,7 +288,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) {
|
if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) {
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
|
||||||
} else {
|
} else {
|
||||||
//subghz_get_preset_name(subghz, subghz->error_str);
|
subghz->txrx->raw_threshold_rssi_low_count = RAW_THRESHOLD_RSSI_LOW_COUNT;
|
||||||
if(subghz_protocol_raw_save_to_file_init(
|
if(subghz_protocol_raw_save_to_file_init(
|
||||||
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result,
|
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result,
|
||||||
RAW_FILE_NAME,
|
RAW_FILE_NAME,
|
||||||
@ -319,7 +334,35 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
|||||||
subghz->subghz_read_raw,
|
subghz->subghz_read_raw,
|
||||||
subghz_protocol_raw_get_sample_write(
|
subghz_protocol_raw_get_sample_write(
|
||||||
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result));
|
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result));
|
||||||
subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi());
|
|
||||||
|
float rssi = furi_hal_subghz_get_rssi();
|
||||||
|
|
||||||
|
if(subghz->txrx->raw_threshold_rssi == SUBGHZ_RAW_TRESHOLD_MIN) {
|
||||||
|
subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, true);
|
||||||
|
subghz_protocol_raw_save_to_file_pause(
|
||||||
|
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, false);
|
||||||
|
} else {
|
||||||
|
if(rssi < subghz->txrx->raw_threshold_rssi) {
|
||||||
|
subghz->txrx->raw_threshold_rssi_low_count++;
|
||||||
|
if(subghz->txrx->raw_threshold_rssi_low_count > RAW_THRESHOLD_RSSI_LOW_COUNT) {
|
||||||
|
subghz->txrx->raw_threshold_rssi_low_count = RAW_THRESHOLD_RSSI_LOW_COUNT;
|
||||||
|
}
|
||||||
|
subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, false);
|
||||||
|
} else {
|
||||||
|
subghz->txrx->raw_threshold_rssi_low_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(subghz->txrx->raw_threshold_rssi_low_count == RAW_THRESHOLD_RSSI_LOW_COUNT) {
|
||||||
|
subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, false);
|
||||||
|
subghz_protocol_raw_save_to_file_pause(
|
||||||
|
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, true);
|
||||||
|
} else {
|
||||||
|
subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, true);
|
||||||
|
subghz_protocol_raw_save_to_file_pause(
|
||||||
|
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SubGhzNotificationStateTx:
|
case SubGhzNotificationStateTx:
|
||||||
notification_message(subghz->notifications, &sequence_blink_magenta_10);
|
notification_message(subghz->notifications, &sequence_blink_magenta_10);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
#include "../views/receiver.h"
|
#include "../views/receiver.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
static const NotificationSequence subghs_sequence_rx = {
|
static const NotificationSequence subghs_sequence_rx = {
|
||||||
&message_green_255,
|
&message_green_255,
|
||||||
@ -181,6 +182,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
|
|||||||
subghz->txrx->idx_menu_chosen =
|
subghz->txrx->idx_menu_chosen =
|
||||||
subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
|
subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo);
|
||||||
|
DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
case SubGhzCustomEventViewReceiverConfig:
|
case SubGhzCustomEventViewReceiverConfig:
|
||||||
|
|||||||
@ -1,10 +1,41 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
|
#include <lib/toolbox/value_index.h>
|
||||||
|
|
||||||
enum SubGhzSettingIndex {
|
enum SubGhzSettingIndex {
|
||||||
SubGhzSettingIndexFrequency,
|
SubGhzSettingIndexFrequency,
|
||||||
SubGhzSettingIndexHopping,
|
SubGhzSettingIndexHopping,
|
||||||
SubGhzSettingIndexModulation,
|
SubGhzSettingIndexModulation,
|
||||||
SubGhzSettingIndexLock,
|
SubGhzSettingIndexLock,
|
||||||
|
SubGhzSettingIndexRAWThesholdRSSI,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RAW_THRESHOLD_RSSI_COUNT 11
|
||||||
|
const char* const raw_theshold_rssi_text[RAW_THRESHOLD_RSSI_COUNT] = {
|
||||||
|
"-----",
|
||||||
|
"-85.0",
|
||||||
|
"-80.0",
|
||||||
|
"-75.0",
|
||||||
|
"-70.0",
|
||||||
|
"-65.0",
|
||||||
|
"-60.0",
|
||||||
|
"-55.0",
|
||||||
|
"-50.0",
|
||||||
|
"-45.0",
|
||||||
|
"-40.0",
|
||||||
|
|
||||||
|
};
|
||||||
|
const float raw_theshold_rssi_value[RAW_THRESHOLD_RSSI_COUNT] = {
|
||||||
|
-90.0f,
|
||||||
|
-85.0f,
|
||||||
|
-80.0f,
|
||||||
|
-75.0f,
|
||||||
|
-70.0f,
|
||||||
|
-65.0f,
|
||||||
|
-60.0f,
|
||||||
|
-55.0f,
|
||||||
|
-50.0f,
|
||||||
|
-45.0f,
|
||||||
|
-40.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HOPPING_COUNT 2
|
#define HOPPING_COUNT 2
|
||||||
@ -136,6 +167,14 @@ static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item)
|
|||||||
subghz->txrx->hopper_state = hopping_value[index];
|
subghz->txrx->hopper_state = hopping_value[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* item) {
|
||||||
|
SubGhz* subghz = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
|
||||||
|
variable_item_set_current_value_text(item, raw_theshold_rssi_text[index]);
|
||||||
|
subghz->txrx->raw_threshold_rssi = raw_theshold_rssi_value[index];
|
||||||
|
}
|
||||||
|
|
||||||
static void subghz_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) {
|
static void subghz_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
@ -204,6 +243,19 @@ void subghz_scene_receiver_config_on_enter(void* context) {
|
|||||||
subghz_scene_receiver_config_var_list_enter_callback,
|
subghz_scene_receiver_config_var_list_enter_callback,
|
||||||
subghz);
|
subghz);
|
||||||
}
|
}
|
||||||
|
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) ==
|
||||||
|
SubGhzCustomEventManagerSet) {
|
||||||
|
item = variable_item_list_add(
|
||||||
|
subghz->variable_item_list,
|
||||||
|
"RSSI Threshold:",
|
||||||
|
RAW_THRESHOLD_RSSI_COUNT,
|
||||||
|
subghz_scene_receiver_config_set_raw_threshold_rssi,
|
||||||
|
subghz);
|
||||||
|
value_index = value_index_float(
|
||||||
|
subghz->txrx->raw_threshold_rssi, raw_theshold_rssi_value, RAW_THRESHOLD_RSSI_COUNT);
|
||||||
|
variable_item_set_current_value_index(item, value_index);
|
||||||
|
variable_item_set_current_value_text(item, raw_theshold_rssi_text[value_index]);
|
||||||
|
}
|
||||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
#include "../helpers/subghz_custom_event.h"
|
#include "../helpers/subghz_custom_event.h"
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) {
|
void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -28,8 +27,8 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
|
|||||||
subghz->txrx->decoder_result,
|
subghz->txrx->decoder_result,
|
||||||
subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
|
subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
|
||||||
|
|
||||||
SubGhzPresetDefinition* preset =
|
SubGhzRadioPreset* preset =
|
||||||
subghz_history_get_preset_def(subghz->txrx->history, subghz->txrx->idx_menu_chosen);
|
subghz_history_get_radio_preset(subghz->txrx->history, subghz->txrx->idx_menu_chosen);
|
||||||
subghz_preset_init(
|
subghz_preset_init(
|
||||||
subghz,
|
subghz,
|
||||||
furi_string_get_cstr(preset->name),
|
furi_string_get_cstr(preset->name),
|
||||||
@ -45,7 +44,6 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
|
|||||||
void subghz_scene_receiver_info_on_enter(void* context) {
|
void subghz_scene_receiver_info_on_enter(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
|
|
||||||
DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo);
|
|
||||||
if(subghz_scene_receiver_info_update_parser(subghz)) {
|
if(subghz_scene_receiver_info_update_parser(subghz)) {
|
||||||
FuriString* frequency_str;
|
FuriString* frequency_str;
|
||||||
FuriString* modulation_str;
|
FuriString* modulation_str;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "../helpers/subghz_custom_event.h"
|
#include "../helpers/subghz_custom_event.h"
|
||||||
#include <lib/subghz/protocols/raw.h>
|
#include <lib/subghz/protocols/raw.h>
|
||||||
#include <gui/modules/validators.h>
|
#include <gui/modules/validators.h>
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
#define MAX_TEXT_INPUT_LEN 22
|
#define MAX_TEXT_INPUT_LEN 22
|
||||||
|
|
||||||
@ -131,6 +132,17 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess);
|
||||||
|
if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSavedMenu)) {
|
||||||
|
// Nothing, do not count editing as saving
|
||||||
|
} else if(scene_manager_has_previous_scene(
|
||||||
|
subghz->scene_manager, SubGhzSceneMoreRAW)) {
|
||||||
|
// Ditto, for RAW signals
|
||||||
|
} else if(scene_manager_has_previous_scene(
|
||||||
|
subghz->scene_manager, SubGhzSceneSetType)) {
|
||||||
|
DOLPHIN_DEED(DolphinDeedSubGhzAddManually);
|
||||||
|
} else {
|
||||||
|
DOLPHIN_DEED(DolphinDeedSubGhzSave);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
furi_string_set(subghz->error_str, "No name file");
|
furi_string_set(subghz->error_str, "No name file");
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
#include "../helpers/subghz_custom_event.h"
|
#include "../helpers/subghz_custom_event.h"
|
||||||
#include <dolphin/helpers/dolphin_deed.h>
|
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
void subghz_scene_save_success_popup_callback(void* context) {
|
void subghz_scene_save_success_popup_callback(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
@ -10,7 +8,6 @@ void subghz_scene_save_success_popup_callback(void* context) {
|
|||||||
|
|
||||||
void subghz_scene_save_success_on_enter(void* context) {
|
void subghz_scene_save_success_on_enter(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
DOLPHIN_DEED(DolphinDeedSubGhzSave);
|
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
Popup* popup = subghz->popup;
|
Popup* popup = subghz->popup;
|
||||||
|
|||||||
@ -3,10 +3,9 @@
|
|||||||
#include <lib/subghz/protocols/secplus_v1.h>
|
#include <lib/subghz/protocols/secplus_v1.h>
|
||||||
#include <lib/subghz/protocols/secplus_v2.h>
|
#include <lib/subghz/protocols/secplus_v2.h>
|
||||||
#include <lib/subghz/blocks/math.h>
|
#include <lib/subghz/blocks/math.h>
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
#include <flipper_format/flipper_format_i.h>
|
#include <flipper_format/flipper_format_i.h>
|
||||||
#include <lib/toolbox/stream/stream.h>
|
#include <lib/toolbox/stream/stream.h>
|
||||||
#include <lib/subghz/protocols/registry.h>
|
#include <lib/subghz/protocols/protocol_items.h>
|
||||||
|
|
||||||
#define TAG "SubGhzSetType"
|
#define TAG "SubGhzSetType"
|
||||||
|
|
||||||
@ -381,7 +380,6 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
if(generated_protocol) {
|
if(generated_protocol) {
|
||||||
subghz_file_name_clear(subghz);
|
subghz_file_name_clear(subghz);
|
||||||
DOLPHIN_DEED(DolphinDeedSubGhzAddManually);
|
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexRead = 10,
|
SubmenuIndexRead = 10,
|
||||||
@ -84,6 +85,7 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
|
|||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
||||||
|
DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer);
|
||||||
return true;
|
return true;
|
||||||
} else if(event.event == SubmenuIndexTest) {
|
} else if(event.event == SubmenuIndexTest) {
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
|
|||||||
@ -50,7 +50,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
|
|||||||
|
|
||||||
void subghz_scene_transmitter_on_enter(void* context) {
|
void subghz_scene_transmitter_on_enter(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
DOLPHIN_DEED(DolphinDeedSubGhzSend);
|
|
||||||
if(!subghz_scene_transmitter_update_data_show(subghz)) {
|
if(!subghz_scene_transmitter_update_data_show(subghz)) {
|
||||||
view_dispatcher_send_custom_event(
|
view_dispatcher_send_custom_event(
|
||||||
subghz->view_dispatcher, SubGhzCustomEventViewTransmitterError);
|
subghz->view_dispatcher, SubGhzCustomEventViewTransmitterError);
|
||||||
@ -78,6 +77,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
|
|||||||
} else {
|
} else {
|
||||||
subghz->state_notifications = SubGhzNotificationStateTx;
|
subghz->state_notifications = SubGhzNotificationStateTx;
|
||||||
subghz_scene_transmitter_update_data_show(subghz);
|
subghz_scene_transmitter_update_data_show(subghz);
|
||||||
|
DOLPHIN_DEED(DolphinDeedSubGhzSend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user