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

Compare commits

...

60 Commits

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

Co-authored-by: あく <alleteam@gmail.com>
2022-09-30 21:56:12 +09:00
Sergey Gavrilov
c92217a109 Thread: Clear TLS after thread stop (#1807) 2022-09-30 19:59:11 +09:00
70 changed files with 1831 additions and 386 deletions

View File

@@ -1,12 +1,5 @@
### New changes
* PR: SubGHz: Long press OK button in SubGHz Frequency analyzer to switch to Read menu (by @derskythe | PR #79)
* PR: Increase Sub-GHz Remote label line length to 16 chars (by @alexberkowitz | PR #78)
* Fixed clock AM/PM logic
* Infrared: Update assets (by @Amec0e)
* OFW: Furi Thread: fixed furi_thread_join, check if thread has not been started
* OFW: (Returned back) Furi Thread: don't use thread pointer after FuriThreadStateStopped callback
* OFW: fbt: reproducible manifest builds & improvements
* OFW PR: iButton GUI fixes (OFW PR 1805 by nminaylov)
* Plugins: RFID Fuzzer - ability to change time delay (between cards), useful for slow readers, you can adjust it on the go
#### [🎲 Download extra apps pack](https://download-directory.github.io/?url=https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed)

View File

@@ -57,6 +57,23 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n"
"Hex data: DE AD BE";
#define READ_TEST_FLP "ff_flp.test"
#define READ_TEST_ODD "ff_oddities.test"
static const char* test_data_odd = "Filetype: Flipper File test\n"
// Tabs before newline
"Version: 666\t\t\n"
"# This is comment\n"
// Windows newline in a UNIX file
"String data: String\r\n"
// Trailing whitespace
"Int32 data: 1234 -6345 7813 0 \n"
// Extra whitespace
"Uint32 data: 1234 0 5678 9098 7654321 \n"
// Mixed whitespace
"Float data: 1.5\t \t1000.0\n"
// Leading tabs after key
"Bool data:\t\ttrue false\n"
// Mixed trailing whitespace
"Hex data: DE AD BE\t ";
// data created by user on linux machine
static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
@@ -64,6 +81,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
static const char* test_file_windows = TEST_DIR READ_TEST_WIN;
// data created by flipper itself
static const char* test_file_flipper = TEST_DIR READ_TEST_FLP;
// data containing odd user input
static const char* test_file_oddities = TEST_DIR READ_TEST_ODD;
static bool storage_write_string(const char* path, const char* data) {
Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -503,6 +522,12 @@ MU_TEST(flipper_format_multikey_test) {
mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error");
}
MU_TEST(flipper_format_oddities_test) {
mu_assert(
storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]");
mu_assert(test_read(test_file_linux), "Read test error [Oddities]");
}
MU_TEST_SUITE(flipper_format) {
tests_setup();
MU_RUN_TEST(flipper_format_write_test);
@@ -516,6 +541,7 @@ MU_TEST_SUITE(flipper_format) {
MU_RUN_TEST(flipper_format_update_2_test);
MU_RUN_TEST(flipper_format_update_2_result_test);
MU_RUN_TEST(flipper_format_multikey_test);
MU_RUN_TEST(flipper_format_oddities_test);
tests_teardown();
}

View File

@@ -58,7 +58,7 @@ MU_TEST(storage_file_open_lock) {
storage_file_close(file);
// file_locker thread stop
mu_check(furi_thread_join(locker_thread) == FuriStatusOk);
mu_check(furi_thread_join(locker_thread));
furi_thread_free(locker_thread);
// clean data
@@ -148,7 +148,7 @@ MU_TEST(storage_dir_open_lock) {
storage_dir_close(file);
// file_locker thread stop
mu_check(furi_thread_join(locker_thread) == FuriStatusOk);
mu_check(furi_thread_join(locker_thread));
furi_thread_free(locker_thread);
// clean data

View File

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

View File

@@ -38,7 +38,6 @@ void lfrfid_scene_write_on_enter(void* context) {
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
app->old_key_data = (uint8_t*)malloc(size);
protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size);
lfrfid_worker_start_thread(app->lfworker);
@@ -92,5 +91,4 @@ void lfrfid_scene_write_on_exit(void* context) {
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size);
free(app->old_key_data);
}

View File

@@ -277,6 +277,8 @@ int32_t nfc_app(void* p) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate);
} else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
}

View File

@@ -1,6 +1,15 @@
#include "../nfc_i.h"
#include <dolphin/dolphin.h>
#define NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX (10U)
static const NotificationSequence sequence_detect_reader = {
&message_green_255,
&message_blue_255,
&message_do_not_reset,
NULL,
};
bool nfc_detect_reader_worker_callback(NfcWorkerEvent event, void* context) {
UNUSED(event);
furi_assert(context);
@@ -20,21 +29,26 @@ void nfc_scene_detect_reader_on_enter(void* context) {
DOLPHIN_DEED(DolphinDeedNfcEmulate);
detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc);
detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX);
// Store number of collected nonces in scene state
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDetectReader, 0);
notification_message(nfc->notifications, &sequence_detect_reader);
nfc_worker_start(
nfc->worker,
NfcWorkerStateAnalyzeReader,
&nfc->dev->dev_data,
nfc_detect_reader_worker_callback,
nfc);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDetectReader);
nfc_blink_read_start(nfc);
}
bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
uint32_t nonces_collected =
scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDetectReader);
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventViewExit) {
@@ -42,8 +56,29 @@ bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfkeyNoncesInfo);
consumed = true;
} else if(event.event == NfcWorkerEventDetectReaderMfkeyCollected) {
detect_reader_inc_nonce_cnt(nfc->detect_reader);
nonces_collected += 2;
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneDetectReader, nonces_collected);
detect_reader_set_nonces_collected(nfc->detect_reader, nonces_collected);
if(nonces_collected >= NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) {
detect_reader_set_state(nfc->detect_reader, DetectReaderStateDone);
nfc_blink_stop(nfc);
notification_message(nfc->notifications, &sequence_single_vibro);
notification_message(nfc->notifications, &sequence_set_green_255);
nfc_worker_stop(nfc->worker);
}
consumed = true;
} else if(event.event == NfcWorkerEventDetectReaderDetected) {
if(nonces_collected < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) {
notification_message(nfc->notifications, &sequence_blink_start_cyan);
detect_reader_set_state(nfc->detect_reader, DetectReaderStateReaderDetected);
}
} else if(event.event == NfcWorkerEventDetectReaderLost) {
if(nonces_collected < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) {
nfc_blink_stop(nfc);
notification_message(nfc->notifications, &sequence_detect_reader);
detect_reader_set_state(nfc->detect_reader, DetectReaderStateReaderLost);
}
}
}
@@ -59,5 +94,7 @@ void nfc_scene_detect_reader_on_exit(void* context) {
// Clear view
detect_reader_reset(nfc->detect_reader);
// Stop notifications
nfc_blink_stop(nfc);
notification_message(nfc->notifications, &sequence_reset_green);
}

View File

@@ -91,6 +91,7 @@ void nfc_scene_mf_classic_dict_attack_on_enter(void* context) {
nfc_scene_mf_classic_dict_attack_prepare_view(nfc, DictAttackStateIdle);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack);
nfc_blink_read_start(nfc);
notification_message(nfc->notifications, &sequence_display_backlight_enforce_on);
}
bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) {
@@ -167,4 +168,5 @@ void nfc_scene_mf_classic_dict_attack_on_exit(void* context) {
}
dict_attack_reset(nfc->dict_attack);
nfc_blink_stop(nfc);
notification_message(nfc->notifications, &sequence_display_backlight_enforce_auto);
}

View File

@@ -16,14 +16,14 @@ void nfc_scene_mfkey_nonces_info_on_enter(void* context) {
uint16_t nonces_saved = mfkey32_get_auth_sectors(temp_str);
widget_add_text_scroll_element(nfc->widget, 0, 22, 128, 42, string_get_cstr(temp_str));
string_printf(temp_str, "Nonces saved %d", nonces_saved);
string_printf(temp_str, "Nonce pairs saved %d", nonces_saved);
widget_add_string_element(
nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, string_get_cstr(temp_str));
widget_add_string_element(
nfc->widget, 0, 12, AlignLeft, AlignTop, FontSecondary, "Authenticated sectors:");
widget_add_button_element(
nfc->widget, GuiButtonTypeRight, "Next", nfc_scene_mfkey_nonces_info_callback, nfc);
nfc->widget, GuiButtonTypeCenter, "OK", nfc_scene_mfkey_nonces_info_callback, nfc);
string_clear(temp_str);
@@ -35,7 +35,7 @@ bool nfc_scene_mfkey_nonces_info_on_event(void* context, SceneManagerEvent event
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeRight) {
if(event.event == GuiButtonTypeCenter) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfkeyComplete);
consumed = true;
}

View File

@@ -20,8 +20,7 @@ void nfc_scene_saved_menu_on_enter(void* context) {
Submenu* submenu = nfc->submenu;
if(nfc->dev->format == NfcDeviceSaveFormatUid ||
nfc->dev->format == NfcDeviceSaveFormatMifareDesfire ||
nfc->dev->format == NfcDeviceSaveFormatBankCard) {
nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) {
submenu_add_item(
submenu,
"Emulate UID",

View File

@@ -10,29 +10,50 @@ struct DetectReader {
typedef struct {
uint16_t nonces;
uint16_t nonces_max;
DetectReaderState state;
} DetectReaderViewModel;
static void detect_reader_draw_callback(Canvas* canvas, void* model) {
DetectReaderViewModel* m = model;
char text[32] = {};
snprintf(text, sizeof(text), "Tap the reader several times");
canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Tap the reader several times");
// Draw header and icon
canvas_draw_icon(canvas, 0, 16, &I_Modern_reader_18x34);
if(m->state == DetectReaderStateStart) {
snprintf(text, sizeof(text), "Touch the reader");
canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39);
} else if(m->state == DetectReaderStateReaderDetected) {
snprintf(text, sizeof(text), "Move the Flipper away");
canvas_draw_icon(canvas, 24, 25, &I_Release_arrow_18x15);
} else if(m->state == DetectReaderStateReaderLost) {
snprintf(text, sizeof(text), "Touch the reader again");
canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39);
}
if(m->nonces == 0) {
canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, text);
// Draw collected nonces
if(m->state == DetectReaderStateStart) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 52, 22, AlignLeft, AlignTop, "Emulating...");
canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Emulating...");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 52, 35, AlignLeft, AlignTop, "MIFARE Classic");
canvas_draw_icon(canvas, 0, 13, &I_Tap_reader_36x38);
canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, "MIFARE MFkey32");
} else {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 54, 22, AlignLeft, AlignTop, "Collecting...");
if(m->state == DetectReaderStateDone) {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Completed!");
} else {
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Collecting...");
}
canvas_set_font(canvas, FontSecondary);
snprintf(text, sizeof(text), "Nonces: %d", m->nonces);
canvas_draw_str_aligned(canvas, 54, 35, AlignLeft, AlignTop, text);
elements_button_right(canvas, "Next");
canvas_draw_icon(canvas, 6, 15, &I_ArrowC_1_36x36);
snprintf(text, sizeof(text), "Nonce pairs: %d/%d", m->nonces, m->nonces_max);
canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, text);
}
// Draw button
if(m->nonces > 0) {
elements_button_center(canvas, "Done");
}
}
@@ -49,7 +70,7 @@ static bool detect_reader_input_callback(InputEvent* event, void* context) {
});
if(event->type == InputTypeShort) {
if(event->key == InputKeyRight) {
if(event->key == InputKeyOk) {
if(nonces > 0) {
detect_reader->callback(detect_reader->context);
consumed = true;
@@ -84,6 +105,8 @@ void detect_reader_reset(DetectReader* detect_reader) {
with_view_model(
detect_reader->view, (DetectReaderViewModel * model) {
model->nonces = 0;
model->nonces_max = 0;
model->state = DetectReaderStateStart;
return false;
});
}
@@ -105,11 +128,31 @@ void detect_reader_set_callback(
detect_reader->context = context;
}
void detect_reader_inc_nonce_cnt(DetectReader* detect_reader) {
void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max) {
furi_assert(detect_reader);
with_view_model(
detect_reader->view, (DetectReaderViewModel * model) {
model->nonces++;
model->nonces_max = nonces_max;
return false;
});
}
void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected) {
furi_assert(detect_reader);
with_view_model(
detect_reader->view, (DetectReaderViewModel * model) {
model->nonces = nonces_collected;
return false;
});
}
void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state) {
furi_assert(detect_reader);
with_view_model(
detect_reader->view, (DetectReaderViewModel * model) {
model->state = state;
return true;
});
}

View File

@@ -5,6 +5,13 @@
typedef struct DetectReader DetectReader;
typedef enum {
DetectReaderStateStart,
DetectReaderStateReaderDetected,
DetectReaderStateReaderLost,
DetectReaderStateDone,
} DetectReaderState;
typedef void (*DetectReaderDoneCallback)(void* context);
DetectReader* detect_reader_alloc();
@@ -20,4 +27,8 @@ void detect_reader_set_callback(
DetectReaderDoneCallback callback,
void* context);
void detect_reader_inc_nonce_cnt(DetectReader* detect_reader);
void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max);
void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected);
void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state);

View File

@@ -86,3 +86,5 @@ typedef enum {
SubGhzViewReceiverModeLive,
SubGhzViewReceiverModeFile,
} SubGhzViewReceiverMode;
#define SUBGHZ_HISTORY_REMOVE_SAVED_ITEMS 1

View File

@@ -13,9 +13,11 @@ ADD_SCENE(subghz, saved_menu, SavedMenu)
ADD_SCENE(subghz, delete, Delete)
ADD_SCENE(subghz, delete_success, DeleteSuccess)
ADD_SCENE(subghz, test, Test)
ADD_SCENE(subghz, test_static, TestStatic)
ADD_SCENE(subghz, test_carrier, TestCarrier)
#if FURI_DEBUG
ADD_SCENE(subghz, test_static, TestStatic)
ADD_SCENE(subghz, test_packet, TestPacket)
#endif
ADD_SCENE(subghz, set_type, SetType)
ADD_SCENE(subghz, set_fix_faac_868, SetFixFaac868)
ADD_SCENE(subghz, set_cnt_faac_868, SetCntFaac868)

View File

@@ -31,7 +31,7 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e
return true;
} else if(event.event == SubGhzCustomEventViewReceiverUnlock) {
// Don't need to save, we already saved on short event
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_W(TAG, "Goto next scene!");
#endif
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);

View File

@@ -134,12 +134,22 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
} else {
//Restore default setting
subghz_preset_init(
subghz,
subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset),
subghz->last_settings->frequency,
NULL,
0);
if(subghz->raw_send_only) {
subghz_preset_init(
subghz,
"AM650",
subghz_setting_get_default_frequency(subghz->setting),
NULL,
0);
} else {
subghz_preset_init(
subghz,
subghz_setting_get_preset_name(
subghz->setting, subghz->last_settings->preset),
subghz->last_settings->frequency,
NULL,
0);
}
if(!scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneSaved)) {
if(!scene_manager_search_and_switch_to_previous_scene(
@@ -340,6 +350,10 @@ void subghz_scene_read_raw_on_exit(void* context) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
notification_message(subghz->notifications, &sequence_reset_rgb);
//filter restoration
//filter restoration
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz_last_settings_set_detect_raw_values(subghz);
#else
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
#endif
}

View File

@@ -6,6 +6,8 @@
const NotificationSequence subghz_sequence_rx = {
&message_green_255,
&message_display_backlight_on,
&message_vibro_on,
&message_note_c6,
&message_delay_50,
@@ -185,6 +187,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
consumed = true;
break;
case SubGhzCustomEventViewReceiverOK:
// Show file info, scene: receiver_info
subghz->txrx->idx_menu_chosen =
subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo);

View File

@@ -29,10 +29,12 @@ const char* const detect_raw_text[DETECT_RAW_COUNT] = {
"ON",
};
#ifndef SUBGHZ_SAVE_DETECT_RAW_SETTING
const SubGhzProtocolFlag detect_raw_value[DETECT_RAW_COUNT] = {
SubGhzProtocolFlag_Decodable,
SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_RAW,
};
#endif
#define RSSI_THRESHOLD_COUNT 7
const char* const rssi_threshold_text[RSSI_THRESHOLD_COUNT] = {
@@ -105,6 +107,7 @@ uint8_t subghz_scene_receiver_config_hopper_value_index(
}
}
#ifndef SUBGHZ_SAVE_DETECT_RAW_SETTING
uint8_t subghz_scene_receiver_config_detect_raw_value_index(
const SubGhzProtocolFlag value,
const SubGhzProtocolFlag values[],
@@ -118,6 +121,7 @@ uint8_t subghz_scene_receiver_config_detect_raw_value_index(
}
return index;
}
#endif
uint8_t subghz_scene_receiver_config_rssi_threshold_value_index(
const int value,
@@ -185,49 +189,64 @@ static void subghz_scene_receiver_config_set_detect_raw(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, detect_raw_text[index]);
subghz_receiver_set_filter(subghz->txrx->receiver, detect_raw_value[index]);
if(subghz->txrx->hopper_state == 0) {
variable_item_set_current_value_text(item, detect_raw_text[index]);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz->last_settings->detect_raw = index;
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
(index == 1));
subghz_last_settings_set_detect_raw_values(subghz);
#else
subghz_receiver_set_filter(subghz->txrx->receiver, detect_raw_value[index]);
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
(index == 1));
#endif
} else {
variable_item_set_current_value_index(item, 0);
}
}
static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, hopping_text[index]);
if(hopping_value[index] == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
snprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_default_frequency(subghz->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000);
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
text_buf);
subghz->txrx->preset->frequency = subghz_setting_get_default_frequency(subghz->setting);
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
} else {
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
" -----");
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
}
if(subghz_receiver_get_filter(subghz->txrx->receiver) == SubGhzProtocolFlag_Decodable) {
variable_item_set_current_value_text(item, hopping_text[index]);
if(hopping_value[index] == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
snprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_default_frequency(subghz->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000);
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
text_buf);
subghz->txrx->preset->frequency =
subghz_setting_get_default_frequency(subghz->setting);
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
} else {
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
" -----");
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
}
subghz->txrx->hopper_state = hopping_value[index];
subghz->txrx->hopper_state = hopping_value[index];
} else {
variable_item_set_current_value_index(item, 0);
}
}
static void subghz_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) {
@@ -244,10 +263,10 @@ void subghz_scene_receiver_config_on_enter(void* context) {
VariableItem* item;
uint8_t value_index;
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_D(
TAG,
"last frequency: %d, preset: %d",
"Last frequency: %d, Preset: %d",
subghz->last_settings->frequency,
subghz->last_settings->preset);
#endif
@@ -304,10 +323,14 @@ void subghz_scene_receiver_config_on_enter(void* context) {
DETECT_RAW_COUNT,
subghz_scene_receiver_config_set_detect_raw,
subghz);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
value_index = subghz->last_settings->detect_raw;
#else
value_index = subghz_scene_receiver_config_detect_raw_value_index(
subghz_receiver_get_filter(subghz->txrx->receiver),
detect_raw_value,
DETECT_RAW_COUNT);
#endif
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, detect_raw_text[value_index]);

View File

@@ -26,6 +26,7 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
subghz->txrx->receiver,
subghz_history_get_protocol_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
if(subghz->txrx->decoder_result) {
// In this case flipper format was changed to short file content
subghz_protocol_decoder_base_deserialize(
subghz->txrx->decoder_result,
subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));

View File

@@ -1,4 +1,6 @@
#include "../subghz_i.h"
#include <lib/subghz/protocols/keeloq.h>
#include <lib/subghz/protocols/star_line.h>
typedef enum {
SubGhzRpcStateIdle,
@@ -97,4 +99,9 @@ void subghz_scene_rpc_on_exit(void* context) {
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
popup_set_icon(popup, 0, 0, NULL);
keeloq_reset_mfname();
keeloq_reset_kl_type();
star_line_reset_mfname();
star_line_reset_kl_type();
}

View File

@@ -21,11 +21,15 @@ void subghz_scene_start_on_enter(void* context) {
if(subghz->state_notifications == SubGhzNotificationStateStarting) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
}
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz_last_settings_set_detect_raw_values(subghz);
#else
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
false);
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
#endif
submenu_add_item(
subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz);
@@ -93,6 +97,7 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
return true;
} else if(event.event == SubmenuIndexTest) {
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest);

