MX 2 лет назад
Родитель
Сommit
3ef7e9e721
4 измененных файлов с 44 добавлено и 34 удалено
  1. 1 1
      application.fam
  2. 34 29
      sam_api.c
  3. 3 0
      scenes/seader_scene_read_card_success.c
  4. 6 4
      seader_worker.c

+ 1 - 1
application.fam

@@ -17,7 +17,7 @@ App(
     ],
     fap_icon="icons/logo.png",
     fap_category="NFC",
-    fap_version="1.3",
+    fap_version="2.0",
     fap_author="bettse",
 #    fap_extbuild=(
 #        ExtFile(

+ 34 - 29
sam_api.c

@@ -7,10 +7,6 @@
 #define ASN1_PREFIX 6
 #define ASN1_DEBUG true
 
-#ifdef ASN1_DEBUG
-char payloadDebug[384] = {0};
-#endif
-
 static char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
 char asn1_log[SEADER_UART_RX_BUF_SIZE] = {0};
 bool requestPacs = true;
@@ -32,7 +28,7 @@ bool seader_send_apdu(
         return false;
     }
 
-    uint8_t* apdu = malloc(APDU_HEADER_LEN + length);
+    uint8_t apdu[SEADER_UART_RX_BUF_SIZE];
     apdu[0] = CLA;
     apdu[1] = INS;
     apdu[2] = P1;
@@ -41,11 +37,10 @@ bool seader_send_apdu(
     memcpy(apdu + APDU_HEADER_LEN, payload, length);
 
     seader_ccid_XfrBlock(seader_uart, apdu, APDU_HEADER_LEN + length);
-    free(apdu);
     return true;
 }
 
