Add new nfc apdu cli command (#2482)

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Leopold 2023-03-15 21:52:32 +08:00 committed by GitHub
parent e22668e196
commit a69ae93871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,6 +2,7 @@
#include <furi_hal.h> #include <furi_hal.h>
#include <cli/cli.h> #include <cli/cli.h>
#include <lib/toolbox/args.h> #include <lib/toolbox/args.h>
#include <lib/toolbox/hex.h>
#include <lib/nfc/nfc_types.h> #include <lib/nfc/nfc_types.h>
#include <lib/nfc/nfc_device.h> #include <lib/nfc/nfc_device.h>
@ -12,6 +13,7 @@ static void nfc_cli_print_usage() {
printf("Cmd list:\r\n"); printf("Cmd list:\r\n");
printf("\tdetect\t - detect nfc device\r\n"); printf("\tdetect\t - detect nfc device\r\n");
printf("\temulate\t - emulate predefined nfca card\r\n"); printf("\temulate\t - emulate predefined nfca card\r\n");
printf("\tapdu\t - Send APDU and print response \r\n");
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
printf("\tfield\t - turn field on\r\n"); printf("\tfield\t - turn field on\r\n");
} }
@ -98,6 +100,67 @@ static void nfc_cli_field(Cli* cli, FuriString* args) {
furi_hal_nfc_sleep(); furi_hal_nfc_sleep();
} }
static void nfc_cli_apdu(Cli* cli, FuriString* args) {
UNUSED(cli);
if(furi_hal_nfc_is_busy()) {
printf("Nfc is busy\r\n");
return;
}
furi_hal_nfc_exit_sleep();
FuriString* data = NULL;
data = furi_string_alloc();
FuriHalNfcTxRxContext tx_rx = {};
FuriHalNfcDevData dev_data = {};
uint8_t* req_buffer = NULL;
uint8_t* resp_buffer = NULL;
size_t apdu_size = 0;
size_t resp_size = 0;
do {
if(!args_read_string_and_trim(args, data)) {
printf(
"Use like `nfc apdu 00a404000e325041592e5359532e444446303100 00a4040008a0000003010102` \r\n");
break;
}
printf("detecting tag\r\n");
if(!furi_hal_nfc_detect(&dev_data, 300)) {
printf("Failed to detect tag\r\n");
break;
}
do {
apdu_size = furi_string_size(data) / 2;
req_buffer = malloc(apdu_size);
hex_chars_to_uint8(furi_string_get_cstr(data), req_buffer);
memcpy(tx_rx.tx_data, req_buffer, apdu_size);
tx_rx.tx_bits = apdu_size * 8;
tx_rx.tx_rx_type = FuriHalNfcTxRxTypeDefault;
printf("Sending APDU:%s to Tag\r\n", furi_string_get_cstr(data));
if(!furi_hal_nfc_tx_rx(&tx_rx, 300)) {
printf("Failed to tx_rx\r\n");
break;
}
resp_size = (tx_rx.rx_bits / 8) * 2;
resp_buffer = malloc(resp_size);
uint8_to_hex_chars(tx_rx.rx_data, resp_buffer, resp_size);
resp_buffer[resp_size] = 0;
printf("Response: %s\r\n", resp_buffer);
free(req_buffer);
free(resp_buffer);
req_buffer = NULL;
resp_buffer = NULL;
} while(args_read_string_and_trim(args, data));
} while(false);
free(req_buffer);
free(resp_buffer);
furi_string_free(data);
furi_hal_nfc_sleep();
}
static void nfc_cli(Cli* cli, FuriString* args, void* context) { static void nfc_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(context); UNUSED(context);
FuriString* cmd; FuriString* cmd;
@ -117,6 +180,11 @@ static void nfc_cli(Cli* cli, FuriString* args, void* context) {
break; break;
} }
if(furi_string_cmp_str(cmd, "apdu") == 0) {
nfc_cli_apdu(cli, args);
break;
}
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
if(furi_string_cmp_str(cmd, "field") == 0) { if(furi_string_cmp_str(cmd, "field") == 0) {
nfc_cli_field(cli, args); nfc_cli_field(cli, args);