فهرست منبع

Add new nfc apdu cli command (#2482)

Co-authored-by: あく <alleteam@gmail.com>
Leopold 2 سال پیش
والد
کامیت
a69ae93871
1فایلهای تغییر یافته به همراه68 افزوده شده و 0 حذف شده
  1. 68 0
      applications/main/nfc/nfc_cli.c

+ 68 - 0
applications/main/nfc/nfc_cli.c

@@ -2,6 +2,7 @@
 #include <furi_hal.h>
 #include <cli/cli.h>
 #include <lib/toolbox/args.h>
+#include <lib/toolbox/hex.h>
 
 #include <lib/nfc/nfc_types.h>
 #include <lib/nfc/nfc_device.h>
@@ -12,6 +13,7 @@ static void nfc_cli_print_usage() {
     printf("Cmd list:\r\n");
     printf("\tdetect\t - detect nfc device\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)) {
         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();
 }
 
+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) {
     UNUSED(context);
     FuriString* cmd;
@@ -117,6 +180,11 @@ static void nfc_cli(Cli* cli, FuriString* args, void* context) {
             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_string_cmp_str(cmd, "field") == 0) {
                 nfc_cli_field(cli, args);