-static int seader_asn_to_string(const void* buffer, size_t size, void* app_key) {
+static int seader_print_struct_callback(const void* buffer, size_t size, void* app_key) {
     if(app_key) {
         char* str = (char*)app_key;
         size_t next = strlen(str);
@@ -70,9 +65,11 @@ void seader_send_payload(
 
 #ifdef ASN1_DEBUG
     if(er.encoded > -1) {
+        char payloadDebug[384] = {0};
         memset(payloadDebug, 0, sizeof(payloadDebug));
         (&asn_DEF_Payload)
-            ->op->print_struct(&asn_DEF_Payload, payload, 1, seader_asn_to_string, payloadDebug);
+            ->op->print_struct(
+                &asn_DEF_Payload, payload, 1, seader_print_struct_callback, payloadDebug);
         if(strlen(payloadDebug) > 0) {
             FURI_LOG_D(TAG, "Sending payload[%d %d %d]: %s", to, from, replyTo, payloadDebug);
         }
@@ -177,12 +174,13 @@ void seader_send_card_detected(SeaderUartBridge* seader_uart, CardDetails_t* car
 
     seader_send_payload(seader_uart, payload, 0x44, 0x0a, 0x44);
 
-    ASN_STRUCT_FREE(asn_DEF_CardDetected, cardDetected);
-    ASN_STRUCT_FREE(asn_DEF_SamCommand, samCommand);
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
+    ASN_STRUCT_FREE(asn_DEF_SamCommand, samCommand);
+    ASN_STRUCT_FREE(asn_DEF_CardDetected, cardDetected);
 }
 
-bool seader_unpack_pacs(SeaderCredential* seader_credential, uint8_t* buf, size_t size) {
+bool seader_unpack_pacs(Seader* seader, uint8_t* buf, size_t size) {
+    SeaderCredential* seader_credential = seader->credential;
     PAC_t* pac = 0;
     pac = calloc(1, sizeof *pac);
     assert(pac);
@@ -192,7 +190,8 @@ bool seader_unpack_pacs(SeaderCredential* seader_credential, uint8_t* buf, size_
 
     if(rval.code == RC_OK) {
         char pacDebug[384] = {0};
-        (&asn_DEF_PAC)->op->print_struct(&asn_DEF_PAC, pac, 1, seader_asn_to_string, pacDebug);
+        (&asn_DEF_PAC)
+            ->op->print_struct(&asn_DEF_PAC, pac, 1, seader_print_struct_callback, pacDebug);
         if(strlen(pacDebug) > 0) {
             FURI_LOG_D(TAG, "Received pac: %s", pacDebug);
 
@@ -216,6 +215,8 @@ bool seader_unpack_pacs(SeaderCredential* seader_credential, uint8_t* buf, size_
             rtn = true;
         } else {
             // PACS too big (probably bad data)
+            view_dispatcher_send_custom_event(
+                seader->view_dispatcher, SeaderCustomEventWorkerExit);
         }
     }
 
@@ -248,7 +249,7 @@ bool seader_parse_version(SeaderWorker* seader_worker, uint8_t* buf, size_t size
         char versionDebug[128] = {0};
         (&asn_DEF_SamVersion)
             ->op->print_struct(
-                &asn_DEF_SamVersion, version, 1, seader_asn_to_string, versionDebug);
+                &asn_DEF_SamVersion, version, 1, seader_print_struct_callback, versionDebug);
         if(strlen(versionDebug) > 0) {
             // FURI_LOG_D(TAG, "Received version: %s", versionDebug);
         }
@@ -266,7 +267,7 @@ bool seader_parse_version(SeaderWorker* seader_worker, uint8_t* buf, size_t size
 bool seader_parse_sam_response(Seader* seader, SamResponse_t* samResponse) {
     SeaderWorker* seader_worker = seader->worker;
     SeaderUartBridge* seader_uart = seader_worker->uart;
-    SeaderCredential* credential = seader->credential;
+    FURI_LOG_D(TAG, "seader_parse_sam_response");
 
     if(samResponse->size == 0) {
         if(requestPacs) {
@@ -274,11 +275,14 @@ bool seader_parse_sam_response(Seader* seader, SamResponse_t* samResponse) {
             sendRequestPacs(seader_uart);
             requestPacs = false;
         } else {
-            FURI_LOG_D(TAG, "samResponse %d, no action", samResponse->size);
+            FURI_LOG_D(
+                TAG, "samResponse %d, PACS already requested, pushing view", samResponse->size);
+            view_dispatcher_send_custom_event(
+                seader->view_dispatcher, SeaderCustomEventWorkerExit);
         }
     } else if(seader_parse_version(seader_worker, samResponse->buf, samResponse->size)) {
         // no-op
-    } else if(seader_unpack_pacs(credential, samResponse->buf, samResponse->size)) {
+    } else if(seader_unpack_pacs(seader, samResponse->buf, samResponse->size)) {
         view_dispatcher_send_custom_event(seader->view_dispatcher, SeaderCustomEventWorkerExit);
     } else {
         memset(display, 0, sizeof(display));
@@ -297,6 +301,7 @@ bool seader_parse_response(Seader* seader, Response_t* response) {
         seader_parse_sam_response(seader, &response->choice.samResponse);
         break;
     default:
+        FURI_LOG_D(TAG, "non-sam response");
         break;
     };
     return false;
@@ -591,6 +596,7 @@ bool seader_worker_state_machine(
     case Payload_PR_errorResponse:
         FURI_LOG_W(TAG, "Error Response");
         processed = true;
+        view_dispatcher_send_custom_event(seader->view_dispatcher, SeaderCustomEventWorkerExit);
         break;
     default:
         FURI_LOG_W(TAG, "unhandled payload");
@@ -618,12 +624,13 @@ bool seader_process_success_response_i(
 
 #ifdef ASN1_DEBUG
         if(processed) {
+            char payloadDebug[384] = {0};
             memset(payloadDebug, 0, sizeof(payloadDebug));
             (&asn_DEF_Payload)
                 ->op->print_struct(
-                    &asn_DEF_Payload, payload, 1, seader_asn_to_string, payloadDebug);
+                    &asn_DEF_Payload, payload, 1, seader_print_struct_callback, payloadDebug);
             if(strlen(payloadDebug) > 0) {
-                FURI_LOG_D(TAG, "Received payload: %s", payloadDebug);
+                FURI_LOG_D(TAG, "Payload processed: %s", payloadDebug);
             }
         }
 #endif
@@ -656,27 +663,25 @@ NfcCommand seader_worker_card_detect(
     assert(cardDetails);
 
     OCTET_STRING_fromBuf(&cardDetails->csn, (const char*)uid, uid_len);
+    OCTET_STRING_t sak_string = {.buf = &sak, .size = 1};
+    OCTET_STRING_t atqa_string = {.buf = atqa, .size = 2};
+    uint8_t protocol_bytes[] = {0x00, 0x00};
 
-    if(sak != 0 && atqa != NULL) {
-        uint8_t protocol_bytes[] = {0x00, FrameProtocol_nfc};
+    if(sak == 0 && atqa == NULL) {
+        protocol_bytes[1] = FrameProtocol_iclass;
         OCTET_STRING_fromBuf(
             &cardDetails->protocol, (const char*)protocol_bytes, sizeof(protocol_bytes));
-
-        OCTET_STRING_t sak_string = {.buf = &sak, .size = 1};
-        cardDetails->sak = &sak_string;
-
-        OCTET_STRING_t atqa_string = {.buf = atqa, .size = 2};
-        cardDetails->atqa = &atqa_string;
-
     } else {
-        uint8_t protocol_bytes[] = {0x00, FrameProtocol_iclass};
+        protocol_bytes[1] = FrameProtocol_nfc;
         OCTET_STRING_fromBuf(
             &cardDetails->protocol, (const char*)protocol_bytes, sizeof(protocol_bytes));
+
+        cardDetails->sak = &sak_string;
+        cardDetails->atqa = &atqa_string;
     }
 
     seader_send_card_detected(seader_uart, cardDetails);
 
     ASN_STRUCT_FREE(asn_DEF_CardDetails, cardDetails);
-
     return NfcCommandContinue;
 }

+ 3 - 0
scenes/seader_scene_read_card_success.c

@@ -97,6 +97,9 @@ bool seader_scene_read_card_success_on_event(void* context, SceneManagerEvent ev
             scene_manager_next_scene(seader->scene_manager, SeaderSceneCardMenu);
             consumed = true;
         }
+    } else if(event.type == SceneManagerEventTypeBack) {
+        scene_manager_search_and_switch_to_previous_scene(seader->scene_manager, SeaderSceneStart);
+        consumed = true;
     }
     return consumed;
 }

+ 6 - 4
seader_worker.c

@@ -182,6 +182,8 @@ void seader_worker_poller_conversation(Seader* seader, SeaderPollerContainer* sp
             if(status != FuriStatusOk) {
                 FURI_LOG_W(TAG, "furi_message_queue_get fail %d", status);
                 seader_worker->stage = SeaderPollerEventTypeComplete;
+                view_dispatcher_send_custom_event(
+                    seader->view_dispatcher, SeaderCustomEventWorkerExit);
             }
 
             if(seader_process_success_response_i(
@@ -231,9 +233,6 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
         } else if(seader_worker->stage == SeaderPollerEventTypeComplete) {
             ret = NfcCommandStop;
         }
-    } else {
-        // add failure callback if failure type
-        FURI_LOG_D(TAG, "14a event type %x", iso14443_4a_event->type);
     }
 
     return ret;
@@ -249,7 +248,9 @@ NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, voi
     PicopassPoller* instance = seader->picopass_poller;
     SeaderPollerContainer spc = {.picopass_poller = instance};
 
-    if(event.type == PicopassPollerEventTypeSuccess) {
+    if(event.type == PicopassPollerEventTypeCardDetected) {
+        seader_worker->stage = SeaderPollerEventTypeCardDetect;
+    } else if(event.type == PicopassPollerEventTypeSuccess) {
         if(seader_worker->stage == SeaderPollerEventTypeCardDetect) {
             uint8_t* csn = picopass_poller_get_csn(instance);
             seader_worker_card_detect(seader, 0, NULL, csn, sizeof(PicopassSerialNum), NULL, 0);
@@ -262,6 +263,7 @@ NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, voi
         }
     } else if(event.type == PicopassPollerEventTypeFail) {
         ret = NfcCommandStop;
+        FURI_LOG_W(TAG, "PicopassPollerEventTypeFail");
     } else {
         FURI_LOG_D(TAG, "picopass event type %x", event.type);
     }