mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-23 05:24:46 -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:
311
applications/main/nfc/cli/commands/apdu/nfc_cli_command_apdu.c
Normal file
311
applications/main/nfc/cli/commands/apdu/nfc_cli_command_apdu.c
Normal file
@@ -0,0 +1,311 @@
|
||||
#include "nfc_cli_command_apdu.h"
|
||||
#include "../helpers/nfc_cli_format.h"
|
||||
#include "../helpers/nfc_cli_protocol_parser.h"
|
||||
|
||||
#include "protocol_handlers/iso14443_4a/nfc_cli_apdu_iso14443_4a.h"
|
||||
#include "protocol_handlers/iso14443_4b/nfc_cli_apdu_iso14443_4b.h"
|
||||
#include "protocol_handlers/iso15693_3/nfc_cli_apdu_iso15693_3.h"
|
||||
|
||||
#include <furi.h>
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc_poller.h>
|
||||
|
||||
#include <toolbox/args.h>
|
||||
#include <m-array.h>
|
||||
#include <m-algo.h>
|
||||
|
||||
#define TAG "APDU"
|
||||
|
||||
#define NFC_CLI_PROTOCOL_SUPPORT_MAX_BUFFER_SIZE (256)
|
||||
|
||||
typedef NfcCommand (
|
||||
*NfcCliApduProtocolHandler)(NfcGenericEvent event, NfcCliApduRequestResponse* instance);
|
||||
|
||||
static const char* raw_error_names[] = {
|
||||
[NfcCliApduErrorNone] = "None",
|
||||
[NfcCliApduErrorTimeout] = "Timeout",
|
||||
[NfcCliApduErrorProtocol] = "Internal protocol",
|
||||
[NfcCliApduErrorWrongCrc] = "Wrong CRC",
|
||||
[NfcCliApduErrorNotPresent] = "No card",
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NfcCliProtocolRequestTypeNormalExecute,
|
||||
NfcCliProtocolRequestTypeAbort,
|
||||
} NfcCliProtocolRequestType;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* data;
|
||||
size_t size;
|
||||
} NfcCliApduData;
|
||||
|
||||
static void ApduItem_init(NfcCliApduData* item) {
|
||||
item->size = 0;
|
||||
item->data = NULL;
|
||||
}
|
||||
|
||||
static void ApduItem_init_set(NfcCliApduData* item, const NfcCliApduData* src) {
|
||||
item->data = malloc(src->size);
|
||||
item->size = src->size;
|
||||
memcpy(item->data, src->data, src->size);
|
||||
}
|
||||
|
||||
static void ApduItem_set(NfcCliApduData* item, const NfcCliApduData* src) {
|
||||
if(item->data == NULL) {
|
||||
item->data = malloc(src->size);
|
||||
} else if(item->size != src->size) {
|
||||
uint8_t* buf = realloc(item->data, src->size);
|
||||
furi_check(buf);
|
||||
item->data = buf;
|
||||
}
|
||||
|
||||
item->size = src->size;
|
||||
memcpy(item->data, src->data, src->size);
|
||||
}
|
||||
|
||||
static void ApduItem_clear(NfcCliApduData* item) {
|
||||
if(item->data) free(item->data);
|
||||
item->data = NULL;
|
||||
item->size = 0;
|
||||
}
|
||||
|
||||
ARRAY_DEF(
|
||||
NfcCliApduItemArray,
|
||||
NfcCliApduData,
|
||||
(INIT(API_2(ApduItem_init)),
|
||||
SET(API_6(ApduItem_set)),
|
||||
INIT_SET(API_6(ApduItem_init_set)),
|
||||
CLEAR(API_2(ApduItem_clear))))
|
||||
|
||||
typedef struct {
|
||||
Nfc* nfc;
|
||||
bool auto_detect;
|
||||
NfcCliApduItemArray_t apdu;
|
||||
NfcCliApduRequestResponse data;
|
||||
FuriSemaphore* sem_done;
|
||||
FuriMessageQueue* input_queue;
|
||||
} NfcCliApduContext;
|
||||
|
||||
static NfcCliActionContext* nfc_cli_apdu_alloc_ctx(Nfc* nfc) {
|
||||
furi_assert(nfc);
|
||||
NfcCliApduContext* instance = malloc(sizeof(NfcCliApduContext));
|
||||
instance->nfc = nfc;
|
||||
instance->data.protocol = NfcProtocolInvalid;
|
||||
instance->auto_detect = true;
|
||||
NfcCliApduItemArray_init(instance->apdu);
|
||||
instance->data.rx_buffer = bit_buffer_alloc(NFC_CLI_PROTOCOL_SUPPORT_MAX_BUFFER_SIZE);
|
||||
instance->data.tx_buffer = bit_buffer_alloc(NFC_CLI_PROTOCOL_SUPPORT_MAX_BUFFER_SIZE);
|
||||
|
||||
instance->sem_done = furi_semaphore_alloc(1, 0);
|
||||
instance->input_queue = furi_message_queue_alloc(1, sizeof(NfcCliProtocolRequestType));
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void nfc_cli_apdu_free_ctx(NfcCliActionContext* action_ctx) {
|
||||
furi_assert(action_ctx);
|
||||
NfcCliApduContext* instance = action_ctx;
|
||||
|
||||
instance->nfc = NULL;
|
||||
NfcCliApduItemArray_clear(instance->apdu);
|
||||
|
||||
bit_buffer_free(instance->data.rx_buffer);
|
||||
bit_buffer_free(instance->data.tx_buffer);
|
||||
furi_semaphore_free(instance->sem_done);
|
||||
furi_message_queue_free(instance->input_queue);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
static inline void nfc_cli_apdu_print_result(const NfcCliApduContext* instance) {
|
||||
nfc_cli_printf_array(
|
||||
bit_buffer_get_data(instance->data.tx_buffer),
|
||||
bit_buffer_get_size_bytes(instance->data.tx_buffer),
|
||||
"\r\nTx: ");
|
||||
|
||||
if(instance->data.result != NfcCliApduErrorNone)
|
||||
printf("\r\nError: \"%s\"\r\n", raw_error_names[instance->data.result]);
|
||||
|
||||
size_t rx_size = bit_buffer_get_size_bytes(instance->data.rx_buffer);
|
||||
if(rx_size > 0) {
|
||||
nfc_cli_printf_array(
|
||||
bit_buffer_get_data(instance->data.rx_buffer),
|
||||
bit_buffer_get_size_bytes(instance->data.rx_buffer),
|
||||
"\r\nRx: ");
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
static NfcProtocol nfc_cli_apdu_protocol_autodetect(Nfc* nfc) {
|
||||
const NfcProtocol supported_protocols[] = {
|
||||
NfcProtocolIso14443_4a,
|
||||
NfcProtocolIso14443_4b,
|
||||
NfcProtocolIso15693_3,
|
||||
};
|
||||
|
||||
const char* supported_names[] = {"Iso14443_4a", "Iso14443_4b", "Iso15693_3"};
|
||||
|
||||
NfcProtocol protocol = NfcProtocolInvalid;
|
||||
for(uint8_t i = 0; i < COUNT_OF(supported_protocols); i++) {
|
||||
NfcPoller* poller = nfc_poller_alloc(nfc, supported_protocols[i]);
|
||||
bool is_detected = nfc_poller_detect(poller);
|
||||
nfc_poller_free(poller);
|
||||
if(is_detected) {
|
||||
protocol = supported_protocols[i];
|
||||
printf("Detected tag: %s\r\n", supported_names[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return protocol;
|
||||
}
|
||||
|
||||
static NfcCliApduProtocolHandler nfc_cli_apdu_poller_get_handler(NfcProtocol protocol) {
|
||||
if(protocol == NfcProtocolIso14443_4a)
|
||||
return nfc_cli_apdu_iso14443_4a_handler;
|
||||
else if(protocol == NfcProtocolIso14443_4b)
|
||||
return nfc_cli_apdu_iso14443_4b_handler;
|
||||
else if(protocol == NfcProtocolIso15693_3)
|
||||
return nfc_cli_apdu_iso15693_3_handler;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static NfcCommand nfc_cli_apdu_poller_callback(NfcGenericEvent event, void* context) {
|
||||
NfcCliApduContext* instance = context;
|
||||
|
||||
FURI_LOG_D(TAG, "Poller callback");
|
||||
NfcCliProtocolRequestType request_type = NfcCliProtocolRequestTypeAbort;
|
||||
furi_message_queue_get(instance->input_queue, &request_type, FuriWaitForever);
|
||||
|
||||
NfcCommand command = NfcCommandStop;
|
||||
if(request_type == NfcCliProtocolRequestTypeAbort) {
|
||||
FURI_LOG_D(TAG, "Aborting poller callback");
|
||||
} else {
|
||||
NfcCliApduProtocolHandler handler =
|
||||
nfc_cli_apdu_poller_get_handler(instance->data.protocol);
|
||||
if(handler) command = handler(event, &instance->data);
|
||||
}
|
||||
furi_semaphore_release(instance->sem_done);
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_cli_apdu_execute(PipeSide* pipe, void* context) {
|
||||
UNUSED(pipe);
|
||||
furi_assert(context);
|
||||
NfcCliApduContext* instance = context;
|
||||
|
||||
if(instance->auto_detect) {
|
||||
instance->data.protocol = nfc_cli_apdu_protocol_autodetect(instance->nfc);
|
||||
}
|
||||
|
||||
if(instance->data.protocol != NfcProtocolInvalid) {
|
||||
NfcPoller* poller = nfc_poller_alloc(instance->nfc, instance->data.protocol);
|
||||
|
||||
NfcCliProtocolRequestType request_type = NfcCliProtocolRequestTypeNormalExecute;
|
||||
nfc_poller_start(poller, nfc_cli_apdu_poller_callback, instance);
|
||||
|
||||
NfcCliApduItemArray_it_t it;
|
||||
for(NfcCliApduItemArray_it(it, instance->apdu); !NfcCliApduItemArray_end_p(it);
|
||||
NfcCliApduItemArray_next(it)) {
|
||||
const NfcCliApduData* item = NfcCliApduItemArray_cref(it);
|
||||
bit_buffer_copy_bytes(instance->data.tx_buffer, item->data, item->size);
|
||||
bit_buffer_reset(instance->data.rx_buffer);
|
||||
|
||||
furi_message_queue_put(instance->input_queue, &request_type, FuriWaitForever);
|
||||
furi_semaphore_acquire(instance->sem_done, FuriWaitForever);
|
||||
nfc_cli_apdu_print_result(instance);
|
||||
if(instance->data.result != NfcCliApduErrorNone) break;
|
||||
}
|
||||
|
||||
request_type = NfcCliProtocolRequestTypeAbort;
|
||||
furi_message_queue_put(instance->input_queue, &request_type, FuriWaitForever);
|
||||
nfc_poller_stop(poller);
|
||||
nfc_poller_free(poller);
|
||||
}
|
||||
}
|
||||
|
||||
static const NfcProtocolNameValuePair supported_protocols[] = {
|
||||
{.name = "4a", .value = NfcProtocolIso14443_4a},
|
||||
{.name = "4b", .value = NfcProtocolIso14443_4b},
|
||||
{.name = "15", .value = NfcProtocolIso15693_3},
|
||||
};
|
||||
|
||||
static bool nfc_cli_apdu_parse_protocol(FuriString* value, void* output) {
|
||||
NfcCliApduContext* ctx = output;
|
||||
ctx->auto_detect = false;
|
||||
|
||||
NfcCliProtocolParser* parser =
|
||||
nfc_cli_protocol_parser_alloc(supported_protocols, COUNT_OF(supported_protocols));
|
||||
|
||||
bool result = nfc_cli_protocol_parser_get(parser, value, &ctx->data.protocol);
|
||||
|
||||
nfc_cli_protocol_parser_free(parser);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool nfc_cli_apdu_parse_data(FuriString* value, void* output) {
|
||||
NfcCliApduContext* ctx = output;
|
||||
|
||||
bool result = false;
|
||||
FuriString* word = furi_string_alloc();
|
||||
|
||||
while(args_read_string_and_trim(value, word)) {
|
||||
size_t len = furi_string_size(word);
|
||||
if(len % 2 != 0) break;
|
||||
|
||||
size_t data_length = len / 2;
|
||||
|
||||
const size_t max_len = UINT16_MAX;
|
||||
if(data_length > max_len) {
|
||||
printf(
|
||||
ANSI_FG_RED "\r\nData payload is too long, max length = %d bytes\r\n" ANSI_RESET,
|
||||
max_len);
|
||||
break;
|
||||
}
|
||||
|
||||
NfcCliApduData* item = NfcCliApduItemArray_push_new(ctx->apdu);
|
||||
item->size = data_length;
|
||||
item->data = malloc(data_length);
|
||||
result = args_read_hex_bytes(word, item->data, item->size);
|
||||
}
|
||||
furi_string_free(word);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const NfcCliKeyDescriptor apdu_keys[] = {
|
||||
{
|
||||
.long_name = "protocol",
|
||||
.short_name = "p",
|
||||
.description = "set protocol (4a, 4b, 15) directly, otherwise autodetected",
|
||||
.features = {.parameter = true, .required = false},
|
||||
.parse = nfc_cli_apdu_parse_protocol,
|
||||
},
|
||||
{
|
||||
.long_name = "data",
|
||||
.short_name = "d",
|
||||
.description = "apdu payloads in format p1 p2 p3",
|
||||
.features = {.parameter = true, .multivalue = true, .required = true},
|
||||
.parse = nfc_cli_apdu_parse_data,
|
||||
},
|
||||
};
|
||||
|
||||
const NfcCliActionDescriptor apdu_action = {
|
||||
.name = "apdu",
|
||||
.description = "Send APDU data to iso14443_4a, iso14443_4b or iso15693_3",
|
||||
.alloc = nfc_cli_apdu_alloc_ctx,
|
||||
.free = nfc_cli_apdu_free_ctx,
|
||||
.execute = nfc_cli_apdu_execute,
|
||||
.key_count = COUNT_OF(apdu_keys),
|
||||
.keys = apdu_keys,
|
||||
};
|
||||
|
||||
const NfcCliActionDescriptor* apdu_actions_collection[] = {&apdu_action};
|
||||
|
||||
//Command descriptor
|
||||
ADD_NFC_CLI_COMMAND(apdu, "", apdu_actions_collection);
|
||||
|
||||
//Command usage: apdu <protocol> <data>
|
||||
//Command examples:
|
||||
//apdu -d 00a404000e325041592e5359532e444446303100 00A4040008A000000333010102
|
||||
//apdu -p 4a -d 00a404000e325041592e5359532e444446303100 00A4040008A000000333010102
|
||||
//apdu -p 4b -d 00a404000e325041592e5359532e444446303100 00A4040008A000000333010102
|
||||
//apdu -p 15 -d 00a404000e325041592e5359532e444446303100 00A4040008A000000333010102
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../nfc_cli_command_base_i.h"
|
||||
|
||||
extern const NfcCliCommandDescriptor apdu_cmd;
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "nfc_cli_apdu_iso14443_4a.h"
|
||||
#include "../../../helpers/nfc_cli_format.h"
|
||||
|
||||
#include <nfc/protocols/iso14443_4a/iso14443_4a.h>
|
||||
#include <nfc/protocols/iso14443_4a/iso14443_4a_poller.h>
|
||||
|
||||
#define TAG "ISO14A_4A"
|
||||
|
||||
#define BIT_BUFFER_EMPTY(buffer) ((bit_buffer_get_size_bytes(buffer) == 0))
|
||||
|
||||
static NfcCliApduError nfc_cli_apdu_iso14443_4a_process_error(Iso14443_4aError error) {
|
||||
switch(error) {
|
||||
case Iso14443_4aErrorNone:
|
||||
return NfcCliApduErrorNone;
|
||||
case Iso14443_4aErrorTimeout:
|
||||
return NfcCliApduErrorTimeout;
|
||||
case Iso14443_4aErrorNotPresent:
|
||||
return NfcCliApduErrorNotPresent;
|
||||
default:
|
||||
return NfcCliApduErrorProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
NfcCommand
|
||||
nfc_cli_apdu_iso14443_4a_handler(NfcGenericEvent event, NfcCliApduRequestResponse* instance) {
|
||||
Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) {
|
||||
Iso14443_4aError err = iso14443_4a_poller_send_block(
|
||||
event.instance, instance->tx_buffer, instance->rx_buffer);
|
||||
instance->result = nfc_cli_apdu_iso14443_4a_process_error(err);
|
||||
if(err != Iso14443_4aErrorNone) command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_apdu_common_types.h"
|
||||
|
||||
NfcCommand
|
||||
nfc_cli_apdu_iso14443_4a_handler(NfcGenericEvent event, NfcCliApduRequestResponse* instance);
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "nfc_cli_apdu_iso14443_4b.h"
|
||||
#include "../../../helpers/nfc_cli_format.h"
|
||||
|
||||
#include <nfc/protocols/iso14443_4b/iso14443_4b.h>
|
||||
#include <nfc/protocols/iso14443_4b/iso14443_4b_poller.h>
|
||||
|
||||
#define TAG "ISO14A_4B"
|
||||
|
||||
#define BIT_BUFFER_EMPTY(buffer) ((bit_buffer_get_size_bytes(buffer) == 0))
|
||||
|
||||
static NfcCliApduError nfc_cli_apdu_iso14443_4b_process_error(Iso14443_4bError error) {
|
||||
switch(error) {
|
||||
case Iso14443_4bErrorNone:
|
||||
return NfcCliApduErrorNone;
|
||||
case Iso14443_4bErrorTimeout:
|
||||
return NfcCliApduErrorTimeout;
|
||||
case Iso14443_4bErrorNotPresent:
|
||||
return NfcCliApduErrorNotPresent;
|
||||
default:
|
||||
return NfcCliApduErrorProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
NfcCommand
|
||||
nfc_cli_apdu_iso14443_4b_handler(NfcGenericEvent event, NfcCliApduRequestResponse* instance) {
|
||||
Iso14443_4bPollerEvent* iso14443_4b_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeReady) {
|
||||
Iso14443_4bError err = iso14443_4b_poller_send_block(
|
||||
event.instance, instance->tx_buffer, instance->rx_buffer);
|
||||
instance->result = nfc_cli_apdu_iso14443_4b_process_error(err);
|
||||
if(err != Iso14443_4bErrorNone) command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_apdu_common_types.h"
|
||||
|
||||
NfcCommand
|
||||
nfc_cli_apdu_iso14443_4b_handler(NfcGenericEvent event, NfcCliApduRequestResponse* instance);
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "nfc_cli_apdu_iso15693_3.h"
|
||||
#include "../../../helpers/nfc_cli_format.h"
|
||||
|
||||
#include <nfc/protocols/iso15693_3/iso15693_3.h>
|
||||
#include <nfc/protocols/iso15693_3/iso15693_3_poller.h>
|
||||
|
||||
#define TAG "ISO15"
|
||||
|
||||
#define BIT_BUFFER_EMPTY(buffer) ((bit_buffer_get_size_bytes(buffer) == 0))
|
||||
|
||||
static NfcCliApduError nfc_cli_apdu_iso15693_3_process_error(Iso15693_3Error error) {
|
||||
switch(error) {
|
||||
case Iso15693_3ErrorNone:
|
||||
return NfcCliApduErrorNone;
|
||||
case Iso15693_3ErrorTimeout:
|
||||
return NfcCliApduErrorTimeout;
|
||||
case Iso15693_3ErrorNotPresent:
|
||||
return NfcCliApduErrorNotPresent;
|
||||
default:
|
||||
return NfcCliApduErrorProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
NfcCommand
|
||||
nfc_cli_apdu_iso15693_3_handler(NfcGenericEvent event, NfcCliApduRequestResponse* instance) {
|
||||
Iso15693_3PollerEvent* iso15693_3_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(iso15693_3_event->type == Iso15693_3PollerEventTypeReady) {
|
||||
Iso15693_3Error err = iso15693_3_poller_send_frame(
|
||||
event.instance, instance->tx_buffer, instance->rx_buffer, ISO15693_3_FDT_POLL_FC);
|
||||
instance->result = nfc_cli_apdu_iso15693_3_process_error(err);
|
||||
if(err != Iso15693_3ErrorNone) command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../nfc_cli_apdu_common_types.h"
|
||||
|
||||
NfcCommand
|
||||
nfc_cli_apdu_iso15693_3_handler(NfcGenericEvent event, NfcCliApduRequestResponse* instance);
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc_poller.h>
|
||||
|
||||
typedef enum {
|
||||
NfcCliApduErrorNone,
|
||||
NfcCliApduErrorTimeout,
|
||||
NfcCliApduErrorNotPresent,
|
||||
NfcCliApduErrorWrongCrc,
|
||||
NfcCliApduErrorProtocol,
|
||||
} NfcCliApduError;
|
||||
|
||||
typedef struct {
|
||||
NfcProtocol protocol;
|
||||
BitBuffer* tx_buffer;
|
||||
BitBuffer* rx_buffer;
|
||||
NfcCliApduError result;
|
||||
} NfcCliApduRequestResponse;
|
||||
Reference in New Issue
Block a user