Просмотр исходного кода

Cleaup conversation code; add online vs offline to state machine

Eric Betts 2 лет назад
Родитель
Сommit
80e6715580
1 измененных файлов с 60 добавлено и 68 удалено
  1. 60 68
      seader_worker.c

+ 60 - 68
seader_worker.c

@@ -470,7 +470,7 @@ NfcCommand seader_iso15693_transmit(Seader* seader, uint8_t* buffer, size_t len)
     do {
     do {
         bit_buffer_append_bytes(
         bit_buffer_append_bytes(
             tx_buffer, buffer, len); // TODO: could this be a `bit_buffer_copy_bytes` ?
             tx_buffer, buffer, len); // TODO: could this be a `bit_buffer_copy_bytes` ?
-            //
+        //
         PicopassError error = picopass_poller_send_frame(
         PicopassError error = picopass_poller_send_frame(
             seader->picopass_poller, tx_buffer, rx_buffer, SEADER_POLLER_MAX_FWT);
             seader->picopass_poller, tx_buffer, rx_buffer, SEADER_POLLER_MAX_FWT);
         if(error == PicopassErrorIncorrectCrc) {
         if(error == PicopassErrorIncorrectCrc) {
@@ -615,33 +615,40 @@ NfcCommand seader_parse_nfc_command(Seader* seader, NFCCommand_t* nfcCommand) {
     return NfcCommandContinue;
     return NfcCommandContinue;
 }
 }
 
 
-NfcCommand seader_worker_state_machine(Seader* seader, Payload_t* payload) {
+bool seader_worker_state_machine(Seader* seader, Payload_t* payload, bool online) {
     SeaderWorker* seader_worker = seader->worker;
     SeaderWorker* seader_worker = seader->worker;
     FURI_LOG_D(TAG, "seader_worker_state_machine");
     FURI_LOG_D(TAG, "seader_worker_state_machine");
+    bool processed = false;
+
     switch(payload->present) {
     switch(payload->present) {
     case Payload_PR_response:
     case Payload_PR_response:
         seader_parse_response(seader_worker, &payload->choice.response);
         seader_parse_response(seader_worker, &payload->choice.response);
+        processed = true;
         break;
         break;
     case Payload_PR_nfcCommand:
     case Payload_PR_nfcCommand:
-        return seader_parse_nfc_command(seader, &payload->choice.nfcCommand);
+        if(online) {
+            seader_parse_nfc_command(seader, &payload->choice.nfcCommand);
+            processed = true;
+        }
         break;
         break;
     case Payload_PR_errorResponse:
     case Payload_PR_errorResponse:
         FURI_LOG_W(TAG, "Error Response");
         FURI_LOG_W(TAG, "Error Response");
+        processed = true;
         break;
         break;
     default:
     default:
         FURI_LOG_W(TAG, "unhandled payload");
         FURI_LOG_W(TAG, "unhandled payload");
         break;
         break;
     };
     };
 
 
-    return NfcCommandContinue;
+    return processed;
 }
 }
 
 
-NfcCommand seader_process_success_response_i(Seader* seader, uint8_t* apdu, size_t len) {
+bool seader_process_success_response_i(Seader* seader, uint8_t* apdu, size_t len, bool online) {
     Payload_t* payload = 0;
     Payload_t* payload = 0;
     payload = calloc(1, sizeof *payload);
     payload = calloc(1, sizeof *payload);
     assert(payload);
     assert(payload);
-    NfcCommand ret = NfcCommandContinue;
-    FURI_LOG_D(TAG, "seader_process_success_response_i");
+    bool processed = false;
+    FURI_LOG_D(TAG, "seader_process_success_response_i [%s]", online ? "online" : "offline");
 
 
     asn_dec_rval_t rval =
     asn_dec_rval_t rval =
         asn_decode(0, ATS_DER, &asn_DEF_Payload, (void**)&payload, apdu + 6, len - 6);
         asn_decode(0, ATS_DER, &asn_DEF_Payload, (void**)&payload, apdu + 6, len - 6);
@@ -654,21 +661,22 @@ NfcCommand seader_process_success_response_i(Seader* seader, uint8_t* apdu, size
             FURI_LOG_D(TAG, "Received payload: %s", payloadDebug);
             FURI_LOG_D(TAG, "Received payload: %s", payloadDebug);
         }
         }
 #endif
 #endif
-        ret = seader_worker_state_machine(seader, payload);
+        processed = seader_worker_state_machine(seader, payload, online);
     } else {
     } else {
         FURI_LOG_D(TAG, "Failed to decode APDU payload");
         FURI_LOG_D(TAG, "Failed to decode APDU payload");
     }
     }
 
 
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
-    return ret;
+    return processed;
 }
 }
 
 
 bool seader_process_success_response(Seader* seader, uint8_t* apdu, size_t len) {
 bool seader_process_success_response(Seader* seader, uint8_t* apdu, size_t len) {
     SeaderWorker* seader_worker = seader->worker;
     SeaderWorker* seader_worker = seader->worker;
 
 
-    // FIXME: use a more semantic method to break nfc related stuff out
-    if(seader->poller || seader->picopass_poller) {
-        FURI_LOG_I(TAG, "New SAM Message, %d bytes", len);
+    if(seader_process_success_response_i(seader, apdu, len, false)) {
+        // no-op, message was processed
+    } else {
+        FURI_LOG_I(TAG, "Queue New SAM Message, %d bytes", len);
         uint32_t space = furi_message_queue_get_space(seader_worker->messages);
         uint32_t space = furi_message_queue_get_space(seader_worker->messages);
         if(space > 0) {
         if(space > 0) {
             BitBuffer* buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
             BitBuffer* buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
@@ -680,8 +688,6 @@ bool seader_process_success_response(Seader* seader, uint8_t* apdu, size_t len)
             }
             }
             //bit_buffer_free(buffer);
             //bit_buffer_free(buffer);
         }
         }
-    } else {
-        seader_process_success_response_i(seader, apdu, len);
     }
     }
     return true;
     return true;
 }
 }