View File

@@ -20,11 +20,12 @@ void subghz_scene_test_on_enter(void* context) {
SubmenuIndexCarrier,
subghz_scene_test_submenu_callback,
subghz);
#if FURI_DEBUG
submenu_add_item(
subghz->submenu, "Packet", SubmenuIndexPacket, subghz_scene_test_submenu_callback, subghz);
submenu_add_item(
subghz->submenu, "Static", SubmenuIndexStatic, subghz_scene_test_submenu_callback, subghz);
#endif
submenu_set_selected_item(
subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTest));
@@ -40,7 +41,9 @@ bool subghz_scene_test_on_event(void* context, SceneManagerEvent event) {
subghz->scene_manager, SubGhzSceneTest, SubmenuIndexCarrier);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestCarrier);
return true;
} else if(event.event == SubmenuIndexPacket) {
}
#if FURI_DEBUG
else if(event.event == SubmenuIndexPacket) {
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneTest, SubmenuIndexPacket);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestPacket);
@@ -51,6 +54,7 @@ bool subghz_scene_test_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestStatic);
return true;
}
#endif
}
return false;
}

View File

@@ -27,4 +27,4 @@ bool subghz_scene_test_carrier_on_event(void* context, SceneManagerEvent event)
void subghz_scene_test_carrier_on_exit(void* context) {
UNUSED(context);
}
}

View File

