mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-29 04:09:58 -07:00
[FL-3569] NFC CLI commands (#4158)
* feat: FuriThread stdin * ci: fix f18 * feat: stdio callback context * feat: FuriPipe * POTENTIALLY EXPLOSIVE pipe welding * fix: non-explosive welding * Revert welding * docs: furi_pipe * feat: pipe event loop integration * update f18 sdk * f18 * docs: make doxygen happy * fix: event loop not triggering when pipe attached to stdio * fix: partial stdout in pipe * allow simultaneous in and out subscription in event loop * feat: vcp i/o * feat: cli ansi stuffs and history * feat: more line editing * working but slow cli rewrite * restore previous speed after 4 days of debugging 🥲 * fix: cli_app_should_stop * fix: cli and event_loop memory leaks * style: remove commented out code * ci: fix pvs warnings * fix: unit tests, event_loop crash * ci: fix build * ci: silence pvs warning * feat: cli gpio * ci: fix formatting * Fix memory leak during event loop unsubscription * Event better memory leak fix * feat: cli completions * Merge remote-tracking branch 'origin/dev' into portasynthinca3/3928-cli-threads * merge fixups * temporarily exclude speaker_debug app * pvs and unit tests fixups * feat: commands in fals * move commands out of flash, code cleanup * ci: fix errors * fix: run commands in buffer when stopping session * speedup cli file transfer * fix f18 * separate cli_shell into modules * fix pvs warning * fix qflipper refusing to connect * remove temp debug logs * remove erroneous conclusion * Fix memory leak during event loop unsubscription * Event better memory leak fix * unit test for the fix * improve thread stdio callback signatures * pipe stdout timeout * update api symbols * fix f18, formatting * fix pvs warnings * increase stack size, hope to fix unit tests * cli completions * more key combos * commands in fals * move commands out of flash * ci: fix errors * speedup cli file transfer * merge fixups * fix f18 * cli: revert flag changes * cli: fix formatting * cli, fbt: loopback perf benchmark * thread, event_loop: subscribing to thread flags * cli: signal internal events using thread flags, improve performance * fix f18, formatting * event_loop: fix crash * storage_cli: increase write_chunk buffer size again * cli: explanation for order=0 * thread, event_loop: thread flags callback refactor * cli: increase stack size * cli: rename cli_app_should_stop -> cli_is_pipe_broken_or_is_etx_next_char * cli: use plain array instead of mlib for history * cli: prepend file name to static fns * cli: fix formatting * cli_shell: increase stack size * Now cli_shell can be customized with another motd and another command set * Added custom motd callback definition * Now user can alloc and free his own cli command set * cli_vcp can now restart shell with another command set * Help command modified to show available commands from different command sets * Api adjustement * Reworked nfc_cli to start new shell with another command set * Revert custom shell changes from vcp * Custom motd callback moved to cli_shell * Cli Shell now can be started from ongoing cli command * Help command moved to a separate function so it can be used for custom shell * Now nfc command spawns separate shell for further nfc commands * cli_shell: give up pipe to command thread * fix formatting * cli_shell: separate into toolbox * speaker_debug: fix * fix: format * Merge branch 'portasynthinca3/3928-3929-cli-fals-threads' into portasynthinca3/3965-cli_shell-toolbox * fix merge * fix. merge. * fix formatting * fix: cmd flags * fix: formatting * Added basic command descriptor structs and macros * Basic nfc commands definitions added * Nfc cli commands collection and functions added * Raw skeleton of nfc cli processor added * cli: increase default stack depth * New callbacks for ctx alloc / free added * nfc_cli moved to cli folder * Some more logic for command processor * Scanner command no works via command_processor * plugin manifest adj * Argument descriptors were removed, now only keys left * Some helper command function implemented * Command processor logic now mostly works * Added all parsers and dummy implementation of raw cmd * Now processor checks duplicated keys and treat them as errors * Some renamings * Arguments processing moved to separate function * Now command processor can reuse context of previuos command for the next one if it's allowed * can_reuse callback added for checking if context can be reused * command processor is now freed on nfc cli exit * Some cleanups * First working version of raw command * Now input data are placed directly to bit buffer * Added tag * Introduced request/response structs * Moved raw command to a separate folder * Moved some common types to header * Added protocol specific handlers for iso14a and felica * Opened felica crc header for referencing * Added handler for iso14443_3b * Opened iso15693_3_poller for referencing * Added iso15693_3 handler for raw command * NfcCliRawError enum introduced for response result * Refactored handlers implementation * Formatting functions now added as helpers * New printing result logic * Not present error value added to enum * Timeout added to raw command * Command processor now supports multivalue keys * Apdu command implementation added * NfcScanner moved to helpers and command now uses it * Helper now can format protocol names * Dump command added * Added some more functions to scanner helper * Dump main logic simplified * Dump handlers moved to protocols folder * Protocol parser added to simplify searching protocol by name * Protocol and key arguments added to dump command * Cleanups * Apdu now parses protocol using helper parser * Raw now parses protocol using helper parser * Wrong naming fix * Emulate command added to cli * Description added to action descriptor and command macros * Description field added to all commands * Removed unnecessary enum for commands * Added functions for formatting command and action info * Proper error messages and help added * Fix for unsupported single action command * Function renamed to more appropriate * Field command moved to all other commands * Cleanups * Nfc commands modified with new cli shell * Removed previous nfc_cli.c after merge * Removed nfc_cli.h header * Some renamings and cleanups * Some comments and instructions added * Some comments and instructions added * TODOs removed * Fix for missing parse callback * Added not implemented dummy for mfu actions, for now * Fix name mismatch * Remove unneeded header * Mfu command moved to separate folder, also raw info action logic added * Dictionary with id/vendors added to assets. It is used by nfc_cli_mfu_info_get_vendor function * One more unneeded header removed * Moved mfu info action to a separate file * Info action now uses sync mfu poller * mfu rdbl action added * wrbl action added for mfu command * Some formatting for rdbl command * Function for formatting mfu errors added * All mfu actions now show errors in the same way * Fix error with sync poller. Previously when read failed function returned ErrorNone, now it processes iso14a error to get proper value * Make PVS happy * Nfc cli now doesn't start if desktop app is running * Make action description look more common * Scanner now has -t key and can show detected protocol hierarchies * Apdu now checks max input payload data * Proper format * Proper error handling added to dump command * Timeout key added dump command * Fix merge issue * formatting * Pragma pack replaced with FURI_PACKED * Fix felica memory leak --------- Co-authored-by: Anna Antonenko <portasynthinca3@gmail.com> Co-authored-by: Georgii Surkov <georgii.surkov@outlook.com> Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: hedger <hedger@users.noreply.github.com> Co-authored-by: hedger <hedger@nanode.su>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
#include "nfc_cli_dump_felica.h"
|
||||
#include <nfc/protocols/felica/felica_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_felica(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolFelica);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const FelicaPollerEvent* felica_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(felica_event->type == FelicaPollerEventTypeReady ||
|
||||
felica_event->type == FelicaPollerEventTypeIncomplete) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolFelica, nfc_poller_get_data(instance->poller));
|
||||
command = NfcCommandStop;
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
} else if(felica_event->type == FelicaPollerEventTypeError) {
|
||||
command = NfcCommandStop;
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
} else if(felica_event->type == FelicaPollerEventTypeRequestAuthContext) {
|
||||
FelicaAuthenticationContext* ctx = felica_event->data->auth_context;
|
||||
const NfcCliDumpAuthContext* dump_auth_ctx = &instance->auth_ctx;
|
||||
ctx->skip_auth = dump_auth_ctx->skip_auth;
|
||||
ctx->card_key = dump_auth_ctx->key.felica_key;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_felica(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "nfc_cli_dump_iso14443_3a.h"
|
||||
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_3a(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolIso14443_3a);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const Iso14443_3aPollerEvent* iso14443_3a_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
if(iso14443_3a_event->type == Iso14443_3aPollerEventTypeReady) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolIso14443_3a, nfc_poller_get_data(instance->poller));
|
||||
command = NfcCommandStop;
|
||||
} else if(iso14443_3a_event->type == Iso14443_3aPollerEventTypeError) {
|
||||
command = NfcCommandStop;
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_3a(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "nfc_cli_dump_iso14443_3b.h"
|
||||
#include <nfc/protocols/iso14443_3b/iso14443_3b_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_3b(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolIso14443_3b);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const Iso14443_3bPollerEvent* iso14443_3b_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
if(iso14443_3b_event->type == Iso14443_3bPollerEventTypeReady) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolIso14443_3b, nfc_poller_get_data(instance->poller));
|
||||
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
command = NfcCommandStop;
|
||||
} else if(iso14443_3b_event->type == Iso14443_3bPollerEventTypeError) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return NfcCommandContinue;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_3b(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "nfc_cli_dump_iso14443_4a.h"
|
||||
#include <nfc/protocols/iso14443_4a/iso14443_4a_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_4a(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolIso14443_4a);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolIso14443_4a, nfc_poller_get_data(instance->poller));
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
command = NfcCommandStop;
|
||||
} else if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeError) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_4a(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "nfc_cli_dump_iso14443_4b.h"
|
||||
#include <nfc/protocols/iso14443_4b/iso14443_4b_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_4b(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolIso14443_4b);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const Iso14443_4bPollerEvent* iso14443_4b_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeReady) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolIso14443_4b, nfc_poller_get_data(instance->poller));
|
||||
command = NfcCommandStop;
|
||||
} else if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeError) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso14443_4b(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "nfc_cli_dump_iso15693_3.h"
|
||||
#include <nfc/protocols/iso15693_3/iso15693_3_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso15693_3(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolIso15693_3);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const Iso15693_3PollerEvent* iso15693_3_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
if(iso15693_3_event->type == Iso15693_3PollerEventTypeReady) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolIso15693_3, nfc_poller_get_data(instance->poller));
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
} else if(iso15693_3_event->type == Iso15693_3PollerEventTypeError) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_iso15693_3(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "nfc_cli_dump_mf_classic.h"
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller.h>
|
||||
|
||||
#define TAG "MFC"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_classic(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolMfClassic);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const MfClassicPollerEvent* mfc_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(mfc_event->type == MfClassicPollerEventTypeRequestMode) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfClassic, nfc_poller_get_data(instance->poller));
|
||||
size_t uid_len = 0;
|
||||
const uint8_t* uid = nfc_device_get_uid(instance->nfc_device, &uid_len);
|
||||
if(mf_classic_key_cache_load(instance->mfc_key_cache, uid, uid_len)) {
|
||||
FURI_LOG_D(TAG, "Key cache found");
|
||||
mfc_event->data->poller_mode.mode = MfClassicPollerModeRead;
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "Key cache not found");
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestReadSector) {
|
||||
uint8_t sector_num = 0;
|
||||
MfClassicKey key = {};
|
||||
MfClassicKeyType key_type = MfClassicKeyTypeA;
|
||||
if(mf_classic_key_cache_get_next_key(
|
||||
instance->mfc_key_cache, §or_num, &key, &key_type)) {
|
||||
mfc_event->data->read_sector_request_data.sector_num = sector_num;
|
||||
mfc_event->data->read_sector_request_data.key = key;
|
||||
mfc_event->data->read_sector_request_data.key_type = key_type;
|
||||
mfc_event->data->read_sector_request_data.key_provided = true;
|
||||
} else {
|
||||
mfc_event->data->read_sector_request_data.key_provided = false;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfClassic, nfc_poller_get_data(instance->poller));
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
command = NfcCommandStop;
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeFail) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_classic(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "nfc_cli_dump_mf_desfire.h"
|
||||
#include <nfc/protocols/mf_desfire/mf_desfire_poller.h>
|
||||
|
||||
#define TAG "MFDES"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_desfire(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolMfDesfire);
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const MfDesfirePollerEvent* mf_desfire_event = event.event_data;
|
||||
|
||||
if(mf_desfire_event->type == MfDesfirePollerEventTypeReadSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfDesfire, nfc_poller_get_data(instance->poller));
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_desfire_event->type == MfDesfirePollerEventTypeReadFailed) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandReset;
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_desfire(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "nfc_cli_dump_mf_plus.h"
|
||||
#include <nfc/protocols/mf_plus/mf_plus_poller.h>
|
||||
|
||||
#define TAG "MFPLUS"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_plus(NfcGenericEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.protocol == NfcProtocolMfPlus);
|
||||
furi_assert(event.event_data);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const MfPlusPollerEvent* mf_plus_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(mf_plus_event->type == MfPlusPollerEventTypeReadSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfPlus, nfc_poller_get_data(instance->poller));
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_plus_event->type == MfPlusPollerEventTypeReadFailed) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandReset;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_plus(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "nfc_cli_dump_mf_ultralight.h"
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller.h>
|
||||
|
||||
#define TAG "MFU"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_ultralight(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolMfUltralight);
|
||||
NfcCliDumpContext* instance = context;
|
||||
const MfUltralightPollerEvent* mf_ultralight_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(mf_ultralight_event->type == MfUltralightPollerEventTypeReadSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfUltralight, nfc_poller_get_data(instance->poller));
|
||||
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeAuthRequest) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfUltralight, nfc_poller_get_data(instance->poller));
|
||||
|
||||
const NfcCliDumpAuthContext* auth_ctx = &instance->auth_ctx;
|
||||
mf_ultralight_event->data->auth_context.skip_auth = auth_ctx->skip_auth;
|
||||
mf_ultralight_event->data->auth_context.password = auth_ctx->key.password;
|
||||
mf_ultralight_event->data->auth_context.tdes_key = auth_ctx->key.tdes_key;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeAuthFailed) {
|
||||
instance->result = NfcCliDumpErrorAuthFailed;
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeReadFailed) {
|
||||
instance->result = NfcCliDumpErrorAuthFailed;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_mf_ultralight(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#include "../../../../helpers/mf_classic_key_cache.h"
|
||||
#include "../../helpers/nfc_cli_scanner.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/protocols/nfc_protocol.h>
|
||||
#include <nfc/nfc_device.h>
|
||||
#include <nfc/nfc_poller.h>
|
||||
|
||||
#include <nfc/protocols/felica/felica.h>
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight.h>
|
||||
|
||||
#include <storage/storage.h>
|
||||
|
||||
#define NFC_CLI_DUMP_KEY_MAX_SIZE (16)
|
||||
|
||||
typedef union {
|
||||
MfUltralightAuthPassword password;
|
||||
FelicaCardKey felica_key;
|
||||
MfUltralightC3DesAuthKey tdes_key;
|
||||
uint8_t key[NFC_CLI_DUMP_KEY_MAX_SIZE];
|
||||
} NfcCliDumpKeyUnion;
|
||||
|
||||
typedef struct {
|
||||
NfcCliDumpKeyUnion key;
|
||||
uint8_t key_size;
|
||||
bool skip_auth;
|
||||
} NfcCliDumpAuthContext;
|
||||
|
||||
typedef enum {
|
||||
NfcCliDumpErrorNone,
|
||||
NfcCliDumpErrorTimeout,
|
||||
NfcCliDumpErrorNotPresent,
|
||||
NfcCliDumpErrorFailedToRead,
|
||||
NfcCliDumpErrorAuthFailed,
|
||||
|
||||
NfcCliDumpErrorNum,
|
||||
} NfcCliDumpError;
|
||||
|
||||
typedef struct {
|
||||
Nfc* nfc;
|
||||
FuriString* file_path;
|
||||
Storage* storage;
|
||||
NfcCliScanner* scanner;
|
||||
NfcProtocol desired_protocol;
|
||||
uint32_t timeout;
|
||||
FuriSemaphore* sem_done;
|
||||
|
||||
NfcCliDumpError result;
|
||||
|
||||
NfcCliDumpAuthContext auth_ctx;
|
||||
MfClassicKeyCache* mfc_key_cache;
|
||||
|
||||
NfcPoller* poller;
|
||||
NfcDevice* nfc_device;
|
||||
} NfcCliDumpContext;
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "nfc_cli_dump_slix.h"
|
||||
#include <nfc/protocols/slix/slix_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_slix(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolSlix);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const SlixPollerEvent* slix_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(slix_event->type == SlixPollerEventTypeReady) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolSlix, nfc_poller_get_data(instance->poller));
|
||||
command = NfcCommandStop;
|
||||
} else if(slix_event->type == SlixPollerEventTypeError) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_slix(NfcGenericEvent event, void* context);
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "nfc_cli_dump_st25tb.h"
|
||||
#include <nfc/protocols/st25tb/st25tb_poller.h>
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_st25tb(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolSt25tb);
|
||||
|
||||
NfcCliDumpContext* instance = context;
|
||||
const St25tbPollerEvent* st25tb_event = event.event_data;
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(st25tb_event->type == St25tbPollerEventTypeRequestMode) {
|
||||
st25tb_event->data->mode_request.mode = St25tbPollerModeRead;
|
||||
} else if(st25tb_event->type == St25tbPollerEventTypeSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolSt25tb, nfc_poller_get_data(instance->poller));
|
||||
instance->result = NfcCliDumpErrorNone;
|
||||
command = NfcCommandStop;
|
||||
} else if(st25tb_event->type == St25tbPollerEventTypeFailure) {
|
||||
instance->result = NfcCliDumpErrorFailedToRead;
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
if(command == NfcCommandStop) {
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_dump_common_types.h"
|
||||
|
||||
NfcCommand nfc_cli_dump_poller_callback_st25tb(NfcGenericEvent event, void* context);
|
||||
Reference in New Issue
Block a user