Eric Betts 2 سال پیش
والد
کامیت
059fbb4540
2فایلهای تغییر یافته به همراه39 افزوده شده و 34 حذف شده
  1. 38 33
      seader_worker.c
  2. 1 1
      seader_worker_i.h

+ 38 - 33
seader_worker.c

@@ -7,7 +7,7 @@
 
 #define APDU_HEADER_LEN 5
 #define ASN1_PREFIX 6
-#define ASN1_DEBUG true
+//#define ASN1_DEBUG true
 
 #define RFAL_PICOPASS_TXRX_FLAGS                                                    \
     (FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | \
@@ -36,6 +36,7 @@ SeaderWorker* seader_worker_alloc() {
     seader_worker->thread =
         furi_thread_alloc_ex("SeaderWorker", 8192, seader_worker_task, seader_worker);
     seader_worker->messages = furi_message_queue_alloc(2, SEADER_UART_RX_BUF_SIZE);
+    seader_worker->mq_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
 
     seader_worker->callback = NULL;
     seader_worker->context = NULL;
@@ -52,6 +53,7 @@ void seader_worker_free(SeaderWorker* seader_worker) {
 
     furi_thread_free(seader_worker->thread);
     furi_message_queue_free(seader_worker->messages);
+    furi_mutex_free(seader_worker->mq_mutex);
 
     furi_record_close(RECORD_STORAGE);
 
@@ -302,7 +304,7 @@ bool seader_unpack_pacs(
         char pacDebug[384] = {0};
         (&asn_DEF_PAC)->op->print_struct(&asn_DEF_PAC, pac, 1, seader_asn_to_string, pacDebug);
         if(strlen(pacDebug) > 0) {
-            FURI_LOG_D(TAG, "Received pac: %s", pacDebug);
+            // FURI_LOG_D(TAG, "Received pac: %s", pacDebug);
 
             memset(display, 0, sizeof(display));
             if(seader_credential->sio[0] == 0x30) {
@@ -310,7 +312,7 @@ bool seader_unpack_pacs(
                     snprintf(
                         display + (i * 2), sizeof(display), "%02x", seader_credential->sio[i]);
                 }
-                FURI_LOG_D(TAG, "SIO %s", display);
+                // FURI_LOG_D(TAG, "SIO %s", display);
             }
         }
 
@@ -361,7 +363,7 @@ bool seader_parse_version(SeaderWorker* seader_worker, uint8_t* buf, size_t size
             ->op->print_struct(
                 &asn_DEF_SamVersion, version, 1, seader_asn_to_string, versionDebug);
         if(strlen(versionDebug) > 0) {
-            FURI_LOG_D(TAG, "Received version: %s", versionDebug);
+            // FURI_LOG_D(TAG, "Received version: %s", versionDebug);
         }
         if(version->version.size == 2) {
             memcpy(seader_worker->sam_version, version->version.buf, version->version.size);
@@ -400,7 +402,7 @@ bool seader_parse_sam_response(SeaderWorker* seader_worker, SamResponse_t* samRe
         for(uint8_t i = 0; i < samResponse->size; i++) {
             snprintf(display + (i * 2), sizeof(display), "%02x", samResponse->buf[i]);
         }
-        FURI_LOG_D(TAG, "unknown samResponse %d: %s", samResponse->size, display);
+        // FURI_LOG_D(TAG, "unknown samResponse %d: %s", samResponse->size, display);
     }
 
     return false;
@@ -451,7 +453,7 @@ void seader_send_nfc_rx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t l
 }
 
 /* Assumes this is called in the context of the NFC API callback */
-bool seader_iso14443a_transmit(
+NfcCommand seader_iso14443a_transmit(
     Seader* seader,
     uint8_t* buffer,
     size_t len,
@@ -459,19 +461,17 @@ bool seader_iso14443a_transmit(
     uint8_t format[3]) {
     UNUSED(timeout);
     UNUSED(format);
-    UNUSED(seader);
-    UNUSED(buffer);
-    UNUSED(len);
 
     BitBuffer* tx_buffer = bit_buffer_alloc(len);
     BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
+    NfcCommand ret = NfcCommandContinue;
 
     do {
         bit_buffer_append_bytes(tx_buffer, buffer, len);
         NfcError error = nfc_poller_trx(seader->nfc, tx_buffer, rx_buffer, SEADER_POLLER_MAX_FWT);
         if(error != NfcErrorNone) {
             FURI_LOG_W(TAG, "nfc_poller_trx error %d", error);
-            //ret = iso14443_3a_poller_process_error(error);
+            ret = NfcCommandStop;
             break;
         }
 
@@ -482,10 +482,10 @@ bool seader_iso14443a_transmit(
     bit_buffer_free(tx_buffer);
     bit_buffer_free(rx_buffer);
 
-    return true;
+    return ret;
 }
 
-bool seader_parse_nfc_command_transmit(Seader* seader, NFCSend_t* nfcSend) {
+NfcCommand seader_parse_nfc_command_transmit(Seader* seader, NFCSend_t* nfcSend) {
     long timeOut = nfcSend->timeOut;
     Protocol_t protocol = nfcSend->protocol;
     FrameProtocol_t frameProtocol = protocol.buf[1];
@@ -517,11 +517,11 @@ bool seader_parse_nfc_command_transmit(Seader* seader, NFCSend_t* nfcSend) {
         return seader_iso14443a_transmit(
             seader, nfcSend->data.buf, nfcSend->data.size, (uint16_t)timeOut, nfcSend->format->buf);
     }
-    return false;
+    return NfcCommandContinue;
 }
 
 NfcCommand seader_parse_nfc_off(SeaderUartBridge* seader_uart) {
-    FURI_LOG_D(TAG, "Set Field Off");
+    // FURI_LOG_D(TAG, "Set Field Off");
     // seader_worker_disable_field();
     // seader_nfc_scene_field_on_exit();
     // nfc_poller_stop(poller);
@@ -548,15 +548,14 @@ NfcCommand seader_parse_nfc_off(SeaderUartBridge* seader_uart) {
     return NfcCommandStop;
 }
 
-bool seader_parse_nfc_command(Seader* seader, NFCCommand_t* nfcCommand) {
+NfcCommand seader_parse_nfc_command(Seader* seader, NFCCommand_t* nfcCommand) {
     // TODO: THIS IS WHERE I WANT TO PUSH EVENTS TO MESSAGE QUEUE
 
     SeaderWorker* seader_worker = seader->worker;
     SeaderUartBridge* seader_uart = seader_worker->uart;
     switch(nfcCommand->present) {
     case NFCCommand_PR_nfcSend:
-        //seader_parse_nfc_command_transmit(seader, &nfcCommand->choice.nfcSend);
-        break;
+        return seader_parse_nfc_command_transmit(seader, &nfcCommand->choice.nfcSend);
     case NFCCommand_PR_nfcOff:
         seader_parse_nfc_off(seader_uart);
         break;
@@ -565,7 +564,7 @@ bool seader_parse_nfc_command(Seader* seader, NFCCommand_t* nfcCommand) {
         break;
     };
 
-    return false;
+    return NfcCommandContinue;
 }
 
 bool seader_worker_state_machine(Seader* seader, Payload_t* payload) {
@@ -610,6 +609,8 @@ bool seader_process_success_response_i(Seader* seader, uint8_t* apdu, size_t len
         }
 #endif
         seader_worker_state_machine(seader, payload);
+    } else {
+      FURI_LOG_D(TAG, "Failed to decode APDU payload");
     }
 
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
@@ -627,8 +628,11 @@ bool seader_process_success_response(Seader* seader, uint8_t* apdu, size_t len)
           BitBuffer* buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
           bit_buffer_append_bytes(buffer, apdu, len);
 
-          furi_message_queue_put(seader_worker->messages, buffer, SEADER_MQ_TIMEOUT);
-          bit_buffer_free(buffer);
+          if (furi_mutex_acquire(seader_worker->mq_mutex, FuriWaitForever) == FuriStatusOk) {
+            furi_message_queue_put(seader_worker->messages, buffer, FuriWaitForever);
+            furi_mutex_release(seader_worker->mq_mutex);
+          }
+          //bit_buffer_free(buffer);
       }
     } else {
       seader_process_success_response_i(seader, apdu, len);
@@ -683,13 +687,13 @@ int32_t seader_worker_task(void* context) {
     if(seader_worker->state == SeaderWorkerStateCheckSam) {
         seader_ccid_check_for_sam(seader_uart);
     } else if(seader_worker->state == SeaderWorkerStateReadPicopass) {
-        FURI_LOG_D(TAG, "Read Picopass");
+        // FURI_LOG_D(TAG, "Read Picopass");
         requestPacs = true;
         seader_credential_clear(seader_worker->credential);
         seader_worker->credential->type = SeaderCredentialTypePicopass;
         // TODO
     } else if(seader_worker->state == SeaderWorkerStateRead14a) {
-        FURI_LOG_D(TAG, "Read 14a");
+        // FURI_LOG_D(TAG, "Read 14a");
         requestPacs = true;
         seader_credential_clear(seader_worker->credential);
         seader_worker->credential->type = SeaderCredentialType14A;
@@ -699,7 +703,7 @@ int32_t seader_worker_task(void* context) {
             // seader_nfc_scene_field_on_exit();
         }
     }
-    FURI_LOG_D(TAG, "Worker Task Complete");
+    // FURI_LOG_D(TAG, "Worker Task Complete");
     seader_worker_change_state(seader_worker, SeaderWorkerStateReady);
 
     return 0;
@@ -727,7 +731,7 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
 
     if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) {
         if(stage == SeaderPollerEventTypeCardDetect) {
-            FURI_LOG_D(TAG, "Card Detect");
+            // FURI_LOG_D(TAG, "Card Detect");
             nfc_device_set_data(
                 seader->nfc_device, NfcProtocolIso14443_4a, nfc_poller_get_data(seader->poller));
 
@@ -761,17 +765,18 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
 
             stage = SeaderPollerEventTypeConversation;
         } else if(stage == SeaderPollerEventTypeConversation) {
-            UNUSED(seader_worker);
+
+          if (furi_mutex_acquire(seader_worker->mq_mutex, 0) == FuriStatusOk) {
+            furi_thread_set_current_priority(FuriThreadPriorityHighest);
             uint32_t count = furi_message_queue_get_count(seader_worker->messages);
             if(count > 0) {
-                furi_thread_set_current_priority(FuriThreadPriorityHighest);
                 FURI_LOG_D(TAG, "Conversation: %ld messages", count);
 
                 BitBuffer* message = bit_buffer_alloc(furi_message_queue_get_message_size(seader_worker->messages));
                 FuriStatus status =
-                    furi_message_queue_get(seader_worker->messages, message, SEADER_MQ_TIMEOUT);
+                    furi_message_queue_get(seader_worker->messages, message, FuriWaitForever);
                 if(status != FuriStatusOk) {
-                    FURI_LOG_D(TAG, "furi_message_queue_get fail %d", status);
+                    FURI_LOG_W(TAG, "furi_message_queue_get fail %d", status);
                     return NfcCommandStop;
                 }
                 size_t len = bit_buffer_get_size_bytes(message);
@@ -779,17 +784,17 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
                 FURI_LOG_D(TAG, "Conversation: message length %d: %p", len, payload);
 
                 seader_process_success_response_i(seader, payload, len);
-                bit_buffer_free(message);
+                //bit_buffer_free(message);
             }
-
-            furi_thread_set_current_priority(FuriThreadPriorityLowest);
-
+            furi_mutex_release(seader_worker->mq_mutex);
+          }
+          furi_thread_set_current_priority(FuriThreadPriorityLowest);
             // TESTING
             //return NfcCommandStop;
 
             //stage = SeaderPollerEventTypeComplete;
         } else if(stage == SeaderPollerEventTypeComplete) {
-            FURI_LOG_D(TAG, "Complete");
+            // FURI_LOG_D(TAG, "Complete");
             return NfcCommandStop;
         }
     }

+ 1 - 1
seader_worker_i.h

@@ -15,13 +15,13 @@
 
 #define SEADER_POLLER_MAX_FWT (200000U)
 #define SEADER_POLLER_MAX_BUFFER_SIZE (64U)
-#define SEADER_MQ_TIMEOUT FuriWaitForever
 
 struct SeaderWorker {
     FuriThread* thread;
     Storage* storage;
     uint8_t sam_version[2];
     FuriMessageQueue* messages;
+    FuriMutex* mq_mutex;
 
     SeaderUartBridge* uart;
     SeaderCredential* credential;