@@ -1,3 +1,4 @@
#if FURI_DEBUG
#include "../subghz_i.h"
#include "../views/subghz_test_packet.h"
@@ -28,3 +29,4 @@ bool subghz_scene_test_packet_on_event(void* context, SceneManagerEvent event) {
void subghz_scene_test_packet_on_exit(void* context) {
UNUSED(context);
}
#endif

View File

@@ -1,3 +1,4 @@
#if FURI_DEBUG
#include "../subghz_i.h"
#include "../views/subghz_test_static.h"
@@ -28,3 +29,4 @@ bool subghz_scene_test_static_on_event(void* context, SceneManagerEvent event) {
void subghz_scene_test_static_on_exit(void* context) {
UNUSED(context);
}
#endif

View File

@@ -61,7 +61,7 @@ void subghz_blink_stop(SubGhz* instance) {
notification_message(instance->notifications, &sequence_blink_stop);
}
SubGhz* subghz_alloc() {
SubGhz* subghz_alloc(bool alloc_for_tx_only) {
SubGhz* subghz = malloc(sizeof(SubGhz));
string_init(subghz->file_path);
@@ -88,38 +88,43 @@ SubGhz* subghz_alloc() {
// Open Notification record
subghz->notifications = furi_record_open(RECORD_NOTIFICATION);
// SubMenu
subghz->submenu = submenu_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdMenu, submenu_get_view(subghz->submenu));
// Receiver
subghz->subghz_receiver = subghz_view_receiver_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdReceiver,
subghz_view_receiver_get_view(subghz->subghz_receiver));
if(!alloc_for_tx_only) {
// SubMenu
subghz->submenu = submenu_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdMenu, submenu_get_view(subghz->submenu));
// Receiver
subghz->subghz_receiver = subghz_view_receiver_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdReceiver,
subghz_view_receiver_get_view(subghz->subghz_receiver));
}
// Popup
subghz->popup = popup_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdPopup, popup_get_view(subghz->popup));
if(!alloc_for_tx_only) {
// Text Input
subghz->text_input = text_input_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdTextInput,
text_input_get_view(subghz->text_input));
// Text Input
subghz->text_input = text_input_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdTextInput, text_input_get_view(subghz->text_input));
// Byte Input
subghz->byte_input = byte_input_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdByteInput, byte_input_get_view(subghz->byte_input));
// Custom Widget
subghz->widget = widget_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdWidget, widget_get_view(subghz->widget));
// Byte Input
subghz->byte_input = byte_input_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdByteInput,
byte_input_get_view(subghz->byte_input));
// Custom Widget
subghz->widget = widget_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher, SubGhzViewIdWidget, widget_get_view(subghz->widget));
}
//Dialog
subghz->dialogs = furi_record_open(RECORD_DIALOGS);
@@ -129,35 +134,36 @@ SubGhz* subghz_alloc() {
subghz->view_dispatcher,
SubGhzViewIdTransmitter,
subghz_view_transmitter_get_view(subghz->subghz_transmitter));
if(!alloc_for_tx_only) {
// Variable Item List
subghz->variable_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdVariableItemList,
variable_item_list_get_view(subghz->variable_item_list));
// Variable Item List
subghz->variable_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdVariableItemList,
variable_item_list_get_view(subghz->variable_item_list));
// Frequency Analyzer
subghz->subghz_frequency_analyzer = subghz_frequency_analyzer_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdFrequencyAnalyzer,
subghz_frequency_analyzer_get_view(subghz->subghz_frequency_analyzer));
// Frequency Analyzer
subghz->subghz_frequency_analyzer = subghz_frequency_analyzer_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdFrequencyAnalyzer,
subghz_frequency_analyzer_get_view(subghz->subghz_frequency_analyzer));
// Carrier Test Module
subghz->subghz_test_carrier = subghz_test_carrier_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdTestCarrier,
subghz_test_carrier_get_view(subghz->subghz_test_carrier));
}
// Read RAW
subghz->subghz_read_raw = subghz_read_raw_alloc();
subghz->subghz_read_raw = subghz_read_raw_alloc(alloc_for_tx_only);
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdReadRAW,
subghz_read_raw_get_view(subghz->subghz_read_raw));
// Carrier Test Module
subghz->subghz_test_carrier = subghz_test_carrier_alloc();
view_dispatcher_add_view(
subghz->view_dispatcher,
SubGhzViewIdTestCarrier,
subghz_test_carrier_get_view(subghz->subghz_test_carrier));
#if FURI_DEBUG
// Packet Test
subghz->subghz_test_packet = subghz_test_packet_alloc();
view_dispatcher_add_view(
@@ -171,41 +177,64 @@ SubGhz* subghz_alloc() {
subghz->view_dispatcher,
SubGhzViewIdStatic,
subghz_test_static_get_view(subghz->subghz_test_static));
#endif
//init setting
subghz->setting = subghz_setting_alloc();
subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user"));
if(alloc_for_tx_only) {
subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user"), false);
} else {
subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user"), true);
}
// Load last used values for Read, Read RAW, etc. or default
subghz->last_settings = subghz_last_settings_alloc();
subghz_last_settings_load(
subghz->last_settings, subghz_setting_get_preset_count(subghz->setting));
if(!alloc_for_tx_only) {
subghz->last_settings = subghz_last_settings_alloc();
subghz_last_settings_load(
subghz->last_settings, subghz_setting_get_preset_count(subghz->setting));
#if FURI_DEBUG
FURI_LOG_D(
TAG,
"last frequency: %d, preset: %d",
subghz->last_settings->frequency,
subghz->last_settings->preset);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
FURI_LOG_D(
TAG,
"last frequency: %d, preset: %d, detect_raw: %d",
subghz->last_settings->frequency,
subghz->last_settings->preset,
subghz->last_settings->detect_raw);
#else
FURI_LOG_D(
TAG,
"last frequency: %d, preset: %d",
subghz->last_settings->frequency,
subghz->last_settings->preset);
#endif
subghz_setting_set_default_frequency(subghz->setting, subghz->last_settings->frequency);
#endif
subghz_setting_set_default_frequency(subghz->setting, subghz->last_settings->frequency);
}
//init Worker & Protocol & History & KeyBoard
subghz->lock = SubGhzLockOff;
subghz->txrx = malloc(sizeof(SubGhzTxRx));
subghz->txrx->preset = malloc(sizeof(SubGhzPresetDefinition));
string_init(subghz->txrx->preset->name);
subghz_preset_init(
subghz,
subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset),
subghz->last_settings->frequency,
NULL,
0);
if(!alloc_for_tx_only) {
subghz_preset_init(
subghz,
subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset),
subghz->last_settings->frequency,
NULL,
0);
} else {
subghz_preset_init(
subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0);
}
subghz->txrx->txrx_state = SubGhzTxRxStateSleep;
subghz->txrx->hopper_state = SubGhzHopperStateOFF;
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
subghz->txrx->history = subghz_history_alloc();
if(!alloc_for_tx_only) {
subghz->txrx->history = subghz_history_alloc();
}
subghz->txrx->worker = subghz_worker_alloc();
subghz->txrx->fff_data = flipper_format_string_alloc();
subghz->txrx->secure_data = malloc(sizeof(SecureData));
@@ -214,8 +243,13 @@ SubGhz* subghz_alloc() {
subghz->txrx->environment, EXT_PATH("subghz/assets/came_atomo"));
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
subghz->txrx->environment, EXT_PATH("subghz/assets/nice_flor_s"));
subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz_last_settings_set_detect_raw_values(subghz);
#else
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
#endif
subghz_worker_set_overrun_callback(
subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
@@ -229,7 +263,7 @@ SubGhz* subghz_alloc() {
return subghz;
}
void subghz_free(SubGhz* subghz) {
void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) {
furi_assert(subghz);
if(subghz->rpc_ctx) {
@@ -239,57 +273,60 @@ void subghz_free(SubGhz* subghz) {
subghz->rpc_ctx = NULL;
}
#if FURI_DEBUG
// Packet Test
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestPacket);
subghz_test_packet_free(subghz->subghz_test_packet);
// Carrier Test
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestCarrier);
subghz_test_carrier_free(subghz->subghz_test_carrier);
// Static
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdStatic);
subghz_test_static_free(subghz->subghz_test_static);
#endif
// Receiver
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdReceiver);
subghz_view_receiver_free(subghz->subghz_receiver);
if(!alloc_for_tx_only) {
// Carrier Test
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestCarrier);
subghz_test_carrier_free(subghz->subghz_test_carrier);
// TextInput
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTextInput);
text_input_free(subghz->text_input);
// Receiver
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdReceiver);
subghz_view_receiver_free(subghz->subghz_receiver);
// ByteInput
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdByteInput);
byte_input_free(subghz->byte_input);
// TextInput
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTextInput);
text_input_free(subghz->text_input);
// Custom Widget
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdWidget);
widget_free(subghz->widget);
// ByteInput
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdByteInput);
byte_input_free(subghz->byte_input);
// Custom Widget
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdWidget);
widget_free(subghz->widget);
}
//Dialog
furi_record_close(RECORD_DIALOGS);
// Transmitter
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTransmitter);
subghz_view_transmitter_free(subghz->subghz_transmitter);
if(!alloc_for_tx_only) {
// Variable Item List
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
variable_item_list_free(subghz->variable_item_list);
// Variable Item List
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
variable_item_list_free(subghz->variable_item_list);
// Frequency Analyzer
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer);
subghz_frequency_analyzer_free(subghz->subghz_frequency_analyzer);
// Frequency Analyzer
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer);
subghz_frequency_analyzer_free(subghz->subghz_frequency_analyzer);
}
// Read RAW
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdReadRAW);
subghz_read_raw_free(subghz->subghz_read_raw);
// Submenu
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdMenu);
submenu_free(subghz->submenu);
if(!alloc_for_tx_only) {
// Submenu
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdMenu);
submenu_free(subghz->submenu);
}
// Popup
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdPopup);
popup_free(subghz->popup);
@@ -306,14 +343,21 @@ void subghz_free(SubGhz* subghz) {
//setting
subghz_setting_free(subghz->setting);
subghz_last_settings_free(subghz->last_settings);
if(!alloc_for_tx_only) {
subghz_last_settings_free(subghz->last_settings);
}
//Worker & Protocol & History
subghz_receiver_free(subghz->txrx->receiver);
subghz_environment_free(subghz->txrx->environment);
subghz_worker_free(subghz->txrx->worker);
flipper_format_free(subghz->txrx->fff_data);
subghz_history_free(subghz->txrx->history);
if(!alloc_for_tx_only) {
subghz_history_free(subghz->txrx->history);
}
string_clear(subghz->txrx->preset->name);
free(subghz->txrx->preset);
free(subghz->txrx->secure_data);
@@ -335,7 +379,20 @@ void subghz_free(SubGhz* subghz) {
}
int32_t subghz_app(void* p) {
SubGhz* subghz = subghz_alloc();
bool alloc_for_tx;
if(p && strlen(p)) {
alloc_for_tx = true;
} else {
alloc_for_tx = false;
}
SubGhz* subghz = subghz_alloc(alloc_for_tx);
if(alloc_for_tx) {
subghz->raw_send_only = true;
} else {
subghz->raw_send_only = false;
}
//Load database
bool load_database = subghz_environment_load_keystore(
@@ -394,7 +451,7 @@ int32_t subghz_app(void* p) {
furi_hal_power_suppress_charge_exit();
subghz_free(subghz);
subghz_free(subghz, alloc_for_tx);
return 0;
}

View File

@@ -1,14 +1,28 @@
#include "subghz_history.h"
#include "subghz_history_private.h"
#include <lib/subghz/receiver.h>
#include <furi.h>
#include <m-string.h>
#include <flipper_format/flipper_format_i.h>
#define SUBGHZ_HISTORY_MAX 65
/**
* @brief Settings for temporary files
*
*/
#define SUBGHZ_HISTORY_TMP_DIR EXT_PATH("subghz/tmp_history")
#define SUBGHZ_HISTORY_TMP_EXTENSION ".tmp"
#define SUBGHZ_HISTORY_TMP_SIGNAL_MAX_LEVEL_DURATION 700
#define SUBGHZ_HISTORY_TMP_SIGNAL_MIN_LEVEL_DURATION 100
#define SUBGHZ_HISTORY_TMP_REMOVE_FILES false
#define SUBGHZ_HISTORY_TMP_RAW_KEY "RAW_Data"
#define TAG "SubGhzHistory"
typedef struct {
string_t item_str;
FlipperFormat* flipper_string;
string_t protocol_name;
bool is_file;
uint8_t type;
SubGhzPresetDefinition* preset;
} SubGhzHistoryItem;
@@ -26,30 +40,143 @@ struct SubGhzHistory {
uint16_t last_index_write;
uint8_t code_last_hash_data;
string_t tmp_string;
bool write_tmp_files;
Storage* storage;
SubGhzHistoryStruct* history;
};
#ifdef FURI_DEBUG
#define LOG_DELAY 0
#endif
void subghz_history_generate_temp_filename(string_t filename, uint32_t index) {
FuriHalRtcDateTime datetime = {0};
furi_hal_rtc_get_datetime(&datetime);
string_init_printf(filename, "%03d%s", index, SUBGHZ_HISTORY_TMP_EXTENSION);
}
bool subghz_history_is_tmp_dir_exists(SubGhzHistory* instance) {
FileInfo file_info;
storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &file_info);
if(storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &file_info) == FSE_OK) {
if(file_info.flags & FSF_DIRECTORY) {
return true;
}
}
return false;
}
bool subghz_history_check_sdcard(SubGhzHistory* instance) {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "check_sdcard");
uint32_t start_time = furi_get_tick();
#endif
bool result = false;
// Stage 0 - check SD Card
FS_Error status = storage_sd_status(instance->storage);
if(status == FSE_OK) {
result = subghz_history_is_tmp_dir_exists(instance);
if(!subghz_history_is_tmp_dir_exists(instance)) {
result = storage_simply_mkdir(instance->storage, SUBGHZ_HISTORY_TMP_DIR);
}
} else {
FURI_LOG_W(TAG, "SD storage not installed! Status: %d", status);
}
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Running time (check_sdcard): %d ms", furi_get_tick() - start_time);
#endif
return result;
}
void subghz_history_clear_tmp_dir(SubGhzHistory* instance) {
furi_assert(instance);
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "clear_tmp_dir");
#endif
if(!instance->write_tmp_files) {
// Nothing to do here!
return;
}
uint32_t start_time = furi_get_tick();
#ifdef SUBGHZ_HISTORY_TMP_REMOVE_FILES
// Stage 0 - Dir exists?
bool res = subghz_history_is_tmp_dir_exists(instance);
if(res) {
// Stage 1 - delete all content if exists
FileInfo fileinfo;
storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &fileinfo);
res = fileinfo.flags & FSF_DIRECTORY ?
storage_simply_remove_recursive(instance->storage, SUBGHZ_HISTORY_TMP_DIR) :
(storage_common_remove(instance->storage, SUBGHZ_HISTORY_TMP_DIR) == FSE_OK);
}
// Stage 2 - create dir if necessary
res = !storage_simply_mkdir(instance->storage, SUBGHZ_HISTORY_TMP_DIR);
if(!res) {
FURI_LOG_E(TAG, "Cannot process temp dir!");
}
#endif
uint32_t stop_time = furi_get_tick() - start_time;
FURI_LOG_I(TAG, "Running time (clear_tmp_dir): %d ms", stop_time);
}
SubGhzHistory* subghz_history_alloc(void) {
SubGhzHistory* instance = malloc(sizeof(SubGhzHistory));
string_init(instance->tmp_string);
instance->history = malloc(sizeof(SubGhzHistoryStruct));
SubGhzHistoryItemArray_init(instance->history->data);
instance->storage = furi_record_open(RECORD_STORAGE);
instance->write_tmp_files = subghz_history_check_sdcard(instance);
if(!instance->write_tmp_files) {
FURI_LOG_E(TAG, "Unstable work! Cannot use SD Card!");
}
return instance;
}
void subghz_history_item_free(void* current_item) {
furi_assert(current_item);
SubGhzHistoryItem* item = (SubGhzHistoryItem*)current_item;
string_clear(item->item_str);
string_clear(item->preset->name);
string_clear(item->protocol_name);
free(item->preset);
item->type = 0;
item->is_file = false;
if(item->flipper_string != NULL) {
flipper_format_free(item->flipper_string);
}
}
void subghz_history_clean_item_array(SubGhzHistory* instance) {
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
subghz_history_item_free(item);
}
}
void subghz_history_free(SubGhzHistory* instance) {
furi_assert(instance);
string_clear(instance->tmp_string);
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
string_clear(item->item_str);
string_clear(item->preset->name);
free(item->preset);
flipper_format_free(item->flipper_string);
item->type = 0;
}
subghz_history_clean_item_array(instance);
SubGhzHistoryItemArray_clear(instance->history->data);
free(instance->history);
// Delete all temporary file, on exit it's ok
subghz_history_clear_tmp_dir(instance);
furi_record_close(RECORD_STORAGE);
free(instance);
}
@@ -74,14 +201,9 @@ const char* subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) {
void subghz_history_reset(SubGhzHistory* instance) {
furi_assert(instance);
string_reset(instance->tmp_string);
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
string_clear(item->item_str);
string_clear(item->preset->name);
free(item->preset);
flipper_format_free(item->flipper_string);
item->type = 0;
}
subghz_history_clean_item_array(instance);
SubGhzHistoryItemArray_reset(instance->history->data);
instance->last_index_write = 0;
instance->code_last_hash_data = 0;
@@ -101,12 +223,8 @@ uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx)
const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t idx) {
furi_assert(instance);
SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx);
flipper_format_rewind(item->flipper_string);
if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) {
FURI_LOG_E(TAG, "Missing Protocol");
string_reset(instance->tmp_string);
}
return string_get_cstr(instance->tmp_string);
return string_get_cstr(item->protocol_name);
}
FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx) {
@@ -115,17 +233,67 @@ FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx
if(item->flipper_string) {
return item->flipper_string;
} else {
return NULL;
bool result_ok = false;
if(instance->write_tmp_files && item->is_file) {
// We have files!
string_t filename;
string_t dir_path;
string_init(filename);
string_init(dir_path);
subghz_history_generate_temp_filename(filename, idx);
string_init_printf(
dir_path, "%s/%s", SUBGHZ_HISTORY_TMP_DIR, string_get_cstr(filename));
if(storage_file_exists(instance->storage, string_get_cstr(dir_path))) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "Exist: %s", dir_path);
furi_delay_ms(LOG_DELAY);
#endif
// Set to current anyway it has NULL value
item->flipper_string = flipper_format_string_alloc();
Stream* dst_stream = flipper_format_get_raw_stream(item->flipper_string);
stream_clean(dst_stream);
size_t size = stream_load_from_file(
dst_stream, instance->storage, string_get_cstr(dir_path));
if(size > 0) {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save ok!");
furi_delay_ms(LOG_DELAY);
#endif
// We changed contents of file, so we no needed to load
// content from disk for the next time
item->is_file = false;
result_ok = true;
} else {
FURI_LOG_E(TAG, "Stream copy failed!");
flipper_format_free(item->flipper_string);
}
} else {
FURI_LOG_E(TAG, "Can't convert filename to file");
}
string_clear(filename);
string_clear(dir_path);
} else {
#ifdef FURI_DEBUG
FURI_LOG_W(TAG, "Write TMP files failed!");
furi_delay_ms(LOG_DELAY);
#endif
}
return result_ok ? item->flipper_string : NULL;
}
}
bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output) {
furi_assert(instance);
if(instance->last_index_write == SUBGHZ_HISTORY_MAX) {
if(output != NULL) string_printf(output, "Memory is FULL");
return true;
}
if(output != NULL)
if(output != NULL) {
string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX);
}
return false;
}
@@ -141,7 +309,9 @@ bool subghz_history_add_to_history(
furi_assert(instance);
furi_assert(context);
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false;
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) {
return false;
}
SubGhzProtocolDecoderBase* decoder_base = context;
if((instance->code_last_hash_data ==
@@ -153,7 +323,6 @@ bool subghz_history_add_to_history(
instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base);
instance->last_update_timestamp = furi_get_tick();
string_t text;
string_init(text);
SubGhzHistoryItem* item = SubGhzHistoryItemArray_push_raw(instance->history->data);
@@ -166,6 +335,11 @@ bool subghz_history_add_to_history(
item->preset->data_size = preset->data_size;
string_init(item->item_str);
string_init(item->protocol_name);
bool tmp_file_for_raw = false;
// At this point file mapped to memory otherwise file cannot decode
item->flipper_string = flipper_format_string_alloc();
subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset);
@@ -177,6 +351,8 @@ bool subghz_history_add_to_history(
if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) {
FURI_LOG_E(TAG, "Missing Protocol");
break;
} else {
string_init_printf(item->protocol_name, "%s", string_get_cstr(instance->tmp_string));
}
if(!strcmp(string_get_cstr(instance->tmp_string), "RAW")) {
string_printf(
@@ -188,7 +364,7 @@ bool subghz_history_add_to_history(
if(!flipper_format_rewind(item->flipper_string)) {
FURI_LOG_E(TAG, "Rewind error");
}
tmp_file_for_raw = true;
break;
} else if(!strcmp(string_get_cstr(instance->tmp_string), "KeeLoq")) {
string_set_str(instance->tmp_string, "KL ");
@@ -234,7 +410,72 @@ bool subghz_history_add_to_history(
}
} while(false);
// If we can write to files
if(instance->write_tmp_files && tmp_file_for_raw) {
string_t filename;
string_t dir_path;
string_init(filename);
string_init(dir_path);
subghz_history_generate_temp_filename(filename, instance->last_index_write);
string_cat_printf(dir_path, "%s/%s", SUBGHZ_HISTORY_TMP_DIR, string_get_cstr(filename));
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save temp file: %s", string_get_cstr(dir_path));
#endif
if(!subghz_history_tmp_write_file_split(instance, item, dir_path)) {
// Plan B!
subghz_history_tmp_write_file_full(instance, item, dir_path);
}
string_clear(filename);
string_clear(dir_path);
} else {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Old fashion way");
#endif
}
string_clear(text);
instance->last_index_write++;
return true;
}
bool subghz_history_tmp_write_file_split(
SubGhzHistory* instance,
void* current_item,
string_t dir_path) {
UNUSED(instance);
UNUSED(current_item);
UNUSED(dir_path);
/*furi_assert(instance);
furi_assert(current_item);
furi_assert(dir_path);*/
//SubGhzHistoryItem* item = (SubGhzHistoryItem*)current_item;
return false;
}
void subghz_history_tmp_write_file_full(
SubGhzHistory* instance,
void* current_item,
string_t dir_path) {
SubGhzHistoryItem* item = (SubGhzHistoryItem*)current_item;
#ifdef FURI_DEBUG
FURI_LOG_W(TAG, "Save temp file full: %s", string_get_cstr(dir_path));
#endif
Stream* dst = flipper_format_get_raw_stream(item->flipper_string);
stream_rewind(dst);
if(stream_save_to_file(dst, instance->storage, string_get_cstr(dir_path), FSOM_CREATE_ALWAYS) >
0) {
flipper_format_free(item->flipper_string);
item->flipper_string = NULL;
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save done!");
#endif
// This item contains fake data to load from SD
item->is_file = true;
} else {
FURI_LOG_E(TAG, "Stream copy failed!");
}
}

View File

@@ -0,0 +1,79 @@
#pragma once
#include "subghz_history.h"
/**
* @brief Generate filename like 000.tmp
*
* @param filename - input parameter
* @param index - index of file, timestamp doesn't accepted!
*/
void subghz_history_generate_temp_filename(string_t filename, uint32_t index);
/**
* @brief Check if directory for temporary files is exists
*
* @param instance SubGhzHistory*
* @return true
* @return false
*/
bool subghz_history_is_tmp_dir_exists(SubGhzHistory* instance);
/**
* @brief Check SD card and create temporary dir if not exists,
* Result write_tmp_files without this unstable work is GUARANTEED
*
* @param instance - SubGhzHistory*
* @return - true all ok
* @return - false we have a problems
*/
bool subghz_history_check_sdcard(SubGhzHistory* instance);
/**
* @brief Recursive delete dir and files and create new temp dir
*
* @param instance - SubGhzHistory*
* @return true - if all ok
* @return false - if something failed
*/
void subghz_history_clear_tmp_dir(SubGhzHistory* instance);
/**
* @brief Free item and free all resources
*
* @param current_item - SubGhzHistoryItem*
*/
void subghz_history_item_free(void* current_item);
/**
* @brief free all items in array
*
* @param instance
*/
void subghz_history_clean_item_array(SubGhzHistory* instance);
/**
* @brief Write temp file fully, without spliting
*
* @param instance - SubGhzHistory*
* @param current_item - SubGhzHistoryItem*
* @param dir_path - full path to file
*/
void subghz_history_tmp_write_file_full(
SubGhzHistory* instance,
void* current_item,
string_t dir_path);
/**
* @brief Write temp splited to lines
*
* @param instance - SubGhzHistory*
* @param current_item - SubGhzHistoryItem*
* @param dir_path - full path to file
* @return true - file saved
* @return false - error occured
*/
bool subghz_history_tmp_write_file_split(
SubGhzHistory* instance,
void* current_item,
string_t dir_path);

View File

@@ -7,10 +7,11 @@
#include "views/subghz_frequency_analyzer.h"
#include "views/subghz_read_raw.h"
#include "views/subghz_test_static.h"
#include "views/subghz_test_carrier.h"
#if FURI_DEBUG
#include "views/subghz_test_static.h"
#include "views/subghz_test_packet.h"
#endif
// #include <furi.h>
// #include <furi_hal.h>
#include <gui/gui.h>
@@ -96,9 +97,12 @@ struct SubGhz {
SubGhzFrequencyAnalyzer* subghz_frequency_analyzer;
SubGhzReadRAW* subghz_read_raw;
SubGhzTestStatic* subghz_test_static;
bool raw_send_only;
SubGhzTestCarrier* subghz_test_carrier;
#if FURI_DEBUG
SubGhzTestStatic* subghz_test_static;
SubGhzTestPacket* subghz_test_packet;
#endif
string_t error_str;
SubGhzSetting* setting;
SubGhzLastSettings* last_settings;

View File

@@ -1,5 +1,8 @@
#include "subghz_last_settings.h"
#include <lib/flipper_format/flipper_format.h>
#include "subghz_i.h"
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
#include <lib/subghz/protocols/raw.h>
#endif
#define TAG "SubGhzLastSettings"
@@ -11,6 +14,14 @@
#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1
#define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
#define SUBGHZ_LAST_SETTING_DEFAULT_READ_RAW 0
#define SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW "DetectRaw"
#endif
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY "Frequency"
#define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset"
SubGhzLastSettings* subghz_last_settings_alloc(void) {
SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings));
return instance;
@@ -23,7 +34,7 @@ void subghz_last_settings_free(SubGhzLastSettings* instance) {
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count) {
furi_assert(instance);
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "subghz_last_settings_load");
#endif
@@ -32,11 +43,20 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
uint32_t temp_frequency = 0;
int32_t temp_preset = 0;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
uint32_t temp_read_raw = 0;
#endif
if(FSE_OK == storage_sd_status(storage) && SUBGHZ_LAST_SETTINGS_PATH &&
flipper_format_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) {
flipper_format_read_int32(fff_data_file, "Preset", (int32_t*)&temp_preset, 1);
flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&temp_frequency, 1);
flipper_format_read_int32(
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (int32_t*)&temp_preset, 1);
flipper_format_read_uint32(
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, (uint32_t*)&temp_frequency, 1);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
flipper_format_read_uint32(
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW, (uint32_t*)&temp_read_raw, 1);
#endif
} else {
FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH);
}
@@ -45,8 +65,14 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
FURI_LOG_W(TAG, "Last used frequency not found or can't be used!");
instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY;
instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
instance->detect_raw = SUBGHZ_LAST_SETTING_DEFAULT_READ_RAW;
#endif
} else {
instance->frequency = temp_frequency;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
instance->detect_raw = temp_read_raw;
#endif
if(temp_preset > (int32_t)preset_count - 1 || temp_preset < 0) {
FURI_LOG_W(TAG, "Last used preset no found");
@@ -63,8 +89,8 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
bool subghz_last_settings_save(SubGhzLastSettings* instance) {
furi_assert(instance);
#if FURI_DEBUG
FURI_LOG_I(TAG, "subghz_last_settings_save");
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "last_settings_save");
#endif
bool saved = false;
@@ -84,12 +110,20 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION))
break;
if(!flipper_format_insert_or_update_int32(file, "Preset", &instance->preset, 1)) {
if(!flipper_format_insert_or_update_int32(
file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset, 1)) {
break;
}
if(!flipper_format_insert_or_update_uint32(file, "Frequency", &instance->frequency, 1)) {
if(!flipper_format_insert_or_update_uint32(
file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) {
break;
}
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
if(!flipper_format_insert_or_update_uint32(
file, SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW, &instance->detect_raw, 1)) {
break;
}
#endif
saved = true;
} while(0);
@@ -102,4 +136,18 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
furi_record_close(RECORD_STORAGE);
return saved;
}
}
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
void subghz_last_settings_set_detect_raw_values(void* context) {
furi_assert(context);
SubGhz* instance = (SubGhz*)context;
bool is_detect_raw = instance->last_settings->detect_raw > 0;
subghz_receiver_set_filter(
instance->txrx->receiver, is_detect_raw ? DETECT_RAW_TRUE : DETECT_RAW_FALSE);
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
instance->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
is_detect_raw);
}
#endif

View File

@@ -1,12 +1,23 @@
#pragma once
// Enable saving detect raw setting state
// #define SUBGHZ_SAVE_DETECT_RAW_SETTING 1
#include <furi_hal.h>
#include <stdint.h>
#include <stdbool.h>
#include <storage/storage.h>
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
#include <lib/subghz/protocols/base.h>
#define DETECT_RAW_FALSE SubGhzProtocolFlag_Decodable
#define DETECT_RAW_TRUE SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_RAW
#endif
typedef struct {
uint32_t frequency;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
uint32_t detect_raw;
#endif
int32_t preset;
} SubGhzLastSettings;
@@ -16,4 +27,7 @@ void subghz_last_settings_free(SubGhzLastSettings* instance);
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count);
bool subghz_last_settings_save(SubGhzLastSettings* instance);
bool subghz_last_settings_save(SubGhzLastSettings* instance);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
void subghz_last_settings_set_detect_raw_values(void* context);
#endif

View File

