Eric Betts 2 лет назад
Родитель
Сommit
fc6219b766
5 измененных файлов с 83 добавлено и 65 удалено
  1. 7 11
      ccid.c
  2. 2 0
      protocol/picopass_poller.h
  3. 1 1
      protocol/picopass_poller_i.c
  4. 73 51
      seader_worker.c
  5. 0 2
      uart.c

+ 7 - 11
ccid.c

@@ -34,7 +34,7 @@ void seader_ccid_IccPowerOn(SeaderUartBridge* seader_uart, uint8_t slot) {
     }
     powered[slot] = true;
 
-    //FURI_LOG_D(TAG, "Sending Power On (%d)", slot);
+    FURI_LOG_D(TAG, "Sending Power On (%d)", slot);
     memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
     seader_uart->tx_buf[0] = SYNC;
     seader_uart->tx_buf[1] = CTRL;
@@ -56,7 +56,7 @@ void seader_ccid_check_for_sam(SeaderUartBridge* seader_uart) {
 }
 
 void seader_ccid_GetSlotStatus(SeaderUartBridge* seader_uart, uint8_t slot) {
-    //FURI_LOG_D(TAG, "seader_ccid_GetSlotStatus(%d)", slot);
+    FURI_LOG_D(TAG, "seader_ccid_GetSlotStatus(%d)", slot);
     memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
     seader_uart->tx_buf[0] = SYNC;
     seader_uart->tx_buf[1] = CTRL;
@@ -125,7 +125,7 @@ void seader_ccid_XfrBlockToSlot(
 
     memcpy(seader_uart->tx_buf + 2 + 10, data, len);
     seader_uart->tx_len = seader_ccid_add_lrc(seader_uart->tx_buf, 2 + 10 + len);
-    // FURI_LOG_I(TAG, "seader_ccid_XfrBlock %d bytes", seader_uart->tx_len);
+    FURI_LOG_I(TAG, "seader_ccid_XfrBlock %d bytes", seader_uart->tx_len);
 
     furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
 }
@@ -150,7 +150,7 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
                 // No change, no-op
                 break;
             case CARD_IN_1:
-                //FURI_LOG_D(TAG, "Card Inserted (0)");
+                FURI_LOG_D(TAG, "Card Inserted (0)");
                 if(hasSAM && sam_slot == 0) {
                     break;
                 }
@@ -159,7 +159,7 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
                 seader_ccid_IccPowerOn(seader_uart, 0);
                 break;
             case CARD_OUT_1:
-                // FURI_LOG_D(TAG, "Card Removed (0)");
+                FURI_LOG_D(TAG, "Card Removed (0)");
                 if(hasSAM && sam_slot == 0) {
                     powered[0] = false;
                     hasSAM = false;
@@ -174,7 +174,7 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
                 // No change, no-op
                 break;
             case CARD_IN_2:
-                // FURI_LOG_D(TAG, "Card Inserted (1)");
+                FURI_LOG_D(TAG, "Card Inserted (1)");
                 if(hasSAM && sam_slot == 1) {
                     break;
                 }
@@ -183,7 +183,7 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
                 seader_ccid_IccPowerOn(seader_uart, 1);
                 break;
             case CARD_OUT_2:
-                // FURI_LOG_D(TAG, "Card Removed (1)");
+                FURI_LOG_D(TAG, "Card Removed (1)");
                 if(hasSAM && sam_slot == 1) {
                     powered[1] = false;
                     hasSAM = false;
@@ -232,7 +232,6 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
         message.consumed += 2 + 10 + message.dwLength + 1;
 
         if(message.dwLength == 0) {
-            /*
             FURI_LOG_D(
                 TAG,
                 "CCID [%d|%d] type: %02x, status: %02x, error: %02x",
@@ -241,9 +240,7 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
                 message.bMessageType,
                 message.bStatus,
                 message.bError);
-                */
         } else {
-            /*
             FURI_LOG_D(
                 TAG,
                 "CCID [%d|%d] %ld: %s",
@@ -251,7 +248,6 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
                 message.bSeq,
                 message.dwLength,
                 display);
-                */
         }
 
         //0306 81 00000000 0000 0200 01 87

+ 2 - 0
protocol/picopass_poller.h

@@ -48,6 +48,8 @@ void picopass_poller_start(
 void picopass_poller_stop(PicopassPoller* instance);
 uint8_t* picopass_poller_get_csn(PicopassPoller* instance);
 
+PicopassError picopass_poller_send_frame(PicopassPoller* instance, BitBuffer* tx_buffer, BitBuffer* rx_buffer, uint32_t fwt_fc);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
protocol/picopass_poller_i.c

@@ -22,7 +22,7 @@ static PicopassError picopass_poller_process_error(NfcError error) {
     return ret;
 }
 
-static PicopassError picopass_poller_send_frame(
+PicopassError picopass_poller_send_frame(
     PicopassPoller* instance,
     BitBuffer* tx_buffer,
     BitBuffer* rx_buffer,

+ 73 - 51
seader_worker.c

@@ -382,11 +382,11 @@ bool seader_parse_sam_response(SeaderWorker* seader_worker, SamResponse_t* samRe
 
     if(samResponse->size == 0) {
         if(requestPacs) {
-            // FURI_LOG_D(TAG, "samResponse %d => requesting PACS", samResponse->size);
+            FURI_LOG_D(TAG, "samResponse %d => requesting PACS", samResponse->size);
             sendRequestPacs(seader_uart);
             requestPacs = false;
         } else {
-            // FURI_LOG_D(TAG, "samResponse %d, no action", samResponse->size);
+            FURI_LOG_D(TAG, "samResponse %d, no action", samResponse->size);
             if(seader_worker->callback) {
                 seader_worker->callback(SeaderWorkerEventFail, seader_worker->context);
             }
@@ -455,20 +455,45 @@ void seader_send_nfc_rx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t l
 NfcCommand seader_iso15693_transmit(
     Seader* seader,
     uint8_t* buffer,
-    size_t len,
-    uint16_t timeout,
-    uint8_t format[3]) {
-    UNUSED(timeout);
-    UNUSED(format);
+    size_t len) {
     UNUSED(seader);
     UNUSED(buffer);
     UNUSED(len);
+    FURI_LOG_D(TAG, "seader_iso15693_transmit");
+
+    NfcCommand ret = NfcCommandContinue;
+    SeaderWorker* seader_worker = seader->worker;
+    SeaderUartBridge* seader_uart = seader_worker->uart;
 
-    /*
     BitBuffer* tx_buffer = bit_buffer_alloc(len);
     BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
-    */
-    NfcCommand ret = NfcCommandContinue;
+
+    //seader_worker_fake_epurse_update(buffer, rxBuffer, &recvLen);
+
+    do {
+        bit_buffer_append_bytes(tx_buffer, buffer, len); // TODO: could this be a `bit_buffer_copy_bytes` ?
+                                                     //
+        PicopassError error = picopass_poller_send_frame(
+            seader->picopass_poller, tx_buffer, rx_buffer, SEADER_POLLER_MAX_FWT);
+        if (error == PicopassErrorIncorrectCrc) {
+          error = PicopassErrorNone;
+        }
+        FURI_LOG_I(TAG, "picopass_poller_send_frame %d", error);
+
+        if(error != PicopassErrorNone) {
+          ret = NfcCommandStop;
+          break;
+        }
+
+        FURI_LOG_I(TAG, "picopass incoming %d bytes", bit_buffer_get_size_bytes(rx_buffer));
+
+        // seader_capture_sio(buffer, len, rxBuffer, credential);
+        seader_send_nfc_rx(seader_uart, (uint8_t*)bit_buffer_get_data(rx_buffer), bit_buffer_get_size_bytes(rx_buffer));
+
+    } while(false);
+    bit_buffer_free(tx_buffer);
+    bit_buffer_free(rx_buffer);
+
 
     return ret;
 }
@@ -484,6 +509,9 @@ NfcCommand seader_iso14443a_transmit(
     UNUSED(format);
     UNUSED(seader);
     UNUSED(buffer);
+    FURI_LOG_D(TAG, "seader_iso14443a_transmit");
+    assert(seader);
+    assert(buffer);
 
     BitBuffer* tx_buffer = bit_buffer_alloc(len);
     BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
@@ -516,6 +544,7 @@ 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];
+    FURI_LOG_D(TAG, "seader_parse_nfc_command_transmit %ld", frameProtocol);
 
 #ifdef ASN1_DEBUG
     memset(display, 0, sizeof(display));
@@ -523,37 +552,29 @@ NfcCommand seader_parse_nfc_command_transmit(Seader* seader, NFCSend_t* nfcSend)
         snprintf(display + (i * 2), sizeof(display), "%02x", nfcSend->data.buf[i]);
     }
 
-    char protocolName[8] = {0};
-    memset(protocolName, 0, sizeof(protocolName));
-    (&asn_DEF_FrameProtocol)
-        ->op->print_struct(
-            &asn_DEF_FrameProtocol, &frameProtocol, 1, seader_asn_to_string, protocolName);
-
     FURI_LOG_D(
         TAG,
-        "Transmit (%ld timeout) %d bytes [%s] via %s",
+        "Transmit (%ld timeout) %d bytes [%s] via %lx",
         timeOut,
         nfcSend->data.size,
         display,
-        protocolName);
+        frameProtocol);
 #endif
 
     if(frameProtocol == FrameProtocol_iclass) {
         return seader_iso15693_transmit(
-            seader, nfcSend->data.buf, nfcSend->data.size, (uint16_t)timeOut, nfcSend->format->buf);
+            seader, nfcSend->data.buf, nfcSend->data.size);
     } else if(frameProtocol == FrameProtocol_nfc) {
         return seader_iso14443a_transmit(
             seader, nfcSend->data.buf, nfcSend->data.size, (uint16_t)timeOut, nfcSend->format->buf);
+    } else {
+      FURI_LOG_W(TAG, "unknown frame protocol %lx", frameProtocol);
     }
     return NfcCommandContinue;
 }
 
 NfcCommand seader_parse_nfc_off(SeaderUartBridge* seader_uart) {
-    // FURI_LOG_D(TAG, "Set Field Off");
-    // seader_worker_disable_field();
-    // seader_nfc_scene_field_on_exit();
-    // nfc_poller_stop(poller);
-    // nfc_poller_free(poller);
+    FURI_LOG_D(TAG, "Set Field Off");
 
     NFCResponse_t* nfcResponse = 0;
     nfcResponse = calloc(1, sizeof *nfcResponse);
@@ -585,7 +606,7 @@ NfcCommand seader_parse_nfc_command(Seader* seader, NFCCommand_t* nfcCommand) {
     case NFCCommand_PR_nfcSend:
         return seader_parse_nfc_command_transmit(seader, &nfcCommand->choice.nfcSend);
     case NFCCommand_PR_nfcOff:
-        seader_parse_nfc_off(seader_uart);
+        return seader_parse_nfc_off(seader_uart);
         break;
     default:
         FURI_LOG_W(TAG, "unparsed NFCCommand");
@@ -595,7 +616,7 @@ NfcCommand seader_parse_nfc_command(Seader* seader, NFCCommand_t* nfcCommand) {
     return NfcCommandContinue;
 }
 
-bool seader_worker_state_machine(Seader* seader, Payload_t* payload) {
+NfcCommand seader_worker_state_machine(Seader* seader, Payload_t* payload) {
     SeaderWorker* seader_worker = seader->worker;
     FURI_LOG_D(TAG, "seader_worker_state_machine");
     switch(payload->present) {
@@ -603,26 +624,24 @@ bool seader_worker_state_machine(Seader* seader, Payload_t* payload) {
         seader_parse_response(seader_worker, &payload->choice.response);
         break;
     case Payload_PR_nfcCommand:
-        seader_parse_nfc_command(seader, &payload->choice.nfcCommand);
+        return seader_parse_nfc_command(seader, &payload->choice.nfcCommand);
         break;
     case Payload_PR_errorResponse:
-        // TODO: screen saying this was a failure, or maybe start over?
-        if(seader_worker->callback) {
-            seader_worker->callback(SeaderWorkerEventFail, seader_worker->context);
-        }
+        FURI_LOG_W(TAG, "Error Response");
         break;
     default:
         FURI_LOG_W(TAG, "unhandled payload");
         break;
     };
 
-    return false;
+    return NfcCommandContinue;
 }
 
-bool seader_process_success_response_i(Seader* seader, uint8_t* apdu, size_t len) {
+NfcCommand seader_process_success_response_i(Seader* seader, uint8_t* apdu, size_t len) {
     Payload_t* payload = 0;
     payload = calloc(1, sizeof *payload);
     assert(payload);
+    NfcCommand ret = NfcCommandContinue;
     FURI_LOG_D(TAG, "seader_process_success_response_i");
 
     asn_dec_rval_t rval =
@@ -636,13 +655,13 @@ bool seader_process_success_response_i(Seader* seader, uint8_t* apdu, size_t len
             FURI_LOG_D(TAG, "Received payload: %s", payloadDebug);
         }
 #endif
-        seader_worker_state_machine(seader, payload);
+        ret = seader_worker_state_machine(seader, payload);
     } else {
         FURI_LOG_D(TAG, "Failed to decode APDU payload");
     }
 
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
-    return (rval.code == RC_OK);
+    return ret;
 }
 
 bool seader_process_success_response(Seader* seader, uint8_t* apdu, size_t len) {
@@ -714,13 +733,12 @@ 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;
@@ -746,6 +764,7 @@ NfcCommand seader_worker_card_detect(
     uint8_t ats_len) {
     UNUSED(ats);
     UNUSED(ats_len);
+
     SeaderWorker* seader_worker = seader->worker;
     SeaderUartBridge* seader_uart = seader_worker->uart;
     CardDetails_t* cardDetails = 0;
@@ -794,6 +813,7 @@ SeaderPollerEventType stage = SeaderPollerEventTypeCardDetect;
 
 NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void* context) {
     furi_assert(event.protocol == NfcProtocolIso14443_4a);
+    NfcCommand ret = NfcCommandContinue;
 
     Seader* seader = context;
     SeaderWorker* seader_worker = seader->worker;
@@ -838,37 +858,34 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
                     }
                     size_t len = bit_buffer_get_size_bytes(message);
                     uint8_t* payload = (uint8_t*)bit_buffer_get_data(message);
-                    FURI_LOG_D(TAG, "Conversation: message length %d: %p", len, payload);
+                    FURI_LOG_D(TAG, "Conversation: message length %d", len);
 
-                    seader_process_success_response_i(seader, payload, len);
+                    ret = seader_process_success_response_i(seader, payload, len);
                     //bit_buffer_free(message);
                 }
                 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");
-            return NfcCommandStop;
+            ret = NfcCommandStop;
         }
     }
 
-    return NfcCommandContinue;
+    return ret;
 }
 
 NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, void* context) {
     furi_assert(context);
-    NfcCommand command = NfcCommandContinue;
+    NfcCommand ret = NfcCommandContinue;
 
     Seader* seader = context;
     SeaderWorker* seader_worker = seader->worker;
     PicopassPoller* instance = seader->picopass_poller;
 
     if(event.type == PicopassPollerEventTypeSuccess) {
-        FURI_LOG_D(TAG, "PicopassPollerEventTypeSuccess");
 
         if(stage == SeaderPollerEventTypeCardDetect) {
             FURI_LOG_D(TAG, "Card Detect");
@@ -881,6 +898,8 @@ NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, voi
             stage = SeaderPollerEventTypeConversation;
 
         } else if(stage == SeaderPollerEventTypeConversation) {
+            FURI_LOG_D(TAG, "picopass conversation");
+
             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);
@@ -897,21 +916,24 @@ NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, voi
                     }
                     size_t len = bit_buffer_get_size_bytes(message);
                     uint8_t* payload = (uint8_t*)bit_buffer_get_data(message);
-                    FURI_LOG_D(TAG, "Conversation: message length %d: %p", len, payload);
+                    FURI_LOG_D(TAG, "Conversation: message length %d", len);
 
-                    seader_process_success_response_i(seader, payload, len);
+                    ret = seader_process_success_response_i(seader, payload, len);
                     //bit_buffer_free(message);
                 }
                 furi_mutex_release(seader_worker->mq_mutex);
 
-                stage = SeaderPollerEventTypeComplete;
+                //stage = SeaderPollerEventTypeComplete;
+            } else {
+              furi_delay_ms(10);
             }
 
         } else if(stage == SeaderPollerEventTypeComplete) {
             FURI_LOG_D(TAG, "Complete");
-            return NfcCommandStop;
+            view_dispatcher_send_custom_event(seader->view_dispatcher, SeaderCustomEventWorkerExit);
+            ret = NfcCommandStop;
         }
     }
 
-    return command;
+    return ret;
 }

+ 0 - 2
uart.c

@@ -160,13 +160,11 @@ int32_t seader_uart_tx_thread(void* context) {
         if(events & WorkerEvtTxStop) break;
         if(events & WorkerEvtSamRx) {
             if(seader_uart->tx_len > 0) {
-                /*
                 char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
                 for(uint8_t i = 0; i < seader_uart->tx_len; i++) {
                     snprintf(display + (i * 2), sizeof(display), "%02x", seader_uart->tx_buf[i]);
                 }
                 FURI_LOG_I(TAG, "SEND %d bytes: %s", seader_uart->tx_len, display);
-                */
                 seader_uart->st.tx_cnt += seader_uart->tx_len;
                 furi_hal_uart_tx(
                     seader_uart->cfg.uart_ch, seader_uart->tx_buf, seader_uart->tx_len);