mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-20 20:38:24 -07:00
Merge branch 'dev' into zlo/tlsf-and-a-temple-of-memcorrupt
This commit is contained in:
@@ -5,6 +5,10 @@ CompileFlags:
|
||||
Remove:
|
||||
- -mword-relocations
|
||||
|
||||
Diagnostics:
|
||||
ClangTidy:
|
||||
FastCheckFilter: None
|
||||
|
||||
---
|
||||
|
||||
If:
|
||||
|
||||
@@ -64,6 +64,6 @@ jobs:
|
||||
python3 scripts/testing/units.py ${{steps.device.outputs.flipper}}
|
||||
|
||||
- name: 'Check GDB output'
|
||||
if: failure()
|
||||
if: failure() && steps.flashing.outcome == 'success'
|
||||
run: |
|
||||
./fbt gdb_trace_all SWD_TRANSPORT_SERIAL=2A0906016415303030303032 LIB_DEBUG=1 FIRMWARE_APP_SET=unit_tests FORCE=1
|
||||
|
||||
Vendored
+1
-1
@@ -10,7 +10,7 @@
|
||||
"clangd": {
|
||||
"initializationOptions": {
|
||||
"clangd.compile-commands-dir": "build/latest",
|
||||
"clangd.header-insertion": null,
|
||||
"clangd.header-insertion": "never",
|
||||
"clangd.query-driver": "**",
|
||||
"clangd.clang-tidy": true,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "../accessor_app.h"
|
||||
#include "../accessor_view_manager.h"
|
||||
#include "../accessor_event.h"
|
||||
#include "callback_connector.h"
|
||||
#include "accessor_scene_start.h"
|
||||
|
||||
void AccessorSceneStart::on_enter(AccessorApp* app) {
|
||||
|
||||
@@ -68,7 +68,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
||||
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
|
||||
} else if(drain_current != 0) {
|
||||
snprintf(header, 20, "...");
|
||||
} else if(data->charging_voltage < 4.2) {
|
||||
} else if(data->charging_voltage < 4.2f) {
|
||||
// Non-default battery charging limit, mention it
|
||||
snprintf(emote, sizeof(emote), "Charged!");
|
||||
snprintf(header, sizeof(header), "Limited to");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <core/common_defines.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ CcidTestApp* ccid_test_app_alloc(void) {
|
||||
|
||||
//message queue
|
||||
app->event_queue = furi_message_queue_alloc(8, sizeof(CcidTestAppEvent));
|
||||
furi_check(app->event_queue);
|
||||
view_port_input_callback_set(app->view_port, ccid_test_app_input_callback, app->event_queue);
|
||||
|
||||
return app;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "display_test.h"
|
||||
|
||||
#include <furi_hal.h>
|
||||
#include <furi.h>
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@@ -64,16 +64,9 @@ static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||
int32_t keypad_test_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||
furi_check(event_queue);
|
||||
|
||||
KeypadTestState state = {{false, false, false, false, false}, 0, 0, 0, 0, 0, NULL};
|
||||
state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
if(!state.mutex) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, keypad_test_render_callback, &state);
|
||||
|
||||
@@ -34,8 +34,8 @@ static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
char buffer[TEMP_STR_LEN + 1];
|
||||
double freq = ((float)SystemCoreClock / ((float)model->ARR + 1));
|
||||
double duty = ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f;
|
||||
double freq = ((double)SystemCoreClock / (model->ARR + 1));
|
||||
double duty = (double)((model->CCR + 1) * 100) / (model->ARR + 1);
|
||||
snprintf(
|
||||
buffer,
|
||||
TEMP_STR_LEN,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_test_app_i.h"
|
||||
#include "../subghz_test_app_i.h" // IWYU pragma: keep
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "subghz_test_app_i.h"
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#define TAG "SubGhzTest"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "subghz_test_carrier.h"
|
||||
#include "../subghz_test_app_i.h"
|
||||
#include "../helpers/subghz_test_frequency.h"
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
@@ -74,7 +73,7 @@ void subghz_test_carrier_draw(Canvas* canvas, SubGhzTestCarrierModel* model) {
|
||||
sizeof(buffer),
|
||||
"RSSI: %ld.%ld dBm",
|
||||
(int32_t)(model->rssi),
|
||||
(int32_t)fabs(model->rssi * 10) % 10);
|
||||
(int32_t)fabsf(model->rssi * 10.f) % 10);
|
||||
canvas_draw_str(canvas, 0, 42, buffer);
|
||||
} else {
|
||||
canvas_draw_str(canvas, 0, 42, "TX");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "subghz_test_packet.h"
|
||||
#include "../subghz_test_app_i.h"
|
||||
#include "../helpers/subghz_test_frequency.h"
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
@@ -123,7 +122,7 @@ static void subghz_test_packet_draw(Canvas* canvas, SubGhzTestPacketModel* model
|
||||
sizeof(buffer),
|
||||
"RSSI: %ld.%ld dBm",
|
||||
(int32_t)(model->rssi),
|
||||
(int32_t)fabs(model->rssi * 10) % 10);
|
||||
(int32_t)fabsf(model->rssi * 10.0f) % 10);
|
||||
canvas_draw_str(canvas, 0, 53, buffer);
|
||||
} else {
|
||||
canvas_draw_str(canvas, 0, 53, "TX");
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include "subghz_test_static.h"
|
||||
#include "../subghz_test_app_i.h"
|
||||
#include "../helpers/subghz_test_frequency.h"
|
||||
#include <lib/subghz/devices/cc1101_configs.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
|
||||
@@ -74,16 +74,8 @@ static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||
int32_t text_box_element_test_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||
furi_check(event_queue);
|
||||
|
||||
TextBoxTestState state = {.idx = 0, .mutex = NULL};
|
||||
state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
||||
if(!state.mutex) {
|
||||
FURI_LOG_E(TAG, "Cannot create mutex");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, text_box_test_render_callback, &state);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
Filetype: Flipper NFC device
|
||||
Version: 4
|
||||
# Device type can be ISO14443-3A, ISO14443-3B, ISO14443-4A, ISO14443-4B, ISO15693-3, FeliCa, NTAG/Ultralight, Mifare Classic, Mifare DESFire, SLIX, ST25TB
|
||||
Device type: FeliCa
|
||||
# UID is common for all formats
|
||||
UID: 29 9F FA 53 AB 75 87 6E
|
||||
# FeliCa specific data
|
||||
Data format version: 1
|
||||
Manufacture id: 29 9F FA 53 AB 75 87 6E
|
||||
Manufacture parameter: 57 4E 10 2A 94 16 BC 8E
|
||||
Blocks total: 28
|
||||
Blocks read: 28
|
||||
Block 0: 00 00 DE AD BE AF 00 00 00 00 00 00 00 00 DE AD BE AF
|
||||
Block 1: 00 00 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
|
||||
Block 2: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 3: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 5: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 6: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 7: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 9: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 11: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 12: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 13: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 14: 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
Block 15: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 16: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 17: 00 00 29 9F FA 53 AB 75 87 6E 57 4E 10 2A 94 16 BC 8E
|
||||
Block 18: 00 00 29 9F FA 53 AB 75 87 6E 00 F1 00 00 00 01 43 00
|
||||
Block 19: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 20: 00 00 88 B4 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 21: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 22: 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
Block 23: 00 00 FF FF FF 00 FF 00 10 00 00 00 00 00 00 00 00 00
|
||||
Block 24: 00 00 24 FE FF 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 25: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 26: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Block 27: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
@@ -72,6 +72,9 @@ void test_runner_free(TestRunner* instance) {
|
||||
free(instance);
|
||||
}
|
||||
|
||||
#define TEST_RUNNER_TMP_DIR EXT_PATH(".tmp")
|
||||
#define TEST_RUNNER_TMP_UNIT_TESTS_DIR TEST_RUNNER_TMP_DIR "/unit_tests"
|
||||
|
||||
static bool test_runner_run_plugin(TestRunner* instance, const char* path) {
|
||||
furi_assert(instance);
|
||||
|
||||
@@ -128,6 +131,16 @@ static void test_runner_run_internal(TestRunner* instance) {
|
||||
File* directory = storage_file_alloc(instance->storage);
|
||||
|
||||
do {
|
||||
if(!storage_simply_mkdir(instance->storage, TEST_RUNNER_TMP_DIR)) {
|
||||
FURI_LOG_E(TAG, "Cannot create dir %s", TEST_RUNNER_TMP_DIR);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!storage_simply_mkdir(instance->storage, TEST_RUNNER_TMP_UNIT_TESTS_DIR)) {
|
||||
FURI_LOG_E(TAG, "Cannot create dir %s", TEST_RUNNER_TMP_UNIT_TESTS_DIR);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!storage_dir_open(directory, PLUGINS_PATH)) {
|
||||
FURI_LOG_E(TAG, "Failed to open directory %s", PLUGINS_PATH);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <bit_lib/bit_lib.h>
|
||||
|
||||
MU_TEST(test_bit_lib_increment_index) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <bt/bt_service/bt_keys_storage.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <toolbox/compress.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <datetime/datetime.h>
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
MU_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields) {
|
||||
mu_assert(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <furi.h>
|
||||
#include <m-dict.h>
|
||||
#include <toolbox/dir_walk.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal_random.h>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#include <flipper_format/flipper_format.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#define TEST_DIR_NAME EXT_PATH(".tmp/unit_tests/ff")
|
||||
#define TEST_DIR TEST_DIR_NAME "/"
|
||||
#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp")
|
||||
|
||||
static const char* test_filetype = "Flipper File test";
|
||||
static const uint32_t test_version = 666;
|
||||
|
||||
+3
-2
@@ -3,7 +3,7 @@
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include <storage/storage.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
static const char* test_filetype = "Flipper Format test";
|
||||
static const uint32_t test_version = 666;
|
||||
@@ -298,7 +298,8 @@ MU_TEST(flipper_format_string_test) {
|
||||
MU_TEST(flipper_format_file_test) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
|
||||
mu_check(flipper_format_file_open_always(flipper_format, EXT_PATH("flipper.fff")));
|
||||
mu_check(
|
||||
flipper_format_file_open_always(flipper_format, EXT_PATH(".tmp/unit_tests/flipper.fff")));
|
||||
Stream* stream = flipper_format_get_raw_stream(flipper_format);
|
||||
|
||||
mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <float.h>
|
||||
#include <float_tools.h>
|
||||
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
MU_TEST(float_tools_equal_test) {
|
||||
mu_check(float_is_equal(FLT_MAX, FLT_MAX));
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
#include "../test.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#define TAG "TestFuriEventLoop"
|
||||
|
||||
#define EVENT_LOOP_EVENT_COUNT (256u)
|
||||
|
||||
typedef struct {
|
||||
FuriMessageQueue* mq;
|
||||
|
||||
FuriEventLoop* producer_event_loop;
|
||||
uint32_t producer_counter;
|
||||
|
||||
FuriEventLoop* consumer_event_loop;
|
||||
uint32_t consumer_counter;
|
||||
} TestFuriData;
|
||||
|
||||
bool test_furi_event_loop_producer_mq_callback(FuriMessageQueue* queue, void* context) {
|
||||
furi_check(context);
|
||||
|
||||
TestFuriData* data = context;
|
||||
furi_check(data->mq == queue, "Invalid queue");
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG, "producer_mq_callback: %lu %lu", data->producer_counter, data->consumer_counter);
|
||||
|
||||
// Remove and add should not cause crash
|
||||
// if(data->producer_counter == EVENT_LOOP_EVENT_COUNT/2) {
|
||||
// furi_event_loop_message_queue_remove(data->producer_event_loop, data->mq);
|
||||
// furi_event_loop_message_queue_add(
|
||||
// data->producer_event_loop,
|
||||
// data->mq,
|
||||
// FuriEventLoopEventOut,
|
||||
// test_furi_event_loop_producer_mq_callback,
|
||||
// data);
|
||||
// }
|
||||
|
||||
if(data->producer_counter == EVENT_LOOP_EVENT_COUNT) {
|
||||
furi_event_loop_stop(data->producer_event_loop);
|
||||
return false;
|
||||
}
|
||||
|
||||
data->producer_counter++;
|
||||
furi_check(
|
||||
furi_message_queue_put(data->mq, &data->producer_counter, 0) == FuriStatusOk,
|
||||
"furi_message_queue_put failed");
|
||||
furi_delay_us(furi_hal_random_get() % 1000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t test_furi_event_loop_producer(void* p) {
|
||||
furi_check(p);
|
||||
|
||||
FURI_LOG_I(TAG, "producer start");
|
||||
|
||||
TestFuriData* data = p;
|
||||
|
||||
data->producer_event_loop = furi_event_loop_alloc();
|
||||
furi_event_loop_message_queue_subscribe(
|
||||
data->producer_event_loop,
|
||||
data->mq,
|
||||
FuriEventLoopEventOut,
|
||||
test_furi_event_loop_producer_mq_callback,
|
||||
data);
|
||||
|
||||
furi_event_loop_run(data->producer_event_loop);
|
||||
|
||||
furi_event_loop_message_queue_unsubscribe(data->producer_event_loop, data->mq);
|
||||
furi_event_loop_free(data->producer_event_loop);
|
||||
|
||||
FURI_LOG_I(TAG, "producer end");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool test_furi_event_loop_consumer_mq_callback(FuriMessageQueue* queue, void* context) {
|
||||
furi_check(context);
|
||||
|
||||
TestFuriData* data = context;
|
||||
furi_check(data->mq == queue);
|
||||
|
||||
furi_delay_us(furi_hal_random_get() % 1000);
|
||||
furi_check(furi_message_queue_get(data->mq, &data->consumer_counter, 0) == FuriStatusOk);
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG, "consumer_mq_callback: %lu %lu", data->producer_counter, data->consumer_counter);
|
||||
|
||||
// Remove and add should not cause crash
|
||||
// if(data->producer_counter == EVENT_LOOP_EVENT_COUNT/2) {
|
||||
// furi_event_loop_message_queue_remove(data->consumer_event_loop, data->mq);
|
||||
// furi_event_loop_message_queue_add(
|
||||
// data->consumer_event_loop,
|
||||
// data->mq,
|
||||
// FuriEventLoopEventIn,
|
||||
// test_furi_event_loop_producer_mq_callback,
|
||||
// data);
|
||||
// }
|
||||
|
||||
if(data->consumer_counter == EVENT_LOOP_EVENT_COUNT) {
|
||||
furi_event_loop_stop(data->consumer_event_loop);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t test_furi_event_loop_consumer(void* p) {
|
||||
furi_check(p);
|
||||
|
||||
FURI_LOG_I(TAG, "consumer start");
|
||||
|
||||
TestFuriData* data = p;
|
||||
|
||||
data->consumer_event_loop = furi_event_loop_alloc();
|
||||
furi_event_loop_message_queue_subscribe(
|
||||
data->consumer_event_loop,
|
||||
data->mq,
|
||||
FuriEventLoopEventIn,
|
||||
test_furi_event_loop_consumer_mq_callback,
|
||||
data);
|
||||
|
||||
furi_event_loop_run(data->consumer_event_loop);
|
||||
|
||||
furi_event_loop_message_queue_unsubscribe(data->consumer_event_loop, data->mq);
|
||||
furi_event_loop_free(data->consumer_event_loop);
|
||||
|
||||
FURI_LOG_I(TAG, "consumer end");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_furi_event_loop(void) {
|
||||
TestFuriData data = {};
|
||||
|
||||
data.mq = furi_message_queue_alloc(16, sizeof(uint32_t));
|
||||
|
||||
FuriThread* producer_thread = furi_thread_alloc();
|
||||
furi_thread_set_name(producer_thread, "producer_thread");
|
||||
furi_thread_set_stack_size(producer_thread, 1 * 1024);
|
||||
furi_thread_set_callback(producer_thread, test_furi_event_loop_producer);
|
||||
furi_thread_set_context(producer_thread, &data);
|
||||
furi_thread_start(producer_thread);
|
||||
|
||||
FuriThread* consumer_thread = furi_thread_alloc();
|
||||
furi_thread_set_name(consumer_thread, "consumer_thread");
|
||||
furi_thread_set_stack_size(consumer_thread, 1 * 1024);
|
||||
furi_thread_set_callback(consumer_thread, test_furi_event_loop_consumer);
|
||||
furi_thread_set_context(consumer_thread, &data);
|
||||
furi_thread_start(consumer_thread);
|
||||
|
||||
// Wait for thread to complete their tasks
|
||||
furi_thread_join(producer_thread);
|
||||
furi_thread_join(consumer_thread);
|
||||
|
||||
// The test itself
|
||||
mu_assert_int_eq(data.producer_counter, data.consumer_counter);
|
||||
|
||||
// Release memory
|
||||
furi_thread_free(consumer_thread);
|
||||
furi_thread_free(producer_thread);
|
||||
furi_message_queue_free(data.mq);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
const uint32_t context_value = 0xdeadbeef;
|
||||
const uint32_t notify_value_0 = 0x12345678;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#define TEST_RECORD_NAME "test/holding"
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
// v2 tests
|
||||
void test_furi_create_open(void);
|
||||
void test_furi_concurrent_access(void);
|
||||
void test_furi_pubsub(void);
|
||||
|
||||
void test_furi_memmgr(void);
|
||||
void test_furi_memmgr_advanced(void);
|
||||
void test_furi_memmgr_aligned8(void);
|
||||
void test_furi_event_loop(void);
|
||||
|
||||
static int foo = 0;
|
||||
|
||||
@@ -43,15 +42,19 @@ MU_TEST(mu_test_furi_memmgr) {
|
||||
test_furi_memmgr_aligned8();
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_event_loop) {
|
||||
test_furi_event_loop();
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_suite) {
|
||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||
|
||||
MU_RUN_TEST(test_check);
|
||||
|
||||
// v2 tests
|
||||
MU_RUN_TEST(mu_test_furi_create_open);
|
||||
MU_RUN_TEST(mu_test_furi_pubsub);
|
||||
MU_RUN_TEST(mu_test_furi_memmgr);
|
||||
MU_RUN_TEST(mu_test_furi_event_loop);
|
||||
}
|
||||
|
||||
int run_minunit_test_furi(void) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#include "furi_hal_rtc.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <lp5562_reg.h>
|
||||
#include "../test.h"
|
||||
#include <stdlib.h>
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#define DATA_SIZE 4
|
||||
#define EEPROM_ADDRESS 0b10101000
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
static const uint8_t key_ctr_1[32] = {
|
||||
0x77, 0x6B, 0xEF, 0xF2, 0x85, 0x1D, 0xB0, 0x6F, 0x4C, 0x8A, 0x05, 0x42, 0xC8, 0x69, 0x6F, 0x6C,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
static void test_setup(void) {
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <flipper_format.h>
|
||||
#include <infrared.h>
|
||||
#include <common/infrared_common_i.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#define IR_TEST_FILES_DIR EXT_PATH("unit_tests/infrared/")
|
||||
#define IR_TEST_FILE_PREFIX "test_"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <toolbox/protocols/protocol_dict.h>
|
||||
#include <lfrfid/protocols/lfrfid_protocols.h>
|
||||
#include <toolbox/pulse_protocols/pulse_glue.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.c>
|
||||
#include "../test.h"
|
||||
#include <furi.h>
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <update_util/resources/manifest.h>
|
||||
|
||||
#define TAG "Manifest"
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight.h>
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller_sync.h>
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
|
||||
#include <nfc/protocols/felica/felica.h>
|
||||
#include <nfc/protocols/felica/felica_poller_sync.h>
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller.h>
|
||||
#include <nfc/protocols/iso15693_3/iso15693_3_poller.h>
|
||||
#include <nfc/protocols/slix/slix.h>
|
||||
@@ -24,7 +26,7 @@
|
||||
#include <toolbox/keys_dict.h>
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#define TAG "NfcTest"
|
||||
|
||||
@@ -646,6 +648,56 @@ MU_TEST(mf_classic_dict_test) {
|
||||
"Remove test dict failed");
|
||||
}
|
||||
|
||||
static FelicaError
|
||||
felica_do_request_response(FelicaData* felica_data, const FelicaCardKey* card_key) {
|
||||
NfcDeviceData* nfc_device = nfc_device_alloc();
|
||||
|
||||
FelicaError error = FelicaErrorNone;
|
||||
if(!nfc_device_load(nfc_device, EXT_PATH("unit_tests/nfc/Felica.nfc"))) {
|
||||
error = FelicaErrorNotPresent;
|
||||
} else {
|
||||
Nfc* poller = nfc_alloc();
|
||||
Nfc* listener = nfc_alloc();
|
||||
NfcListener* felica_listener = nfc_listener_alloc(
|
||||
listener, NfcProtocolFelica, nfc_device_get_data(nfc_device, NfcProtocolFelica));
|
||||
nfc_listener_start(felica_listener, NULL, NULL);
|
||||
|
||||
error = felica_poller_sync_read(poller, felica_data, card_key);
|
||||
|
||||
nfc_listener_stop(felica_listener);
|
||||
nfc_listener_free(felica_listener);
|
||||
|
||||
nfc_free(listener);
|
||||
nfc_free(poller);
|
||||
}
|
||||
|
||||
nfc_device_free(nfc_device);
|
||||
return error;
|
||||
}
|
||||
|
||||
MU_TEST(felica_read) {
|
||||
FelicaData* felica_data = felica_alloc();
|
||||
FelicaError error = felica_do_request_response(felica_data, NULL);
|
||||
mu_assert(error == FelicaErrorNone, "felica_poller() failed");
|
||||
mu_assert(felica_data->data.fs.spad[4].SF1 == 0x01, "block[4].SF1 != 0x01");
|
||||
mu_assert(felica_data->data.fs.spad[4].SF2 == 0xB1, "block[4].SF2 != 0xB1");
|
||||
|
||||
felica_free(felica_data);
|
||||
}
|
||||
|
||||
MU_TEST(felica_read_auth) {
|
||||
FelicaData* felica_data = felica_alloc();
|
||||
FelicaCardKey card_key;
|
||||
memset(card_key.data, 0xFF, FELICA_DATA_BLOCK_SIZE);
|
||||
|
||||
FelicaError error = felica_do_request_response(felica_data, &card_key);
|
||||
mu_assert(error == FelicaErrorNone, "felica_poller() failed");
|
||||
mu_assert(felica_data->data.fs.spad[4].SF1 == 0x00, "block[4].SF1 != 0x00");
|
||||
mu_assert(felica_data->data.fs.spad[4].SF2 == 0x00, "block[4].SF2 != 0x00");
|
||||
|
||||
felica_free(felica_data);
|
||||
}
|
||||
|
||||
MU_TEST(slix_file_with_capabilities_test) {
|
||||
NfcDevice* nfc_device_missed_cap = nfc_device_alloc();
|
||||
mu_assert(
|
||||
@@ -807,6 +859,8 @@ MU_TEST_SUITE(nfc) {
|
||||
MU_RUN_TEST(mf_classic_value_block);
|
||||
MU_RUN_TEST(mf_classic_send_frame_test);
|
||||
MU_RUN_TEST(mf_classic_dict_test);
|
||||
MU_RUN_TEST(felica_read);
|
||||
MU_RUN_TEST(felica_read_auth);
|
||||
|
||||
MU_RUN_TEST(slix_file_with_capabilities_test);
|
||||
MU_RUN_TEST(slix_set_password_default_cap_correct_pass);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
static void power_test_deinit(void) {
|
||||
// Try to reset to default charge voltage limit
|
||||
@@ -13,46 +13,47 @@ MU_TEST(test_power_charge_voltage_limit_exact) {
|
||||
//
|
||||
// This test may need adapted if other charge controllers are used in the future.
|
||||
for(uint16_t charge_mv = 3840; charge_mv <= 4208; charge_mv += 16) {
|
||||
float charge_volt = (float)charge_mv / 1000.0f;
|
||||
float charge_volt = (float)charge_mv / 1000;
|
||||
furi_hal_power_set_battery_charge_voltage_limit(charge_volt);
|
||||
mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(
|
||||
(double)charge_volt, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
}
|
||||
}
|
||||
|
||||
MU_TEST(test_power_charge_voltage_limit_floating_imprecision) {
|
||||
// 4.016f should act as 4.016 V, even with floating point imprecision
|
||||
furi_hal_power_set_battery_charge_voltage_limit(4.016f);
|
||||
mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(4.016, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
}
|
||||
|
||||
MU_TEST(test_power_charge_voltage_limit_inexact) {
|
||||
// Charge voltage limits that are not power of 16mV get truncated down
|
||||
furi_hal_power_set_battery_charge_voltage_limit(3.841f);
|
||||
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(3.840, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
|
||||
furi_hal_power_set_battery_charge_voltage_limit(3.900f);
|
||||
mu_assert_double_eq(3.888, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(3.888, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
|
||||
furi_hal_power_set_battery_charge_voltage_limit(4.200f);
|
||||
mu_assert_double_eq(4.192, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(4.192, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
}
|
||||
|
||||
MU_TEST(test_power_charge_voltage_limit_invalid_clamped) {
|
||||
// Out-of-range charge voltage limits get clamped to 3.840 V and 4.208 V
|
||||
furi_hal_power_set_battery_charge_voltage_limit(3.808f);
|
||||
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(3.840, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
furi_hal_power_set_battery_charge_voltage_limit(1.0f);
|
||||
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(3.840, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
|
||||
// NOTE: Intentionally picking a small increment above 4.208 V to reduce the risk of an
|
||||
// unhappy battery if this fails.
|
||||
furi_hal_power_set_battery_charge_voltage_limit(4.240f);
|
||||
mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(4.208, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
// Likewise, picking a number that the uint8_t wraparound in the driver would result in a
|
||||
// VREG value under 23 if this test fails.
|
||||
// E.g. (uint8_t)((8105-3840)/16) -> 10
|
||||
furi_hal_power_set_battery_charge_voltage_limit(8.105f);
|
||||
mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit());
|
||||
mu_assert_double_eq(4.208, (double)furi_hal_power_get_battery_charge_voltage_limit());
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(test_power_suite) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <furi.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <toolbox/protocols/protocol_dict.h>
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
#include <core/check.h>
|
||||
#include <core/record.h>
|
||||
#include <furi.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <semphr.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpc_i.h>
|
||||
#include <cli/cli.h>
|
||||
@@ -17,7 +12,7 @@
|
||||
#include <lib/toolbox/path.h>
|
||||
|
||||
#include <m-list.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <protobuf_version.h>
|
||||
#include <pb.h>
|
||||
@@ -40,8 +35,8 @@ static uint32_t command_id = 0;
|
||||
typedef struct {
|
||||
RpcSession* session;
|
||||
FuriStreamBuffer* output_stream;
|
||||
SemaphoreHandle_t close_session_semaphore;
|
||||
SemaphoreHandle_t terminate_semaphore;
|
||||
FuriSemaphore* close_session_semaphore;
|
||||
FuriSemaphore* terminate_semaphore;
|
||||
uint32_t timeout;
|
||||
} RpcSessionContext;
|
||||
|
||||
@@ -51,8 +46,8 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS];
|
||||
#define MAX_RECEIVE_OUTPUT_TIMEOUT 3000
|
||||
#define MAX_NAME_LENGTH 255
|
||||
#define MAX_DATA_SIZE 512u // have to be exact as in rpc_storage.c
|
||||
#define TEST_DIR_NAME EXT_PATH(".tmp/unit_tests/rpc")
|
||||
#define TEST_DIR TEST_DIR_NAME "/"
|
||||
#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp")
|
||||
#define MD5SUM_SIZE 16
|
||||
|
||||
#define PING_REQUEST 0
|
||||
@@ -96,8 +91,8 @@ static void test_rpc_setup(void) {
|
||||
|
||||
rpc_session[0].output_stream = furi_stream_buffer_alloc(4096, 1);
|
||||
rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback);
|
||||
rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary();
|
||||
rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary();
|
||||
rpc_session[0].close_session_semaphore = furi_semaphore_alloc(1, 0);
|
||||
rpc_session[0].terminate_semaphore = furi_semaphore_alloc(1, 0);
|
||||
rpc_session_set_close_callback(rpc_session[0].session, test_rpc_session_close_callback);
|
||||
rpc_session_set_terminated_callback(
|
||||
rpc_session[0].session, test_rpc_session_terminated_callback);
|
||||
@@ -116,8 +111,8 @@ static void test_rpc_setup_second_session(void) {
|
||||
|
||||
rpc_session[1].output_stream = furi_stream_buffer_alloc(1000, 1);
|
||||
rpc_session_set_send_bytes_callback(rpc_session[1].session, output_bytes_callback);
|
||||
rpc_session[1].close_session_semaphore = xSemaphoreCreateBinary();
|
||||
rpc_session[1].terminate_semaphore = xSemaphoreCreateBinary();
|
||||
rpc_session[1].close_session_semaphore = furi_semaphore_alloc(1, 0);
|
||||
rpc_session[1].terminate_semaphore = furi_semaphore_alloc(1, 0);
|
||||
rpc_session_set_close_callback(rpc_session[1].session, test_rpc_session_close_callback);
|
||||
rpc_session_set_terminated_callback(
|
||||
rpc_session[1].session, test_rpc_session_terminated_callback);
|
||||
@@ -126,13 +121,15 @@ static void test_rpc_setup_second_session(void) {
|
||||
|
||||
static void test_rpc_teardown(void) {
|
||||
furi_check(rpc_session[0].close_session_semaphore);
|
||||
xSemaphoreTake(rpc_session[0].terminate_semaphore, 0);
|
||||
furi_semaphore_acquire(rpc_session[0].terminate_semaphore, 0);
|
||||
rpc_session_close(rpc_session[0].session);
|
||||
furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY));
|
||||
furi_check(
|
||||
furi_semaphore_acquire(rpc_session[0].terminate_semaphore, FuriWaitForever) ==
|
||||
FuriStatusOk);
|
||||
furi_record_close(RECORD_RPC);
|
||||
furi_stream_buffer_free(rpc_session[0].output_stream);
|
||||
vSemaphoreDelete(rpc_session[0].close_session_semaphore);
|
||||
vSemaphoreDelete(rpc_session[0].terminate_semaphore);
|
||||
furi_semaphore_free(rpc_session[0].close_session_semaphore);
|
||||
furi_semaphore_free(rpc_session[0].terminate_semaphore);
|
||||
++command_id;
|
||||
rpc_session[0].output_stream = NULL;
|
||||
rpc_session[0].close_session_semaphore = NULL;
|
||||
@@ -142,12 +139,14 @@ static void test_rpc_teardown(void) {
|
||||
|
||||
static void test_rpc_teardown_second_session(void) {
|
||||
furi_check(rpc_session[1].close_session_semaphore);
|
||||
xSemaphoreTake(rpc_session[1].terminate_semaphore, 0);
|
||||
furi_semaphore_acquire(rpc_session[1].terminate_semaphore, 0);
|
||||
rpc_session_close(rpc_session[1].session);
|
||||
furi_check(xSemaphoreTake(rpc_session[1].terminate_semaphore, portMAX_DELAY));
|
||||
furi_check(
|
||||
furi_semaphore_acquire(rpc_session[1].terminate_semaphore, FuriWaitForever) ==
|
||||
FuriStatusOk);
|
||||
furi_stream_buffer_free(rpc_session[1].output_stream);
|
||||
vSemaphoreDelete(rpc_session[1].close_session_semaphore);
|
||||
vSemaphoreDelete(rpc_session[1].terminate_semaphore);
|
||||
furi_semaphore_free(rpc_session[1].close_session_semaphore);
|
||||
furi_semaphore_free(rpc_session[1].terminate_semaphore);
|
||||
++command_id;
|
||||
rpc_session[1].output_stream = NULL;
|
||||
rpc_session[1].close_session_semaphore = NULL;
|
||||
@@ -204,14 +203,14 @@ static void test_rpc_session_close_callback(void* context) {
|
||||
furi_check(context);
|
||||
RpcSessionContext* callbacks_context = context;
|
||||
|
||||
xSemaphoreGive(callbacks_context->close_session_semaphore);
|
||||
furi_check(furi_semaphore_release(callbacks_context->close_session_semaphore) == FuriStatusOk);
|
||||
}
|
||||
|
||||
static void test_rpc_session_terminated_callback(void* context) {
|
||||
furi_check(context);
|
||||
RpcSessionContext* callbacks_context = context;
|
||||
|
||||
xSemaphoreGive(callbacks_context->terminate_semaphore);
|
||||
furi_check(furi_semaphore_release(callbacks_context->terminate_semaphore) == FuriStatusOk);
|
||||
}
|
||||
|
||||
static void test_rpc_print_message_list(MsgList_t msg_list) {
|
||||
@@ -1645,7 +1644,7 @@ static void test_rpc_feed_rubbish_run(
|
||||
|
||||
test_rpc_add_empty_to_list(expected, PB_CommandStatus_ERROR_DECODE, 0);
|
||||
|
||||
furi_check(!xSemaphoreTake(rpc_session[0].close_session_semaphore, 0));
|
||||
furi_check(furi_semaphore_acquire(rpc_session[0].close_session_semaphore, 0) != FuriStatusOk);
|
||||
test_rpc_encode_and_feed(input_before, 0);
|
||||
test_send_rubbish(rpc_session[0].session, pattern, pattern_size, size);
|
||||
test_rpc_encode_and_feed(input_after, 0);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <furi.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <toolbox/stream/file_stream.h>
|
||||
#include <toolbox/stream/buffered_file_stream.h>
|
||||
#include <storage/storage.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
static const char* stream_test_data = "I write differently from what I speak, "
|
||||
"I speak differently from what I think, "
|
||||
@@ -15,6 +15,8 @@ static const char* stream_test_left_data = "There are two cardinal human sins ";
|
||||
static const char* stream_test_right_data =
|
||||
"from which all others derive: impatience and indolence.";
|
||||
|
||||
#define FILESTREAM_PATH EXT_PATH(".tmp/unit_tests/filestream.str")
|
||||
|
||||
MU_TEST_1(stream_composite_subtest, Stream* stream) {
|
||||
const size_t data_size = 128;
|
||||
uint8_t data[data_size];
|
||||
@@ -304,15 +306,14 @@ MU_TEST(stream_composite_test) {
|
||||
// test file stream
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
stream = file_stream_alloc(storage);
|
||||
mu_check(
|
||||
file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_check(file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
MU_RUN_TEST_1(stream_composite_subtest, stream);
|
||||
stream_free(stream);
|
||||
|
||||
// test buffered file stream
|
||||
stream = buffered_file_stream_alloc(storage);
|
||||
mu_check(buffered_file_stream_open(
|
||||
stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_check(
|
||||
buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
MU_RUN_TEST_1(stream_composite_subtest, stream);
|
||||
stream_free(stream);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
@@ -346,7 +347,7 @@ MU_TEST(stream_write_read_save_load_test) {
|
||||
mu_check(stream_seek(stream_orig, 0, StreamOffsetFromStart));
|
||||
mu_assert_int_eq(
|
||||
strlen(stream_test_data),
|
||||
stream_save_to_file(stream_orig, storage, EXT_PATH("filestream.str"), FSOM_CREATE_ALWAYS));
|
||||
stream_save_to_file(stream_orig, storage, FILESTREAM_PATH, FSOM_CREATE_ALWAYS));
|
||||
|
||||
stream_free(stream_copy);
|
||||
stream_free(stream_orig);
|
||||
@@ -354,8 +355,7 @@ MU_TEST(stream_write_read_save_load_test) {
|
||||
// load from file, read
|
||||
Stream* stream_new = string_stream_alloc();
|
||||
mu_assert_int_eq(
|
||||
strlen(stream_test_data),
|
||||
stream_load_from_file(stream_new, storage, EXT_PATH("filestream.str")));
|
||||
strlen(stream_test_data), stream_load_from_file(stream_new, storage, FILESTREAM_PATH));
|
||||
MU_RUN_TEST_1(stream_read_subtest, stream_new);
|
||||
stream_free(stream_new);
|
||||
|
||||
@@ -396,15 +396,14 @@ MU_TEST(stream_split_test) {
|
||||
// test file stream
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
stream = file_stream_alloc(storage);
|
||||
mu_check(
|
||||
file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_check(file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
MU_RUN_TEST_1(stream_split_subtest, stream);
|
||||
stream_free(stream);
|
||||
|
||||
// test buffered stream
|
||||
stream = buffered_file_stream_alloc(storage);
|
||||
mu_check(buffered_file_stream_open(
|
||||
stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_check(
|
||||
buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
MU_RUN_TEST_1(stream_split_subtest, stream);
|
||||
stream_free(stream);
|
||||
|
||||
@@ -424,8 +423,8 @@ MU_TEST(stream_buffered_write_after_read_test) {
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
Stream* stream = buffered_file_stream_alloc(storage);
|
||||
mu_check(buffered_file_stream_open(
|
||||
stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_check(
|
||||
buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_assert_int_eq(strlen(stream_test_data), stream_write_cstring(stream, stream_test_data));
|
||||
mu_check(stream_rewind(stream));
|
||||
mu_assert_int_eq(prefix_len, stream_read(stream, (uint8_t*)buf, prefix_len));
|
||||
@@ -458,8 +457,8 @@ MU_TEST(stream_buffered_large_file_test) {
|
||||
|
||||
// write test data to file
|
||||
Stream* stream = buffered_file_stream_alloc(storage);
|
||||
mu_check(buffered_file_stream_open(
|
||||
stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_check(
|
||||
buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
|
||||
mu_assert_int_eq(0, stream_size(stream));
|
||||
mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data));
|
||||
mu_assert_int_eq(furi_string_size(input_data), stream_size(stream));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/subghz_keystore.h>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include "../test.h"
|
||||
#include "../test.h" // IWYU pragma: keep
|
||||
|
||||
#include <toolbox/varint.h>
|
||||
#include <toolbox/profiler.h>
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
|
||||
#include <rpc/rpc_i.h>
|
||||
#include <flipper.pb.h>
|
||||
#include <core/event_loop.h>
|
||||
|
||||
static constexpr auto unit_tests_api_table = sort(create_array_t<sym_entry>(
|
||||
API_METHOD(resource_manifest_reader_alloc, ResourceManifestReader*, (Storage*)),
|
||||
API_METHOD(resource_manifest_reader_free, void, (ResourceManifestReader*)),
|
||||
API_METHOD(resource_manifest_reader_open, bool, (ResourceManifestReader*, const char* filename)),
|
||||
API_METHOD(resource_manifest_reader_open, bool, (ResourceManifestReader*, const char*)),
|
||||
API_METHOD(resource_manifest_reader_next, ResourceManifestEntry*, (ResourceManifestReader*)),
|
||||
API_METHOD(resource_manifest_reader_previous, ResourceManifestEntry*, (ResourceManifestReader*)),
|
||||
API_METHOD(slix_process_iso15693_3_error, SlixError, (Iso15693_3Error)),
|
||||
@@ -19,11 +20,24 @@ static constexpr auto unit_tests_api_table = sort(create_array_t<sym_entry>(
|
||||
API_METHOD(xQueueSemaphoreTake, BaseType_t, (QueueHandle_t, TickType_t)),
|
||||
API_METHOD(vQueueDelete, void, (QueueHandle_t)),
|
||||
API_METHOD(
|
||||
xQueueGenericCreate,
|
||||
xQueueGenericCreateStatic,
|
||||
QueueHandle_t,
|
||||
(const UBaseType_t, const UBaseType_t, const uint8_t)),
|
||||
(const UBaseType_t, const UBaseType_t, uint8_t*, StaticQueue_t*, const uint8_t)),
|
||||
API_METHOD(
|
||||
xQueueGenericSend,
|
||||
BaseType_t,
|
||||
(QueueHandle_t, const void* const, TickType_t, const BaseType_t)),
|
||||
API_METHOD(furi_event_loop_alloc, FuriEventLoop*, (void)),
|
||||
API_METHOD(furi_event_loop_free, void, (FuriEventLoop*)),
|
||||
API_METHOD(
|
||||
furi_event_loop_message_queue_subscribe,
|
||||
void,
|
||||
(FuriEventLoop*,
|
||||
FuriMessageQueue*,
|
||||
FuriEventLoopEvent,
|
||||
FuriEventLoopMessageQueueCallback,
|
||||
void*)),
|
||||
API_METHOD(furi_event_loop_message_queue_unsubscribe, void, (FuriEventLoop*, FuriMessageQueue*)),
|
||||
API_METHOD(furi_event_loop_run, void, (FuriEventLoop*)),
|
||||
API_METHOD(furi_event_loop_stop, void, (FuriEventLoop*)),
|
||||
API_VARIABLE(PB_Main_msg, PB_Main_msg_t)));
|
||||
|
||||
@@ -40,7 +40,6 @@ static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) {
|
||||
int32_t usb_mouse_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(UsbMouseEvent));
|
||||
furi_check(event_queue);
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "archive_files.h"
|
||||
#include "archive_apps.h"
|
||||
#include "archive_browser.h"
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <core/log.h>
|
||||
#include <gui/modules/file_browser_worker.h>
|
||||
#include <flipper_application/flipper_application.h>
|
||||
#include <math.h>
|
||||
|
||||
static void
|
||||
archive_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "../archive_i.h"
|
||||
#include "../helpers/archive_files.h"
|
||||
#include "../helpers/archive_apps.h"
|
||||
#include "../helpers/archive_favorites.h"
|
||||
#include "../helpers/archive_browser.h"
|
||||
#include "../views/archive_browser_view.h"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "../archive_i.h"
|
||||
#include "../helpers/archive_favorites.h"
|
||||
#include "../helpers/archive_files.h"
|
||||
#include "../helpers/archive_apps.h"
|
||||
#include "../helpers/archive_browser.h"
|
||||
|
||||
@@ -18,13 +18,18 @@ void archive_scene_rename_on_enter(void* context) {
|
||||
|
||||
TextInput* text_input = archive->text_input;
|
||||
ArchiveFile_t* current = archive_get_current_file(archive->browser);
|
||||
const bool is_file = current->type != ArchiveFileTypeFolder;
|
||||
|
||||
FuriString* filename;
|
||||
filename = furi_string_alloc();
|
||||
path_extract_filename(current->path, filename, true);
|
||||
path_extract_filename(current->path, filename, is_file);
|
||||
strlcpy(archive->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN);
|
||||
|
||||
path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN);
|
||||
if(is_file) {
|
||||
path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN);
|
||||
} else {
|
||||
memset(archive->file_extension, 0, sizeof(archive->file_extension));
|
||||
}
|
||||
|
||||
text_input_set_header_text(text_input, "Rename:");
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "assets_icons.h"
|
||||
#include "toolbox/path.h"
|
||||
#include <furi.h>
|
||||
#include "../archive_i.h"
|
||||
#include "archive_browser_view.h"
|
||||
#include "../helpers/archive_browser.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "../bad_usb_app_i.h"
|
||||
#include "furi_hal_power.h"
|
||||
|
||||
enum SubmenuIndex {
|
||||
ConfigIndexKeyboardLayout,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "../bad_usb_app_i.h"
|
||||
#include "furi_hal_power.h"
|
||||
#include <storage/storage.h>
|
||||
|
||||
static bool bad_usb_layout_select(BadUsbApp* bad_usb) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "gpio_usb_uart.h"
|
||||
#include "../usb_uart_bridge.h"
|
||||
#include "../gpio_app_i.h"
|
||||
#include <furi_hal.h>
|
||||
#include <gui/elements.h>
|
||||
#include <assets_icons.h>
|
||||
|
||||
struct GpioUsbUart {
|
||||
View* view;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../infrared_app_i.h"
|
||||
#include "../infrared_app_i.h" // IWYU pragma: keep
|
||||
|
||||
#include "common/infrared_scene_universal_common.h"
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ MfUserDict* mf_user_dict_alloc(size_t max_keys_to_load) {
|
||||
|
||||
KeysDict* dict = keys_dict_alloc(
|
||||
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
|
||||
furi_assert(dict);
|
||||
|
||||
size_t dict_keys_num = keys_dict_get_total_keys(dict);
|
||||
instance->keys_num = MIN(max_keys_to_load, dict_keys_num);
|
||||
@@ -69,7 +68,6 @@ bool mf_user_dict_delete_key(MfUserDict* instance, uint32_t index) {
|
||||
|
||||
KeysDict* dict = keys_dict_alloc(
|
||||
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
|
||||
furi_assert(dict);
|
||||
|
||||
bool key_delete_success =
|
||||
keys_dict_delete_key(dict, instance->keys_arr[index].data, sizeof(MfClassicKey));
|
||||
|
||||
@@ -26,12 +26,6 @@ static void nfc_scene_info_on_enter_felica(NfcApp* instance) {
|
||||
widget_add_text_scroll_element(
|
||||
instance->widget, 0, 0, 128, 48, furi_string_get_cstr(temp_str));
|
||||
|
||||
widget_add_button_element(
|
||||
instance->widget,
|
||||
GuiButtonTypeRight,
|
||||
"More",
|
||||
nfc_protocol_support_common_widget_callback,
|
||||
instance);
|
||||
furi_string_free(temp_str);
|
||||
}
|
||||
|
||||
@@ -177,7 +171,7 @@ static bool nfc_scene_read_menu_on_event_felica(NfcApp* instance, SceneManagerEv
|
||||
}
|
||||
|
||||
const NfcProtocolSupportBase nfc_protocol_support_felica = {
|
||||
.features = NfcProtocolFeatureEmulateUid,
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
||||
|
||||
.scene_info =
|
||||
{
|
||||
|
||||
@@ -197,7 +197,10 @@ static bool nfc_scene_read_menu_on_event_mf_classic(NfcApp* instance, SceneManag
|
||||
dolphin_deed(DolphinDeedNfcDetectReader);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexDictAttack) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, NfcSceneMfClassicDictAttack)) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexCommonEdit) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
||||
@@ -222,7 +225,10 @@ static bool nfc_scene_saved_menu_on_event_mf_classic(NfcApp* instance, SceneMana
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicUpdateInitial);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexDictAttack) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, NfcSceneMfClassicDictAttack)) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#include "mf_plus.h"
|
||||
#include "mf_plus_render.h"
|
||||
|
||||
#include <nfc/protocols/mf_plus/mf_plus_poller.h>
|
||||
|
||||
#include "nfc/nfc_app_i.h"
|
||||
|
||||
#include "../nfc_protocol_support_common.h"
|
||||
#include "../nfc_protocol_support_gui_common.h"
|
||||
#include "../iso14443_4a/iso14443_4a_i.h"
|
||||
|
||||
static void nfc_scene_info_on_enter_mf_plus(NfcApp* instance) {
|
||||
const NfcDevice* device = instance->nfc_device;
|
||||
const MfPlusData* data = nfc_device_get_data(device, NfcProtocolMfPlus);
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
nfc_append_filename_string_when_present(instance, temp_str);
|
||||
furi_string_cat_printf(
|
||||
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
|
||||
furi_string_replace(temp_str, "Mifare", "MIFARE");
|
||||
nfc_render_mf_plus_info(data, NfcProtocolFormatTypeFull, temp_str);
|
||||
|
||||
widget_add_text_scroll_element(
|
||||
instance->widget, 0, 0, 128, 64, furi_string_get_cstr(temp_str));
|
||||
|
||||
furi_string_free(temp_str);
|
||||
}
|
||||
static NfcCommand nfc_scene_read_poller_callback_mf_plus(NfcGenericEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.protocol == NfcProtocolMfPlus);
|
||||
furi_assert(event.event_data);
|
||||
|
||||
NfcApp* instance = context;
|
||||
const MfPlusPollerEvent* mf_plus_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(mf_plus_event->type == MfPlusPollerEventTypeReadSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfPlus, nfc_poller_get_data(instance->poller));
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_plus_event->type == MfPlusPollerEventTypeReadFailed) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_read_on_enter_mf_plus(NfcApp* instance) {
|
||||
nfc_poller_start(instance->poller, nfc_scene_read_poller_callback_mf_plus, instance);
|
||||
}
|
||||
|
||||
static void nfc_scene_read_success_on_enter_mf_plus(NfcApp* instance) {
|
||||
const NfcDevice* device = instance->nfc_device;
|
||||
const MfPlusData* data = nfc_device_get_data(device, NfcProtocolMfPlus);
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
furi_string_cat_printf(
|
||||
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
|
||||
furi_string_replace(temp_str, "Mifare", "MIFARE");
|
||||
nfc_render_mf_plus_info(data, NfcProtocolFormatTypeShort, temp_str);
|
||||
|
||||
widget_add_text_scroll_element(
|
||||
instance->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str));
|
||||
|
||||
furi_string_free(temp_str);
|
||||
}
|
||||
|
||||
static void nfc_scene_emulate_on_enter_mf_plus(NfcApp* instance) {
|
||||
const Iso14443_4aData* iso14443_4a_data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolIso14443_4a);
|
||||
|
||||
instance->listener =
|
||||
nfc_listener_alloc(instance->nfc, NfcProtocolIso14443_4a, iso14443_4a_data);
|
||||
nfc_listener_start(
|
||||
instance->listener, nfc_scene_emulate_listener_callback_iso14443_4a, instance);
|
||||
}
|
||||
|
||||
const NfcProtocolSupportBase nfc_protocol_support_mf_plus = {
|
||||
.features = NfcProtocolFeatureEmulateUid,
|
||||
|
||||
.scene_info =
|
||||
{
|
||||
.on_enter = nfc_scene_info_on_enter_mf_plus,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_more_info =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_read =
|
||||
{
|
||||
.on_enter = nfc_scene_read_on_enter_mf_plus,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_read_menu =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_read_success =
|
||||
{
|
||||
.on_enter = nfc_scene_read_success_on_enter_mf_plus,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_saved_menu =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_save_name =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_emulate =
|
||||
{
|
||||
.on_enter = nfc_scene_emulate_on_enter_mf_plus,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_protocol_support_base.h"
|
||||
|
||||
extern const NfcProtocolSupportBase nfc_protocol_support_mf_plus;
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "mf_plus_render.h"
|
||||
|
||||
#include "../iso14443_4a/iso14443_4a_render.h"
|
||||
|
||||
void nfc_render_mf_plus_info(
|
||||
const MfPlusData* data,
|
||||
NfcProtocolFormatType format_type,
|
||||
FuriString* str) {
|
||||
nfc_render_iso14443_4a_brief(mf_plus_get_base_data(data), str);
|
||||
|
||||
if(format_type != NfcProtocolFormatTypeFull) return;
|
||||
|
||||
furi_string_cat(str, "\n\e#ISO14443-4 data");
|
||||
nfc_render_iso14443_4a_extra(mf_plus_get_base_data(data), str);
|
||||
}
|
||||
|
||||
void nfc_render_mf_plus_data(const MfPlusData* data, FuriString* str) {
|
||||
nfc_render_mf_plus_version(&data->version, str);
|
||||
}
|
||||
|
||||
void nfc_render_mf_plus_version(const MfPlusVersion* data, FuriString* str) {
|
||||
furi_string_cat_printf(
|
||||
str,
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
data->uid[0],
|
||||
data->uid[1],
|
||||
data->uid[2],
|
||||
data->uid[3],
|
||||
data->uid[4],
|
||||
data->uid[5],
|
||||
data->uid[6]);
|
||||
furi_string_cat_printf(
|
||||
str,
|
||||
"hw %02x type %02x sub %02x\n"
|
||||
" maj %02x min %02x\n"
|
||||
" size %02x proto %02x\n",
|
||||
data->hw_vendor,
|
||||
data->hw_type,
|
||||
data->hw_subtype,
|
||||
data->hw_major,
|
||||
data->hw_minor,
|
||||
data->hw_storage,
|
||||
data->hw_proto);
|
||||
furi_string_cat_printf(
|
||||
str,
|
||||
"sw %02x type %02x sub %02x\n"
|
||||
" maj %02x min %02x\n"
|
||||
" size %02x proto %02x\n",
|
||||
data->sw_vendor,
|
||||
data->sw_type,
|
||||
data->sw_subtype,
|
||||
data->sw_major,
|
||||
data->sw_minor,
|
||||
data->sw_storage,
|
||||
data->sw_proto);
|
||||
furi_string_cat_printf(
|
||||
str,
|
||||
"batch %02x:%02x:%02x:%02x:%02x\n"
|
||||
"week %d year %d\n",
|
||||
data->batch[0],
|
||||
data->batch[1],
|
||||
data->batch[2],
|
||||
data->batch[3],
|
||||
data->batch[4],
|
||||
data->prod_week,
|
||||
data->prod_year);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <nfc/protocols/mf_plus/mf_plus.h>
|
||||
|
||||
#include "../nfc_protocol_support_render_common.h"
|
||||
|
||||
void nfc_render_mf_plus_info(
|
||||
const MfPlusData* data,
|
||||
NfcProtocolFormatType format_type,
|
||||
FuriString* str);
|
||||
|
||||
void nfc_render_mf_plus_data(const MfPlusData* data, FuriString* str);
|
||||
|
||||
void nfc_render_mf_plus_version(const MfPlusVersion* data, FuriString* str);
|
||||
@@ -167,7 +167,7 @@ bool nfc_scene_read_on_event_mf_ultralight(NfcApp* instance, SceneManagerEvent e
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventCardDetected) {
|
||||
nfc_unlock_helper_card_detected_handler(instance);
|
||||
} else if((event.event == NfcCustomEventPollerIncomplete)) {
|
||||
} else if(event.event == NfcCustomEventPollerIncomplete) {
|
||||
notification_message(instance->notifications, &sequence_semi_success);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
|
||||
dolphin_deed(DolphinDeedNfcReadSuccess);
|
||||
@@ -191,7 +191,8 @@ static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instanc
|
||||
instance);
|
||||
} else if(
|
||||
data->type == MfUltralightTypeNTAG213 || data->type == MfUltralightTypeNTAG215 ||
|
||||
data->type == MfUltralightTypeNTAG216) {
|
||||
data->type == MfUltralightTypeNTAG216 || data->type == MfUltralightTypeUL11 ||
|
||||
data->type == MfUltralightTypeUL21) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "felica/felica.h"
|
||||
#include "mf_ultralight/mf_ultralight.h"
|
||||
#include "mf_classic/mf_classic.h"
|
||||
#include "mf_plus/mf_plus.h"
|
||||
#include "mf_desfire/mf_desfire.h"
|
||||
#include "slix/slix.h"
|
||||
#include "st25tb/st25tb.h"
|
||||
@@ -38,6 +39,7 @@ const NfcProtocolSupportBase* nfc_protocol_support[NfcProtocolNum] = {
|
||||
[NfcProtocolFelica] = &nfc_protocol_support_felica,
|
||||
[NfcProtocolMfUltralight] = &nfc_protocol_support_mf_ultralight,
|
||||
[NfcProtocolMfClassic] = &nfc_protocol_support_mf_classic,
|
||||
[NfcProtocolMfPlus] = &nfc_protocol_support_mf_plus,
|
||||
[NfcProtocolMfDesfire] = &nfc_protocol_support_mf_desfire,
|
||||
[NfcProtocolSlix] = &nfc_protocol_support_slix,
|
||||
[NfcProtocolSt25tb] = &nfc_protocol_support_st25tb,
|
||||
|
||||
@@ -5,11 +5,54 @@
|
||||
#include <nfc/nfc_device.h>
|
||||
#include <bit_lib/bit_lib.h>
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
|
||||
#include <flipper_format/flipper_format.h>
|
||||
|
||||
#define TAG "Skylanders"
|
||||
|
||||
static const uint64_t skylanders_key = 0x4b0b20107ccb;
|
||||
|
||||
static const char* nfc_resources_header = "Flipper NFC resources";
|
||||
static const uint32_t nfc_resources_file_version = 1;
|
||||
|
||||
static bool skylanders_search_data(
|
||||
Storage* storage,
|
||||
const char* file_name,
|
||||
FuriString* key,
|
||||
FuriString* data) {
|
||||
bool parsed = false;
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
FuriString* temp_str;
|
||||
temp_str = furi_string_alloc();
|
||||
|
||||
do {
|
||||
// Open file
|
||||
if(!flipper_format_file_open_existing(file, file_name)) break;
|
||||
// Read file header and version
|
||||
uint32_t version = 0;
|
||||
if(!flipper_format_read_header(file, temp_str, &version)) break;
|
||||
if(furi_string_cmp_str(temp_str, nfc_resources_header) ||
|
||||
(version != nfc_resources_file_version))
|
||||
break;
|
||||
if(!flipper_format_read_string(file, furi_string_get_cstr(key), data)) break;
|
||||
parsed = true;
|
||||
} while(false);
|
||||
|
||||
furi_string_free(temp_str);
|
||||
flipper_format_free(file);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
bool skylanders_get_name(Storage* storage, uint16_t id, FuriString* name) {
|
||||
bool parsed = false;
|
||||
FuriString* key;
|
||||
key = furi_string_alloc_printf("%04X", id);
|
||||
if(skylanders_search_data(storage, EXT_PATH("nfc/assets/skylanders.nfc"), key, name)) {
|
||||
parsed = true;
|
||||
}
|
||||
furi_string_free(key);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
bool skylanders_verify(Nfc* nfc) {
|
||||
bool verified = false;
|
||||
|
||||
@@ -75,742 +118,6 @@ static bool skylanders_read(Nfc* nfc, NfcDevice* device) {
|
||||
return is_read;
|
||||
}
|
||||
|
||||
static uint8_t fill_name(const uint16_t id, FuriString* name) {
|
||||
// USED RESEARCH FROM https://github.com/silicontrip/SkyReader/blob/master/toynames.cpp#L15C1-L163C1
|
||||
// AND https://github.com/bettse/Solarbreeze/blob/master/Solarbreeze/ThePoster.swift#L438C1-L681C1
|
||||
switch(id) {
|
||||
case 0x0000:
|
||||
furi_string_cat_printf(name, "Whirlwind");
|
||||
break;
|
||||
case 0x0001:
|
||||
furi_string_cat_printf(name, "Sonic Boom");
|
||||
break;
|
||||
case 0x0002:
|
||||
furi_string_cat_printf(name, "Warnado");
|
||||
break;
|
||||
case 0x0003:
|
||||
furi_string_cat_printf(name, "Lightning Rod");
|
||||
break;
|
||||
case 0x0004:
|
||||
case 0x0194:
|
||||
furi_string_cat_printf(name, "Bash");
|
||||
break;
|
||||
case 0x0005:
|
||||
furi_string_cat_printf(name, "Terrafin");
|
||||
break;
|
||||
case 0x0006:
|
||||
furi_string_cat_printf(name, "Dino-Rang");
|
||||
break;
|
||||
case 0x0007:
|
||||
furi_string_cat_printf(name, "Prism Break");
|
||||
break;
|
||||
case 0x0008:
|
||||
furi_string_cat_printf(name, "Sunburn");
|
||||
break;
|
||||
case 0x0009:
|
||||
furi_string_cat_printf(name, "Eruptor");
|
||||
break;
|
||||
case 0x000A:
|
||||
furi_string_cat_printf(name, "Ignitor");
|
||||
break;
|
||||
case 0x000B:
|
||||
furi_string_cat_printf(name, "Flameslinger");
|
||||
break;
|
||||
case 0x000C:
|
||||
furi_string_cat_printf(name, "Zap");
|
||||
break;
|
||||
case 0x000D:
|
||||
furi_string_cat_printf(name, "Wham-Shell");
|
||||
break;
|
||||
case 0x000E:
|
||||
furi_string_cat_printf(name, "Gill Grunt");
|
||||
break;
|
||||
case 0x000F:
|
||||
furi_string_cat_printf(name, "Slam Bam");
|
||||
break;
|
||||
case 0x0010:
|
||||
case 0x01A0:
|
||||
furi_string_cat_printf(name, "Spyro");
|
||||
break;
|
||||
case 0x0011:
|
||||
furi_string_cat_printf(name, "Voodood");
|
||||
break;
|
||||
case 0x0012:
|
||||
furi_string_cat_printf(name, "Double Trouble");
|
||||
break;
|
||||
case 0x0013:
|
||||
case 0x01A3:
|
||||
furi_string_cat_printf(name, "Trigger Happy");
|
||||
break;
|
||||
case 0x0014:
|
||||
furi_string_cat_printf(name, "Drobot");
|
||||
break;
|
||||
case 0x0015:
|
||||
furi_string_cat_printf(name, "Drill Sergeant");
|
||||
break;
|
||||
case 0x0016:
|
||||
furi_string_cat_printf(name, "Boomer");
|
||||
break;
|
||||
case 0x0017:
|
||||
furi_string_cat_printf(name, "Wrecking Ball");
|
||||
break;
|
||||
case 0x0018:
|
||||
furi_string_cat_printf(name, "Camo");
|
||||
break;
|
||||
case 0x0019:
|
||||
furi_string_cat_printf(name, "Zook");
|
||||
break;
|
||||
case 0x001A:
|
||||
furi_string_cat_printf(name, "Stealth Elf");
|
||||
break;
|
||||
case 0x001B:
|
||||
furi_string_cat_printf(name, "Stump Smash");
|
||||
break;
|
||||
case 0x001C:
|
||||
furi_string_cat_printf(name, "Dark Spyro");
|
||||
break;
|
||||
case 0x001D:
|
||||
furi_string_cat_printf(name, "Hex");
|
||||
break;
|
||||
case 0x001E:
|
||||
case 0x01AE:
|
||||
furi_string_cat_printf(name, "Chop Chop");
|
||||
break;
|
||||
case 0x001F:
|
||||
furi_string_cat_printf(name, "Ghost Roaster");
|
||||
break;
|
||||
case 0x0020:
|
||||
furi_string_cat_printf(name, "Cynder");
|
||||
break;
|
||||
case 0x0064:
|
||||
furi_string_cat_printf(name, "Jet Vac");
|
||||
break;
|
||||
case 0x0065:
|
||||
furi_string_cat_printf(name, "Swarm");
|
||||
break;
|
||||
case 0x0066:
|
||||
furi_string_cat_printf(name, "Crusher");
|
||||
break;
|
||||
case 0x0067:
|
||||
furi_string_cat_printf(name, "Flashwing");
|
||||
break;
|
||||
case 0x0068:
|
||||
furi_string_cat_printf(name, "Hot Head");
|
||||
break;
|
||||
case 0x0069:
|
||||
furi_string_cat_printf(name, "Hot Dog");
|
||||
break;
|
||||
case 0x006A:
|
||||
furi_string_cat_printf(name, "Chill");
|
||||
break;
|
||||
case 0x006B:
|
||||
furi_string_cat_printf(name, "Thumpback");
|
||||
break;
|
||||
case 0x006C:
|
||||
furi_string_cat_printf(name, "Pop Fizz");
|
||||
break;
|
||||
case 0x006D:
|
||||
furi_string_cat_printf(name, "Ninjini");
|
||||
break;
|
||||
case 0x006E:
|
||||
furi_string_cat_printf(name, "Bouncer");
|
||||
break;
|
||||
case 0x006F:
|
||||
furi_string_cat_printf(name, "Sprocket");
|
||||
break;
|
||||
case 0x0070:
|
||||
furi_string_cat_printf(name, "Tree Rex");
|
||||
break;
|
||||
case 0x0071:
|
||||
furi_string_cat_printf(name, "Shroomboom");
|
||||
break;
|
||||
case 0x0072:
|
||||
furi_string_cat_printf(name, "Eye-Brawl");
|
||||
break;
|
||||
case 0x0073:
|
||||
furi_string_cat_printf(name, "Fright Rider");
|
||||
break;
|
||||
case 0x00C8:
|
||||
furi_string_cat_printf(name, "Anvil Rain");
|
||||
break;
|
||||
case 0x00C9:
|
||||
furi_string_cat_printf(name, "Treasure Chest");
|
||||
break;
|
||||
case 0x00CA:
|
||||
furi_string_cat_printf(name, "Healing Elixer");
|
||||
break;
|
||||
case 0x00CB:
|
||||
furi_string_cat_printf(name, "Ghost Swords");
|
||||
break;
|
||||
case 0x00CC:
|
||||
furi_string_cat_printf(name, "Time Twister");
|
||||
break;
|
||||
case 0x00CD:
|
||||
furi_string_cat_printf(name, "Sky-Iron Shield");
|
||||
break;
|
||||
case 0x00CE:
|
||||
furi_string_cat_printf(name, "Winged Boots");
|
||||
break;
|
||||
case 0x00CF:
|
||||
furi_string_cat_printf(name, "Sparx Dragonfly");
|
||||
break;
|
||||
case 0x00D0:
|
||||
furi_string_cat_printf(name, "Dragonfire Cannon");
|
||||
break;
|
||||
case 0x00D1:
|
||||
furi_string_cat_printf(name, "Scorpion Striker Catapult");
|
||||
break;
|
||||
case 0x00D2:
|
||||
furi_string_cat_printf(name, "Trap - Magic");
|
||||
break;
|
||||
case 0x00D3:
|
||||
furi_string_cat_printf(name, "Trap - Water");
|
||||
break;
|
||||
case 0x00D4:
|
||||
furi_string_cat_printf(name, "Trap - Air");
|
||||
break;
|
||||
case 0x00D5:
|
||||
furi_string_cat_printf(name, "Trap - Undead");
|
||||
break;
|
||||
case 0x00D6:
|
||||
furi_string_cat_printf(name, "Trap - Tech");
|
||||
break;
|
||||
case 0x00D7:
|
||||
furi_string_cat_printf(name, "Trap - Fire");
|
||||
break;
|
||||
case 0x00D8:
|
||||
furi_string_cat_printf(name, "Trap - Earth");
|
||||
break;
|
||||
case 0x00D9:
|
||||
furi_string_cat_printf(name, "Trap - Life");
|
||||
break;
|
||||
case 0x00DA:
|
||||
furi_string_cat_printf(name, "Trap - Light");
|
||||
break;
|
||||
case 0x00DB:
|
||||
furi_string_cat_printf(name, "Trap - Dark");
|
||||
break;
|
||||
case 0x00DC:
|
||||
furi_string_cat_printf(name, "Trap - Kaos");
|
||||
break;
|
||||
case 0x00E6:
|
||||
furi_string_cat_printf(name, "Hand Of Fate");
|
||||
break;
|
||||
case 0x00E7:
|
||||
furi_string_cat_printf(name, "Piggy Bank");
|
||||
break;
|
||||
case 0x00E8:
|
||||
furi_string_cat_printf(name, "Rocket Ram");
|
||||
break;
|
||||
case 0x00E9:
|
||||
furi_string_cat_printf(name, "Tiki Speaky");
|
||||
break;
|
||||
case 0x00EB:
|
||||
furi_string_cat_printf(name, "Imaginite Mystery Chest");
|
||||
break;
|
||||
case 0x012C:
|
||||
furi_string_cat_printf(name, "Dragons Peak");
|
||||
break;
|
||||
case 0x012D:
|
||||
furi_string_cat_printf(name, "Empire of Ice");
|
||||
break;
|
||||
case 0x012E:
|
||||
furi_string_cat_printf(name, "Pirate Seas");
|
||||
break;
|
||||
case 0x012F:
|
||||
furi_string_cat_printf(name, "Darklight Crypt");
|
||||
break;
|
||||
case 0x0130:
|
||||
furi_string_cat_printf(name, "Volcanic Vault");
|
||||
break;
|
||||
case 0x0131:
|
||||
furi_string_cat_printf(name, "Mirror Of Mystery");
|
||||
break;
|
||||
case 0x0132:
|
||||
furi_string_cat_printf(name, "Nightmare Express");
|
||||
break;
|
||||
case 0x0133:
|
||||
furi_string_cat_printf(name, "Sunscraper Spire");
|
||||
break;
|
||||
case 0x0134:
|
||||
furi_string_cat_printf(name, "Midnight Museum");
|
||||
break;
|
||||
case 0x01C2:
|
||||
furi_string_cat_printf(name, "Gusto");
|
||||
break;
|
||||
case 0x01C3:
|
||||
furi_string_cat_printf(name, "Thunderbolt");
|
||||
break;
|
||||
case 0x01C4:
|
||||
furi_string_cat_printf(name, "Fling Kong");
|
||||
break;
|
||||
case 0x01C5:
|
||||
furi_string_cat_printf(name, "Blades");
|
||||
break;
|
||||
case 0x01C6:
|
||||
furi_string_cat_printf(name, "Wallop");
|
||||
break;
|
||||
case 0x01C7:
|
||||
furi_string_cat_printf(name, "Head Rush");
|
||||
break;
|
||||
case 0x01C8:
|
||||
furi_string_cat_printf(name, "Fist Bump");
|
||||
break;
|
||||
case 0x01C9:
|
||||
furi_string_cat_printf(name, "Rocky Roll");
|
||||
break;
|
||||
case 0x01CA:
|
||||
furi_string_cat_printf(name, "Wildfire");
|
||||
break;
|
||||
case 0x01CB:
|
||||
furi_string_cat_printf(name, "Ka Boom");
|
||||
break;
|
||||
case 0x01CC:
|
||||
furi_string_cat_printf(name, "Trail Blazer");
|
||||
break;
|
||||
case 0x01CD:
|
||||
furi_string_cat_printf(name, "Torch");
|
||||
break;
|
||||
case 0x01CE:
|
||||
furi_string_cat_printf(name, "Snap Shot");
|
||||
break;
|
||||
case 0x01CF:
|
||||
furi_string_cat_printf(name, "Lob Star");
|
||||
break;
|
||||
case 0x01D0:
|
||||
furi_string_cat_printf(name, "Flip Wreck");
|
||||
break;
|
||||
case 0x01D1:
|
||||
furi_string_cat_printf(name, "Echo");
|
||||
break;
|
||||
case 0x01D2:
|
||||
furi_string_cat_printf(name, "Blastermind");
|
||||
break;
|
||||
case 0x01D3:
|
||||
furi_string_cat_printf(name, "Enigma");
|
||||
break;
|
||||
case 0x01D4:
|
||||
furi_string_cat_printf(name, "Deja Vu");
|
||||
break;
|
||||
case 0x01D5:
|
||||
furi_string_cat_printf(name, "Cobra Cadabra");
|
||||
break;
|
||||
case 0x01D6:
|
||||
furi_string_cat_printf(name, "Jawbreaker");
|
||||
break;
|
||||
case 0x01D7:
|
||||
furi_string_cat_printf(name, "Gearshift");
|
||||
break;
|
||||
case 0x01D8:
|
||||
furi_string_cat_printf(name, "Chopper");
|
||||
break;
|
||||
case 0x01D9:
|
||||
furi_string_cat_printf(name, "Tread Head");
|
||||
break;
|
||||
case 0x01DA:
|
||||
furi_string_cat_printf(name, "Bushwhack");
|
||||
break;
|
||||
case 0x01DB:
|
||||
furi_string_cat_printf(name, "Tuff Luck");
|
||||
break;
|
||||
case 0x01DC:
|
||||
furi_string_cat_printf(name, "Food Fight");
|
||||
break;
|
||||
case 0x01DD:
|
||||
furi_string_cat_printf(name, "High Five");
|
||||
break;
|
||||
case 0x01DE:
|
||||
furi_string_cat_printf(name, "Krypt King");
|
||||
break;
|
||||
case 0x01DF:
|
||||
furi_string_cat_printf(name, "Short Cut");
|
||||
break;
|
||||
case 0x01E0:
|
||||
furi_string_cat_printf(name, "Bat Spin");
|
||||
break;
|
||||
case 0x01E1:
|
||||
furi_string_cat_printf(name, "Funny Bone");
|
||||
break;
|
||||
case 0x01E2:
|
||||
furi_string_cat_printf(name, "Knight light");
|
||||
break;
|
||||
case 0x01E3:
|
||||
furi_string_cat_printf(name, "Spotlight");
|
||||
break;
|
||||
case 0x01E4:
|
||||
furi_string_cat_printf(name, "Knight Mare");
|
||||
break;
|
||||
case 0x01E5:
|
||||
furi_string_cat_printf(name, "Blackout");
|
||||
break;
|
||||
case 0x01F6:
|
||||
furi_string_cat_printf(name, "Bop");
|
||||
break;
|
||||
case 0x01F7:
|
||||
furi_string_cat_printf(name, "Spry");
|
||||
break;
|
||||
case 0x01F8:
|
||||
furi_string_cat_printf(name, "Hijinx");
|
||||
break;
|
||||
case 0x01F9:
|
||||
furi_string_cat_printf(name, "Terrabite");
|
||||
break;
|
||||
case 0x01FA:
|
||||
furi_string_cat_printf(name, "Breeze");
|
||||
break;
|
||||
case 0x01FB:
|
||||
furi_string_cat_printf(name, "Weeruptor");
|
||||
break;
|
||||
case 0x01FC:
|
||||
furi_string_cat_printf(name, "Pet Vac");
|
||||
break;
|
||||
case 0x01FD:
|
||||
furi_string_cat_printf(name, "Small Fry");
|
||||
break;
|
||||
case 0x01FE:
|
||||
furi_string_cat_printf(name, "Drobit");
|
||||
break;
|
||||
case 0x0202:
|
||||
furi_string_cat_printf(name, "Gill Runt");
|
||||
break;
|
||||
case 0x0207:
|
||||
furi_string_cat_printf(name, "Trigger Snappy");
|
||||
break;
|
||||
case 0x020E:
|
||||
furi_string_cat_printf(name, "Whisper Elf");
|
||||
break;
|
||||
case 0x021C:
|
||||
furi_string_cat_printf(name, "Barkley");
|
||||
break;
|
||||
case 0x021D:
|
||||
furi_string_cat_printf(name, "Thumpling");
|
||||
break;
|
||||
case 0x021E:
|
||||
furi_string_cat_printf(name, "Mini Jini");
|
||||
break;
|
||||
case 0x021F:
|
||||
furi_string_cat_printf(name, "Eye Small");
|
||||
break;
|
||||
case 0x0259:
|
||||
furi_string_cat_printf(name, "King Pen");
|
||||
break;
|
||||
case 0x0265:
|
||||
furi_string_cat_printf(name, "Golden Queen");
|
||||
break;
|
||||
case 0x02AD:
|
||||
furi_string_cat_printf(name, "Fire Acorn");
|
||||
break;
|
||||
case 0x03E8:
|
||||
furi_string_cat_printf(name, "(Boom) Jet");
|
||||
break;
|
||||
case 0x03E9:
|
||||
furi_string_cat_printf(name, "(Free) Ranger");
|
||||
break;
|
||||
case 0x03EA:
|
||||
furi_string_cat_printf(name, "(Rubble) Rouser");
|
||||
break;
|
||||
case 0x03EB:
|
||||
furi_string_cat_printf(name, "(Doom) Stone");
|
||||
break;
|
||||
case 0x03EC:
|
||||
furi_string_cat_printf(name, "Blast Zone");
|
||||
break;
|
||||
case 0x03ED:
|
||||
furi_string_cat_printf(name, "(Fire) Kraken");
|
||||
break;
|
||||
case 0x03EE:
|
||||
furi_string_cat_printf(name, "(Stink) Bomb");
|
||||
break;
|
||||
case 0x03EF:
|
||||
furi_string_cat_printf(name, "(Grilla) Drilla");
|
||||
break;
|
||||
case 0x03F0:
|
||||
furi_string_cat_printf(name, "(Hoot) Loop");
|
||||
break;
|
||||
case 0x03F1:
|
||||
furi_string_cat_printf(name, "(Trap) Shadow");
|
||||
break;
|
||||
case 0x03F2:
|
||||
furi_string_cat_printf(name, "(Magna) Charge");
|
||||
break;
|
||||
case 0x03F3:
|
||||
furi_string_cat_printf(name, "(Spy) Rise");
|
||||
break;
|
||||
case 0x03F4:
|
||||
furi_string_cat_printf(name, "(Night) Shift");
|
||||
break;
|
||||
case 0x03F5:
|
||||
furi_string_cat_printf(name, "(Rattle) Shake");
|
||||
break;
|
||||
case 0x03F6:
|
||||
furi_string_cat_printf(name, "(Freeze) Blade");
|
||||
break;
|
||||
case 0x03F7:
|
||||
furi_string_cat_printf(name, "Wash Buckler");
|
||||
break;
|
||||
case 0x07D0:
|
||||
furi_string_cat_printf(name, "Boom (Jet)");
|
||||
break;
|
||||
case 0x07D1:
|
||||
furi_string_cat_printf(name, "Free (Ranger)");
|
||||
break;
|
||||
case 0x07D2:
|
||||
furi_string_cat_printf(name, "Rubble (Rouser)");
|
||||
break;
|
||||
case 0x07D3:
|
||||
furi_string_cat_printf(name, "Doom (Stone)");
|
||||
break;
|
||||
case 0x07D4:
|
||||
furi_string_cat_printf(name, "Blast Zone (Head)");
|
||||
break;
|
||||
case 0x07D5:
|
||||
furi_string_cat_printf(name, "Fire (Kraken)");
|
||||
break;
|
||||
case 0x07D6:
|
||||
furi_string_cat_printf(name, "Stink (Bomb)");
|
||||
break;
|
||||
case 0x07D7:
|
||||
furi_string_cat_printf(name, "Grilla (Drilla)");
|
||||
break;
|
||||
case 0x07D8:
|
||||
furi_string_cat_printf(name, "Hoot (Loop)");
|
||||
break;
|
||||
case 0x07D9:
|
||||
furi_string_cat_printf(name, "Trap (Shadow)");
|
||||
break;
|
||||
case 0x07DA:
|
||||
furi_string_cat_printf(name, "Magna (Charge)");
|
||||
break;
|
||||
case 0x07DB:
|
||||
furi_string_cat_printf(name, "Spy (Rise)");
|
||||
break;
|
||||
case 0x07DC:
|
||||
furi_string_cat_printf(name, "Night (Shift)");
|
||||
break;
|
||||
case 0x07DD:
|
||||
furi_string_cat_printf(name, "Rattle (Shake)");
|
||||
break;
|
||||
case 0x07DE:
|
||||
furi_string_cat_printf(name, "Freeze (Blade)");
|
||||
break;
|
||||
case 0x07DF:
|
||||
furi_string_cat_printf(name, "Wash Buckler (Head)");
|
||||
break;
|
||||
case 0x0BB8:
|
||||
furi_string_cat_printf(name, "Scratch");
|
||||
break;
|
||||
case 0x0BB9:
|
||||
furi_string_cat_printf(name, "Pop Thorn");
|
||||
break;
|
||||
case 0x0BBA:
|
||||
furi_string_cat_printf(name, "Slobber Tooth");
|
||||
break;
|
||||
case 0x0BBB:
|
||||
furi_string_cat_printf(name, "Scorp");
|
||||
break;
|
||||
case 0x0BBC:
|
||||
furi_string_cat_printf(name, "Fryno");
|
||||
break;
|
||||
case 0x0BBD:
|
||||
furi_string_cat_printf(name, "Smolderdash");
|
||||
break;
|
||||
case 0x0BBE:
|
||||
furi_string_cat_printf(name, "Bumble Blast");
|
||||
break;
|
||||
case 0x0BBF:
|
||||
furi_string_cat_printf(name, "Zoo Lou");
|
||||
break;
|
||||
case 0x0BC0:
|
||||
furi_string_cat_printf(name, "Dune Bug");
|
||||
break;
|
||||
case 0x0BC1:
|
||||
furi_string_cat_printf(name, "Star Strike");
|
||||
break;
|
||||
case 0x0BC2:
|
||||
furi_string_cat_printf(name, "Countdown");
|
||||
break;
|
||||
case 0x0BC3:
|
||||
furi_string_cat_printf(name, "Wind Up");
|
||||
break;
|
||||
case 0x0BC4:
|
||||
furi_string_cat_printf(name, "Roller Brawl");
|
||||
break;
|
||||
case 0x0BC5:
|
||||
furi_string_cat_printf(name, "Grim Creeper");
|
||||
break;
|
||||
case 0x0BC6:
|
||||
furi_string_cat_printf(name, "Rip Tide");
|
||||
break;
|
||||
case 0x0BC7:
|
||||
furi_string_cat_printf(name, "Punk Shock");
|
||||
break;
|
||||
case 0x0C80:
|
||||
furi_string_cat_printf(name, "Battle Hammer");
|
||||
break;
|
||||
case 0x0C81:
|
||||
furi_string_cat_printf(name, "Sky Diamond");
|
||||
break;
|
||||
case 0x0C82:
|
||||
furi_string_cat_printf(name, "Platinum Sheep");
|
||||
break;
|
||||
case 0x0C83:
|
||||
furi_string_cat_printf(name, "Groove Machine");
|
||||
break;
|
||||
case 0x0C84:
|
||||
furi_string_cat_printf(name, "UFO Hat");
|
||||
break;
|
||||
case 0x0C94:
|
||||
furi_string_cat_printf(name, "Jet Stream");
|
||||
break;
|
||||
case 0x0C95:
|
||||
furi_string_cat_printf(name, "Tomb Buggy");
|
||||
break;
|
||||
case 0x0C96:
|
||||
furi_string_cat_printf(name, "Reef Ripper");
|
||||
break;
|
||||
case 0x0C97:
|
||||
furi_string_cat_printf(name, "Burn Cycle");
|
||||
break;
|
||||
case 0x0C98:
|
||||
furi_string_cat_printf(name, "Hot Streak");
|
||||
break;
|
||||
case 0x0C99:
|
||||
furi_string_cat_printf(name, "Shark Tank");
|
||||
break;
|
||||
case 0x0C9A:
|
||||
furi_string_cat_printf(name, "Thump Truck");
|
||||
break;
|
||||
case 0x0C9B:
|
||||
furi_string_cat_printf(name, "Crypt Crusher");
|
||||
break;
|
||||
case 0x0C9C:
|
||||
furi_string_cat_printf(name, "Stealth Stinger");
|
||||
break;
|
||||
case 0x0C9F:
|
||||
furi_string_cat_printf(name, "Dive Bomber");
|
||||
break;
|
||||
case 0x0CA0:
|
||||
furi_string_cat_printf(name, "Sky Slicer");
|
||||
break;
|
||||
case 0x0CA1:
|
||||
furi_string_cat_printf(name, "Clown Cruiser");
|
||||
break;
|
||||
case 0x0CA2:
|
||||
furi_string_cat_printf(name, "Gold Rusher");
|
||||
break;
|
||||
case 0x0CA3:
|
||||
furi_string_cat_printf(name, "Shield Striker");
|
||||
break;
|
||||
case 0x0CA4:
|
||||
furi_string_cat_printf(name, "Sun Runner");
|
||||
break;
|
||||
case 0x0CA5:
|
||||
furi_string_cat_printf(name, "Sea Shadow");
|
||||
break;
|
||||
case 0x0CA6:
|
||||
furi_string_cat_printf(name, "Splatter Splasher");
|
||||
break;
|
||||
case 0x0CA7:
|
||||
furi_string_cat_printf(name, "Soda Skimmer");
|
||||
break;
|
||||
case 0x0CA8:
|
||||
furi_string_cat_printf(name, "Barrel Blaster");
|
||||
break;
|
||||
case 0x0CA9:
|
||||
furi_string_cat_printf(name, "Buzz Wing");
|
||||
break;
|
||||
case 0x0CE4:
|
||||
furi_string_cat_printf(name, "Sheep Wreck Island");
|
||||
break;
|
||||
case 0x0CE5:
|
||||
furi_string_cat_printf(name, "Tower of Time");
|
||||
break;
|
||||
case 0x0CE6:
|
||||
furi_string_cat_printf(name, "Fiery Forge");
|
||||
break;
|
||||
case 0x0CE7:
|
||||
furi_string_cat_printf(name, "Arkeyan Crossbow");
|
||||
break;
|
||||
case 0x0D48:
|
||||
furi_string_cat_printf(name, "Fiesta");
|
||||
break;
|
||||
case 0x0D49:
|
||||
furi_string_cat_printf(name, "High Volt");
|
||||
break;
|
||||
case 0x0D4A:
|
||||
furi_string_cat_printf(name, "Splat");
|
||||
break;
|
||||
case 0x0D4E:
|
||||
furi_string_cat_printf(name, "Stormblade");
|
||||
break;
|
||||
case 0x0D53:
|
||||
furi_string_cat_printf(name, "Smash It");
|
||||
break;
|
||||
case 0x0D54:
|
||||
furi_string_cat_printf(name, "Spitfire");
|
||||
break;
|
||||
case 0x0D55:
|
||||
furi_string_cat_printf(name, "Hurricane Jet-Vac");
|
||||
break;
|
||||
case 0x0D56:
|
||||
furi_string_cat_printf(name, "Double Dare Trigger Happy");
|
||||
break;
|
||||
case 0x0D57:
|
||||
furi_string_cat_printf(name, "Super Shot Stealth Elf");
|
||||
break;
|
||||
case 0x0D58:
|
||||
furi_string_cat_printf(name, "Shark Shooter Terrafin");
|
||||
break;
|
||||
case 0x0D59:
|
||||
furi_string_cat_printf(name, "Bone Bash Roller Brawl");
|
||||
break;
|
||||
case 0x0D5C:
|
||||
furi_string_cat_printf(name, "Big Bubble Pop Fizz");
|
||||
break;
|
||||
case 0x0D5D:
|
||||
furi_string_cat_printf(name, "Lava Lance Eruptor");
|
||||
break;
|
||||
case 0x0D5E:
|
||||
furi_string_cat_printf(name, "Deep Dive Gill Grunt");
|
||||
break;
|
||||
case 0x0D5F:
|
||||
furi_string_cat_printf(name, "Turbo Charge Donkey Kong");
|
||||
break;
|
||||
case 0x0D60:
|
||||
furi_string_cat_printf(name, "Hammer Slam Bowser");
|
||||
break;
|
||||
case 0x0D61:
|
||||
furi_string_cat_printf(name, "Dive-Clops");
|
||||
break;
|
||||
case 0x0D62:
|
||||
furi_string_cat_printf(name, "Astroblast");
|
||||
break;
|
||||
case 0x0D63:
|
||||
furi_string_cat_printf(name, "Nightfall");
|
||||
break;
|
||||
case 0x0D64:
|
||||
furi_string_cat_printf(name, "Thrillipede");
|
||||
break;
|
||||
case 0x0DAC:
|
||||
furi_string_cat_printf(name, "Sky Trophy");
|
||||
break;
|
||||
case 0x0DAD:
|
||||
furi_string_cat_printf(name, "Land Trophy");
|
||||
break;
|
||||
case 0x0DAE:
|
||||
furi_string_cat_printf(name, "Sea Trophy");
|
||||
break;
|
||||
case 0x0DAF:
|
||||
furi_string_cat_printf(name, "Kaos Trophy");
|
||||
break;
|
||||
default:
|
||||
furi_string_cat_printf(name, "Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool skylanders_parse(const NfcDevice* device, FuriString* parsed_data) {
|
||||
furi_assert(device);
|
||||
|
||||
@@ -830,7 +137,11 @@ static bool skylanders_parse(const NfcDevice* device, FuriString* parsed_data) {
|
||||
const uint16_t id = (uint16_t)*data->block[1].data;
|
||||
if(id == 0) break;
|
||||
|
||||
bool success = fill_name(id, name);
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
bool success = skylanders_get_name(storage, id, name);
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
if(!success) break;
|
||||
|
||||
furi_string_printf(parsed_data, "\e#Skylanders\n%s", furi_string_get_cstr(name));
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <bit_lib/bit_lib.h>
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
|
||||
#include "../../api/mosgortrans/mosgortrans_util.h"
|
||||
#include "furi_hal_rtc.h"
|
||||
|
||||
#define TAG "Troika"
|
||||
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
Filetype: Flipper NFC resources
|
||||
Version: 1
|
||||
# ID: Name
|
||||
0000: Whirlwind
|
||||
0001: Sonic Boom
|
||||
0002: Warnado
|
||||
0003: Lightning Rod
|
||||
0004: Bash
|
||||
0194: Bash
|
||||
0005: Terrafin
|
||||
0006: Dino-Rang
|
||||
0007: Prism Break
|
||||
0008: Sunburn
|
||||
0009: Eruptor
|
||||
000A: Ignitor
|
||||
000B: Flameslinger
|
||||
000C: Zap
|
||||
000D: Wham-Shell
|
||||
000E: Gill Grunt
|
||||
000F: Slam Bam
|
||||
0010: Spyro
|
||||
01A0: Spyro
|
||||
0011: Voodood
|
||||
0012: Double Trouble
|
||||
0013: Trigger Happy
|
||||
01A3: Trigger Happy
|
||||
0014: Drobot
|
||||
0015: Drill Sergeant
|
||||
0016: Boomer
|
||||
0017: Wrecking Ball
|
||||
0018: Camo
|
||||
0019: Zook
|
||||
001A: Stealth Elf
|
||||
001B: Stump Smash
|
||||
001C: Dark Spyro
|
||||
001D: Hex
|
||||
001E: Chop Chop
|
||||
01AE: Chop Chop
|
||||
001F: Ghost Roaster
|
||||
0020: Cynder
|
||||
0064: Jet Vac
|
||||
0065: Swarm
|
||||
0066: Crusher
|
||||
0067: Flashwing
|
||||
0068: Hot Head
|
||||
0069: Hot Dog
|
||||
006A: Chill
|
||||
006B: Thumpback
|
||||
006C: Pop Fizz
|
||||
006D: Ninjini
|
||||
006E: Bouncer
|
||||
006F: Sprocket
|
||||
0070: Tree Rex
|
||||
0071: Shroomboom
|
||||
0072: Eye-Brawl
|
||||
0073: Fright Rider
|
||||
00C8: Anvil Rain
|
||||
00C9: Treasure Chest
|
||||
00CA: Healing Elixer
|
||||
00CB: Ghost Swords
|
||||
00CC: Time Twister
|
||||
00CD: Sky-Iron Shield
|
||||
00CE: Winged Boots
|
||||
00CF: Sparx Dragonfly
|
||||
00D0: Dragonfire Cannon
|
||||
00D1: Scorpion Striker Catapult
|
||||
00D2: Trap - Magic
|
||||
00D3: Trap - Water
|
||||
00D4: Trap - Air
|
||||
00D5: Trap - Undead
|
||||
00D6: Trap - Tech
|
||||
00D7: Trap - Fire
|
||||
00D8: Trap - Earth
|
||||
00D9: Trap - Life
|
||||
00DA: Trap - Light
|
||||
00DB: Trap - Dark
|
||||
00DC: Trap - Kaos
|
||||
00E6: Hand Of Fate
|
||||
00E7: Piggy Bank
|
||||
00E8: Rocket Ram
|
||||
00E9: Tiki Speaky
|
||||
00EB: Imaginite Mystery Chest
|
||||
012C: Dragons Peak
|
||||
012D: Empire of Ice
|
||||
012E: Pirate Seas
|
||||
012F: Darklight Crypt
|
||||
0130: Volcanic Vault
|
||||
0131: Mirror Of Mystery
|
||||
0132: Nightmare Express
|
||||
0133: Sunscraper Spire
|
||||
0134: Midnight Museum
|
||||
01C2: Gusto
|
||||
01C3: Thunderbolt
|
||||
01C4: Fling Kong
|
||||
01C5: Blades
|
||||
01C6: Wallop
|
||||
01C7: Head Rush
|
||||
01C8: Fist Bump
|
||||
01C9: Rocky Roll
|
||||
01CA: Wildfire
|
||||
01CB: Ka Boom
|
||||
01CC: Trail Blazer
|
||||
01CD: Torch
|
||||
01CE: Snap Shot
|
||||
01CF: Lob Star
|
||||
01D0: Flip Wreck
|
||||
01D1: Echo
|
||||
01D2: Blastermind
|
||||
01D3: Enigma
|
||||
01D4: Deja Vu
|
||||
01D5: Cobra Cadabra
|
||||
01D6: Jawbreaker
|
||||
01D7: Gearshift
|
||||
01D8: Chopper
|
||||
01D9: Tread Head
|
||||
01DA: Bushwhack
|
||||
01DB: Tuff Luck
|
||||
01DC: Food Fight
|
||||
01DD: High Five
|
||||
01DE: Krypt King
|
||||
01DF: Short Cut
|
||||
01E0: Bat Spin
|
||||
01E1: Funny Bone
|
||||
01E2: Knight light
|
||||
01E3: Spotlight
|
||||
01E4: Knight Mare
|
||||
01E5: Blackout
|
||||
01F6: Bop
|
||||
01F7: Spry
|
||||
01F8: Hijinx
|
||||
01F9: Terrabite
|
||||
01FA: Breeze
|
||||
01FB: Weeruptor
|
||||
01FC: Pet Vac
|
||||
01FD: Small Fry
|
||||
01FE: Drobit
|
||||
0202: Gill Runt
|
||||
0207: Trigger Snappy
|
||||
020E: Whisper Elf
|
||||
021C: Barkley
|
||||
021D: Thumpling
|
||||
021E: Mini Jini
|
||||
021F: Eye Small
|
||||
0259: King Pen
|
||||
0265: Golden Queen
|
||||
02AD: Fire Acorn
|
||||
03E8: (Boom) Jet
|
||||
03E9: (Free) Ranger
|
||||
03EA: (Rubble) Rouser
|
||||
03EB: (Doom) Stone
|
||||
03EC: Blast Zone
|
||||
03ED: (Fire) Kraken
|
||||
03EE: (Stink) Bomb
|
||||
03EF: (Grilla) Drilla
|
||||
03F0: (Hoot) Loop
|
||||
03F1: (Trap) Shadow
|
||||
03F2: (Magna) Charge
|
||||
03F3: (Spy) Rise
|
||||
03F4: (Night) Shift
|
||||
03F5: (Rattle) Shake
|
||||
03F6: (Freeze) Blade
|
||||
03F7: Wash Buckler
|
||||
07D0: Boom (Jet)
|
||||
07D1: Free (Ranger)
|
||||
07D2: Rubble (Rouser)
|
||||
07D3: Doom (Stone)
|
||||
07D4: Blast Zone (Head)
|
||||
07D5: Fire (Kraken)
|
||||
07D6: Stink (Bomb)
|
||||
07D7: Grilla (Drilla)
|
||||
07D8: Hoot (Loop)
|
||||
07D9: Trap (Shadow)
|
||||
07DA: Magna (Charge)
|
||||
07DB: Spy (Rise)
|
||||
07DC: Night (Shift)
|
||||
07DD: Rattle (Shake)
|
||||
07DE: Freeze (Blade)
|
||||
07DF: Wash Buckler (Head)
|
||||
0BB8: Scratch
|
||||
0BB9: Pop Thorn
|
||||
0BBA: Slobber Tooth
|
||||
0BBB: Scorp
|
||||
0BBC: Fryno
|
||||
0BBD: Smolderdash
|
||||
0BBE: Bumble Blast
|
||||
0BBF: Zoo Lou
|
||||
0BC0: Dune Bug
|
||||
0BC1: Star Strike
|
||||
0BC2: Countdown
|
||||
0BC3: Wind Up
|
||||
0BC4: Roller Brawl
|
||||
0BC5: Grim Creeper
|
||||
0BC6: Rip Tide
|
||||
0BC7: Punk Shock
|
||||
0C80: Battle Hammer
|
||||
0C81: Sky Diamond
|
||||
0C82: Platinum Sheep
|
||||
0C83: Groove Machine
|
||||
0C84: UFO Hat
|
||||
0C94: Jet Stream
|
||||
0C95: Tomb Buggy
|
||||
0C96: Reef Ripper
|
||||
0C97: Burn Cycle
|
||||
0C98: Hot Streak
|
||||
0C99: Shark Tank
|
||||
0C9A: Thump Truck
|
||||
0C9B: Crypt Crusher
|
||||
0C9C: Stealth Stinger
|
||||
0C9F: Dive Bomber
|
||||
0CA0: Sky Slicer
|
||||
0CA1: Clown Cruiser
|
||||
0CA2: Gold Rusher
|
||||
0CA3: Shield Striker
|
||||
0CA4: Sun Runner
|
||||
0CA5: Sea Shadow
|
||||
0CA6: Splatter Splasher
|
||||
0CA7: Soda Skimmer
|
||||
0CA8: Barrel Blaster
|
||||
0CA9: Buzz Wing
|
||||
0CE4: Sheep Wreck Island
|
||||
0CE5: Tower of Time
|
||||
0CE6: Fiery Forge
|
||||
0CE7: Arkeyan Crossbow
|
||||
0D48: Fiesta
|
||||
0D49: High Volt
|
||||
0D4A: Splat
|
||||
0D4E: Stormblade
|
||||
0D53: Smash It
|
||||
0D54: Spitfire
|
||||
0D55: Hurricane Jet-Vac
|
||||
0D56: Double Dare Trigger Happy
|
||||
0D57: Super Shot Stealth Elf
|
||||
0D58: Shark Shooter Terrafin
|
||||
0D59: Bone Bash Roller Brawl
|
||||
0D5C: Big Bubble Pop Fizz
|
||||
0D5D: Lava Lance Eruptor
|
||||
0D5E: Deep Dive Gill Grunt
|
||||
0D5F: Turbo Charge Donkey Kong
|
||||
0D60: Hammer Slam Bowser
|
||||
0D61: Dive-Clops
|
||||
0D62: Astroblast
|
||||
0D63: Nightfall
|
||||
0D64: Thrillipede
|
||||
0DAC: Sky Trophy
|
||||
0DAD: Land Trophy
|
||||
0DAE: Sea Trophy
|
||||
0DAF: Kaos Trophy
|
||||
@@ -28,13 +28,9 @@ bool nfc_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.event == DialogExResultRight) {
|
||||
consumed = scene_manager_previous_scene(nfc->scene_manager);
|
||||
} else if(event.event == DialogExResultLeft) {
|
||||
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSelectProtocol)) {
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||
nfc->scene_manager, NfcSceneSelectProtocol);
|
||||
} else if(
|
||||
scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack) &&
|
||||
(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneReadMenu) ||
|
||||
scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu))) {
|
||||
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack) &&
|
||||
(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneReadMenu) ||
|
||||
scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu))) {
|
||||
const uint32_t possible_scenes[] = {NfcSceneReadMenu, NfcSceneSavedMenu};
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
nfc->scene_manager, possible_scenes, COUNT_OF(possible_scenes));
|
||||
|
||||
@@ -16,19 +16,15 @@ void nfc_scene_mf_classic_keys_on_enter(void* context) {
|
||||
uint32_t flipper_dict_keys_total = 0;
|
||||
KeysDict* dict = keys_dict_alloc(
|
||||
NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, KeysDictModeOpenExisting, sizeof(MfClassicKey));
|
||||
if(dict) {
|
||||
flipper_dict_keys_total = keys_dict_get_total_keys(dict);
|
||||
keys_dict_free(dict);
|
||||
}
|
||||
flipper_dict_keys_total = keys_dict_get_total_keys(dict);
|
||||
keys_dict_free(dict);
|
||||
|
||||
// Load user dict keys total
|
||||
uint32_t user_dict_keys_total = 0;
|
||||
dict = keys_dict_alloc(
|
||||
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
|
||||
if(dict) {
|
||||
user_dict_keys_total = keys_dict_get_total_keys(dict);
|
||||
keys_dict_free(dict);
|
||||
}
|
||||
user_dict_keys_total = keys_dict_get_total_keys(dict);
|
||||
keys_dict_free(dict);
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
widget_add_string_element(
|
||||
|
||||
@@ -31,7 +31,6 @@ bool nfc_scene_mf_classic_keys_add_on_event(void* context, SceneManagerEvent eve
|
||||
// Add key to dict
|
||||
KeysDict* dict = keys_dict_alloc(
|
||||
NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
|
||||
furi_assert(dict);
|
||||
|
||||
MfClassicKey key = {};
|
||||
memcpy(key.data, instance->byte_input_store, sizeof(MfClassicKey));
|
||||
|
||||
@@ -49,7 +49,7 @@ static uint32_t subghz_frequency_analyzer_worker_expRunningAverageAdaptive(
|
||||
float k;
|
||||
float newValFloat = newVal;
|
||||
// the sharpness of the filter depends on the absolute value of the difference
|
||||
if(fabs(newValFloat - instance->filVal) > 500000)
|
||||
if(fabsf(newValFloat - instance->filVal) > 500000.f)
|
||||
k = 0.9;
|
||||
else
|
||||
k = 0.03;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "subghz_threshold_rssi.h"
|
||||
#include "../views/subghz_read_raw.h"
|
||||
#include <float_tools.h>
|
||||
#include "../subghz_i.h"
|
||||
|
||||
#define TAG "SubGhzThresholdRssi"
|
||||
#define THRESHOLD_RSSI_LOW_COUNT 10
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "subghz_txrx_i.h"
|
||||
#include "subghz_txrx_i.h" // IWYU pragma: keep
|
||||
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "subghz_txrx_i.h"
|
||||
#include "subghz_txrx_i.h" // IWYU pragma: keep
|
||||
#include "subghz_txrx_create_protocol_key.h"
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
|
||||
@@ -52,6 +52,7 @@ typedef enum {
|
||||
SubGhzRxKeyStateAddKey,
|
||||
SubGhzRxKeyStateExit,
|
||||
SubGhzRxKeyStateRAWLoad,
|
||||
SubGhzRxKeyStateRAWMore,
|
||||
SubGhzRxKeyStateRAWSave,
|
||||
} SubGhzRxKeyState;
|
||||
|
||||
|
||||
@@ -58,7 +58,13 @@ bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.event == SubGhzCustomEventSceneDeleteRAW) {
|
||||
furi_string_set(subghz->file_path_tmp, subghz->file_path);
|
||||
if(subghz_delete_file(subghz)) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess);
|
||||
if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateRAWLoad) {
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess);
|
||||
} else {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved);
|
||||
}
|
||||
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
subghz->scene_manager, SubGhzSceneStart);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
|
||||
void subghz_scene_delete_success_popup_callback(void* context) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
#include "../views/subghz_frequency_analyzer.h"
|
||||
|
||||
void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* context) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
#include <lib/toolbox/value_index.h>
|
||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "../views/subghz_read_raw.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <toolbox/path.h>
|
||||
|
||||
#define RAW_FILE_NAME "Raw_signal_"
|
||||
#define TAG "SubGhzSceneReadRaw"
|
||||
@@ -77,6 +77,7 @@ void subghz_scene_read_raw_on_enter(void* context) {
|
||||
subghz->subghz_read_raw, SubGhzReadRAWStatusIDLE, "", threshold_rssi);
|
||||
break;
|
||||
case SubGhzRxKeyStateRAWLoad:
|
||||
case SubGhzRxKeyStateRAWMore:
|
||||
path_extract_filename(subghz->file_path, file_name, true);
|
||||
subghz_read_raw_set_status(
|
||||
subghz->subghz_read_raw,
|
||||
@@ -98,7 +99,8 @@ void subghz_scene_read_raw_on_enter(void* context) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) {
|
||||
if((subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) &&
|
||||
(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateRAWLoad)) {
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
|
||||
}
|
||||
furi_string_free(file_name);
|
||||
@@ -177,7 +179,9 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
if(subghz_scene_read_raw_update_filename(subghz)) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet);
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWLoad);
|
||||
if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateRAWLoad) {
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWMore);
|
||||
}
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW);
|
||||
consumed = true;
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
|
||||
#include <furi_hal_region.h>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexEmulate,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
|
||||
static const NotificationSequence subghs_sequence_sd_error = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../subghz_i.h"
|
||||
#include "../subghz_i.h" // IWYU pragma: keep
|
||||
#include "../helpers/subghz_custom_event.h"
|
||||
|
||||
void subghz_scene_show_error_sub_popup_callback(void* context) {
|
||||
|
||||
@@ -344,7 +344,6 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx));
|
||||
instance->stream =
|
||||
furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration));
|
||||
furi_check(instance->stream);
|
||||
|
||||
SubGhzEnvironment* environment = subghz_cli_environment_init();
|
||||
|
||||
@@ -425,7 +424,6 @@ void subghz_cli_command_rx_raw(Cli* cli, FuriString* args, void* context) {
|
||||
SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx));
|
||||
instance->stream =
|
||||
furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration));
|
||||
furi_check(instance->stream);
|
||||
|
||||
// Configure radio
|
||||
furi_hal_subghz_reset();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "assets_icons.h"
|
||||
#include "subghz/types.h"
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
@@ -10,7 +9,6 @@
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <flipper_format/flipper_format.h>
|
||||
#include "views/receiver.h"
|
||||
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <lib/toolbox/stream/stream.h>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "receiver.h"
|
||||
#include "../subghz_i.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "types.h"
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <assets_icons.h>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "subghz_frequency_analyzer.h"
|
||||
#include "../subghz_i.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "subghz_read_raw.h"
|
||||
#include "../subghz_i.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
@@ -72,7 +70,7 @@ void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi, bool tra
|
||||
if(rssi < SUBGHZ_RAW_THRESHOLD_MIN) {
|
||||
u_rssi = 0;
|
||||
} else {
|
||||
u_rssi = (uint8_t)((rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7);
|
||||
u_rssi = (uint8_t)((rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7f);
|
||||
}
|
||||
|
||||
with_view_model(
|
||||
@@ -272,7 +270,7 @@ void subghz_read_raw_draw_threshold_rssi(Canvas* canvas, SubGhzReadRAWModel* mod
|
||||
|
||||
if(model->raw_threshold_rssi > SUBGHZ_RAW_THRESHOLD_MIN) {
|
||||
uint8_t x = 118;
|
||||
y -= (uint8_t)((model->raw_threshold_rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7);
|
||||
y -= (uint8_t)((model->raw_threshold_rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7f);
|
||||
|
||||
uint8_t width = 3;
|
||||
for(uint8_t i = 0; i < x; i += width * 2) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "transmitter.h"
|
||||
#include "../subghz_i.h"
|
||||
|
||||
#include <assets_icons.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "u2f.h"
|
||||
#include "u2f_hid.h"
|
||||
#include "u2f_data.h"
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
@@ -435,6 +435,8 @@ int32_t bt_srv(void* p) {
|
||||
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||
ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT);
|
||||
furi_record_create(RECORD_BT, bt);
|
||||
|
||||
furi_thread_suspend(furi_thread_get_current_id());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ Cli* cli_alloc(void) {
|
||||
cli->session = NULL;
|
||||
|
||||
cli->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
furi_check(cli->mutex);
|
||||
|
||||
cli->idle_sem = furi_semaphore_alloc(1, 0);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "cli_i.h" // IWYU pragma: keep
|
||||
#include <furi_hal_usb_cdc.h>
|
||||
#include <furi_hal.h>
|
||||
#include <furi.h>
|
||||
#include "cli_i.h"
|
||||
|
||||
#define TAG "CliVcp"
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "animation_manager.h"
|
||||
#include "animation_storage.h"
|
||||
#include "animation_storage_i.h"
|
||||
#include <assets_dolphin_internal.h>
|
||||
#include <assets_dolphin_blocking.h>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user