@@ -181,7 +181,7 @@ void subghz_setting_load_default(SubGhzSetting* instance) {
instance, subghz_frequency_list, subghz_hopper_frequency_list);
}
void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
void subghz_setting_load(SubGhzSetting* instance, const char* file_path, bool not_skip_frequencies) {
furi_assert(instance);
Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -214,53 +214,56 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
}
// Standard frequencies (optional)
temp_bool = true;
flipper_format_read_bool(fff_data_file, "Add_standard_frequencies", &temp_bool, 1);
if(!temp_bool) {
FURI_LOG_I(TAG, "Removing standard frequencies");
FrequencyList_reset(instance->frequencies);
FrequencyList_reset(instance->hopper_frequencies);
} else {
FURI_LOG_I(TAG, "Keeping standard frequencies");
}
// Load frequencies
if(!flipper_format_rewind(fff_data_file)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
while(flipper_format_read_uint32(
fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) {
if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
FrequencyList_push_back(instance->frequencies, temp_data32);
if(not_skip_frequencies) {
temp_bool = true;
flipper_format_read_bool(fff_data_file, "Add_standard_frequencies", &temp_bool, 1);
if(!temp_bool) {
FURI_LOG_I(TAG, "Removing standard frequencies");
FrequencyList_reset(instance->frequencies);
FrequencyList_reset(instance->hopper_frequencies);
} else {
FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32);
FURI_LOG_I(TAG, "Keeping standard frequencies");
}
}
// Load hopper frequencies
if(!flipper_format_rewind(fff_data_file)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
while(flipper_format_read_uint32(
fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) {
if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32);
FrequencyList_push_back(instance->hopper_frequencies, temp_data32);
} else {
FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32);
// Load frequencies
if(!flipper_format_rewind(fff_data_file)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
while(flipper_format_read_uint32(
fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) {
if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
FrequencyList_push_back(instance->frequencies, temp_data32);
} else {
FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32);
}
}
}
// Default frequency (optional)
if(!flipper_format_rewind(fff_data_file)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
if(flipper_format_read_uint32(fff_data_file, "Default_frequency", &temp_data32, 1)) {
subghz_setting_set_default_frequency(instance, temp_data32);
// Load hopper frequencies
if(!flipper_format_rewind(fff_data_file)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
while(flipper_format_read_uint32(
fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) {
if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32);
FrequencyList_push_back(instance->hopper_frequencies, temp_data32);
} else {
FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32);
}
}
// Default frequency (optional)
if(!flipper_format_rewind(fff_data_file)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
if(flipper_format_read_uint32(
fff_data_file, "Default_frequency", &temp_data32, 1)) {
subghz_setting_set_default_frequency(instance, temp_data32);
}
}
// custom preset (optional)

View File

@@ -14,7 +14,7 @@ SubGhzSetting* subghz_setting_alloc(void);
void subghz_setting_free(SubGhzSetting* instance);
void subghz_setting_load(SubGhzSetting* instance, const char* file_path);
void subghz_setting_load(SubGhzSetting* instance, const char* file_path, bool not_skip_frequencies);
size_t subghz_setting_get_frequency_count(SubGhzSetting* instance);

View File

@@ -40,6 +40,25 @@ static const NotificationSequence sequence_saved = {
&message_vibro_off,
NULL,
};
static const NotificationSequence sequence_frequency = {
&message_display_backlight_on,
&message_green_255,
&message_vibro_on,
&message_delay_100,
&message_green_0,
&message_blue_255,
&message_vibro_off,
&message_delay_100,
&message_blue_0,
&message_green_255,
&message_vibro_on,
&message_delay_100,
&message_green_0,
&message_vibro_off,
NULL,
};
//static const NotificationSequence sequence_not_saved = {
// &message_blink_stop,
// &message_green_255,
@@ -194,7 +213,7 @@ uint32_t subghz_frequency_find_correct(uint32_t input) {
uint32_t prev_freq = 0;
uint32_t current = 0;
uint32_t result = 0;
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "input: %d", input);
#endif
for(size_t i = 0; i < sizeof(subghz_frequency_list); i++) {
@@ -274,7 +293,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
frequency_candidate = subghz_frequency_find_correct(frequency_candidate);
}
if(frequency_candidate > 0 && frequency_candidate != model->frequency_to_save) {
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_D(
TAG,
"frequency_to_save: %d, candidate: %d",
@@ -289,7 +308,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
return true;
});
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_I(
TAG,
"updated: %d, long: %d, type: %d",
@@ -304,7 +323,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
// First device receive short, then when user release button we get long
if(event->type == InputTypeLong) {
#if FURI_DEBUG
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Longpress!");
#endif
// Stop blinking
@@ -366,12 +385,13 @@ void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency,
switch(instance->feedback_level) {
case 1: // 1 - only vibro
notification_message(instance->notifications, &sequence_single_vibro);
notification_message(instance->notifications, &sequence_frequency);
break;
case 2: // 2 - vibro and beep
notification_message(instance->notifications, &sequence_success);
break;
default: // 0 - no feedback
notification_message(instance->notifications, &sequence_display_backlight_on);
break;
}

View File

@@ -27,6 +27,7 @@ typedef struct {
uint8_t ind_write;
uint8_t ind_sin;
SubGhzReadRAWStatus status;
bool raw_send_only;
} SubGhzReadRAWModel;
void subghz_read_raw_set_callback(
@@ -232,9 +233,11 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) {
elements_button_right(canvas, "Save");
break;
case SubGhzReadRAWStatusLoadKeyIDLE:
elements_button_left(canvas, "New");
if(!model->raw_send_only) {
elements_button_left(canvas, "New");
elements_button_right(canvas, "More");
}
elements_button_center(canvas, "Send");
elements_button_right(canvas, "More");
elements_text_box(
canvas,
4,
@@ -362,31 +365,35 @@ bool subghz_read_raw_input(InputEvent* event, void* context) {
} else if(event->key == InputKeyLeft && event->type == InputTypeShort) {
with_view_model(
instance->view, (SubGhzReadRAWModel * model) {
if(model->status == SubGhzReadRAWStatusStart) {
//Config
instance->callback(SubGhzCustomEventViewReadRAWConfig, instance->context);
} else if(
(model->status == SubGhzReadRAWStatusIDLE) ||
(model->status == SubGhzReadRAWStatusLoadKeyIDLE)) {
//Erase
model->status = SubGhzReadRAWStatusStart;
model->rssi_history_end = false;
model->ind_write = 0;
string_set_str(model->sample_write, "0 spl.");
string_reset(model->file_name);
instance->callback(SubGhzCustomEventViewReadRAWErase, instance->context);
if(!model->raw_send_only) {
if(model->status == SubGhzReadRAWStatusStart) {
//Config
instance->callback(SubGhzCustomEventViewReadRAWConfig, instance->context);
} else if(
(model->status == SubGhzReadRAWStatusIDLE) ||
(model->status == SubGhzReadRAWStatusLoadKeyIDLE)) {
//Erase
model->status = SubGhzReadRAWStatusStart;
model->rssi_history_end = false;
model->ind_write = 0;
string_set_str(model->sample_write, "0 spl.");
string_reset(model->file_name);
instance->callback(SubGhzCustomEventViewReadRAWErase, instance->context);
}
}
return true;
});
} else if(event->key == InputKeyRight && event->type == InputTypeShort) {
with_view_model(
instance->view, (SubGhzReadRAWModel * model) {
if(model->status == SubGhzReadRAWStatusIDLE) {
//Save
instance->callback(SubGhzCustomEventViewReadRAWSave, instance->context);
} else if(model->status == SubGhzReadRAWStatusLoadKeyIDLE) {
//More
instance->callback(SubGhzCustomEventViewReadRAWMore, instance->context);
if(!model->raw_send_only) {
if(model->status == SubGhzReadRAWStatusIDLE) {
//Save
instance->callback(SubGhzCustomEventViewReadRAWSave, instance->context);
} else if(model->status == SubGhzReadRAWStatusLoadKeyIDLE) {
//More
instance->callback(SubGhzCustomEventViewReadRAWMore, instance->context);
}
}
return true;
});
@@ -487,7 +494,7 @@ void subghz_read_raw_exit(void* context) {
});
}
SubGhzReadRAW* subghz_read_raw_alloc() {
SubGhzReadRAW* subghz_read_raw_alloc(bool raw_send_only) {
SubGhzReadRAW* instance = malloc(sizeof(SubGhzReadRAW));
// View allocation and configuration
@@ -505,6 +512,7 @@ SubGhzReadRAW* subghz_read_raw_alloc() {
string_init(model->preset_str);
string_init(model->sample_write);
string_init(model->file_name);
model->raw_send_only = raw_send_only;
model->rssi_history = malloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t));
return true;
});

View File

@@ -25,7 +25,7 @@ void subghz_read_raw_set_callback(
SubGhzReadRAWCallback callback,
void* context);
SubGhzReadRAW* subghz_read_raw_alloc();
SubGhzReadRAW* subghz_read_raw_alloc(bool raw_send_only);
void subghz_read_raw_free(SubGhzReadRAW* subghz_static);

View File

@@ -827,7 +827,7 @@ static void input_callback(InputEvent* input_event, void* ctx) {
void unirfremix_subghz_alloc(UniRFRemix* app) {
// load subghz presets
app->setting = subghz_setting_alloc();
subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user"));
subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user"), false);
// load mfcodes
app->environment = subghz_environment_alloc();

View File

@@ -31,6 +31,8 @@ typedef enum {
typedef enum {
EM4100,
HIDProx,
PAC,
H10301,
} FlipFridProtos;
typedef enum {
@@ -79,6 +81,8 @@ typedef struct {
ProtocolDict* dict;
ProtocolId protocol;
uint8_t time_between_cards;
// Used for custom dictionnary
Stream* uids_stream;
} FlipFridState;

View File

@@ -1,7 +1,7 @@
#include "flipfrid_scene_entrypoint.h"
string_t menu_items[4];
string_t menu_proto_items[2];
string_t menu_proto_items[4];
void flipfrid_scene_entrypoint_menu_callback(
FlipFridState* context,
@@ -41,6 +41,14 @@ void flipfrid_scene_entrypoint_menu_callback(
context->proto = HIDProx;
string_set_str(context->proto_name, "HIDProx");
break;
case PAC:
context->proto = PAC;
string_set_str(context->proto_name, "PAC/Stanley");
break;
case H10301:
context->proto = H10301;
string_set_str(context->proto_name, "H10301");
break;
default:
break;
}
@@ -66,12 +74,14 @@ void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) {
string_set(menu_items[3], "Load uids from file");
context->menu_proto_index = 0;
for(uint32_t i = 0; i < 2; i++) {
for(uint32_t i = 0; i < 4; i++) {
string_init(menu_proto_items[i]);
}
string_set(menu_proto_items[0], "EM4100");
string_set(menu_proto_items[1], "HIDProx");
string_set(menu_proto_items[2], "PAC/Stanley");
string_set(menu_proto_items[3], "H10301");
}
void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) {
@@ -80,7 +90,7 @@ void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) {
string_clear(menu_items[i]);
}
for(uint32_t i = 0; i < 2; i++) {
for(uint32_t i = 0; i < 4; i++) {
string_clear(menu_proto_items[i]);
}
}
@@ -106,11 +116,15 @@ void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* cont
case InputKeyLeft:
if(context->menu_proto_index > EM4100) {
context->menu_proto_index--;
} else if(context->menu_proto_index == EM4100) {
context->menu_proto_index = H10301;
}
break;
case InputKeyRight:
if(context->menu_proto_index < HIDProx) {
if(context->menu_proto_index < H10301) {
context->menu_proto_index++;
} else if(context->menu_proto_index == H10301) {
context->menu_proto_index = EM4100;
}
break;
case InputKeyOk:
@@ -167,7 +181,7 @@ void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) {
}
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 34, 4, AlignCenter, AlignTop, "<");
canvas_draw_str_aligned(canvas, 27, 4, AlignCenter, AlignTop, "<");
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
@@ -179,9 +193,9 @@ void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) {
string_get_cstr(menu_proto_items[context->menu_proto_index]));
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 94, 4, AlignCenter, AlignTop, ">");
canvas_draw_str_aligned(canvas, 101, 4, AlignCenter, AlignTop, ">");
if(context->menu_proto_index < HIDProx) {
if(context->menu_proto_index < H10301) {
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas,

View File

@@ -44,6 +44,20 @@ bool flipfrid_load(FlipFridState* context, const char* file_path) {
string_set_str(context->notification_msg, "Unsupported Key type");
break;
}
} else if(context->proto == PAC) {
if(strcmp(string_get_cstr(temp_str), "PAC/Stanley") != 0) {
FURI_LOG_E(TAG, "Unsupported Key type");
string_reset(context->notification_msg);
string_set_str(context->notification_msg, "Unsupported Key type");
break;
}
} else if(context->proto == H10301) {
if(strcmp(string_get_cstr(temp_str), "H10301") != 0) {
FURI_LOG_E(TAG, "Unsupported Key type");
string_reset(context->notification_msg);
string_set_str(context->notification_msg, "Unsupported Key type");
break;
}
} else {
if(strcmp(string_get_cstr(temp_str), "HIDProx") != 0) {
FURI_LOG_E(TAG, "Unsupported Key type");
@@ -70,6 +84,20 @@ bool flipfrid_load(FlipFridState* context, const char* file_path) {
string_set_str(context->notification_msg, "Incorrect Key length");
break;
}
} else if(context->proto == PAC) {
if(string_size(context->data_str) != 11) {
FURI_LOG_E(TAG, "Incorrect Key length");
string_reset(context->notification_msg);
string_set_str(context->notification_msg, "Incorrect Key length");
break;
}
} else if(context->proto == H10301) {
if(string_size(context->data_str) != 8) {
FURI_LOG_E(TAG, "Incorrect Key length");
string_reset(context->notification_msg);
string_set_str(context->notification_msg, "Incorrect Key length");
break;
}
} else {
if(string_size(context->data_str) != 17) {
FURI_LOG_E(TAG, "Incorrect Key length");

View File

@@ -2,7 +2,7 @@
#include <gui/elements.h>
uint8_t counter = 0;
#define TIME_BETWEEN_CARDS 6
uint8_t id_list[17][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF
@@ -40,12 +40,54 @@ uint8_t id_list_hid[14][6] = {
{0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA}, // From arha
};
uint8_t id_list_pac[17][4] = {
{0x00, 0x00, 0x00, 0x00}, // Null bytes
{0xFF, 0xFF, 0xFF, 0xFF}, // Only FF
{0x11, 0x11, 0x11, 0x11}, // Only 11
{0x22, 0x22, 0x22, 0x22}, // Only 22
{0x33, 0x33, 0x33, 0x33}, // Only 33
{0x44, 0x44, 0x44, 0x44}, // Only 44
{0x55, 0x55, 0x55, 0x55}, // Only 55
{0x66, 0x66, 0x66, 0x66}, // Only 66
{0x77, 0x77, 0x77, 0x77}, // Only 77
{0x88, 0x88, 0x88, 0x88}, // Only 88
{0x99, 0x99, 0x99, 0x99}, // Only 99
{0x12, 0x34, 0x56, 0x78}, // Incremental UID
{0x9A, 0x78, 0x56, 0x34}, // Decremental UID
{0x04, 0xd0, 0x9b, 0x0d}, // From arha
{0x34, 0x00, 0x29, 0x3d}, // From arha
{0x04, 0xdf, 0x00, 0x00}, // From arha
{0xCA, 0xCA, 0xCA, 0xCA}, // From arha
};
uint8_t id_list_h[14][3] = {
{0x00, 0x00, 0x00}, // Null bytes
{0xFF, 0xFF, 0xFF}, // Only FF
{0x11, 0x11, 0x11}, // Only 11
{0x22, 0x22, 0x22}, // Only 22
{0x33, 0x33, 0x33}, // Only 33
{0x44, 0x44, 0x44}, // Only 44
{0x55, 0x55, 0x55}, // Only 55
{0x66, 0x66, 0x66}, // Only 66
{0x77, 0x77, 0x77}, // Only 77
{0x88, 0x88, 0x88}, // Only 88
{0x99, 0x99, 0x99}, // Only 99
{0x12, 0x34, 0x56}, // Incremental UID
{0x56, 0x34, 0x12}, // Decremental UID
{0xCA, 0xCA, 0xCA}, // From arha
};
void flipfrid_scene_run_attack_on_enter(FlipFridState* context) {
context->time_between_cards = 10;
context->attack_step = 0;
context->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
context->worker = lfrfid_worker_alloc(context->dict);
if(context->proto == HIDProx) {
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "HIDProx");
} else if(context->proto == PAC) {
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "PAC/Stanley");
} else if(context->proto == H10301) {
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "H10301");
} else {
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "EM4100");
}
@@ -79,7 +121,38 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->payload[3] = id_list[context->attack_step][3];
context->payload[4] = id_list[context->attack_step][4];
if(context->attack_step == 15) {
if(context->attack_step == 16) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else {
context->attack_step++;
}
break;
} else if(context->proto == PAC) {
context->payload[0] = id_list_pac[context->attack_step][0];
context->payload[1] = id_list_pac[context->attack_step][1];
context->payload[2] = id_list_pac[context->attack_step][2];
context->payload[3] = id_list_pac[context->attack_step][3];
if(context->attack_step == 16) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else {
context->attack_step++;
}
break;
} else if(context->proto == H10301) {
context->payload[0] = id_list_h[context->attack_step][0];
context->payload[1] = id_list_h[context->attack_step][1];
context->payload[2] = id_list_h[context->attack_step][2];
if(context->attack_step == 13) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
@@ -97,7 +170,7 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->payload[4] = id_list_hid[context->attack_step][4];
context->payload[5] = id_list_hid[context->attack_step][5];
if(context->attack_step == 15) {
if(context->attack_step == 13) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
@@ -118,6 +191,37 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->payload[3] = 0x00;
context->payload[4] = 0x00;
if(context->attack_step == 255) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else {
context->attack_step++;
}
break;
} else if(context->proto == PAC) {
context->payload[0] = context->attack_step;
context->payload[1] = 0x00;
context->payload[2] = 0x00;
context->payload[3] = 0x00;
if(context->attack_step == 255) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else {
context->attack_step++;
}
break;
} else if(context->proto == H10301) {
context->payload[0] = context->attack_step;
context->payload[1] = 0x00;
context->payload[2] = 0x00;
if(context->attack_step == 255) {
context->attack_step = 0;
counter = 0;
@@ -158,6 +262,43 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->payload[context->key_index] = context->attack_step;
if(context->attack_step == 255) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
break;
} else {
context->attack_step++;
}
break;
} else if(context->proto == PAC) {
context->payload[0] = context->data[0];
context->payload[1] = context->data[1];
context->payload[2] = context->data[2];
context->payload[3] = context->data[3];
context->payload[context->key_index] = context->attack_step;
if(context->attack_step == 255) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
break;
} else {
context->attack_step++;
}
break;
} else if(context->proto == H10301) {
context->payload[0] = context->data[0];
context->payload[1] = context->data[1];
context->payload[2] = context->data[2];
context->payload[context->key_index] = context->attack_step;
if(context->attack_step == 255) {
context->attack_step = 0;
counter = 0;
@@ -194,6 +335,7 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
case FlipFridAttackLoadFileCustomUids:
if(context->proto == EM4100) {
bool end_of_list = false;
while(true) {
string_reset(context->data_str);
if(!stream_read_line(context->uids_stream, context->data_str)) {
@@ -202,13 +344,24 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
stream_rewind(context->uids_stream);
end_of_list = true;
break;
};
if(string_get_char(context->data_str, 0) == '#') continue;
if(string_size(context->data_str) != 11) continue;
if(string_size(context->data_str) != 11) break;
break;
}
if(end_of_list) break;
FURI_LOG_D(TAG, string_get_cstr(context->data_str));
if(string_size(context->data_str) != 11) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_error);
break;
};
// string is valid, parse it in context->payload
for(uint8_t i = 0; i < 5; i++) {
@@ -219,7 +372,8 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
}
break;
} else {
} else if(context->proto == PAC) {
bool end_of_list = false;
while(true) {
string_reset(context->data_str);
if(!stream_read_line(context->uids_stream, context->data_str)) {
@@ -228,13 +382,100 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
stream_rewind(context->uids_stream);
end_of_list = true;
break;
};
if(string_get_char(context->data_str, 0) == '#') continue;
if(string_size(context->data_str) != 13) continue;
if(string_size(context->data_str) != 9) break;
break;
}
if(end_of_list) break;
FURI_LOG_D(TAG, string_get_cstr(context->data_str));
if(string_size(context->data_str) != 9) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_error);
break;
};
// string is valid, parse it in context->payload
for(uint8_t i = 0; i < 4; i++) {
char temp_str[3];
temp_str[0] = string_get_cstr(context->data_str)[i * 2];
temp_str[1] = string_get_cstr(context->data_str)[i * 2 + 1];
temp_str[2] = '\0';
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
}
break;
} else if(context->proto == H10301) {
bool end_of_list = false;
while(true) {
string_reset(context->data_str);
if(!stream_read_line(context->uids_stream, context->data_str)) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
stream_rewind(context->uids_stream);
end_of_list = true;
break;
};
if(string_get_char(context->data_str, 0) == '#') continue;
if(string_size(context->data_str) != 7) break;
break;
}
if(end_of_list) break;
FURI_LOG_D(TAG, string_get_cstr(context->data_str));
if(string_size(context->data_str) != 7) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_error);
break;
};
// string is valid, parse it in context->payload
for(uint8_t i = 0; i < 3; i++) {
char temp_str[3];
temp_str[0] = string_get_cstr(context->data_str)[i * 2];
temp_str[1] = string_get_cstr(context->data_str)[i * 2 + 1];
temp_str[2] = '\0';
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
}
break;
} else {
bool end_of_list = false;
while(true) {
string_reset(context->data_str);
if(!stream_read_line(context->uids_stream, context->data_str)) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
stream_rewind(context->uids_stream);
end_of_list = true;
break;
};
if(string_get_char(context->data_str, 0) == '#') continue;
if(string_size(context->data_str) != 13) break;
break;
}
FURI_LOG_D(TAG, string_get_cstr(context->data_str));
if(end_of_list) break;
if(string_size(context->data_str) != 13) {
context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_error);
break;
};
// string is valid, parse it in context->payload
for(uint8_t i = 0; i < 6; i++) {
@@ -249,7 +490,7 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
}
}
if(counter > TIME_BETWEEN_CARDS) {
if(counter > context->time_between_cards) {
counter = 0;
} else {
counter++;
@@ -262,9 +503,22 @@ void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* cont
if(event.input_type == InputTypeShort) {
switch(event.key) {
case InputKeyDown:
break;
case InputKeyUp:
break;
case InputKeyLeft:
if(!context->is_attacking) {
if(context->time_between_cards > 0) {
context->time_between_cards--;
}
}
break;
case InputKeyRight:
if(!context->is_attacking) {
if(context->time_between_cards < 60) {
context->time_between_cards++;
}
}
break;
case InputKeyOk:
counter = 0;
@@ -303,9 +557,10 @@ void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context) {
// Title
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 64, 8, AlignCenter, AlignTop, string_get_cstr(context->attack_name));
canvas, 64, 2, AlignCenter, AlignTop, string_get_cstr(context->attack_name));
char uid[18];
char speed[16];
if(context->proto == HIDProx) {
snprintf(
uid,
@@ -317,6 +572,23 @@ void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context) {
context->payload[3],
context->payload[4],
context->payload[5]);
} else if(context->proto == PAC) {
snprintf(
uid,
sizeof(uid),
"%02X:%02X:%02X:%02X",
context->payload[0],
context->payload[1],
context->payload[2],
context->payload[3]);
} else if(context->proto == H10301) {
snprintf(
uid,
sizeof(uid),
"%02X:%02X:%02X",
context->payload[0],
context->payload[1],
context->payload[2]);
} else {
snprintf(
uid,
@@ -329,15 +601,25 @@ void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context) {
context->payload[4]);
}
canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignTop, uid);
canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignTop, uid);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 64, 26, AlignCenter, AlignTop, string_get_cstr(context->proto_name));
snprintf(speed, sizeof(speed), "Time delay: %d", context->time_between_cards);
//canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Speed:");
canvas_draw_str_aligned(canvas, 64, 14, AlignCenter, AlignTop, speed);
//char start_stop_msg[20];
if(context->is_attacking) {
elements_button_center(canvas, "Stop");
//snprintf(start_stop_msg, sizeof(start_stop_msg), " Press OK to stop ");
} else {
elements_button_center(canvas, "Start");
elements_button_left(canvas, "TD -");
elements_button_right(canvas, "+ TD");
}
//canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignTop, start_stop_msg);
}

View File

@@ -1,8 +1,31 @@
#include "flipfrid_scene_select_field.h"
void flipfrid_center_displayed_key(FlipFridState* context, uint8_t index) {
const char* key_cstr = string_get_cstr(context->data_str);
char key_cstr[18];
uint8_t key_len = 18;
uint8_t str_index = (index * 3);
int data_len = sizeof(context->data) / sizeof(context->data[0]);
int key_index = 0;
if(context->proto == EM4100) {
key_len = 16;
}
if(context->proto == PAC) {
key_len = 13;
}
if(context->proto == H10301) {
key_len = 10;
}
for(uint8_t i = 0; i < data_len; i++) {
if(context->data[i] < 9) {
key_index +=
snprintf(&key_cstr[key_index], key_len - key_index, "0%X ", context->data[i]);
} else {
key_index +=
snprintf(&key_cstr[key_index], key_len - key_index, "%X ", context->data[i]);
}
}
char display_menu[17] = {
'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'};
@@ -62,6 +85,7 @@ void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* co
if(event.evt_type == EventTypeKey) {
if(event.input_type == InputTypeShort) {
const char* key_cstr = string_get_cstr(context->data_str);
int data_len = sizeof(context->data) / sizeof(context->data[0]);
// don't look, it's ugly but I'm a python dev so...
uint8_t nb_bytes = 0;
@@ -73,7 +97,18 @@ void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* co
switch(event.key) {
case InputKeyDown:
for(uint8_t i = 0; i < data_len; i++) {
if(context->key_index == i) {
context->data[i] = (context->data[i] - 1);
}
}
break;
case InputKeyUp:
for(uint8_t i = 0; i < data_len; i++) {
if(context->key_index == i) {
context->data[i] = (context->data[i] + 1);
}
}
break;
case InputKeyLeft:
if(context->key_index > 0) {
@@ -90,6 +125,7 @@ void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* co
context->current_scene = SceneAttack;
break;
case InputKeyBack:
context->key_index = 0;
string_reset(context->notification_msg);
context->current_scene = SceneSelectFile;
break;
@@ -106,16 +142,17 @@ void flipfrid_scene_select_field_on_draw(Canvas* canvas, FlipFridState* context)
// Frame
//canvas_draw_frame(canvas, 0, 0, 128, 64);
// Title
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignTop, "Use < > to select byte.");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 12, 5, AlignLeft, AlignTop, "Left and right: select byte");
canvas_draw_str_aligned(canvas, 12, 15, AlignLeft, AlignTop, "Up and down: adjust byte");
char msg_index[18];
canvas_set_font(canvas, FontPrimary);
snprintf(msg_index, sizeof(msg_index), "Field index : %d", context->key_index);
canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignTop, msg_index);
canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignTop, msg_index);
flipfrid_center_displayed_key(context, context->key_index);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 64, 40, AlignCenter, AlignTop, string_get_cstr(context->notification_msg));
canvas, 64, 45, AlignCenter, AlignTop, string_get_cstr(context->notification_msg));
}