@@ -810,12 +816,49 @@ typedef enum {
 
 
 SeaderPollerEventType stage = SeaderPollerEventTypeCardDetect;
 SeaderPollerEventType stage = SeaderPollerEventTypeCardDetect;
 
 
+NfcCommand seader_worker_poller_conversation(Seader* seader) {
+    NfcCommand ret = NfcCommandContinue;
+    SeaderWorker* seader_worker = 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_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, FuriWaitForever);
+            if(status != FuriStatusOk) {
+                FURI_LOG_W(TAG, "furi_message_queue_get fail %d", status);
+                return NfcCommandStop;
+            }
+            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", len);
+
+            if(seader_process_success_response_i(seader, payload, len, true)) {
+            } else {
+                ret = NfcCommandStop;
+            }
+            //bit_buffer_free(message);
+        }
+        furi_mutex_release(seader_worker->mq_mutex);
+
+        //stage = SeaderPollerEventTypeComplete;
+    } else {
+        furi_delay_ms(10);
+    }
+
+    return ret;
+}
+
 NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void* context) {
 NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void* context) {
     furi_assert(event.protocol == NfcProtocolIso14443_4a);
     furi_assert(event.protocol == NfcProtocolIso14443_4a);
     NfcCommand ret = NfcCommandContinue;
     NfcCommand ret = NfcCommandContinue;
 
 
     Seader* seader = context;
     Seader* seader = context;
-    SeaderWorker* seader_worker = seader->worker;
 
 
     const Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data;
     const Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data;
     const Iso14443_4aPoller* iso14443_4a_poller = event.instance;
     const Iso14443_4aPoller* iso14443_4a_poller = event.instance;
@@ -841,30 +884,7 @@ NfcCommand seader_worker_poller_callback_iso14443_4a(NfcGenericEvent event, void
             furi_thread_set_current_priority(FuriThreadPriorityLowest);
             furi_thread_set_current_priority(FuriThreadPriorityLowest);
             stage = SeaderPollerEventTypeConversation;
             stage = SeaderPollerEventTypeConversation;
         } else if(stage == SeaderPollerEventTypeConversation) {
         } else if(stage == SeaderPollerEventTypeConversation) {
-            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_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, FuriWaitForever);
-                    if(status != FuriStatusOk) {
-                        FURI_LOG_W(TAG, "furi_message_queue_get fail %d", status);
-                        return NfcCommandStop;
-                    }
-                    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", 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);
+            ret = seader_worker_poller_conversation(seader);
 
 
             // stage = SeaderPollerEventTypeComplete;
             // stage = SeaderPollerEventTypeComplete;
         } else if(stage == SeaderPollerEventTypeComplete) {
         } else if(stage == SeaderPollerEventTypeComplete) {
@@ -881,7 +901,6 @@ NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, voi
     NfcCommand ret = NfcCommandContinue;
     NfcCommand ret = NfcCommandContinue;
 
 
     Seader* seader = context;
     Seader* seader = context;
-    SeaderWorker* seader_worker = seader->worker;
     PicopassPoller* instance = seader->picopass_poller;
     PicopassPoller* instance = seader->picopass_poller;
 
 
     if(event.type == PicopassPollerEventTypeSuccess) {
     if(event.type == PicopassPollerEventTypeSuccess) {
@@ -898,34 +917,7 @@ NfcCommand seader_worker_poller_callback_picopass(PicopassPollerEvent event, voi
         } else if(stage == SeaderPollerEventTypeConversation) {
         } else if(stage == SeaderPollerEventTypeConversation) {
             FURI_LOG_D(TAG, "picopass conversation");
             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);
-                if(count > 0) {
-                    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, FuriWaitForever);
-                    if(status != FuriStatusOk) {
-                        FURI_LOG_W(TAG, "furi_message_queue_get fail %d", status);
-                        return NfcCommandStop;
-                    }
-                    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", len);
-
-                    ret = seader_process_success_response_i(seader, payload, len);
-                    //bit_buffer_free(message);
-                }
-                furi_mutex_release(seader_worker->mq_mutex);
-
-                //stage = SeaderPollerEventTypeComplete;
-            } else {
-                furi_delay_ms(10);
-            }
-
+            ret = seader_worker_poller_conversation(seader);
         } else if(stage == SeaderPollerEventTypeComplete) {
         } else if(stage == SeaderPollerEventTypeComplete) {
             FURI_LOG_D(TAG, "Complete");
             FURI_LOG_D(TAG, "Complete");
             view_dispatcher_send_custom_event(
             view_dispatcher_send_custom_event(