소스 검색

Merge passy from https://github.com/bettse/passy

Willy-JL 9 달 전
부모
커밋
5347f915fc
8개의 변경된 파일148개의 추가작업 그리고 48개의 파일을 삭제
  1. 2 0
      passy/.catalog/README.md
  2. 2 0
      passy/.catalog/changelog.md
  3. 2 0
      passy/README.md
  4. 1 1
      passy/application.fam
  5. 3 0
      passy/passy_i.h
  6. 90 42
      passy/passy_reader.c
  7. 2 0
      passy/passy_reader.h
  8. 46 5
      passy/scenes/passy_scene_read.c

+ 2 - 0
passy/.catalog/README.md

@@ -2,6 +2,8 @@
 ## Tested with the following countries:
 🇺🇸
 🇨🇱
+🇫🇷
+🇬🇧
 
 (If it works for yours, submit a PR to add your country flag)
 

+ 2 - 0
passy/.catalog/changelog.md

@@ -1,3 +1,5 @@
+## 1.1
+ - ISO14443a-4 support for French passports (Thanks @luu176)
 ## 1.0
  - Better DG1 parsing
  - Added reading DG2 and saving photo

+ 2 - 0
passy/README.md

@@ -3,6 +3,8 @@
 ## Tested with the following countries:
 🇺🇸
 🇨🇱
+🇫🇷
+🇬🇧
 
 (If it works for yours, submit a PR to add your country flag)
 

+ 1 - 1
passy/application.fam