View File

@@ -1,12 +1,17 @@
#include "../signal_gen_app_i.h"
typedef enum {
LineIndexPin,
LineIndexSource,
LineIndexDivision,
} LineIndex;
static const char* const mco_pin_names[] = {
"13(Tx)",
};
static const char* const mco_source_names[] = {
"32768",
"32768Hz",
"64MHz",
"~100K",
"~200K",
@@ -81,14 +86,22 @@ void signal_gen_scene_mco_on_enter(void* context) {
VariableItem* item;
item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL);
variable_item_set_current_value_index(item, 0);
variable_item_set_current_value_text(item, mco_pin_names[0]);
item = variable_item_list_add(
var_item_list, "Source", COUNT_OF(mco_source_names), mco_source_list_change_callback, app);
var_item_list,
"Frequency",
COUNT_OF(mco_source_names),
mco_source_list_change_callback,
app);
variable_item_set_current_value_index(item, 0);
variable_item_set_current_value_text(item, mco_source_names[0]);
item = variable_item_list_add(
var_item_list,
"Division",
"Freq. divider",
COUNT_OF(mco_divisor_names),
mco_divisor_list_change_callback,
app);

View File

@@ -16,10 +16,10 @@ void signal_gen_scene_start_on_enter(void* context) {
Submenu* submenu = app->submenu;
submenu_add_item(
submenu, "PWM", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app);
submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app);
submenu_add_item(
submenu,
"Clock Output",
"Clock Generator",
SubmenuIndexClockOutput,
signal_gen_scene_start_submenu_callback,
app);

View File

@@ -9,7 +9,7 @@ typedef enum {
LineIndexTotalCount
} LineIndex;
static const char* const pwm_ch_names[] = {"TIM1(2)", "LPTIM2(4)"};
static const char* const pwm_ch_names[] = {"2(A7)", "4(A4)"};
struct SignalGenPwm {
View* view;
@@ -31,8 +31,8 @@ typedef struct {
#define ITEM_H 64 / 3
#define ITEM_W 128
#define VALUE_X 95
#define VALUE_W 55
#define VALUE_X 100
#define VALUE_W 45
#define FREQ_VALUE_X 62
#define FREQ_MAX 1000000UL
@@ -126,11 +126,11 @@ static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) {
for(uint8_t line = 0; line < LineIndexTotalCount; line++) {
if(line == LineIndexChannel) {
line_label = "PWM Channel";
line_label = "GPIO Pin";
} else if(line == LineIndexFrequency) {
line_label = "Frequency";
} else if(line == LineIndexDuty) {
line_label = "Duty Cycle";
line_label = "Pulse width";
}
canvas_set_color(canvas, ColorBlack);
@@ -162,9 +162,9 @@ static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) {
canvas_set_font(canvas, FontSecondary);
if(model->edit_mode) {
uint8_t icon_x = (FREQ_VALUE_X - 1) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6;
uint8_t icon_x = (FREQ_VALUE_X) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6;
canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_4x7);
canvas_draw_icon(canvas, icon_x, text_y + 4, &I_SmallArrowDown_4x7);
canvas_draw_icon(canvas, icon_x, text_y + 5, &I_SmallArrowDown_4x7);
}
} else if(line == LineIndexDuty) {
snprintf(val_text, sizeof(val_text), "%d%%", model->duty);

View File

@@ -143,11 +143,37 @@ void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* conte
xStreamBufferSend(context, buffer, size, 0);
}
void cli_command_log_level_set_from_string(string_t level) {
if(string_cmpi_str(level, "default") == 0) {
furi_log_set_level(FuriLogLevelDefault);
} else if(string_cmpi_str(level, "none") == 0) {
furi_log_set_level(FuriLogLevelNone);
} else if(string_cmpi_str(level, "error") == 0) {
furi_log_set_level(FuriLogLevelError);
} else if(string_cmpi_str(level, "warn") == 0) {
furi_log_set_level(FuriLogLevelWarn);
} else if(string_cmpi_str(level, "info") == 0) {
furi_log_set_level(FuriLogLevelInfo);
} else if(string_cmpi_str(level, "debug") == 0) {
furi_log_set_level(FuriLogLevelDebug);
} else if(string_cmpi_str(level, "trace") == 0) {
furi_log_set_level(FuriLogLevelTrace);
} else {
printf("Unknown log level\r\n");
}
}
void cli_command_log(Cli* cli, string_t args, void* context) {
UNUSED(args);
UNUSED(context);
StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1);
uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE];
FuriLogLevel previous_level = furi_log_get_level();
bool restore_log_level = false;
if(string_size(args) > 0) {
cli_command_log_level_set_from_string(args);
restore_log_level = true;
}
furi_hal_console_set_tx_callback(cli_command_log_tx_callback, ring);
@@ -159,6 +185,11 @@ void cli_command_log(Cli* cli, string_t args, void* context) {
furi_hal_console_set_tx_callback(NULL, NULL);
if(restore_log_level) {
// There will be strange behaviour if log level is set from settings while log command is running
furi_log_set_level(previous_level);
}
vStreamBufferDelete(ring);
}

View File

@@ -14,6 +14,7 @@
#define ASSETS_DIR "assets"
#define BADUSB_LAYOUTS_DIR "layouts"
#define SUBGHZ_TEMP_DIR "tmp_history"
#define BROWSER_ROOT STORAGE_ANY_PATH_PREFIX
#define FILE_NAME_LEN_MAX 256
#define LONG_LOAD_THRESHOLD 100
@@ -80,7 +81,8 @@ static bool browser_filter_by_name(BrowserWorker* browser, string_t name, bool i
// Skip assets folders (if enabled)
if(browser->skip_assets) {
return ((string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)) &&
((string_cmp_str(name, BADUSB_LAYOUTS_DIR) == 0) ? (false) : (true));
((string_cmp_str(name, BADUSB_LAYOUTS_DIR) == 0) ? (false) : (true)) &&
((string_cmp_str(name, SUBGHZ_TEMP_DIR) == 0) ? (false) : (true));
} else {
return true;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,19 +1,67 @@
Filetype: IR library file
Version: 1
# Last Updated 25th Sept, 2022
# Last Updated 4th Oct, 2022
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3469 1719 450 447 423 1293 447 451 419 452 418 454 416 455 425 446 424 447 423 449 421 450 420 451 419 452 418 454 416 1300 450 447 423 449 421 450 420 451 419 453 417 454 416 455 425 1291 449 449 421 1295 445 452 418 454 416 1300 450 1292 448 1295 445 453 417 454 426 445 425 1291 449 449 421 1295 445 1297 453 1289 451 1292 448 450 420 452 418 1298 452 445 425 446 424 448 422 449 420 450 420 452 418 1298 452 74868 3471 1717 453 445 425 1291 449 449 421 451 419 452 418 453 417 455 425 446 424 447 423 448 422 449 421 451 419 452 418 1298 452 445 425 447 423 448 422 449 421 451 419 452 418 454 416 1300 450 447 423 1293 447 451 419 453 417 1299 451 1291 449 1293 447 451 419 453 417 454 426 1290 450 447 423 1293 447 1296 444 1299 451 1291 449 449 421 450 420 1296 444 454 426 445 425 446 424 448 422 449 421 450 420 1296 444 74877 3472 1716 443 455 425 1291 449 448 422 450 420 451 419 453 417 454 426 445 425 446 424 447 423 449 421 450 420 451 419 1298 452 445 425 446 424 448 422 449 421 450 420 452 418 453 417 1299 451 447 423 1293 447 451 419 452 418 1298 452 1290 450 1293 447 451 419 452 418 454 416 1300 450 447 423 1293 447 1296 444 1299 451 1291 449 449 421 450 420 1296 444 454 426 445 425 446 424 447 423 449 421 450 420 1296 444
#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3472 1743 416 455 425 1317 422 449 420 451 418 453 416 454 426 445 424 447 422 448 421 450 419 452 417 453 416 455 425 1317 422 449 420 450 419 452 417 454 415 455 425 446 423 448 421 1320 419 452 417 1325 425 447 422 448 421 450 419 452 417 453 416 455 425 446 423 448 421 449 420 451 418 452 417 454 415 456 424 1317 422 449 420 451 418 453 416 455 425 446 423 447 422 449 420 450 419 452 417 1324 426 74911 3469 1746 423 448 421 1321 418 453 416 455 425 446 423 447 422 449 420 450 419 452 417 454 415 455 425 446 423 448 421 1320 419 452 417 454 426 445 424 447 422 448 421 450 419 452 417 1324 426 446 423 1291 448 450 419 452 417 454 415 455 425 446 423 448 421 450 419 451 418 453 416 454 426 446 423 447 422 449 420 1294 445 453 416 455 425 446 423 448 421 449 420 451 418 453 416 454 426 445 424 1290 449
#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3473 1742 417 454 426 1317 422 448 421 450 419 452 417 453 416 455 425 446 423 447 422 449 420 451 418 452 417 454 415 1326 424 448 421 449 420 451 418 453 416 454 426 445 425 447 422 1320 419 452 417 1324 426 446 423 447 422 449 420 450 419 452 417 454 415 455 425 446 423 1319 420 451 418 453 416 454 426 445 424 1318 421 450 419 452 417 1324 426 446 423 447 422 449 420 451 418 452 417 454 415 1326 424 74913 3467 1748 421 450 419 1323 416 455 425 446 423 447 422 449 420 451 418 452 417 454 415 455 425 446 423 448 421 449 420 1322 417 454 426 445 424 447 422 448 421 450 419 452 417 453 416 1326 424 447 422 1320 419 452 417 454 415 455 425 446 423 448 421 450 419 451 418 453 416 1325 425 447 422 448 421 450 419 452 417 1324 426 446 423 447 422 1320 419 452 417 454 415 455 425 446 423 448 421 450 419 1322 417
#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3473 1716 453 445 425 1291 448 422 447 424 446 453 416 427 453 446 423 420 449 449 420 423 446 425 444 454 426 418 451 1291 448 423 446 452 417 454 415 428 452 446 423 421 448 422 447 1296 443 455 425 1290 449 449 420 423 446 425 444 427 453 445 424 420 449 449 420 423 446 425 444 1298 452 419 450 448 421 1294 445 1298 452 446 423 448 421 449 420 1296 443 427 453 445 424 1292 447 423 446 452 417 1299 451 74922 3472 1717 452 446 423 1292 447 451 418 452 417 454 426 445 424 447 423 449 420 450 419 452 417 454 415 455 425 446 424 1293 446 451 418 453 416 455 425 446 423 447 422 449 420 451 418 1297 453 445 424 1292 447 450 419 452 417 454 415 455 425 446 423 448 421 450 419 451 418 453 416 1300 450 448 421 449 420 1296 443 1299 451 447 422 449 420 450 419 1297 442 455 425 447 422 1293 446 451 418 453 416 1300 450
#
name: POWER
type: parsed
protocol: NEC
address: 01 00 00 00
command: 02 00 00 00
#
name: VOL+
type: parsed
protocol: NEC
address: 01 00 00 00
command: 01 00 00 00
#
name: VOL-
type: parsed
protocol: NEC
address: 01 00 00 00
command: 0B 00 00 00
#
name: MUTE
type: parsed
protocol: NEC
address: 01 00 00 00
command: 06 00 00 00
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 9150 4435 643 1608 643 468 644 469 642 364 749 468 643 447 665 449 663 469 643 452 660 470 642 450 662 442 670 449 662 469 643 1579 672 1608 642 1580 671 1609 641 1607 643 1578 672 1607 643 1608 642 1606 644 1606 644 1606 644 1607 643 1576 675 1579 671 1605 674 438 645 466 673 438 646 466 674 437 673 439 672 439 673 438 646 1604 673 1577 673 1578 673 1577 674 1577 673 23799 9095 4485 616
#
#
name: VOL+
type: parsed
protocol: NEC42
address: 01 00 00 00
command: 0C 00 00 00
#
#
name: VOL-
type: raw
frequency: 38000
@@ -1471,19 +1519,19 @@ type: parsed
protocol: NECext
address: 12 36 00 00
command: 0A F5 00 00
#
#
name: VOL-
type: parsed
protocol: NECext
address: 12 36 00 00
command: 0B F4 00 00
#
#
name: MUTE
type: parsed
protocol: NECext
address: 12 36 00 00
command: 09 F6 00 00
#
#
name: POWER
type: parsed
protocol: NECext

View File

@@ -1,7 +1,36 @@
Filetype: IR library file
Version: 1
# Last Updated 22th Sept, 2022
# Last Updated 3rd Oct, 2022
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 2356 608 934 1216 825 1320 826 1348 793 646 824 673 792 667 792 663 792 720 793 692 793 687 818 657 817 652 817 649 816 1310 815 1306 815 102511 2320 668 819 1332 817 1328 817 1325 815 655 815 650 815 645 815 640 815 699 814 671 814 666 814 661 814 657 813 652 813 1337 788 1333 787
#
name: ROTATE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 390 9025 2296 666 821 1329 821 1324 821 1319 821 647 822 642 822 666 793 661 793 1385 793 691 819 660 819 655 818 652 816 1314 815 644 815 1305 815 101869 2318 668 818 1331 817 1328 816 1323 816 654 815 649 815 645 814 640 814 1363 815 670 815 665 814 660 815 655 814 1316 814 645 814 1306 814
#
name: SPEED+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 2346 612 875 1275 931 1214 929 1211 875 594 875 588 876 582 822 633 821 691 848 1303 847 659 819 1321 817 652 816 1314 815 1310 814 640 814 101247 2320 667 819 1330 818 1327 816 1324 815 654 815 649 815 644 815 639 815 698 814 1335 815 665 814 1325 814 655 814 1315 815 1310 815 640 814
#
name: SPEED-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 2313 646 841 1308 841 1303 841 1298 841 626 843 621 842 614 819 634 820 1359 844 1333 817 1328 815 1324 814 1321 812 1317 812 647 812 1308 811 99132 2317 670 816 1333 815 1330 813 1326 813 657 812 652 812 647 812 642 812 1366 812 1338 811 1332 812 1328 812 1323 811 1317 813 647 812 1307 812
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3533 1663 476 420 450 1234 508 421 449 394 477 420 450 420 474 387 459 421 475 396 558 385 432 386 484 386 485 386 434 1263 479 419 447 395 475 394 476 393 478 393 478 392 478 1264 477 393 478 1264 478 1266 500 387 483 395 475 1268 473 397 474 397 474 397 474 397 474 1268 473 397 474 397 474 397 474 397 474 1268 472 1270 472 398 473 398 473 1269 473 398 473 398 473 397 474 1268 473 1269 473 398 473 398 473 1269 472 398 473 1269 472 398 473 1269 472 398 473 1269 472 398 473 74625 3552 1673 473 397 472 1270 472 399 471 399 471 400 470 400 470 401 470 401 470 401 469 401 470 402 469 402 469 402 469 1272 471 400 470 400 470 401 469 402 468 427 444 427 444 1273 471 400 470 1272 470 1271 471 400 470 401 469 1273 470 401 469 427 443 428 442 428 417 1300 469 426 443 428 417 453 442 428 417 1325 443 1274 468 427 443 428 417 1325 443 427 417 454 416 454 416 1326 417 1325 442 427 417 453 417 1325 417 453 417 1325 418 453 416 1326 416 453 417 1326 416 454 416
# TIMER UP
name: TIMER
type: parsed
@@ -788,11 +817,6 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1313 405 1314 405 449 1250 1313 420 1320 406 448 1252 447 1253 446 1254 445 1255 443 1255 1319 404 450 8002 1316 406 1313 409 445 1253 1311 422 1318 407 499 1202 445 1253 446 1253 445 1254 445 1254 1320 404 450 7999 1309 408 1311 406 448 1248 1305 421 1308 411 443 1253 446 1251 447 1249 449 1248 440 1257 1306 409 445 8000 1308 408 1311 405 449 1247 1306 418 1311 405 449 1248 440 1256 443 1253 446 1251 448 1250 1313 404 450 7996 1312 436 1283 407 447 1250 1313 414 1315 405 449 1250 448 1249 449 1248 450 1246 442 1255 1319 402 452 7991 1307 439 1280 412 442 1255 1308 420 1309 411 443 1255 444 1254 445 1253 446 1253 446 1253 1321 406 448 7998 1320 406 1323 403 451 1249 1314 421 1319 408 446 1254 444 1255 443 1255 443 1256 442 1256 1318 408 446 8004 1314 412 1317 409 445 1255 1318 417 1323 404 450 1250 448 1251 447 1252 447 1253 445 1255 1319 407 447 8003 1315 410 1319 407 447 1252 1322 414 1315 410 444 1256 453 1247 451 1248 450 1247 441 1256 1307 438 416 8002 1316 431 1288 429 415 1252 1311 444 1285 431 423 1241 447 1249 449 1247 451 1248 450 1246 1317 402 442 8002 1316 403 1306 411 443 1251 1312 416 1313 404 450 1244 444 1252 447 1251 447 1249 449 1247 1316 402 442 8002 1316 403 1306 410 444 1250 1313 414 1305 410 444 1249 450 1246 452 1244 444 1253 446 1252 1311 407 447
name: SPEED+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1313 405 1314 405 449 1250 1313 420 1320 406 448 1252 447 1253 446 1254 445 1255 443 1255 1319 404 450 8002 1316 406 1313 409 445 1253 1311 422 1318 407 499 1202 445 1253 446 1253 445 1254 445 1254 1320 404 450 7999 1309 408 1311 406 448 1248 1305 421 1308 411 443 1253 446 1251 447 1249 449 1248 440 1257 1306 409 445 8000 1308 408 1311 405 449 1247 1306 418 1311 405 449 1248 440 1256 443 1253 446 1251 448 1250 1313 404 450 7996 1312 436 1283 407 447 1250 1313 414 1315 405 449 1250 448 1249 449 1248 450 1246 442 1255 1319 402 452 7991 1307 439 1280 412 442 1255 1308 420 1309 411 443 1255 444 1254 445 1253 446 1253 446 1253 1321 406 448 7998 1320 406 1323 403 451 1249 1314 421 1319 408 446 1254 444 1255 443 1255 443 1256 442 1256 1318 408 446 8004 1314 412 1317 409 445 1255 1318 417 1323 404 450 1250 448 1251 447 1252 447 1253 445 1255 1319 407 447 8003 1315 410 1319 407 447 1252 1322 414 1315 410 444 1256 453 1247 451 1248 450 1247 441 1256 1307 438 416 8002 1316 431 1288 429 415 1252 1311 444 1285 431 423 1241 447 1249 449 1247 451 1248 450 1246 1317 402 442 8002 1316 403 1306 411 443 1251 1312 416 1313 404 450 1244 444 1252 447 1251 447 1249 449 1247 1316 402 442 8002 1316 403 1306 410 444 1250 1313 414 1305 410 444 1249 450 1246 452 1244 444 1253 446 1252 1311 407 447
#
name: POWER
type: raw
@@ -973,10 +997,16 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1395 359 1367 358 499 1213 1368 359 1366 359 473 1239 474 1239 474 1238 475 1238 1368 360 497 1215 497 8209 1362 364 1361 366 492 1221 1360 366 1359 366 491 1222 492 1222 491 1221 493 1245 1336 366 492 1222 492 8213 1360 366 1359 389 468 1222 1359 367 1358 390 467 1246 468 1246 468 1245 468 1246 1335 390 467 1246 467 8238 1335 390 1335 390 468 1246 1335 390 1335 390 467 1246 467 1246 468 1246 467 1246 1335 390 467 1246 467 8238 1334 390 1335 390 467 1247 1334 390 1335 391 466 1247 466 1247 466 1247 466 1247 1334 390 467 1247 466 8239 1334 391 1334 391 466 1247 1334 391 1334 391 467 1247 466 1247 466 1247 466 1248 1333 391 466 1248 465 8239 1333 392 1333 392 466 1248 1333 392 1333 392 465 1248 465 1248 465 1248 465 1248 1333 392 465 1248 465 8240 1332 392 1333 392 465 1248 1333 393 1332 393 464 1249 464 1249 464 1249 464 1249 1331 393 465 1249 464 8241 1331 393 1332 393 464 1250 1331 394 1331 394 463 1250 463 1251 462 1250 463 1251 1329 396 462 1251 462 8243 1305 420 1305 444 436 1277 1280 444 1281 445 435 1277 412 1301 436 1277 435 1277 1280 445 436 1277 436 8268 1280 445 1279 445 412 1301 1280 445 1280 445 411 1302 411 1302 411 1302 411 1302 1279 446 411 1302 411 8293 1278 446 1279 446 411 1303 1278 447 1277 447 410 1303 410 1304 409 1329 384 1329 1252 472 385 1329 384 8320 1252 473 1251 473 383 1330 1251 473 1252 473 384 1330 383 1330 383 1330 383 1330 1251 474 382 1330 383 8321 1250 474 1251 475 381 1331 1250 500 1224 500 356 1358 355 1358 355 1358 355 1358 1223 501 355 1358 355 8349 1223 502 1222 528 327 1386 1196 528 1196 530 326 1386 327 1387 326 1386 327 1413 1169 556 299 1414 299 8404 1169 556 1168 584 271 1441 1141 611 1113 637 216 1498 215 1524 178 1562 122 1564 1058 11171 970
#
#
name: TIMER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 1366 359 1366 360 496 1214 1367 360 1395 331 524 1185 474 1239 474 1238 475 1238 475 1238 1343 383 498 8205 1366 386 1338 386 470 1244 1338 386 1339 386 470 1243 470 1244 469 1244 469 1243 470 1244 1338 386 470 8234 1338 386 1339 386 469 1244 1338 386 1339 386 470 1243 470 1220 493 1219 494 1243 470 1244 1338 362 494 8233 1339 362 1363 386 469 1244 1338 386 1339 386 469 1244 469 1244 469 1244 469 1244 469 1244 1338 387 468 8234 1338 386 1338 387 468 1244 1338 387 1337 387 468 1244 469 1244 468 1245 469 1244 469 1244 1338 387 468 8234 1337 387 1338 387 465 1247 1338 387 1338 387 468 1245 468 1244 444 1269 468 1246 467 1245 1337 387 468 8235 1337 387 1337 388 468 1245 1336 388 1336 388 466 1246 467 1245 468 1245 467 1247 467 1245 1312 412 467 8235 1312 412 1312 412 443 1270 1335 390 1311 412 468 1246 466 1246 467 1246 467 1246 467 1246 1311 412 467 8236 1311 413 1311 413 442 1271 1311 413 1311 413 442 1271 466 1247 466 1246 442 1271 442 1271 1311 413 442 8260 1311 413 1311 413 442 1271 1311 413 1311 414 441 1271 442 1271 465 1248 464 1249 465 1247 1310 414 441 8261 1334 390 1310 414 466 1247 1335 390 1333 391 465 1248 465 1248 465 1248 465 1248 465 1248 1334 390 465 8237 1334 391 1333 390 465 1248 1309 415 1309 416 464 1249 464 1249 463 1250 462 1275 438 1274 1307 394 438 8287 1283 441 1283 441 438 1274 1283 441 1283 442 436 1276 414 1299 438 1275 413 1300 412 1300 1282 442 413 8289 1282 443 1281 443 412 1301 1281 443 1281 443 412 1301 411 1302 411 1302 410 1327 385 1327 1255 469 386 8316 1255 470 1254 470 385 1327 1255 470 1254 470 385 1327 385 1328 384 1328 385 1328 385 1328 1254 470 385 8317 1253 471 1253 470 385 1329 1253 471 1253 471 384 1329 383 1330 382 1330 382 1330 383 1330 1252 473 382 8344 1226 498 1226 498 357 1356 1226 498 1226 498 356 1356 356 1356 356 1356 356 1356 356 1356 1226 499 355 8346 1224 499 1225 525 329 1384 1198 526 1198 525 329 1384 328 1384 328 1384 328 1384 329 1384 1198 526 328 8373 1198 526 1198 527 327 1385 1197 553 1171 553 301 1412 300 1412 300 1412 300 1386 327 1412 1170 554 299 8401 1170 554 1170 555 298 1414 1169 581 1143 582 271 1440 272 1440 272 1440 272 1441 271 1441 1142 609 244 8458 1113 636 1088 663 178 1507 1088 691 1033
# TIMER OFF
name: TIMER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3583 1639 534 386 484 1208 534 386 484 386 485 386 484 387 483 386 484 386 485 386 457 394 476 394 451 419 452 419 476 1237 506 393 477 394 475 395 474 396 473 397 473 398 472 1270 472 399 471 1271 471 1270 471 399 470 401 469 1273 469 402 468 427 443 427 443 427 443 1299 443 427 443 427 444 427 444 427 444 1298 443 1299 442 427 444 427 445 426 445 425 446 425 447 424 447 399 472 398 473 1294 445 426 446 400 471 399 472 1294 446 425 447 398 473 1295 446 400 471 398 472 74544 3552 1672 472 399 471 1271 471 399 471 400 470 400 470 400 470 400 471 400 470 400 470 401 470 401 469 401 469 401 470 1273 470 400 470 401 469 401 469 401 470 401 469 401 470 1273 470 401 469 1273 470 1272 469 401 469 401 469 1274 468 401 469 401 469 401 470 402 469 1273 469 401 469 401 469 402 469 401 469 1273 469 1273 469 401 469 402 468 402 469 426 444 427 444 427 444 426 445 426 444 1274 468 402 469 426 444 427 443 1275 467 403 467 427 443 1275 467 402 468 427 443
#

View File

@@ -1,7 +1,30 @@
Filetype: IR library file
Version: 1
# Last Updated 27th Sept, 2022
# Last Updated 30th Sept, 2022
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 9014 4332 661 1570 661 471 660 473 658 474 657 476 655 498 633 498 634 502 633 499 633 1599 632 1599 632 1599 632 1599 632 1599 632 1600 631 1603 632 500 632 501 631 501 631 501 631 501 631 501 631 1601 631 504 631 1601 631 1601 631 1601 631 1601 631 1601 630 1601 630 501 631 1601 631 38177 8983 2149 630
#
name: VOL+
type: parsed
protocol: NEC
address: 01 00 00 00
command: 11 00 00 00
#
name: VOL-
type: parsed
protocol: NEC
address: 01 00 00 00
command: 4C 00 00 00
#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 9042 4306 690 1541 665 468 664 468 664 469 663 470 662 471 660 495 636 499 636 497 634 1597 634 1598 633 1598 633 1599 633 1599 632 1599 633 1603 632 1599 633 499 633 499 633 500 632 499 633 500 632 1600 632 503 633 500 632 1600 632 1600 632 1600 633 1600 632 1600 632 500 632 1600 632 37912 8986 2145 633
# ON
name: POWER
type: raw
@@ -422,3 +445,4 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3523 1701 472 426 444 1269 472 426 444 426 442 429 443 427 443 426 444 426 444 426 443 427 442 429 440 430 439 432 438 1304 437 433 437 432 438 432 438 433 437 433 437 433 437 433 437 433 437 433 437 1304 437 433 437 433 437 433 437 1304 437 433 437 433 437 1304 437 433 437 434 436 433 437 434 436 434 436 434 436 433 437 433 437 434 436 1304 437 1305 436 1305 436 1305 436 1305 436 1305 436 434 436 434 436 1305 436 1305 436 1305 436 434 436 1305 436 1305 436 1306 435 1306 435 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 434 436 434 436 1304 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1306 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 436 434 435 435 1307 434 1331 410 1307 434 1307 434 1330 411 1307 434 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 434 436 433 437 433 437 1304 437 434 436 434 436 434 437 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 435 435 434 436 1305 436 434 436 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 1307 434 1306 435 1307 434 1307 434 1307 434 1331 410 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 1304 437 433 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 437 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1306 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 1307 434 1330 411 1330 411 1330 411 1330 411 1330 411 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410
#

View File

@@ -1,6 +1,204 @@
Filetype: IR library file
Version: 1
# Last Updated 29th Sept, 2022
# Last Updated 4th Oct, 2022
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3529 1712 447 431 449 1307 454 451 419 433 447 459 421 458 422 429 451 455 425 426 454 425 455 423 447 460 420 459 421 1308 453 452 428 424 446 433 447 459 421 430 450 457 423 428 452 426 454 453 427 1302 448 457 423 456 424 427 453 453 427 452 428 451 419 460 420 459 421 1308 453 453 427 1302 448 1307 454 1301 449 1306 455 451 419 461 419 1310 451 455 425 1304 446 1309 452 1304 446 1309 452 454 426 1303 447 74691 3528 1715 455 451 419 1310 451 427 453 426 454 425 455 451 419 433 447 431 449 430 450 429 451 428 452 426 454 453 427 1302 448 430 450 429 451 428 452 426 454 453 427 424 446 460 420 431 449 430 450 1307 454 452 428 423 447 460 420 431 449 457 423 429 451 455 425 454 426 1303 447 459 421 1308 453 1303 447 1309 452 1304 446 459 421 431 449 1307 454 425 455 1302 448 1307 454 1302 448 1308 453 425 455 1302 448 70427 175
#
name: CH+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3524 1717 453 426 454 1302 448 430 450 429 451 427 453 426 454 425 455 424 446 433 447 432 448 430 450 429 451 428 452 1304 446 433 447 432 448 430 450 429 451 428 452 427 453 426 454 424 456 423 447 1310 451 428 452 427 453 425 455 424 446 433 447 432 448 431 449 429 451 428 452 427 453 1303 447 432 448 1308 453 1303 447 431 449 430 450 429 451 427 453 1304 446 432 448 1308 453 1303 447 432 448 1308 453 74692 3530 1712 447 431 449 1307 454 425 455 424 446 433 447 432 448 431 449 430 450 429 451 427 453 426 454 425 455 424 446 1311 449 429 451 428 452 427 453 425 455 424 446 433 447 432 448 431 449 430 450 1306 455 424 456 423 447 432 448 431 449 430 450 429 451 428 452 426 454 425 455 424 446 1311 450 429 451 1306 455 1301 449 429 451 428 452 427 453 426 454 1303 447 432 448 1308 453 1303 447 432 448 1309 452
#
name: CH-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3523 1718 451 427 453 1302 448 431 449 430 450 429 451 428 452 426 454 425 455 424 456 423 447 432 448 431 449 430 450 1306 455 425 455 424 446 433 447 432 448 431 449 430 450 429 451 428 452 427 453 1303 447 432 448 431 449 430 450 429 451 428 452 427 453 425 455 424 456 1300 450 429 451 1306 455 424 446 1310 451 1305 456 423 447 433 479 1277 452 427 485 1272 447 432 479 1277 452 1303 447 431 480 1276 485 74664 3526 1715 475 403 477 1279 482 397 483 396 484 395 475 404 476 403 477 402 478 401 479 400 480 399 481 398 482 396 453 1305 477 402 478 401 448 431 449 430 450 429 451 428 452 427 453 425 455 424 456 1301 480 398 451 428 452 427 453 426 454 425 455 424 445 433 447 432 448 1309 483 395 454 1303 479 401 448 1309 452 1304 478 401 448 432 448 1308 453 427 453 1303 447 432 448 1308 453 1304 446 432 448 1309 452
#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3553 1687 451 427 453 1303 447 431 449 430 450 429 451 427 484 395 454 425 455 424 446 433 447 432 448 431 449 430 450 1306 454 424 456 423 447 432 448 431 449 430 450 429 451 428 452 426 454 425 455 1301 449 430 450 429 451 427 453 426 454 425 455 424 446 433 447 432 448 430 450 429 451 428 452 427 453 426 454 1302 448 431 449 430 450 429 451 427 453 426 454 425 455 424 456 1300 450 429 451 1305 456 74679 3520 1721 448 430 450 1306 454 424 446 433 447 432 448 430 450 429 451 428 452 427 453 425 455 424 456 423 447 432 448 1308 453 426 454 425 455 424 446 433 447 432 448 430 450 429 451 428 452 427 453 1303 447 431 449 430 450 429 451 428 452 426 454 425 455 423 447 433 447 431 449 430 450 429 451 428 452 426 454 1303 447 432 448 431 449 429 451 428 452 427 453 426 454 425 455 1301 449 430 450 1306 454 70419 174
#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3524 1717 452 453 427 1301 449 456 424 428 452 454 426 453 427 452 428 423 447 460 420 459 421 457 423 456 424 455 425 1304 446 460 420 458 422 457 423 456 424 455 425 453 427 452 428 451 419 461 419 1310 450 455 425 454 426 453 427 452 428 450 419 460 420 459 421 458 422 1307 454 452 428 451 418 460 420 459 421 1309 452 454 426 453 427 1302 448 458 422 457 423 456 424 455 425 1304 446 460 420 1309 452 74701 3528 1715 454 451 419 1310 451 456 424 455 425 454 426 453 427 452 428 451 419 460 420 459 421 458 422 457 423 456 424 1305 456 451 419 460 420 459 421 458 422 457 423 456 424 455 425 454 426 453 427 1302 448 431 449 457 423 456 424 455 425 454 426 453 427 452 428 451 419 1311 450 456 424 455 425 454 426 453 427 1303 447 459 421 458 422 1307 454 452 428 452 428 451 419 460 420 1310 451 455 425 1304 446
#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3525 1716 453 452 428 1300 450 456 424 454 426 425 455 424 456 451 419 432 448 431 449 430 450 456 424 455 425 454 426 1303 447 459 421 458 422 429 451 455 425 427 453 453 427 452 428 423 457 450 420 1309 452 455 425 426 454 452 428 451 429 450 430 449 421 458 422 457 423 456 424 1305 456 450 430 449 431 1299 451 1304 446 459 421 458 422 457 423 1306 455 451 429 450 430 1300 450 1306 455 450 430 1300 450 74695 3530 1711 448 458 422 1307 454 452 428 451 429 449 421 459 421 458 422 456 424 455 425 454 426 453 427 452 428 451 429 1300 450 456 424 427 453 453 427 452 428 451 429 450 420 459 421 458 422 457 423 1306 455 424 456 423 447 459 421 458 422 457 423 456 424 455 425 454 426 453 427 1302 448 458 422 429 451 1306 455 1301 449 457 423 428 452 455 425 1304 446 460 420 431 449 1308 453 1303 447 459 421 1308 453
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3514 1773 418 456 424 1329 421 453 427 446 424 451 419 460 420 453 427 447 423 451 419 461 419 454 426 447 423 450 420 1333 428 447 423 457 423 450 420 453 427 447 423 457 423 450 420 453 427 447 423 1329 421 453 427 453 417 456 424 449 421 453 417 462 418 455 425 449 421 1332 418 455 425 1301 449 1305 445 1313 448 1306 444 457 423 456 424 1307 454 453 427 1304 446 1309 504 1249 501 1251 499 376 452 1300 450 75472 3513 1755 446 455 425 1300 450 451 419 456 424 455 425 448 422 451 419 456 424 455 425 448 422 452 418 456 424 455 425 1334 427 453 427 447 423 450 420 455 425 454 426 447 423 451 419 455 425 454 426 1306 455 452 418 456 424 449 421 454 426 453 427 446 424 450 420 454 426 1299 451 451 419 1307 454 1302 501 1253 445 1315 498 381 447 454 426 1299 451 450 420 1308 453 1307 454 1300 450 1304 446 454 426 1301 449 75485 3520 1770 421 453 427 1300 450 450 420 453 427 448 422 457 423 451 419 454 426 448 422 458 422 451 419 455 425 449 421 1305 445 457 423 457 423 450 420 454 426 448 422 457 423 450 420 454 426 447 423 1303 447 454 426 453 427 446 424 450 420 454 426 453 427 446 424 450 420 1307 454 446 424 1304 446 1307 454 1305 456 1298 452 450 420 460 420 1313 448 459 421 1310 451 1304 446 1308 453 1300 450 424 446 1307 454
#
name: CH+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3514 1774 427 453 417 1342 419 461 419 454 426 447 423 451 419 461 419 454 426 447 423 451 419 461 419 454 426 447 423 1330 420 453 427 447 423 457 423 450 420 453 427 448 422 457 423 450 420 454 426 1327 423 450 420 455 425 454 426 448 422 451 419 456 424 455 425 448 422 452 418 456 424 1330 420 453 427 1327 423 1303 447 454 426 448 422 458 422 451 419 1335 426 448 422 1333 417 1342 419 461 419 1341 420 75512 3516 1771 420 454 426 1327 423 451 419 461 419 454 426 447 423 452 418 461 419 454 426 447 423 452 418 462 418 455 425 1327 424 450 420 454 426 448 422 457 423 450 420 454 426 448 422 457 423 450 420 1333 418 456 424 448 422 453 417 462 418 454 426 447 423 451 419 461 419 453 427 446 424 1329 421 452 418 1336 425 1328 422 451 419 454 426 448 422 458 422 1309 452 455 425 1306 455 1326 424 449 421 1306 445
#
name: CH-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3519 1775 426 448 422 1332 418 455 425 449 421 459 421 452 418 456 424 450 420 459 421 452 418 456 424 450 420 460 420 1339 422 458 422 451 419 455 425 449 421 459 421 452 418 455 425 449 421 459 421 1339 422 457 423 451 419 454 426 448 422 458 422 451 419 454 426 448 422 1331 419 454 426 1327 423 450 420 1307 454 1299 451 449 421 453 427 1326 424 449 421 1333 417 456 424 1329 421 1304 446 454 426 1327 423
#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3516 1772 419 455 425 1328 422 452 418 462 418 455 425 448 422 453 417 462 418 455 425 448 422 453 417 462 418 455 425 1328 422 451 419 454 426 448 422 458 422 451 419 455 425 448 422 458 422 451 419 1335 426 448 422 451 419 456 424 455 425 448 422 451 419 456 424 455 425 447 423 451 419 455 425 454 426 447 423 1331 419 454 426 447 423 452 418 461 419 454 426 447 423 451 419 1335 426 447 423 1331 419 75481 3511 1755 446 454 426 1326 424 449 421 454 426 453 427 446 424 449 421 454 426 453 427 446 424 449 421 454 426 453 427 1332 418 461 419 454 426 447 423 451 419 460 420 453 427 446 424 451 419 460 420 1339 422 457 423 451 419 454 426 448 422 458 422 451 419 454 426 448 422 458 422 451 419 454 426 449 421 459 421 1338 423 456 424 450 420 454 426 448 422 458 422 451 419 455 425 1328 422 452 418 1336 425
#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3516 1747 444 456 424 1329 421 453 427 446 424 451 419 460 420 454 426 447 423 451 419 461 419 454 426 447 423 451 419 1334 427 448 422 458 422 451 419 455 425 450 420 459 421 453 417 456 424 450 420 1333 417 457 423 456 424 449 421 453 427 447 423 457 423 450 420 454 426 1328 422 451 419 456 424 455 425 448 422 1331 419 455 425 448 422 1332 418 455 425 449 421 459 421 452 418 1336 425 449 421 1332 418
#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3515 1747 454 446 424 1303 447 454 426 453 427 446 424 450 419 454 426 453 427 446 424 449 420 454 426 453 427 446 424 1303 447 427 453 447 423 451 419 461 419 454 426 447 422 452 417 462 418 456 424 1303 447 453 427 446 424 451 418 461 419 454 426 447 423 452 418 462 418 455 425 1302 448 452 417 456 424 1303 447 1307 506 368 449 451 418 455 425 1301 449 453 427 453 427 1331 419 1308 452 448 422 1306 454 75492 3517 1777 424 450 419 1306 454 447 423 452 418 462 418 456 424 449 420 454 426 453 427 446 424 450 419 454 426 454 426 1333 427 452 428 446 424 450 419 454 426 454 426 447 422 451 418 455 425 455 425 1334 426 453 427 447 423 450 419 455 425 454 426 447 423 451 418 456 424 455 425 1334 426 453 427 447 423 1303 447 1314 447 459 421 453 427 446 423 1330 420 453 427 447 422 1303 447 1307 453 447 423 1303 447
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 926 751 1760 756 922 756 921 782 897 782 897 783 897 784 897 784 897 1624 897 784 1736 787 895 85521 921 780 1734 784 896 783 894 785 895 784 895 784 895 785 895 784 896 1625 895 785 1735 787 896 85546 894 783 1732 763 917 783 896 783 896 784 895 784 895 785 894 785 897 1624 897 784 1734 786 897
#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 953 724 927 750 1764 755 924 755 924 758 922 782 898 782 899 1624 1737 786 898 784 897 784 898 85552 923 756 921 757 1759 783 898 782 898 782 898 783 897 783 897 1623 1737 785 897 784 897 784 897 85557 927 750 926 753 1762 782 898 782 898 759 921 782 898 783 898 1623 1737 785 898 784 898 783 898
#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 952 725 1763 752 927 753 925 756 922 780 899 781 899 782 899 1623 1737 786 897 784 897 1626 895 84746 892 785 1731 787 894 785 894 785 895 786 895 789 891 786 895 1627 1732 789 894 788 893 1628 894 84705 929 748 1766 751 930 750 929 750 929 750 929 752 928 753 927 1593 1766 756 926 756 925 1597 924
#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 896 782 895 784 1733 785 896 785 868 812 894 784 920 762 871 812 918 1605 893 787 1735 1629 892 84752 893 784 895 781 1735 762 919 783 895 786 897 783 896 785 896 786 895 1625 897 784 1738 1625 896 84727 916 784 896 781 1736 785 897 783 896 784 896 785 897 784 895 785 897 1624 897 783 1737 1627 897
#
name: CH+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 921 753 1759 785 896 782 897 782 897 783 895 784 896 1623 1733 786 895 784 895 784 893 785 895 85568 893 783 1734 786 893 785 895 783 895 785 894 785 895 1622 1733 786 894 784 896 784 895 784 895
#
name: CH-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 5349 102096 3672 530 1194 102545 5171 102367 969 658 1613 481 1499 103984 503 388 210 337 161
#
name: POWER
type: parsed
protocol: NEC
address: 01 00 00 00
command: 03 00 00 00
#
name: CH+
type: parsed
protocol: RC5
address: 00 00 00 00
command: 20 00 00 00
#
name: CH-
type: parsed
protocol: RC5
address: 00 00 00 00
command: 21 00 00 00
#
name: VOL-
type: parsed
protocol: RC5
address: 00 00 00 00
command: 11 00 00 00
#
name: VOL+
type: parsed
protocol: RC5
address: 00 00 00 00
command: 10 00 00 00
#
name: POWER
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3515 1718 468 411 466 1285 468 411 465 410 466 410 466 410 466 437 465 412 464 412 463 414 461 416 460 417 459 417 460 1295 458 417 460 417 459 417 459 417 460 417 459 417 460 417 460 417 459 417 460 1294 459 417 460 417 460 417 460 417 460 417 460 417 459 417 460 417 459 1295 459 417 460 1295 458 1295 459 1295 458 1295 458 418 459 418 459 1295 459 418 459 1295 459 1296 457 1296 458 1296 458 418 459 1296 457 74712 3536 1727 459 418 459 1295 458 418 459 417 460 417 460 417 459 417 460 417 459 417 460 417 459 417 459 417 460 417 460 1295 458 418 459 418 458 417 460 418 458 418 458 418 458 418 459 418 459 418 458 1296 457 419 457 419 458 418 459 418 458 418 458 419 458 418 458 418 458 1296 457 419 458 1297 457 1298 455 1322 431 1322 431 421 456 420 457 1322 431 421 456 1322 431 1322 431 1323 430 1323 430 446 431 1322 431 74712 3536 1727 458 418 459 1295 458 418 459 418 458 418 459 418 459 417 460 417 460 417 460 417 460 417 460 417 460 417 460 1294 459 418 459 417 460 417 459 418 459 418 459 418 458 418 459 418 458 418 459 1295 458 418 458 418 459 418 459 418 459 417 460 418 459 418 458 418 458 1296 458 418 458 1296 457 1296 458 1297 456 1297 456 420 457 419 458 1296 458 420 457 1297 456 1297 457 1297 456 1297 456 421 456 1297 456 74713 3534 1729 458 418 459 1295 459 417 459 417 459 418 458 418 458 418 458 418 459 418 458 418 459 418 459 418 458 418 459 1295 459 417 459 418 459 417 459 418 459 418 458 418 459 418 458 418 458 418 459 1295 459 418 459 418 459 418 459 418 458 418 459 418 459 418 458 418 459 1295 459 418 458 1295 459 1294 459 1295 459 1295 459 417 459 418 459 1295 459 417 459 1295 459 1295 459 1295 458 1295 459 417 459 1295 458 74711 3534 1728 459 417 459 1294 460 417 459 417 459 418 459 417 459 418 458 418 459 418 458 418 458 418 459 418 458 418 459 1295 459 418 458 418 459 418 458 418 458 418 459 418 459 418 459 418 458 418 458 1295 459 418 458 418 459 418 458 418 458 418 458 418 458 419 458 418 458 1296 458 418 458 1295 458 1296 458 1295 459 1295 459 418 458 419 457 1296 458 418 458 1296 458 1295 458 1296 458 1296 458 418 458 1296 457 74711 3534 1729 458 417 459 1295 459 417 459 417 459 417 459 418 459 418 459 418 458 418 459 418 458 418 459 418 459 418 458 1295 459 418 458 418 458 418 459 418 458 418 459 418 459 418 458 418 458 419 458 1295 458 418 459 418 458 418 459 418 458 418 458 419 458 418 459 419 457 1296 458 418 458 1296 458 1295 459 1295 459 1295 458 418 459 418 458 1296 458 418 458 1296 457 1296 458 1296 457 1296 458 419 458 1296 457 74711 3534 1729 459 418 458 1295 459 418 458 418 459 418 458 418 458 418 458 418 459 418 458 418 459 418 458 419 458 419 457 1296 458 419 457 419 458 419 458 419 458 419 458 419 457 419 458 419 457 419 458 1296 458 419 457 419 457 420 456 420 456 420 457 420 457 420 456 420 457 1297 457 419 457 1296 458 1296 458 1296 457 1296 458 419 457 419 457 1296 458 419 457 1297 457 1297 457 1297 456 1297 457 420 456 1298 456
#
name: MUTE
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3545 1720 468 412 494 1256 497 381 493 384 465 410 493 384 492 411 464 412 463 413 462 415 460 417 459 418 458 418 458 1295 458 418 459 418 459 418 459 418 458 418 458 419 458 418 458 418 459 418 458 1296 458 418 458 418 458 419 458 419 457 419 457 419 458 419 458 419 458 419 457 1296 457 419 458 419 457 1296 458 1296 458 419 457 419 457 419 457 1296 458 419 458 419 457 1297 457 1296 457 420 457 1297 456 74623 3534 1729 459 418 458 1295 459 418 458 418 458 418 459 418 458 418 458 418 458 418 459 418 458 418 458 419 458 418 458 1296 458 418 459 418 458 418 458 418 459 418 459 418 458 419 457 419 458 419 457 1296 458 418 459 418 458 418 458 419 458 418 458 418 458 419 458 419 458 419 458 1295 459 418 458 418 459 1295 459 1295 458 418 458 418 458 419 457 1296 458 418 459 419 457 1296 458 1295 458 418 458 1295 459
#
name: VOL+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 228 144285 3545 1690 497 411 495 1256 496 382 465 410 466 410 493 383 493 386 489 411 464 413 462 415 460 417 459 417 459 418 459 1295 458 418 459 418 459 418 458 418 458 418 459 418 458 418 459 418 459 418 459 1295 459 418 459 418 458 418 459 418 458 418 458 418 458 419 458 418 458 419 458 419 458 418 458 419 458 419 458 1296 458 418 458 418 458 419 457 419 458 419 457 419 458 419 458 1296 457 419 457 1296 458
#
name: CH+
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3513 1720 468 411 494 1257 496 383 465 410 492 384 493 384 492 385 490 411 464 413 462 415 460 417 459 418 458 418 459 1295 459 418 458 418 458 418 458 418 459 418 458 418 459 418 458 418 459 418 458 1295 459 418 458 418 459 418 458 418 459 419 457 418 459 419 457 419 458 419 458 419 457 1296 458 419 457 1296 458 1296 457 419 457 419 458 419 457 419 458 1297 457 419 458 1297 457 1296 457 420 457 1296 457 74624 3534 1729 458 417 460 1294 460 417 459 417 459 418 458 418 459 417 459 417 459 418 459 418 458 418 458 418 459 418 459 1295 458 418 459 418 459 418 459 418 458 418 459 418 458 418 459 418 458 418 459 1295 459 418 458 418 458 418 459 418 459 418 458 418 458 418 459 418 458 418 458 418 459 1295 459 418 458 1295 459 1295 459 418 458 418 458 418 459 418 458 1295 459 418 458 1295 458 1295 459 418 458 1295 459
#
name: VOL-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3513 1720 468 411 465 1285 468 410 466 410 466 410 493 383 493 385 490 412 462 413 462 415 460 417 459 417 459 417 460 1294 459 417 459 417 459 417 459 417 460 417 459 418 459 418 459 417 459 418 458 1295 459 418 459 418 458 418 458 418 459 418 458 418 459 418 458 418 458 1295 459 418 459 418 458 418 458 419 458 1295 459 418 458 418 459 1296 457 418 458 419 457 419 458 419 458 1296 457 419 458 1296 458 74841 3534 1729 459 417 459 1294 460 417 459 417 460 417 460 417 460 417 460 417 459 417 460 417 459 417 460 417 459 417 459 1295 459 417 459 417 460 417 459 417 460 418 458 418 459 418 459 417 459 418 459 1295 458 418 459 418 458 418 459 417 460 417 459 417 459 418 458 418 459 1295 459 418 458 418 459 418 458 418 459 1295 459 418 458 418 458 1295 458 418 459 418 458 418 459 418 458 1295 459 418 458 1295 459
#
name: CH-
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3514 1720 467 412 494 1257 497 381 465 410 466 410 466 410 466 412 490 411 464 413 462 414 461 416 459 418 459 417 460 1294 460 417 460 417 459 417 459 417 459 417 460 417 460 417 459 417 459 417 459 1295 459 417 459 418 459 418 459 417 459 418 459 418 458 418 458 418 458 1295 459 418 458 1295 459 417 459 1295 459 1295 458 418 459 418 459 1294 460 417 459 1294 460 417 459 1295 459 1294 460 417 459 1295 459 74408 3533 1729 459 417 459 1294 459 418 459 418 458 417 460 418 458 418 459 418 458 418 458 418 459 418 458 418 459 418 459 1295 458 418 458 418 459 418 458 418 459 418 459 418 458 419 458 419 458 419 457 1296 458 419 457 419 458 419 457 419 458 419 457 419 457 419 457 419 458 1297 456 419 457 1297 457 419 457 1297 456 1297 457 419 457 420 457 1297 456 420 457 1297 456 420 456 1298 456 1297 456 421 455 1298 456
#
name: POWER
type: parsed
protocol: NEC
address: 03 00 00 00
command: 1D 00 00 00
#
name: MUTE
type: parsed
protocol: NECext
address: 00 7F 00 00
command: 4E B1 00 00
#
name: VOL+
type: parsed
protocol: NEC
address: 03 00 00 00
command: 11 00 00 00
#
name: VOL-
type: parsed
protocol: NEC
address: 03 00 00 00
command: 15 00 00 00
#
name: POWER
type: raw
@@ -73,7 +271,7 @@ type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3540 1691 494 383 465 1284 468 409 492 383 493 383 492 384 491 386 488 388 486 414 461 415 460 416 460 416 460 416 460 1293 459 416 460 416 460 416 460 416 460 416 460 416 460 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1293 459 416 460 417 459 417 459 416 459 1294 458 417 459 417 458 1294 458 417 459 417 459 417 459 417 459 1294 458 417 459 1294 458 74801 3534 1725 459 416 460 1293 459 416 460 416 460 416 460 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1294 458 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1294 458 417 459 417 459 418 458 418 458 1294 458 418 458 418 458 1294 458 418 458 418 458 418 458 418 458 1294 458 418 458 1294 458
#
#
name: MUTE
type: raw
frequency: 38000

View File

@@ -0,0 +1,8 @@
# Example file, P.S. keep empty line at the end!
000000
F00000
E00000
FE0000
CAFE00
00CAFE
0000CA

View File

@@ -0,0 +1,8 @@
# Example file, P.S. keep empty line at the end!
000000000000
00FE00000000
00CAFE000000
0000CAFE0000
000000CAFE00
00000000CAFE
0000000000CA

View File

@@ -0,0 +1,8 @@
# Example file, P.S. keep empty line at the end!
00000000
F0000000
FE000000
CAFE0000
00CAFE00
0000CAFE
000000CA

View File

@@ -4182,6 +4182,8 @@ Variable,+,I_MHz_25x11,const Icon,
Variable,+,I_Medium_chip_22x21,const Icon,
Variable,+,I_Mode_25x27,const Icon,
Variable,+,I_Mode_hvr_25x27,const Icon,
Variable,+,I_Modern_reader_18x34,const Icon,
Variable,+,I_Move_flipper_26x39,const Icon,
Variable,+,I_Mute_25x27,const Icon,
Variable,+,I_Mute_hvr_25x27,const Icon,
Variable,+,I_NFC_manual_60x50,const Icon,
@@ -4207,6 +4209,7 @@ Variable,+,I_RFIDDolphinReceive_97x61,const Icon,
Variable,+,I_RFIDDolphinSend_97x61,const Icon,
Variable,+,I_RFIDDolphinSuccess_108x57,const Icon,
Variable,+,I_RFIDSmallChip_14x14,const Icon,
Variable,+,I_Release_arrow_18x15,const Icon,
Variable,+,I_Restoring_38x32,const Icon,
Variable,+,I_Right_mouse_icon_9x9,const Icon,
Variable,+,I_Rotate_25x27,const Icon,
1 entry status name type params
4182 Variable + I_Medium_chip_22x21 const Icon
4183 Variable + I_Mode_25x27 const Icon
4184 Variable + I_Mode_hvr_25x27 const Icon
4185 Variable + I_Modern_reader_18x34 const Icon
4186 Variable + I_Move_flipper_26x39 const Icon
4187 Variable + I_Mute_25x27 const Icon
4188 Variable + I_Mute_hvr_25x27 const Icon
4189 Variable + I_NFC_manual_60x50 const Icon
4209 Variable + I_RFIDDolphinSend_97x61 const Icon
4210 Variable + I_RFIDDolphinSuccess_108x57 const Icon
4211 Variable + I_RFIDSmallChip_14x14 const Icon
4212 Variable + I_Release_arrow_18x15 const Icon
4213 Variable + I_Restoring_38x32 const Icon
4214 Variable + I_Right_mouse_icon_9x9 const Icon
4215 Variable + I_Rotate_25x27 const Icon

View File

@@ -93,14 +93,16 @@ static void furi_thread_body(void* context) {
thread->name ? thread->name : "<unknown service>");
}
// clear thread local storage
// flush stdout
__furi_thread_stdout_flush(thread);
furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL);
vTaskSetThreadLocalStoragePointer(NULL, 0, NULL);
// from here we can't use thread pointer
furi_thread_set_state(thread, FuriThreadStateStopped);
// clear thread local storage
furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL);
vTaskSetThreadLocalStoragePointer(NULL, 0, NULL);
vTaskDelete(NULL);
furi_thread_catch();
}