@@ -8,7 +8,7 @@ App(
     stack_size=2 * 1024,
     fap_category="NFC",
     # Optional values
-    fap_version="1.0",
+    fap_version="1.1",
     fap_icon="passy.png",  # 10x10 1-bit PNG
     fap_description="eMRTD Reader",
     fap_author="bettse",

+ 3 - 0
passy/passy_i.h

@@ -23,6 +23,7 @@
 #include <lib/nfc/nfc.h>
 #include <nfc/nfc_listener.h>
 #include <nfc/nfc_poller.h>
+#include <nfc/nfc_scanner.h>
 #include <nfc/nfc_device.h>
 
 /* generated by fbt from .png files in images folder */
@@ -76,6 +77,7 @@ struct Passy {
     DialogsApp* dialogs;
 
     Nfc* nfc;
+    NfcScanner* scanner;
     NfcListener* listener;
     NfcPoller* poller;
     NfcDevice* nfc_device;
@@ -97,6 +99,7 @@ struct Passy {
     size_t bytes_total;
 
     uint16_t last_sw;
+    const char* proto;
 };
 
 typedef enum {

+ 90 - 42
passy/passy_reader.c

@@ -88,16 +88,29 @@ void passy_reader_free(PassyReader* passy_reader) {
 
 NfcCommand passy_reader_send(PassyReader* passy_reader) {
     NfcCommand ret = NfcCommandContinue;
+    Passy* passy = passy_reader->passy;
     BitBuffer* tx_buffer = passy_reader->tx_buffer;
     BitBuffer* rx_buffer = passy_reader->rx_buffer;
-    Iso14443_4bPoller* iso14443_4b_poller = passy_reader->iso14443_4b_poller;
-    Iso14443_4bError error;
-
-    // passy_log_bitbuffer(TAG, "NFC transmit", tx_buffer);
-    error = iso14443_4b_poller_send_block(iso14443_4b_poller, tx_buffer, rx_buffer);
-    if(error != Iso14443_4bErrorNone) {
-        FURI_LOG_W(TAG, "iso14443_4b_poller_send_block error %d", error);
-        return NfcCommandStop;
+    if(strcmp(passy->proto, "4a") == 0) {
+        Iso14443_4aPoller* iso14443_4a_poller = passy_reader->iso14443_4a_poller;
+        Iso14443_4aError error;
+
+        // passy_log_bitbuffer(TAG, "NFC transmit", tx_buffer);
+        error = iso14443_4a_poller_send_block(iso14443_4a_poller, tx_buffer, rx_buffer);
+        if(error != Iso14443_4aErrorNone) {
+            FURI_LOG_W(TAG, "iso14443_4a_poller_send_block error %d", error);
+            return NfcCommandStop;
+        }
+    } else {
+        Iso14443_4bPoller* iso14443_4b_poller = passy_reader->iso14443_4b_poller;
+        Iso14443_4bError error;
+
+        // passy_log_bitbuffer(TAG, "NFC transmit", tx_buffer);
+        error = iso14443_4b_poller_send_block(iso14443_4b_poller, tx_buffer, rx_buffer);
+        if(error != Iso14443_4bErrorNone) {
+            FURI_LOG_W(TAG, "iso14443_4b_poller_send_block error %d", error);
+            return NfcCommandStop;
+        }
     }
     bit_buffer_reset(tx_buffer);
     // passy_log_bitbuffer(TAG, "NFC response", rx_buffer);
@@ -467,43 +480,78 @@ NfcCommand passy_reader_state_machine(PassyReader* passy_reader) {
 }
 
 NfcCommand passy_reader_poller_callback(NfcGenericEvent event, void* context) {
-    furi_assert(event.protocol == NfcProtocolIso14443_4b);
     PassyReader* passy_reader = context;
     NfcCommand ret = NfcCommandContinue;
-
-    const Iso14443_4bPollerEvent* iso14443_4b_event = event.event_data;
-    Iso14443_4bPoller* iso14443_4b_poller = event.instance;
-
-    FURI_LOG_D(TAG, "iso14443_4b_event->type %i", iso14443_4b_event->type);
-
-    passy_reader->iso14443_4b_poller = iso14443_4b_poller;
-
-    if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeReady) {
-        view_dispatcher_send_custom_event(
-            passy_reader->passy->view_dispatcher, PassyCustomEventReaderDetected);
-        nfc_device_set_data(
-            passy_reader->passy->nfc_device,
-            NfcProtocolIso14443_4b,
-            nfc_poller_get_data(passy_reader->passy->poller));
-
-        ret = passy_reader_state_machine(passy_reader);
-
-        furi_thread_set_current_priority(FuriThreadPriorityLowest);
-    } else if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeError) {
-        Iso14443_4bPollerEventData* data = iso14443_4b_event->data;
-        Iso14443_4bError error = data->error;
-        FURI_LOG_W(TAG, "Iso14443_4bError %i", error);
-        switch(error) {
-        case Iso14443_4bErrorNone:
-            break;
-        case Iso14443_4bErrorNotPresent:
-            break;
-        case Iso14443_4bErrorProtocol:
-            ret = NfcCommandStop;
-            break;
-        case Iso14443_4bErrorTimeout:
-            break;
+    Passy* passy = passy_reader->passy;
+    if(strcmp(passy->proto, "4a") == 0) {
+        furi_assert(event.protocol == NfcProtocolIso14443_4a);
+        const Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data;
+        Iso14443_4aPoller* iso14443_4a_poller = event.instance;
+
+        FURI_LOG_D(TAG, "iso14443_4a_event->type %i", iso14443_4a_event->type);
+
+        passy_reader->iso14443_4a_poller = iso14443_4a_poller;
+        if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) {
+            nfc_device_set_data(
+                passy_reader->passy->nfc_device,
+                NfcProtocolIso14443_4a,
+                nfc_poller_get_data(passy_reader->passy->poller));
+
+            ret = passy_reader_state_machine(passy_reader);
+
+            furi_thread_set_current_priority(FuriThreadPriorityLowest);
+        } else if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeError) {
+            Iso14443_4aPollerEventData* data = iso14443_4a_event->data;
+            Iso14443_4aError error = data->error;
+            FURI_LOG_W(TAG, "Iso14443_4aError %i", error);
+            switch(error) {
+            case Iso14443_4aErrorNone:
+                break;
+            case Iso14443_4aErrorNotPresent:
+                break;
+            case Iso14443_4aErrorProtocol:
+                ret = NfcCommandStop;
+                break;
+            case Iso14443_4aErrorTimeout:
+                break;
+            }
+        }
+    } else if(strcmp(passy->proto, "4b") == 0) {
+        furi_assert(event.protocol == NfcProtocolIso14443_4b);
+        const Iso14443_4bPollerEvent* iso14443_4b_event = event.event_data;
+        Iso14443_4bPoller* iso14443_4b_poller = event.instance;
+
+        FURI_LOG_D(TAG, "iso14443_4b_event->type %i", iso14443_4b_event->type);
+
+        passy_reader->iso14443_4b_poller = iso14443_4b_poller;
+
+        if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeReady) {
+            nfc_device_set_data(
+                passy_reader->passy->nfc_device,
+                NfcProtocolIso14443_4b,
+                nfc_poller_get_data(passy_reader->passy->poller));
+
+            ret = passy_reader_state_machine(passy_reader);
+
+            furi_thread_set_current_priority(FuriThreadPriorityLowest);
+        } else if(iso14443_4b_event->type == Iso14443_4bPollerEventTypeError) {
+            Iso14443_4bPollerEventData* data = iso14443_4b_event->data;
+            Iso14443_4bError error = data->error;
+            FURI_LOG_W(TAG, "Iso14443_4bError %i", error);
+            switch(error) {
+            case Iso14443_4bErrorNone:
+                break;
+            case Iso14443_4bErrorNotPresent:
+                break;
+            case Iso14443_4bErrorProtocol:
+                ret = NfcCommandStop;
+                break;
+            case Iso14443_4bErrorTimeout:
+                break;
+            }
         }
+    } else {
+        view_dispatcher_send_custom_event(passy->view_dispatcher, PassyCustomEventReaderError);
     }
 
     return ret;

+ 2 - 0
passy/passy_reader.h

@@ -6,6 +6,7 @@
 #include <nfc/nfc_device.h>
 #include <lib/nfc/protocols/nfc_generic_event.h>
 #include <lib/nfc/protocols/iso14443_4b/iso14443_4b_poller.h>
+#include <lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h>
 #include <lib/nfc/helpers/iso14443_crc.h>
 #include <mbedtls/des.h>
 
@@ -24,6 +25,7 @@ typedef struct {
     Passy* passy;
 
     Iso14443_4bPoller* iso14443_4b_poller;
+    Iso14443_4aPoller* iso14443_4a_poller;
     BitBuffer* tx_buffer;
     BitBuffer* rx_buffer;
 

+ 46 - 5
passy/scenes/passy_scene_read.c

@@ -6,6 +6,24 @@
 
 static PassyReader* passy_reader = NULL;
 
+void passy_scene_detect_scan_callback(NfcScannerEvent event, void* context) {
+    furi_assert(context);
+    Passy* passy = context;
+
+    // detect the type of protocol, either 4a/4b and then run the specific poller callback functions yada yada yada
+    if(event.type == NfcScannerEventTypeDetected) {
+        if(event.data.protocols && *event.data.protocols == NfcProtocolIso14443_4a) {
+            passy->proto = "4a";
+        } else if(event.data.protocols && *event.data.protocols == NfcProtocolIso14443_4b) {
+            passy->proto = "4b";
+        } else {
+            passy->proto = "";
+            // just continue as expected..
+        }
+        view_dispatcher_send_custom_event(passy->view_dispatcher, PassyCustomEventReaderDetected);
+    }
+}
+
 void passy_scene_read_on_enter(void* context) {
     Passy* passy = context;
     dolphin_deed(DolphinDeedNfcRead);
@@ -14,11 +32,9 @@ void passy_scene_read_on_enter(void* context) {
     Popup* popup = passy->popup;
     popup_set_header(popup, "Reading", 68, 30, AlignLeft, AlignTop);
     popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
-
-    passy->poller = nfc_poller_alloc(passy->nfc, NfcProtocolIso14443_4b);
-    passy_reader = passy_reader_alloc(passy);
-    nfc_poller_start(passy->poller, passy_reader_poller_callback, passy_reader);
-    passy->bytes_total = 0;
+    passy->scanner = nfc_scanner_alloc(passy->nfc);
+    nfc_scanner_start(
+        passy->scanner, passy_scene_detect_scan_callback, passy); // starts a scanner instance
 
     passy_blink_start(passy);
 
@@ -43,6 +59,26 @@ bool passy_scene_read_on_event(void* context, SceneManagerEvent event) {
             scene_manager_next_scene(passy->scene_manager, PassySceneReadError);
             consumed = true;
         } else if(event.event == PassyCustomEventReaderDetected) {
+            nfc_scanner_stop(passy->scanner);
+            nfc_scanner_free(passy->scanner);
+            passy->scanner = NULL;
+            if(strcmp(passy->proto, "4b") == 0) {
+                FURI_LOG_I(TAG, "detected 4B protocol");
+                passy->poller = nfc_poller_alloc(passy->nfc, NfcProtocolIso14443_4b);
+                passy_reader = passy_reader_alloc(passy);
+                FURI_LOG_I(TAG, "mhm");
+                nfc_poller_start(passy->poller, passy_reader_poller_callback, passy_reader);
+                passy->bytes_total = 0;
+            } else if(strcmp(passy->proto, "4a") == 0) {
+                FURI_LOG_I(TAG, "detected 4A protocol");
+                passy->poller = nfc_poller_alloc(passy->nfc, NfcProtocolIso14443_4a);
+                passy_reader = passy_reader_alloc(passy);
+                nfc_poller_start(passy->poller, passy_reader_poller_callback, passy_reader);
+                passy->bytes_total = 0;
+            } else {
+                view_dispatcher_send_custom_event(
+                    passy->view_dispatcher, PassyCustomEventReaderError);
+            }
             popup_set_header(popup, "Detected", 68, 30, AlignLeft, AlignTop);
         } else if(event.event == PassyCustomEventReaderAuthenticated) {
             popup_set_header(popup, "Authenticated", 68, 30, AlignLeft, AlignTop);
@@ -82,6 +118,11 @@ void passy_scene_read_on_exit(void* context) {
         nfc_poller_free(passy->poller);
         passy->poller = NULL;
     }
+    if(passy->scanner) {
+        nfc_scanner_stop(passy->scanner);
+        nfc_scanner_free(passy->scanner);
+        passy->scanner = NULL;
+    }
 
     // Clear view
     popup_reset(passy->popup);