View File

@@ -4,6 +4,10 @@
#include "flipper_format_stream.h"
#include "flipper_format_stream_i.h"
static inline bool flipper_format_stream_is_space(char c) {
return c == ' ' || c == '\t' || c == flipper_format_eolr;
}
static bool flipper_format_stream_write(Stream* stream, const void* data, size_t data_size) {
size_t bytes_written = stream_write(stream, data, data_size);
return bytes_written == data_size;
@@ -118,55 +122,64 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str
}
static bool flipper_format_stream_read_value(Stream* stream, string_t value, bool* last) {
string_reset(value);
enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace;
const size_t buffer_size = 32;
uint8_t buffer[buffer_size];
bool result = false;
bool error = false;
string_reset(value);
while(true) {
size_t was_read = stream_read(stream, buffer, buffer_size);
if(was_read == 0) {
// check EOF
if(stream_eof(stream) && string_size(value) > 0) {
if(state != LeadingSpace && stream_eof(stream)) {
result = true;
*last = true;
break;
} else {
error = true;
}
}
for(uint16_t i = 0; i < was_read; i++) {
uint8_t data = buffer[i];
if(data == flipper_format_eoln) {
if(string_size(value) > 0) {
if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
error = true;
break;
}
const uint8_t data = buffer[i];
result = true;
*last = true;
if(state == LeadingSpace) {
if(flipper_format_stream_is_space(data)) {
continue;
} else if(data == flipper_format_eoln) {
stream_seek(stream, i - was_read, StreamOffsetFromCurrent);
error = true;
break;
} else {
error = true;
state = ReadValue;
string_push_back(value, data);
}
} else if(data == ' ') {
if(string_size(value) > 0) {
} else if(state == ReadValue) {
if(flipper_format_stream_is_space(data)) {
state = TrailingSpace;
} else if(data == flipper_format_eoln) {
if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
error = true;
break;
} else {
result = true;
*last = true;
}
result = true;
*last = false;
break;
} else {
string_push_back(value, data);
}
} else if(data == flipper_format_eolr) {
// Ignore
} else {
string_push_back(value, data);
} else if(state == TrailingSpace) {
if(flipper_format_stream_is_space(data)) {
continue;
} else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
error = true;
} else {
*last = (data == flipper_format_eoln);
result = true;
}
break;
}
}

View File

@@ -205,8 +205,15 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) {
LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data;
bool result = false;
// Fix incorrect length byte
if(protocol->data[0] != 26 && protocol->data[0] != 50 && protocol->data[0] != 37 &&
protocol->data[0] != 34) {
protocol->data[0] = 26;
}
// Correct protocol data by redecoding
protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data);
bit_lib_remove_bit_every_nth((uint8_t*)protocol->encoded_data, 8, 88, 4);
protocol_awid_decode(protocol->encoded_data, protocol->data);
protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data);

View File

@@ -79,6 +79,14 @@ static bool protocol_fdx_a_decode(const uint8_t* from, uint8_t* to) {
return true;
}
static void protocol_fdx_a_fix_parity(ProtocolFDXA* protocol) {
for(size_t i = 0; i < FDXA_DECODED_DATA_SIZE; i++) {
if(bit_lib_test_parity_32(protocol->data[i], BitLibParityOdd)) {
protocol->data[i] ^= (1 << 7);
}
}
}
static bool protocol_fdx_a_can_be_decoded(const uint8_t* data) {
// check preamble
if(data[0] != FDXA_PREAMBLE_0 || data[1] != FDXA_PREAMBLE_1 || data[12] != FDXA_PREAMBLE_0 ||
@@ -179,6 +187,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) {
bool result = false;
// Correct protocol data by redecoding
protocol_fdx_a_fix_parity(protocol);
protocol_fdx_a_encoder_start(protocol);
protocol_fdx_a_decode(protocol->encoded_data, protocol->data);

View File

@@ -170,6 +170,7 @@ bool protocol_keri_encoder_start(ProtocolKeri* protocol) {
memset(protocol->encoded_data, 0, KERI_ENCODED_DATA_SIZE);
*(uint32_t*)&protocol->encoded_data[0] = 0b00000000000000000000000011100000;
bit_lib_copy_bits(protocol->encoded_data, 32, 32, protocol->data, 0);
bit_lib_set_bits(protocol->encoded_data, 32, 1, 1);
protocol->encoder.last_bit =
bit_lib_get_bit(protocol->encoded_data, KERI_ENCODED_BIT_SIZE - 1);
@@ -224,6 +225,8 @@ bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) {
LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data;
bool result = false;
// Start bit should be always set
protocol->data[0] |= (1 << 7);
protocol_keri_encoder_start(protocol);
if(request->write_type == LFRFIDWriteTypeT5577) {

View File

@@ -221,6 +221,7 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) {
// Correct protocol data by redecoding
protocol_pyramid_encode(protocol);
bit_lib_remove_bit_every_nth(protocol->encoded_data, 8, 15 * 8, 8);
protocol_pyramid_decode(protocol);
protocol_pyramid_encoder_start(protocol);

View File

@@ -94,7 +94,7 @@ static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) {
string_t str;
string_init_printf(
str,
"Sector %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n",
"Sec %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n",
params->sector,
params->key == MfClassicKeyA ? 'A' : 'B',
params->cuid,

View File

@@ -647,7 +647,8 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void*
furi_assert(context);
NfcWorker* nfc_worker = context;
if(event == ReaderAnalyzerEventMfkeyCollected) {
if((nfc_worker->state == NfcWorkerStateAnalyzeReader) &&
(event == ReaderAnalyzerEventMfkeyCollected)) {
if(nfc_worker->callback) {
nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context);
}
@@ -655,6 +656,8 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void*
}
void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
furi_assert(nfc_worker->callback);
FuriHalNfcTxRxContext tx_rx = {};
ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer;
@@ -673,17 +676,32 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
rfal_platform_spi_acquire();
FURI_LOG_D(TAG, "Start reader analyzer");
uint8_t reader_no_data_received_cnt = 0;
bool reader_no_data_notified = true;
while(nfc_worker->state == NfcWorkerStateAnalyzeReader) {
furi_hal_nfc_stop_cmd();
furi_delay_ms(5);
furi_hal_nfc_listen_start(nfc_data);
if(furi_hal_nfc_listen_rx(&tx_rx, 300)) {
if(reader_no_data_notified) {
nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context);
}
reader_no_data_received_cnt = 0;
reader_no_data_notified = false;
NfcProtocol protocol =
reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8);
if(protocol == NfcDeviceProtocolMifareClassic) {
mf_classic_emulator(&emulator, &tx_rx);
}
} else {
reader_no_data_received_cnt++;
if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) {
nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context);
reader_no_data_received_cnt = 0;
reader_no_data_notified = true;
}
FURI_LOG_D(TAG, "No data from reader");
continue;
}

View File

@@ -56,6 +56,8 @@ typedef enum {
NfcWorkerEventFoundKeyB,
// Detect Reader events
NfcWorkerEventDetectReaderDetected,
NfcWorkerEventDetectReaderLost,
NfcWorkerEventDetectReaderMfkeyCollected,
// Mifare Ultralight events